Elasticsearch是一款很是流行的日志检索和分析工具,尤为在实时性、扩展性、易用性和全文检索方面有着很是优异的综合表现。知乎上有一篇文章,Golion:降维打击!使用ElasticSearch做为时序数据库,而且取得了很是不错的效果。不少知乎用户不由询问,Elasticsearch是否能够用于海量金融数据的存储和分析?git
为此咱们对DolphinDB和Elasticsearch在不一样规模的金融数据集作了综合的对比测试。测试的内容包括I/O,磁盘空间占用,内存消耗,数据库查询(过滤查询和分组统计)4大项。测试结果没有意外,在金融数据处理领域表现十分抢眼的时序数据库DolphinDB完胜Elasticsearch。github
1.1 DolphinDB简介数据库
DolphinDB是一款分析型的分布式时序数据库,采用列式存储,内置流数据处理引擎,并行计算和分布式计算引擎,并提供分布式文件系统,支持集群扩展。DolphinDB以C++编写,响应速度极快。提供类SQL和Python的脚本语言对数据进行操做。提供其它经常使用编程语言的API,方便与已有应用程序集成。在金融领域中的历史数据分析建模与实时流数据处理,以及物联网领域中的海量传感器数据处理与实时分析等场景中表现出色。编程
1.2 Elasticsearch简介服务器
Elasticsearch是一个基于Lucene的搜索服务器,它是基于本地磁盘存储数据的分布式系统,并面向文档进行存储。它和传统的数据库有如下相似的对比关系:app
Relational DB =>Databases =>Tables => Rows => Columns编程语言
Elasticsearch =>Indices=>Types=>Documents => Fields分布式
Elasticsearch集群能够包含多个索引(Indices),对应DolphinDB的数据库;每个索引能够包含多个类型(Types),对应DolphinDB中的表;每个类型包含多个文档(Documents),对应DolphinDB数据中的行;而后每一个文档包含多个字段(Fields),对应DolphinDB中的列的概念。ide
2.1 硬件配置函数
本次测试的硬件配置以下:
设备:DELL OptiPlex 7060
CPU:Inter(R) Core™ i7-8700 CPU @ 3.20GHz,6核心12线程
内存:32GB
硬盘:2TB机械硬盘
操做系统:Ubuntu 16.04 x64
2.2 环境配置
本次的测试环境为单服务器下的多节点集群。为了在单机环境下最大限度地发挥出二者的性能,须要对DolphinDB以及Elasticsearch进行节点参数的设置。设置DolphinDB的数据节点的个数为4个,单个数据节点最大可用内存设置为7 GB。设置Elasticsearch的节点个数为4个,因为Elasticsearch基于Lucene,故须要分配必定内存用于Lucene中的段被加载入内存中,这对Elasticsearch的性能也会形成很大的影响,本次测试分配8 GB内存给Lucene,并设置Elasticsearch中的单个节点的最大可用内存为6 GB,且禁止swapping。
为了更加全面地测试DolphinDB和Elasticsearch的性能,咱们使用了三个不一样规模的股票数据集。数据表CN_Stock中包含了从2008.01.01到2017.12.31中国沪深股票的每日报价数据。数据表US_Prices中包含了从1990.01.02到2016.12.30美国股票市场的每日报价数据。数据表TAQ中包含了2007年8月份的4天美国股票市场level1的高频数据,共60.6 GB。测试数据集的概况以下表所示:
测试数据集在DolphinDB和Elasticsearch中各个字段的数据类型以下所示:
(1)CN_Stock表数据类型映射
(2)US_Prices表数据类型映射
(3)TAQ表数据类型映射
DolphinDB database 提供了灵活的分区机制,包括值分区,范围分区,列表分区,哈希分区和组合分区,而Elasticsearch仅支持基于哈希的分片机制。
在DolphinDB中,对于表CN_Stock,按时间每半年做为一个分区,共分红了20个分区;对于表US_Prices,按时间每一年做为一个分区,共分红27个分区;对于表TAQ,采用日期、股票代码组合分区方式,共100个分区。副本个数设置为1。
Elasticsearch仅容许定义分片的个数。对于表CN_Stock和表US_Prices,定义分片个数为4;对于表TAQ,定义分片个数为100。副本个数设置为1。
咱们从数据库查询性能、I/O性能、磁盘占用空间、以及内存消耗等方面对DolphinDB和Elasticsearch进行了对比测试。
5.1 数据库查询性能测试
DolphinDB脚本语言支持SQL语法,同时还在其基础上进行了必定程度的扩展,功能更增强大。而在Elasticsearch中,须要安装插件来进行SQL语句查询,同时也提供了基于JSON数据格式的DSL(Domain Specific Language特定领域语言)语言来进行查询,本次测试采用DSL语言。
Elasticsearch的主要应用场景为搜索引擎,它支持模糊查询,对于普通的query,Elasticsearch返回的查询hits默认仅为10条;对于聚合查询,其返回的buckets的默认大小也为10。而DolphinDB中每次查询返回的结果都是所有的结果,不存在模糊查询的状况。
在Elasticsearch的聚合查询中,返回结果中存在字段doc_count_error_upper_bound以及sum_other_doc_count,二者分别表示没有在此次聚合中返回、可是可能存在的潜在聚合结果以及此次聚合中没有统计到的文档数。这也很好的证实了Elasticsearch默认的对于数据查询操做仅仅只是对数据库中的部分数据进行模糊查询,而不是精确的查询数据库中的全部数据记录。为了将二者放在公平的环境下进行测试,咱们须要关闭Elasticsearch的模糊查询,处理的方式是采用Elasticsearch中的scroll接口以及定义buckets的大小来对控制Elasticsearch返回所有的查询结果。
在本次测试中,使用了DolphinDB脚本完成了DolphinDB的查询性能测试。使用了Python脚本+DSL来完成Elasticsearch的查询性能测试。
咱们对三张数据表进行了若干种经常使用的SQL查询。为了减少偶然因素对结果的影响,本次查询性能测试对每种查询操做均进行10次查询,而后对总时间取平均值,时间以毫秒为单位。各个测试数据集的测试脚本和结果以下表所示。
(1)CN_Stock表
DolphinDB中的查询脚本:
查询性能测试结果(数据量:5,332,932):
(2)US_Prices表
DolphinDB中的查询脚本:
查询性能测试结果(数据量:50,591,907):
(3)TAQ表
DolphinDB中的查询脚本:
查询性能测试结果(数据量:1,366,036,384):
对于本次的查询性能测试,咱们能够得出如下结论:
(1)在同一张表的全部测试中,DolphinDB的性能都领先Elasticsearch多倍。特别的,对于简单的过滤查询,DolphinDB的性能是Elasticsearch的性能的1~2个数量级(见CN_Stock表测试结果的1~四、US_Prices表测试结果的1~4)。
(2)在有关聚合查询的测试结果中,DolphinDB的性能也都优于Elasticsearch,平均是8~9倍。特别的,按时间分组的聚合查询中,DolphinDB的性能是Elasticsearch的13~15倍(见CN_Stock表测试结果的5~10,US_Prices表测试结果的5~10)。
(3)在不一样的数据规模的相同类型的查询测试中,咱们能够看出随着数据规模的上升,Elasticsearch的精确查询的耗时增加幅度远大于DolphinDB,DolphinDB在不一样数据规模下的稳定性优于Elasticsearch。
5.2 I/O性能测试
Elasticsearch提供了_bulk API批量写入数据的功能。在建立一条新的文档时,首先须要描述文档中可能包含的每一个字段的属性,数据类型(好比 keyword, text, integer 或 date),以及这些字段是否须要被 Lucene 索引或储存。而后Elasticsearch为文档的这些属性构建相应的映射,并建立倒排索引后造成Lucene中的段。最后经过refresh以及flush机制将倒排索引存储于磁盘上。其中将内存中的倒排索引flush到磁盘上这一过程是决定Elasticsearch性能的关键。值得注意的是,虽然Elasticsearch提供了_bulk API 来批量导入数据,同时也能够设置index.refresh_interval = -1 以及index. number_of_replicas = 0 来进行导入优化。可是在大批量数据导入的状况下,当内存中的缓冲区满的时候,仍然会触发refresh,而且进行flush将数据存储到磁盘上,所以优化的效果并非很明显,Elasticsearch数据导入缓慢是一个很显著的缺点。
DolphinDB中建立一张分布式数据表并写入数据的时候,首先根据分布式数据表的分区类型决定不一样分区的数据写入的数据节点位置。在分区内部,数据是采用列式存储的方式进行组织,经过节点之间的配合来进行数据的导入与查询等操做,数据导入很快,性能极高。
下表是二者的数据导入的I/O性能测试结果,从中能够明显的观察到ES/DDB的载入耗时比随着数据量的上升而增大,特别的,当数据量为60.6GB时,Elasticsearch导入耗时12个小时以上。数据导入脚本见附录。
5.3 磁盘占用空间测试
Elasticsearch以其搜索的高效性与时效性著称。它是基于Lucene而构建起来的分布式搜索引擎且对source字段的内容进行了压缩处理,但其内部是为每一个建立的文档构建倒排索引,并将倒排索引存储在磁盘中的。由于在磁盘上须要对每一个文档添加额外的索引信息,从而须要更大的存储空间来存放。而DolphinDB并不须要其他的索引信息,真正作到了对原数据的压缩存储。测试结果以下表所示。
5.4 内存占用
为了更加全面的观测到DolphinDB与Elasticsearch在执行过程当中的内存占用状况,使用Linux命令htop来监视DolphinDB和Elasticsearch的内存占用状况(内存总大小为32GB),结果以下:
5.5 其余方面比较
(1)Elasticsearch经过须要安装插件来支持SQL语言,同时其内置的DSL语言是JSON格式,语法比较复杂。而DolphinDB内置了完整的脚本语言,不只支持SQL语言,并且支持命令式、向量化、函数化、元编程、RPC等多种编程范式,能够轻松实现更多的功能。
(2)Elasticsearch的主要用途是提供了一个分布式多用户能力的全文搜索引擎,支持模糊查询,文档(行)不须要固定结构,不一样文档能够具备不一样字段集合。而DolphinDB只支持结构化数据。
(3)DolphinDB提供600余种内置函数,可知足金融领域的历史数据建模与实时流数据处理,及物联网领域中的实时监控与数据实时分析处理等不一样的场景需求。提供时序数据处理须要的领先、滞后、累积窗口、滑动窗口等多种指标的函数,且在性能上进行了优化,性能极优。 于是与Elasticsearch相比,DolphinDB拥有更多的适用场景。
(4)Elasticsearch用于时序数据库中时并不支持表链接,而DolphinDB不只支持表链接,还对asof join及window join等非同时链接方式作了优化。
(5)DolphinDB对数据写入支持分布式事务,Elasticsearch不支持事务。
Elasticsearch支持结构化数据和非结构化数据,支持模糊查询,精确查询,和聚合计算,适合不少应用场景。可是与DolphinDB这样专业的时序数据库相比,不管在功能上和性能上,都有很大的差距。尤为当数据量急剧膨胀,超过物理内存上限时,内存耗用高、磁盘空间占用高的缺点暴露出来,对历史数据计算时性能有明显的降低。
DolphinDB和Elasticsearch的详细配置信息、DolphinDB和Elasticsearch的测试代码以及数据导入脚本见附录。