摘 要:本文设计了一种海量传感器数据存储系统,使用MongoDB作为数据库,同时使用Boos.Asio网络库应对终端高并发请求。
【关键词】MongoDB Asio 传感器数据 存储系统
1 引言
在物联网当中,每个终端节点每隔几秒钟就会将多个传感器采集的数据传输到服务器中,在大量终端节点的情况下会产生海量的数据。传统关系型数据库已经无法满足海量数据的存储和管理,MongoDB是专门为解决海量数据而产生的,本系统使用MongoDB存储海量传感器数据。服务器端必须能够处理大量终端节点的高并发请求,本系统使用Boost.Asio网络库应对终端海量高并发请求。
2 MongoDB及其部署
2.1 MongoDB简介
MongoDB的文档、集合相当于关系型数据库中的行和表,其文档使用BSON格式存储,其典型格式如:{ id:123,temperature:23, humidity: 60}。可见其非常适合物联网终端节点的传感器数据的存储。
MongoDB通过分片(Shard)和副本集(replica set)实现对数据的备份和高性能处理。分片,就是将一份数据分成多个片段,每个分片储存不同的部分,分片不仅分担了数据在硬盘的存储,还分担了数据操作对机器内存、CPU、网络的IO和硬盘的读写压力。如图1所示。
2.2 MongoDB集群部署
典型的MongoDB集群部署模型如图1所示。每个分片就是mongod程序的实例,在进行数据的增删查改操作时需要通过mongos程序将请求分发到对应的分片上,mongos起到了路由的功能,它需要从配置服务器(config server)读分片和路由等元数据信息。replica set就是数据的备份,也是mongod程序的实例。在生产环境下根据业务的需求来确定服务器的数量和mongos、mongod以及config server的数量。在程序连接数据库时,只要连接mongos的地址和端口即可。
3 程序设计
本程序的主要功能是处理终端海量的高并发请求,将数据解析后写入MongoDB数据库。
3.1 Boost.Asio简介
Boost.Asio是一款非常优秀的C++开源网络库,支持同步编程和异步编程,能够构建出能够承受数千并发连接的应用程序,并且不必涉及显式锁定和线程并发模型,从而避免使用多线程编程带来的死锁、条件竞争等。
3.2 配置模块和日志模块设计
在程序中,服务器端口号、MongoDB集群地址、程序并发执行线程数等配置信息采用JSON格式文件存储。使用Boost库中的property_tree作为程序解析JSON文件的工具。日志可以帮助程序员在开发中快速定位bug,本程序使用boost::log记录日志。
3.3 MongoDB模块设计
在高并发请求下,为避免每次请求到来频繁连接和关闭数据库,MongoDB的C++驱动提供了线程安全的连接池。本模块设计了Mymongo类,内部封装了mongo::ScopedDBConnection类,实例化该类,便获得一个数据库连接。在Mymongo类的构造函数中完成对数据库的连接认证等,在析构函数中释放连接到连接池。本程序只需要将终端数据插入到数据库中,因此Mymongo类只实现了数据的插入功能。
3.4 请求处理模块
本模块实现了Service类,包含start()、accept_handler()、read_handler()三个成员函数。使用该类时,其执行流程如图2所示:首先执行其start成员函数,在函数中采用异步accept方式等待连接到来,其回调函数为accept_handler,当连接到来后,执行回调函数,在其中采用异步方式读取套接字,并注册回调函数read_handler,因为是异步读取,不等待读取完毕,再次调用start函数,等待下一个连接到来。当套接字读取完毕后,会调用read_handler,在函数中会解析终端发来的请求,并使用Mymongo类将数据写入MongoDB数据库。如图2所示。
3.5 io_service模型选择
io_service类是Boost.Asio的核心,相当于前摄器模式中的Proactor角色,asio的任何操作都需要其参与。在主函数中首先实例化一个io_service对象,在实例化Service对象时作为其参数,启动Service对象的start()函数后,在多个线程中调用这个io_service对象的run()函数。这相当于在多个线程中同时阻塞等待异步操作的完成,当有异步操作完成时,便会调用相应的回调函数。这是其最为常用的模型,可以编写出非常健壮的应用程序,本程序选择一个io_service实例多个线程的模型。
4 结语
本文所设计的传感器数据存储系统,使用了MongoDB数据库存储管理海量数据,并使用Boost.Asio网络库的异步编程方式,配合多线程技术,编写了能够接收海量高并发请求的服务器端程序,在程序中使用MongoDB连接池来连接数据库,避免资源的浪费。
参考文献
[1]郭匡宇.基于MongoDB的传感器数据分布式存储的研究与应用[D].南京邮电大学,2013.
[2]MongoDB.sharding. https://docs.mongodb.org/manual/core/sharding-introduction/.
[3]Boost.Asio. http://www.boost.org/doc/libs/1_57_0/doc/html/boost_asio.html.
作者简介
李晓(1989-),男,现为中国海洋大学信息科学与工程学院信号与信息处理专业在读研究生。
作者单位
中国海洋大学信息科学与工程学院 山东省青岛市 266100