面向物联网设备的通用云平台接入服务研究及实现
2020-06-22闫佼
摘要:为了解决随物联网快速发展而来的海量设备接入难题,在集群模式的架构下,如何最大化的提高单台服务器的接入能力,成为研究的重要方向之一。本文分析了目前主流编程语言的执行效率、IO复用模型、线程池模型、内存数据库存取模型等相关技术,提出了一种适合物联网设备接入的通用服务结构设计,并以实际应用案例进行验证,达到了预期的效果。
关键词:物联网;云平台;设备接入;高并发
中图分类号:TP311.1 文献标识码:A 文章编号:1007-9416(2020)04-0000-00
0 引言
随着物联网技术及市场的发展,海量异构设备需要接入云平台进行统一管理。目前云平台架构中的分布式处理、集群化等技术对于设备的并发连接和数量规模有了大幅提升,但仍然存在接入服务处理效率低、延时较大等问题。而物联网提出的物物相互联接,相互通信感知,甚至相互操作的特点,不仅大大增加了通信量,还大幅提高了对于通信低延时的需求。基于这个现状,需要有针对性地讨论并设计基于物物联接的通用性云平台接入服务。
本文从单台服务器系统入手,重点分析了不同语言技术的执行效率,Linux系统IO复用、线程池技术和内存数据库存取等模型,阐述如何较大幅度提升物联网设备TCP连接管理及数据处理效率,并通过实际数据进行测试验证。
1 语言选择
JAVA语言拥有跨平台性、安全性高、网络移动性等众多的优点。C语言具有代码简洁,执行速度快,功能丰富、表达力强等优点。在选用语言的时候,应该将项目的需求与语言的特点结合起来,充分发挥语言的优点[1]。对于服务于物联网设备的通用云平台接入应用,执行效率是最优先评判的指标,在这一方面C语言优势明显。
从资源及框架选择方面,虽然C的资源库没有JAVA的资源库丰富,但是在针对本文项目所用到的I/O多路复用等相关技术方面,也有比较成熟稳定的工具库,例如LibEvent等。并且C语言在操作指针方面的天然特性,可大大提升程序开发中的灵活性。
实际项目应用方面,使用C为基础语言编写的Linux内核、Redis内存数据库等众多著名项目,稳定可靠,性能极致,被广泛使用。故本文选取C语言作为物联网云平台接入服务的基础开发语言。
2 I/O多路复用
在Linux系统中,使用VFS机制,将所有磁盘文件和各类I/O设备统一抽象为文件,并通过文件描述符进行操作。多路复用就是同时监视多个I/O文件描述符,根据文件描述符的设定状态进入执行或休眠。
Linux内核中实现I/O多路复用主要有三种机制模型:select、poll和epoll。select机制主要逻辑是:当有相应的数据可以操作时,则进行读写操作;若没有,则强制sleep。虽然select实现了I/O多路复用,但其效率相对较低,每次都需要遍历整个文件描述表,直到找到目标。并且每次返回都会修改fd_set,需要额外的存储和拷贝,才能重复利用。
poll机制改良了select的一些缺点,可以不需要备份fd_set,但依然需要遍历整个文件描述符表,查询效率没有提升。
epoll机制改进了遍历整个文件描述符表的缺点,不仅效率大幅提升,而且还实现了更为健壮的接口,并新加触发功能,提升了使用方面的灵活性。
I/O多路复用最大的特点就是大幅减少了多线程并发的系统开销,但是由于其并没有实现真正的多任务,所以当并发压力大时,响应会变慢。所以选择线程池技术模型有望实现多任务的I/O多路复用,最大化地提升整个系统对于I/O的并发处理能力。
使用I/O多路复用技术的主要设计思路是尽可能保证系统对于I/O处理的开销不随TCP连接数或设备数量的增加而過快增长。
3 线程池
为了避免多线程服务收到请求后创建新线程的系统开销,在应用程序启动后,马上创建一定数量的线程,当有任务需要处理时,预先分配或临时分配目标线程,待任务处理完成后,线程并不退出,继续等待后续任务。使用负载均衡算法和内部线程间通信,动态地调整线程的负载,实现静态代码功能与动态实例的有效分离。
使用线程池的主要设计思路是尽可能保证线程的数量不随TCP连接数或设备数量的增加而过快增长,将系统的线程开销限制在可控范围内。
4 内存数据库存取模型
数据库操作是云平台系统不可或缺的一环,特别是内存数据库在提升系统处理能力方面发挥着重大的作用。大量研究集中于此,例如Tingli Li等提出基于NoSQL的物联网数据处理框架IOTMDB[2];Suna Yin等提出基于NoSQL的分布式物联网数据处理框架STNoSQL[3];田野等提出基于NoSQL、REST的物联网数据存储与共享策略[4]。研究数据库存取模型的主要思路是从系统角度,找到效率较低的处理环节,并提出优化方案。
在内存数据库中,Redis、Mongo使用量较大,特别是Redis数据库在key-value存取模型中速度远远胜出,适用于数据变化快且数据库大小可预见的应用程序中。
根据上述特点,本文使用Redis数据库保存热数据,例如socket fd与网关mac的对应关系等。由于云平台接入服务需要同时处理尽可能多的设备连接或设备数据帧,而且处理的数量会随设备连接数量的增加而不可避免地增加,所以对于这部分逻辑的每一点优化进步,都会对最终的处理效率产生较大影响。
本文深入研究Redis数据库部分实现逻辑,发现其对数据的增删改查操作主要通过对数据key字符串进行hash操作,生成的结果作为数组下标对表进行寻址。遇到冲突的表项则将两数据链接,作为链表进行保存。当冲突项大于一定数量后,扩容表空间,进行重hash操作。同时当统计占用量小于一定百分比时,缩减表空间,并进行重hash操作,以减少对资源的占用。
5 设備接入服务模型
本文在综合上述要点分析后,提出一种基于I/O多路复用和线程池技术的设备接入服务模型。网络处理部分主要业务逻辑如图1所示。首先在初始化时,由主线程一次性创建多个子线程。每个子线程中使用管道建立一对读写接口,并对这对接口进行读事件监控。同时在子线程中建立客户端连接描述符管理队列,用于管理已经建立TCP连接的设备。
主线程负责监听TCP端口,当有连接请求时,获取相应的客户端连接描述符,通过负载均衡算法,将其发送至选择的工作线程。负载均衡算法主要解决多个工作线程的负载均衡问题,简单实现可按照每个线程的实际client fd个数,保证每个线程都有相同数量的连接数。但由于每个网关设备下面连接的子设备数量不同,所以改进算法可在每个工作线程统计实际的连接设备数量,以平均分配每个工作线程所处理的设备数量。还可以各自统计工作线程的实际执行时间,将新的连接分配给执行时间最少的工作线程。目前本文实现的是以实际子设备数量进行平均。
当工作线程监控到管道的读事件后,将收到的客户端连接描述符取出,构造连接结构体,并完成socket的后续连接动作后,将其加入连接队列中,监控其事件。连接结构体与实际的业务相关,本文的连接结构体定义如图2所示。其中主要属性有连接描述符sfd,用于记录client的连接;互斥mutex信号量lock,用于对共用数据加锁,以保证多线程操作结果的一致性;libevent的连接事件管理和数据缓冲区,用于监控连接的读事件和错误事件,并触发相应的回调进行处理;本连接状态机状态指示state;双向链表的前后指针,用于在某些轮询逻辑中进行遍历;所属的线程描述结构体指针,用于标识与线程本身的关系等。其它属性是具体业务需要暂时保存的属性变量,例如realTimeCmdQueue也是个队列,记录了当前连接需要串行发送的命令列表;gatewayType记录了当前连接的网关的设备类型等等。
经过上述处理后,实际上每个线程的实例与一定数量的设备客户端TCP连接实例进行了绑定,每当设备需要有数据交互时,相应的工作线程可直接触发进行处理,大大降低了创建、销毁线程带来的系统开销,较大程度的提升了系统TCP连接处理能力。
6 缓存处理模型
经过对Redis数据库模型的深入分析,发现其在数据增删改查操作时的复杂度主要集中于Hash算法部分逻辑,其时间复杂度基本为常数。远远小于关系型数据库的投影等算法的时间复杂度。本文在追求极致高效的设备TCP连接处理能力的驱动下,将Redis主要数据结构,例如集合、列表等的增删改查操作主要逻辑移植到自主设计的设备接入模型中,并根据实际情况进行了修改调整,同时使用单独线程进行调度处理。编写了测试程序,与直接使用Redis数据库服务本身的相同操作进行对比测试,力求寻找缓存操作本身与socket通信对于系统CPU时间占用的相对比较数据。
测试程序主要逻辑是先打印系统时间,精确到us。使用新设备接入模型的缓存操作接口进行普通key-value数据、集合、列表等相关操作39项。打印系统时间。再直接使用Redis数据库操作接口hiredis进行相同的39项操作。打印系统时间。最后得到的时间如表1所示。
经过计算,使用设备接入模型的单项操作时间平均值约为22.36us,使用hiredis模型的单项操作时间平均值约为194.9us。经过多次测试基本维持上述数据。同时为了避免不同负载下可能对于hash冲突的解决时间产生影响,本文测试时,已经将Redis数据库本身的数据内容全部清除,基本可保证两个模型测试环境相同。
根据上述验证结果,基本可断定两次socket通信本身所花费的CPU时间远大于缓存数据操作的时间,约为缓存数据操作时间的8倍。缓存数据操作在设备接入处理服务中属于规模较大的操作逻辑,所有的设备信息都需要通过这个模型进行实时的存取,此处的大幅优化,对整个服务的处理能力的明显提升做于重大贡献。
7 结语
为了解决随物联网快速发展而来的海量设备接入问题,本文从群集化部署和单机接入性能提升两个方面进行了研究改进,提出了基于I/O多路复用和线程池的接入服务模型。同时根据实际测试结果,将缓存操作原理移植入接入服务模型,可使得接入服务处理能力得到了很大提升。
通过在实际项目中的长期运行,及与相似云平台系统对比,使用本文研究结果实施的物联网云平台系统在接入处理方面能力明显占优势。下一步将继续研究优化,寻找CPU占用环节,为得到更极致的接入处理能力而努力。
参考文献
[1]卢晓苗,李从龙,张建明.一例Java语言与C语言代码运行效率的比较[J].现代计算机,2010,01:116-118.
[2] Tingli Li,Yang Liu,Ye Tian,Shuo Shen,Wei Mao.A Storage Solution for Massive IoT Data Based on NoSQL[M].Proceedings of the IEEE International Conference on Internet of Things, 2012:50-57.
[3] Suna Yin,Dehua Chen,Jiajin Le.STNoSQL:Creating NoSQL database on the Sensible Things platform[C].IEEE Ieee/acis International Conference on Software Engineering,Artificial Intelligence,Networking and Parallel/Distributed Computing,2016:669-674.
[4]田野,袁博,李廷力.物联网海量异构数据存储与共享策略研究[J].电子学报,2016,44(2):247-257.
收稿日期:2020-02-12
作者简介:闫佼(1985—),男,河北邢台人,研究生,工程师,研究方向:物联网系统设计及应用。
Research and Implementation of General Accessing Cloud Services for IOT Devices
YAN Jiao
(Shanghai Shuncom Smart Technology Co., Ltd,Shanghai 201203)
Abstract: For solving the problem of huge intelligent equipment connecting with the rapid development of the IOT. Based on the cluster architecture, elevating single server ability of device accessing is an important manner. This paper studies the execution efficiency of the mainly used programming languages, I/O multiplexing model, thread pool model, main memory database (MMDB) accessing model and presents a general service for IOT device accessing. The expected service effect is proved when checking with the real application cases.
Key words: internet of things;cloud platform;device accessing;giant concurrent