DolphinDB与MongoDB在时序数据上的对比测试

2020-05-22 00:00:00 查询 数据 字段 分区 导入

DolphinDB和MongoDB都是为大数据而生的数据库。但是两者有这较大的区别。前者是列式存储的多模型数据库,主要用于结构化时序数据的高速存储、查询和分析。后者是文档型的NoSQL数据库,可用于处理非结构化和结构化的数据,可以根据键值快速查找或写入一个文档。MongoDB有着自己合适的应用场景。但是市场上缺少的大数据产品,不少用户试图使用MongoDB来存储和查询物联网和金融领域的结构化时序数据。本测试的目的是评估MongoDB是否适合此类海量时序数据集。

时间序列数据库DolphinDB和MongoDB在时序数据库集上的对比测试,主要结论如下:

  • DolphinDB的数据导入速度比MongoDB高出两个数量级。数据量越大,性能差距越明显。数据导出方面,DolphinDB比MongoDB快50倍左右。
  • 磁盘空间占用方面,MongoDB占用磁盘是DolphinDB的2~3倍。
  • 数据库查询性能方面,DolphinDB在4个查询性能测试中速度比MongoDB快30倍;在5个查询性能测试中速度比MongoDB快10~30倍;在12个查询性能测试中速度比MongoDB快数倍;仅在两个点查询测试中,DolphinDB慢于MongoDB。

1. 测试环境

本次测试在单机上进行,测试设备配置如下:

主机:DELL OptiPlex 7060

CPU:Intel(R) Core(TM) i7-8700 CPU@3.20GHZ,6核12线程

内存:32 GB (8GB x 4, 2,666 MHz)

硬盘: 2T HDD (222MB/s读取;210MB/s写入)

OS:Ubuntu 18.04 LTS

DolphinDB选用Linux0.89作为测试版本,所有节点大连接数为128,数据副本设置为2,设置1个控制节点,1个代理节点,3个数据节点。

MongoDB选用Linux4.0.5社区版作为测试版本,shard集群线程数为12,所有服务器的大连接数均为128。MongoDB的shard集群设置为1个config服务器,1个mongos路由服务器,3个分片服务器,其中config服务器设置为有1个主节点和2个从节点的replica集群,3个分片服务器均设置为有1个主节点,1个从节点,1个仲裁节点的replica集群。DolphinDB和MongoDB的参数配置请参考附录1。

2. 数据集

本报告测试了DolphinDB和MongoDB在小数据量级(4.2GB)和大数据量级(62.4GB)下的性能。

对于大小两种数据集,我们测试两种数据库在磁盘分区情况下的性能,查询时间均包含了磁盘IO的时间。为了保证测试的公平,我们在测试前通过linux命令:sync,echo1,2,3 | tee /proc/sys/vm/drop_caches清空页面缓存,目录缓存和硬盘缓存,随后依次执行13条查询,并记录执行的时间。

以下是两个数据集的表结构和分区方法:

设备传感器信息小数据集(CSV文件,4.2G, 3千万条数据)

我们选用TimescaleDB官网提供的devices_readings_big.csv(以下简称readings数据集)和device_info_big.csv(以下简称info数据集)设备传感器数据作为小数据测试集。readings数据集包含3,000个设备在10,000个时间间隔(2016.11.15-2016.11.19)上的传感器信息,包括传感器时间,设备ID,电池,内存,CPU等时序统计信息。info数据集包括3,000个设备的设备ID,版本号,制造商,模式和操作系统等统计信息。

数据来源:docs.timescale.com/v1.1

数据集共3千万 条数据(4.2G),压缩包内包含一张设备信息表和一张设备传感器信息记录表,表结构以及分区方式如下:

readings数据集

info数据集

数据集中device_id这一字段有3000个不同的值,且在readings数据集中重复出现,这种情况下使用string类型不仅占用大量空间而且查询效率低,DolphinDB的symbol类型可以很好地解决占用空间和效率两个问题。

我们在 DolphinDB database 中采用组合分区,将time字段作为分区的个维度,按天分为 4 个区,再将device_id作为分区的第二个维度,每天一共分 10 个区,后每个分区所包含的原始数据大小约为100MB。

我们在MongoDB中同样采用组合分区的方式,将time作为分区的维度,根据日期进行范围分区,再将设备ID作为第二分区维度,根据设备ID进行范围分区。MongoDB的范围分区是根据块的大小进行分区的,当数据块大小大于某个阈值,数据库会自动将一个大的数据块分为两个小的数据块,实现分区。经过测试,我们发现当chunkSize(数据块分区阈值)为1024时,性能佳。终,readings数据集总共分为17个分区。

MongoDB要求分区字段必须建立索引,因此我们建立日期+设备ID的复合索引,复合索引可以加快查询速度,但是MongoDB在建立索引时会消耗时间和空间。readings数据集分区建立time_1_device_id_1增序索引耗时为5分钟,占用空间大小为1.1G。建立索引的脚本如下所示:

use device_pt
db.device_readings.createIndex({time:1,device_id:1}

相关文章