DolphinDB和MongoDB都是为大数据而生的数据库。然而两者有这较大的区别。前者是列式存储的多模型数据库,次要用于结构化时序数据的高速存储、查问和剖析。后者是文档型的NoSQL数据库,可用于解决非结构化和结构化的数据,能够依据键值疾速查找或写入一个文档。MongoDB有着本人最合适的利用场景。然而市场上短少优良的大数据产品,不少用户试图应用MongoDB来存储和查问物联网和金融畛域的结构化时序数据。本测试的目标是评估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,版本号,制造商,模式和操作系统等统计信息。

数据起源:https://docs.timescale.com/v1.1/tutorials/other-sample-datasets

数据集共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_ptdb.device_readings.createIndex({time:1,device_id:1}

股票交易大数据集(CSV文件,62.4G,16亿条数据)

咱们选用纽约证券交易所(NYSE)提供的2007.08.07-2007.08.10四天的股市Level1报价数据(以下简称TAQ数据集)作为大数据测试集,数据集蕴含8,000多支股票在4天内的交易工夫,股票代码,买入价,卖出价,买入量,卖出量等报价信息。

数据集有4个csv文件,每个文件在14G到17G之间,总共大小为62.4G,大概16亿条数据,每个CSV文件保留一个交易日的交易信息,数据来源于(https://www.nyse.com/market-data/historical)。TAQ数据集构造如下所示:

在DolphinDB中,咱们采纳组合分区,将date字段作为分区的第一维度,每天一个分区,共四个分区,再将symbol字段作为分区的第二维度,依据范畴分区,每天分为100个分区。最初总共分为400个分区,每个分区大概40MB。

在MongoDB中同样采纳组合分区形式,分区维度与DolphinDB雷同,将chunkSize设置为1024,总共分为385个分区。

MongoDB在对TAQ数据集分区时建设date_1_symbol_1增序索引耗费的工夫为53分钟,占用空间大小为19G,建设索引的脚本如下所示:

use taq_pt_dbdb.taq_pt_col.createIndex({date:1,symbol:1}

3. 数据库导入导出性能比照

3.1 导入性能

在DolphinDB中应用以下脚本导入:

timer {    for (fp in fps) {        job_id_tmp = fp.strReplace(".csv", "")        job_id_tmp1=split(job_id_tmp,"/")        job_id=job_id_tmp1[6]        job_name = job_id        submitJob(job_id, job_name, loadTextEx{db, `taq, `date`symbol, fp})        print now() + ": 已导入 " + fp    }    getRecentJobs(size(fps))}

在MongoDB导入TAQ数据集时,为了放慢导入速度,将63G的数据分为16个小文件导入,每个文件大小在3.5G~4.4G之间,而后应用以下脚本导入:

for f in /media/xllu/aa/TAQ/mongo_split/*.csv ; do        /usr/bin/mongoimport         -h localhost         --port 40000         -d taq_pt_db         -c taq_pt_col         --type csv         --columnsHaveTypes         --fields "symbol.string(),date.date(20060102),time.date(15:04:05),bid.double(),ofr.double(),bidsiz.int32(),ofrsiz.int32(),mode.int32(),ex.string(),mmid.string()"         --parseGrace skipRow         --numInsertionWorkers 12         --file $f    echo "文件 $f 导入实现"done

导入性能如下表所示:

从上表可得,DolphinDB在导入结构化的时序数据时,速度远快于MongoDB,上面从几个方面剖析导入后果。

(1)横向比拟

因为两个数据集的字段数量和字段类型不一样,readings数据集多为字符串类型,TAQ数据集多为数值类型,相比于字符串类型,数值类型导入更快,因而能够看到MongoDB和DolphinDB在导入TAQ数据集时,速率更快。

(2)纵向比拟

MongoDB属于文档型数据库,导入速度受文档数量的影响很大,能够看出导入3千万条记录大概需1小时,导入16亿条记录大概需55小时,记录条数相差大概53倍,导入工夫相差约55倍,思考到每条记录字段类型和数据的影响,能够认为导入速度和记录条数大概成正比。

DolphinDB属于列式数据库,存储这种结构化的数据时,DolphinDB会将一个字段当成一个列,存储在一个列文件中。导入readings数据集时创立了12个列文件,导入TAQ数据集时,创立了10个列文件,列文件数量相差不多。导入4.2G数据,须要63秒,导入62.4G数据,须要11分30秒。数据集大小相差大概14.8倍,导入工夫相差大概11倍,思考到列文件数量和存储类型的不同,能够认为导入工夫和文件大小大概成正比。

DolphinDB在导入时序结构化数据时,在列字段类型和数量相差不大的状况下,导入工夫和文件大小成正相干,合乎列式存储数据库的特点。MongoDB在导入时序结构化数据时,在字段相差不大的状况下,导入工夫和记录条数成正相干,合乎文档型存储数据库的特点。

(3)MongoDB导入绝对迟缓的起因剖析

DolphinDB采纳列式存储,效率远远高于MongoDB的文档型存储。MongoDB依照记录逐条导入,在记录条数很大的状况下,MongoDB数据导入时长减少,性能降落。

MongoDB在sharding集群配置时,必须开启journaling日志,先写入记录再进行导入操作,升高了其导入速度。

因为MongoDB属于NoSQL数据库,其没有主键概念,为了保障唯一性束缚,数据在导入时必须创立一个数据库主动生成的惟一索引来表征每一条记录,数据导入和索引必须同时进行,因而升高了导入速度。

3.2 导出性能

在DolphinDB中应用以下脚本进行数据导出:

timer saveText((select * from t),"/media/xllu/aa/device/device_readings_out.csv")

在MongoDB中应用以下脚本进行数据导出:

mongoexport -h localhost:40000 -d db_nopt -c device_readings -o /media/xllu/aa/device/device_readings_mongo_out.csv

小数据集导出性能如下表所示:

4. 数据库磁盘空间占用比照

数据库磁盘空间占用性能比照次要比照DolphinDB和MongoDB数据库导入readings数据集和TAQ数据集这两种大小的数据集后,在分区状况下各数据库中的数据所占磁盘空间的大小。磁盘占用指标为数据在磁盘中的大小。

DolphinDB间接通过读取所有列式数据文件的大小获取,MongoDB通过db.stats()取得数据存储的大小。两个数据库均有一个备份,MongoDB中数据存储大小还包含索引的大小。测试后果如下表所示:

雷同数据量,MongoDB的磁盘占用空间大概是DolphinDB的2~3倍,次要有以下起因:

(1)DolphinDB采纳列式存储形式,每个列有固定的类型,通过LZ4压缩算法,将每个字段依照类型压缩存储为一个列文件。并且针对symbol类型,还采纳位图压缩算法解决存储空间占用的问题,进一步提高了压缩率。MongoDB本次测试采纳的是WiredTiger存储引擎,选用snappy压缩算法。

(2)MongoDB中建设分区数据库均要对分区字段建设索引,进一步导致其存储空间变大,经剖析发现,readings数据集对time和device_id字段建设的索引大小为1.1G,TAQ数据集对date和symbol字段建设的索引大小为19G。

5. 数据库查问性能

对于readings数据集和TAQ数据集,咱们比照了以下8种罕用的SQL查问。

1、点查问:依据某一字段的具体值进行查问。

2、范畴查问:依据一个或者多个字段的范畴依据工夫区间进行查问。

3、聚合查问:依据数据库提供的针对字段列进行计数,平均值,求和,最大值,最小值,标准差等聚合函数进行查问。

4、精度查问:依据不同标签维度列进行数据聚合,实现高维或者低维的字段范畴查问,测试有hour精度,minute精度。

5、关联查问:依据不同的字段,在进行雷同精度,雷同的工夫范畴内进行过滤查问的根底上,筛选出有关联关系的指标列并进行分组。

6、比照查问:依据两个维度将表中某字段的内容重新整理为一张表格(第一维度作为列,第二维度作为行)

7、抽样查问:依据数据库提供的数据采样API,能够为每一次查问手动指定采样形式进行数据的稠密解决,避免查问工夫范畴太大数据量过载的问题。

8、经典查问:理论业务中罕用的查问。

执行工夫是以毫秒为单位的。为了打消网络传输等不稳固因素的影响,查问性能比拟的工夫指标为服务器执行某个查问的工夫,不包含后果传输和显示的工夫。

4.2G设施传感器信息小数据集查问测试

对于小数据集的测试,咱们均测试磁盘分区数据,执行工夫包含了磁盘IO的工夫。为了保障测试的准确性和公正性,每次启动测试前均通过Linux系统命令sync;echo 1,2,3 | tee /proc/sys/vm/drop_caches革除零碎的页面缓存,目录项缓存和硬盘缓存,启动程序后一次执行样例一遍,并记录执行的工夫。

DolphinDB中应用以下脚本失去数据库句柄:

dp_readings = "dfs://db_range_dfs"device_readings=loadTable(dp_readings, `readings_pt) 

MongoDB中执行use device_pt语句切换数据库至device_pt数据库。在执行关联查问时,因为info数据集的数据量较小,因而能够把数据加载到内存中。在MongoDB中执行db.device_info.find({})将3,000条设施记录全副加载,在DolphinDB中执行loadText(dp_info)将3,000条设施记录加载至内存。在DolphinDB中应用timer计算查问执行耗时,在MongoDB中应用explain()函数获取执行工夫。上面是DolphinDB在小数据集上的查问脚本,MongoDB的查问脚本见附录。

查问性能如下表所示:

对于范畴查问,在包含了分区字段的查问中,如查问3,4所示,MongoDB能够调用复合索引,DolphinDB能够通过分区字段放慢查问,这种状况下两个数据库的差距在4倍之内,并不是很大。在包含了未分区字段的查问中,如查问5所示,MongoDB没法调用未分区字段的索引,须要进行全字段搜寻过滤,DolphinDB则无需搜寻不在where过滤条件中的字段,这种状况下DolphinDB和MongoDB的差距进一步扩充。能够看出在解决这种结构化时序数据时, DolphinDB采取的列式存储的形式的效率比MongoDB建设索引的形式更加高效,也更加实用于多维结构化数据的查问。

对于点查问,在查问1中,MongoDB在建设有time+device_id索引的状况下能够疾速的找到某个工夫点的记录,DolphinDB中依照日期分为4天,查找某一天的具体的工夫点须要选定一个分区再进行检索,这种状况下DolphinDB比MongoDB慢。在查问2中,MongoDB的过滤字段仅为设施ID,没有包含time字段,咱们从explain()中发现查问过程中没有调用复合索引,这是因为查问字段必须包含复合索引的首字段,索引才会起作用,查问1仅仅依据设施ID过滤,不波及time字段的过滤, MongoDB不会调用复合索引,因而这种状况下,DolphinDB比MongoDB快。

对于关联查问,MongoDB作为NoSQL数据库,仅反对左外连贯,并且因为其没有关系型数据库的主键束缚,要实现表连贯查问只能应用内嵌文档的形式,这种形式并不利于计算和聚合。DolphinDB作为关系型数据,其反对等值连贯,左连贯,全连贯,asof连贯,窗口连贯和穿插连贯,表连贯查问功能丰富,能够高效不便地解决海量结构化时序数据。从查问9~10中咱们能够看出DolphinDB快于MongoDB,并且关联查问越简单,性能差距越大。

对于抽样查问,MongoDB能够在aggregation函数中通过sample语句实现抽样查问,抽样形式取决于汇合的大小,N(抽样数)的大小和sample语句实现抽样查问,抽样形式取决于汇合的大小,N(抽样数)的大小和sample语句在pipeline中的地位。DolphinDB不反对全表抽样,仅反对分区字段抽样。因为两种数据抽样查问的实现过程差异较大,所以不做比拟。

对于插值查问,MongoDB并没有内置的函数能够实现插值查问,而 DolphinDB 反对 4 种插值形式,ffill 向后取非空值填充、bfill 向前去非空值填充、lfill 线性插值、nullFill 指定值填充。

对于比照查问,MongoDB作为文档型数据库,其存储单元是文档,汇合中蕴含若干文档,文档采纳BSON格局,没有行和列的概念,因而无奈实现抉择两个维度将表中某字段的内容整顿为一张表(第一个维度作为列,第二个维度作为行)的性能。DolphinDB中内置有pivot by函数语句,选定分类的维度能够不便的将制订内容整顿为一张表。因为MongoDB不反对比照查问,所以不做比拟。

62.4G股票交易大数据集查问测试

DolphinDB中应用以下脚本失去数据库句柄:

taq_pt_db= "dfs://db_compound_dfs"taq_pt_col=loadTable(taq_pt_db, `readings_pt) 

MongoDB中执行use taq_pt_db语句切换数据库至taq_pt_db数据库。

大数据集DolphinDB的查问脚本如下所示:

查问性能如下表所示:

在大数据量,两个数据库均做了分区的状况下,DolphinDB仍然比MongoDB大概快5-20倍。查问1是依据日期,股票代码进行的点查问,这种状况下MongoDB和DolphinDB的性能差距不大,DolphinDB略慢于MongoDB,这是MongoDB进行复合分区时会建设date+symbol复合索引能够较为疾速的找到后果,是MongoDB比拟好的利用场景,然而比照查问5~9可知,MongoDB的计算性能仍不如DolphinDB,差距大概在10-20倍之间。

6. 小结

工夫序列数据库DolphinDB和MongoDB在时序数据库集上的比照测试,次要论断如下:

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

在解决结构化的时序数据时,无论是数据导入导出、磁盘空间占用还是查问速度,DolphinDB的性能都比MongoDB更加优越。然而,MongoDB作为文档型的NoSQL数据库,在数据模型多变的场景下以及解决非结构化数据方面更有劣势。

附录

1. DolphinDB环境配置

  • controller.cfg
  • agent.cfg
  • cluster.cfg
  • cluster.nodes

2. MongoDB环境配置

  • 分片服务器配置:

    • 主节点:master_shard.txt
    • 从节点:slave_shard.txt
    • 仲裁节点:arbiter_shard.txt
  • 路由服务器配置:master_mongos.txt
  • 配置服务器:

    • 主节点:master_config.txt
    • 从节点:slave_config.txt
    • 仲裁节点:arbiter_config.txt

3. DolphinDB分区脚本

  • readings分区脚本
  • TAQ分区脚本

4. MongoDB分区脚本

  • readings分区脚本
  • TAQ分区脚本

5. MongoDB查问脚本

  • readings查问脚本
  • TAQ查问脚本