NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

时序数据库 DolphinDB 和 TimescaleDB 性能对比测试报告

  • 2019-03-07
  • 本文字数:6394 字

    阅读完需:约 21 分钟

时序数据库DolphinDB和TimescaleDB 性能对比测试报告

在本文中,我们对 TimescaleDB 和 DolphinDB 在时间序列数据集上进行了性能对比测试。测试涵盖了 CSV 数据文件的导入导出、磁盘空间占用、查询性能等三方面。


在我们进行的所有测试中,DolphinDB 表现得更出色,主要结论如下:


  • 数据导入方面,小数据集情况下 DolphinDB 的导入性能是 TimescaleDB 的 10 多 倍 ,大数据集的情况下导入性能是其 100 多 倍 ,而且在导入过程中可以观察到随着导入时间的增加,TimescaleDB 的导入速率不断下降,而 DolphinDB 保持稳定。

  • 数据导出方面,DolphinDB 的性能是 TimescaleDB 的 3 倍左右。

  • 磁盘空间占用方面,小数据集下 DolphinDB 占用的空间仅仅是 TimescaleDB 的 1/6 ,大数据集下占用空间仅仅是 TimescaleDB 的 1/17。

  • 查询性能方面,DolphinDB 在 4 个 测试样例中性能超过 TimescaleDB 的 50 多 倍 ;在 15 个 测试样例中性能为 TimescaleDB 10 ~ 50 倍 ; 在 10 个 测试样例中性能是 TimescaleDB 的数倍;仅有 2 个 测试样例性能不足 TimescaleDB。

一、系统介绍

DolphinDB 是以 C++ 编写的一款分析型的高性能分布式时序数据库,使用高吞吐低延迟的列式内存引擎,集成了功能强大的编程语言和高容量高速度的流数据分析系统,可在数据库中进行复杂的编程和运算,显著减少数据迁移所耗费的时间。


DolphinDB 通过内存引擎、数据本地化、细粒度数据分区和并行计算实现高速的分布式计算,内置流水线、 Map Reduce 和迭代计算等多种计算框架,使用内嵌的分布式文件系统自动管理分区数据及其副本,为分布式计算提供负载均衡和容错能力。


DolphinDB 支持类标准 SQL 的语法,提供类似于 Python 的脚本语言对数据进行操作,也提供其它常用编程语言的 API,在金融领域中的历史数据分析建模与实时流数据处理,以及物联网领域中的海量传感器数据处理与实时分析等场景中表现出色。


TimescaleDB 是目前市面上唯一的开源且完全支持 SQL 的时序数据库。它在 PostgreSQL 数据库的基础上进行开发,本质上是一个 PostgreSQL 的插件。


TimescaleDB 完全支持 SQL 且拥有 PostgreSQL 的丰富生态、并针对时间序列数据的快速插入和复杂查询进行了优化,支持自动分片,支持时间空间维度自动分区,支持多个 SERVER、多个 CHUNK 的并行查询,内部写优化(批量提交、内存索引、事务支持、数据倒灌)。


然而,目前 TimerscaleDB 仍不支持水平扩展(集群),即不能动态增加新的数据结点以写入数据(Write clustering for multi-node Timescale deployments is under active development. https://github.com/timescale/timescaledb/issues/9),


只支持通过 PostgreSQL 的流复制(streaming repliaction)实现的只读集群(read-only clustering)。

二、测试环境

TimescaleDB 目前仍未支持能够写入数据的集群,因此我们使用单机进行测试,单机的配置为


主机:DELL OptiPlex 7060


CPU :Intel Core i7-8700(6 核 12 线程 3.20 GHz)


内存:32 GB (8GB × 4, 2666 MHz)


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


OS:Ubuntu 16.04 LTS


我们测试时使用的 DolphinDB 版本为 Linux v0.89 (2019.01.31),最大内存设置为 28GB


我们测试时使用的 PostgreSQL 版本为 Ubuntu 10.6-1 on x8664, TimescaleDB 插件的版本为 v1.1.1。


根据 TimescaleDB 官方指南推荐的性能调优方法,结合测试机器的实际硬件配置,我们在 https://pgtune.leopard.in.ua/ 网站上生成了配置文件,同时参考了https://wiki.postgresql.org/wiki/TuningYourPostgreSQLServer 这一官方配置指南作了优化,主要将 shared_buffers 和 effective_cache_size 设置为 16GB,并根据 12 线程 CPU 设置了 parallel workers ,由于仅使用一块机械硬盘,我们将 effective_io_concurrency 设置为 1,具体修改的配置详见附录中 postgresql_test.conf 文件。

三、数据集

本报告测试了 小数据量级(4.2 GB) 和 大数据量级(270 GB) 下 DolphinDB 和 TimescaleDB 的表现情况:


在小数据量级的测试中我们预先将硬盘中的分区数据表全部加载到内存中,即在 DolphinDB 中使用 loadTable(memoryMode=true),在 PostgresQL 中使用 pgprewarm 插件将其加载至 sharedbuffers。


在大数据量级的测试中我们不预先加载硬盘分区表,查询测试的时间包含磁盘 I/O 的时间,为保证测试公平,每次启动程序测试前均通过 Linux 系统命令 sync; echo 1,2,3 | tee /proc/sys/vm/drop_caches 分别清除系统的页面缓存、目录项缓存和硬盘缓存。


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


1.4.2 GB 设备传感器记录小数据集(CSV 格式,3 千万条)


我们从 TimescaleDB 官方给出的样例数据集中选择了 devices_big 作为小数据集来测试,数据集包含 3000 个设备在 10000 个时间间隔(2016.11.15 - 2016.11.19)上的 传感器时间, 设备 ID, 电池, 内存, CPU 等时序统计信息。


来源:https://docs.timescale.com/v1.1/tutorials/other-sample-datasets


下载地址:https://timescaledata.blob.core.windows.net/datasets/devices_big.tar.gz


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


device_info 表



readings 表



数据集中 device_id 这一字段有 3000 个不同的值,这些值在 readings 表的记录中反复出现,用 text 类型不仅占用大量空间而且查询效率较低,但是在 TimescaleDB 中我们难以对这一字段采用 enum 类型,而 DolphinDB 的 Symbol 类型简单高效地解决了存储空间和查询效率这两大问题。


同样,对于 bssid 和 ssid 这两个字段表示设备连接的 WiFi 信息,在实际中因为数据的不确定性,虽然有大量的重复值,但并不适合使用 enum 类型。


我们在 DolphinDB 中的分区方案是将 time 作为分区的第一个维度,按天分为 4 个区,分区边界为 [2016.11.15 00:00:00, 2016.11.16 00:00:00, 2016.11.17 00:00:00, 2016.11.18 00:00:00, 2016.11.19 00:00:00];再将 device_id 作为分区的第二个维度,每天一共分 10 个区,最后每个分区所包含的原始数据大小约为 100 MB。


我们尝试了在 TimescaleDB 中将 device_id 作为分区的第二个维度,但经测试 90% 查询样例的性能反而不如仅由时间维度进行分区,因此我们选择仅按照时间维度和按天分为 4 个区,该维度和 DolphinDB 的分区方式相同,而 device_id 这一维度以官方推荐的建立索引的方式 create index on readings (device_id, time desc); create index on readings (ssid, time desc);(参考 https://docs.timescale.com/v1.0/using-timescaledb/schema-management#indexing )来提高查询速度。


2.270 GB 股票交易大数据集(CSV 格式,23 个 CSV,65 亿条)


我们将纽约证券交易所(NYSE)提供的 2007.08.01 - 2007.08.31 一个月的股市 Level 1 报价数据作为大数据集进行测试,数据集包含 8000 多支股票在一个月内的 交易时间, 股票代码, 买入价, 卖出价, 买入量, 卖出量 等报价信息。


数据集中共有 65 亿(6,561,693,704)条报价记录,一个 CSV 中保存一个交易日的记录,该月共 23 个交易日,未压缩的 CSV 文件共计 270 GB。


来源:https://www.nyse.com/market-data/historical


taq 表



我们按 date(日期), symbol(股票代码) 进行分区,每天再根据 symbol 分为 100 个分区,每个分区大概 120 MB 左右。

四、数据导入导出测试

1.从 CSV 文件导入数据

DolphinDB 使用以下脚本导入:


timer {
for (fp in fps) {
loadTextEx(db, `taq, `date`symbol, fp, ,schema)
print now() + ": 已导入 " + fp
}
}
复制代码


4.2 GB 设备传感器记录小数据集共 30,000,000 条数据导入用时 20 秒, 平均速率 1,500,000 条/秒


270 GB 股票交易大数据集共 6,561,693,704 条数据(TAQ20070801 - TAQ20070831 23 个文件),导入用时 38 分钟


在 TimescaleDB 的导入中,由于 timescaledb-parallel-copy 工具不支持 CSV 首行为列名称,我们先用 tail -n +2 跳过 CSV 首行,再将文件流写入其标准输入。



for f in /data/TAQ/csv/*.csv ; do
tail -n +2 $f | timescaledb-parallel-copy \
--workers 12 \
--reporting-period 1s \
--copy-options "CSV" \
--connection "host=localhost user=postgres password=postgres dbname=test sslmode=disable" \
--db-name test \
--table taq \
--batch-size 200000

echo "文件 $f 导入完成"
done
复制代码


4.2 GB 设备传感器记录小数据集共 30,000,000 条数据导入用时 5 分钟 45 秒, 平均速率 87,000 条/秒


270 GB 股票交易大数据集仅 TAQ20070801, TAQ20070802, TAQ20070803, TAQ20070806, TAQ20070807 五个文件(总大小 70 GB)所包含的 16.7 亿 条数据导入用时 24 小时,导入速率 19400 条/秒,预计将数据全部 270 GB 数据导入需要 92 小时。


导入性能如下表所示:



结果显示 DolphinDB 的导入速率远大于 TimescaleDB 的导入速率,数据量大时差距更加明显,而且在导入过程中可以观察到随着导入时间的增加,TimescaleDB 的导入速率不断下降,而 DolphinDB 保持稳定。


另,TimescaleDB 在导入小数据集后仍需花费 2 min 左右的时间建立索引。

2.导出数据为 CSV 文件

在 DolphinDB 中使用 saveText((select * from readings), ‘/data/devices/readings_dump.csv’) 进行数据导出。


在 TimescaleDB 中使用 time psql -d test -c “\COPY (SELECT * FROM readings) TO /data/devices/devices_dump.csv DELIMITER ‘,’ CSV” 进行数据导出。


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


五、磁盘空间占用对比

导入数据后对 TimescaleDB 和 DolphinDB 数据库占用空间的分析如下表所示:



DolphinDB 的空间利用率远大于 TimescaleDB,而且 TimescaleDB 中数据库占用的存储空间甚至大于原始 CSV 数据文件的大小,这主要有以下几方面的原因:


  • Timescale 只对比较大的字段进行自动压缩(TOAST),对数据表没有自动压缩的功能,即如果字段较小、每行较短而行数较多,则数据表不会进行自动压缩,若使用 ZFS 等压缩文件系统,则会显著影响查询性能;而 DolphinDB 默认采用 LZ4 格式的压缩。

  • TimescaleDB 使用 SELECT create_hypertable(‘readings’, ‘time’, chunk_time_interval => interval ‘1 day’) 将原始数据表转化为 hypertable 抽象表来为不同的数据分区提供统一的查询、操作接口,其底层使用 hyperchunk 来存储数据,经分析发现 hyperchunk 中对时序数据字段的索引共计 0.8 GB,对 device_id, ssid 两个字段建立的索引共计 2.3 GB

  • device_id, ssid, bssid 字段有大量的重复值,但 bssid 和 ssid 这两个字段表示设备连接的 WiFi 信息,在实际中因为数据的不确定性,因此不适合使用 enum 类型,只能以重复字符串的形式存储;而 DolphinDB 的 Symbol 类型可以根据实际数据动态适配,简单高效地解决了存储空间的问题。

六、查询测试

我们一共对比了以下八种类别的查询:


  • 点查询指定某一字段取值进行查询

  • 范围查询针对单个或多个字段根据时间区间查询数据

  • 精度查询针对不同的标签维度列进行数据聚合,实现高维或者低维的字段范围查询功能

  • 聚合查询是指时序数据库有提供针对字段进行计数、平均值、求和、最大值、最小值、滑动平均值、标准差、归一等聚合类 API 支持

  • 对比查询按照两个维度将表中某字段的内容重新整理为一张表格(第一个维度作为列,第二个维度作为行)

  • 抽样查询指的是数据库提供数据采样的 API,可以为每一次查询手动指定采样方式进行数据的稀疏处理,防止查询时间范围太大数据量过载的问题

  • 关联查询对不同的字段,在进行相同精度、相同的时间范围进行过滤查询的基础上,筛选出有关联关系的字段并进行分组

  • 经典查询是实际业务中常用的查询


1.4.2 GB 设备传感器记录小数据集查询测试


对于小数据集的测试,我们先将数据表全部加载至内存中:


DolphinDB 使用 loadTable(memoryMode=true) 加载至内存。


TimescaleDB 使用 select pg_prewarm(’_hyper_2_41_chunk’) 加载至 shared_buffers。



对于抽样查询,TimescaleDB 中有 tablesample 子句对数据表进行抽样,参数是采样的比例,但只有两种抽样方式(system, bernoulli),system 方式按数据块进行取样,性能较好,但采样选中的块内的所有行都会被选中,随机性较差。bernoulli 对全表进行取样,但速度较慢。这两种取样方式不支持按某一个字段进行取样;而 DolphinDB 不支持全表取样,只支持按分区取样,由于实现方式不同,我们不进行性能对比。


对于插值查询,TimescaleDB (PostgreSQL) 无内置插值查询支持,需要上百行代码来实现,见 https://wiki.postgresql.org/wiki/Linear_Interpolation ;而 DolphinDB 支持 4 种插值方式,ffill 向后取非空值填充、bfill 向前去非空值填充、lfill 线性插值、nullFill 指定值填充。


对于对比查询,TimescaleDB 的对比查询功能由 PostgresQL 内置的 tablefunc 插件所提供的 crosstab() 函数实现,但是从样例查询中可以看出该函数有很大的局限性:


第一,它需要用户手动硬编码第二个维度(行)中所有可能的取值和对应的数据类型,无法根据数据动态生成,非常繁琐,因此不能对动态数据或取值多的字段使用。


第二,它只能根据 text 的类型维度进行整理,或者由其它类型的维度事先转换为 text 类型。数据量大时该转换操作效率低下且浪费空间。


而 DolphinDB 原生支持 pivot by 语句,只需指定分类的两个维度即可自动整理。


对于关联查询,双时间连接(asof join)对于时间序列数据分析非常方便。DolphinDB 原生支持 asof join 而 PostgresQL 暂不支持 (https://github.com/timescale/timescaledb/issues/271)。


使用 count(*) 查询总记录数时,TimescaleDB 会对全表进行扫描,效率极低。


2.270 GB 股票交易大数据集查询测试


在大数据量级的测试中我们不预先加载硬盘分区表至内存,查询测试的时间包含磁盘 I/O 的时间,为保证测试公平,每次启动程序测试前均通过 Linux 系统命令 sync; echo 1,2,3 | tee /proc/sys/vm/drop_caches 清除系统的页面缓存、目录项缓存和硬盘缓存,启动程序后依次执行所有测试样例一遍。


七、小结

除了性能上的优势,DolphinDB 还具有以下优势:


在架构上,DolphinDB 采用分布式架构,可以充分利用计算和存储资源,提高效率。从 TimescaleDB 当前的产品架构来看,它仍然是一个单机版的数据库。


在分区上,DolphinDB 支持顺序分区、值分区、范围分区、列表分区、哈希分区和组合分区。灵活的分区方式可以满足更多的业务场景需求。由于 DolphinDB 采用了分布式架构,不易出现数据或查询集中到某个节点的情况,在查询时 DolphinDB 所需要扫描的数据块也更少,响应时间更短。


在功能上,DolphinDB 是一个分析型(OLAP)的时序数据库,对于时间序列数据特有的 sliding function, asof join, window join,更复杂的内存计算,分布式计算以及流计算,都能够良好的支持。TimescaleDB 基于 PostgreSQL,良好支持事务,并且单点查询的性能优势明显优于 DolphinDB,但是它面向时序数据的场景还比较有限,更像是传统的 OLTP 数据库加上了部分时序数据库的功能。

八、附录

  • CSV 数据格式预览(取前 20 行)


device_info:devices.csv


readings:readings.csv


TAQ:TAQ.csv


  • DolphinDB


安装、配置、启动脚本:test_dolphindb.sh


配置文件:dolphindb.cfg


小数据集测试完整脚本:test_dolphindb_small.txt


大数据集测试完整脚本:test_dolphindb_big.txt


  • TimescaleDB


安装、配置、启动脚本:test_timescaledb.sh


小数据集测试完整脚本:test_timescaledb_small.sql


大数据集测试完整脚本:test_timescaledb_big.sql


PostgresQL 修改配置:postgresql_test.conf


PostgresQL 完整配置:postgresql.conf


PostgresQL 权限配置:pg_hba.conf


股票代码所有可能值:symbols.txt


创建 Symbol 枚举类型 SQL 语句:make_symbol_enum.sql


生成 Symbol 枚举类型脚本:make_symbol_enum.coffee


  • 测试结果处理脚本


REPL.coffee


本文作者:沈鸿飞,浙江智臾科技有限公司


2019-03-07 17:5452541

评论

发布
暂无评论
发现更多内容

在中国程序员是青春饭吗?,android开发基础入门教程

android 程序员 移动开发

太卷了!程序员面试前刷面经“神似,2021最新Android大厂面试真题大全

android 程序员 移动开发

“神算子”上线!EasyDL时序预测模型零门槛轻松上手

百度大脑

人工智能 百度

大牛耗时一年:深入探索-Android-包体积优化,共三万字建议收藏上(1)

android 程序员 移动开发

天高任鸟飞,在你还苦闷Android出路时,总有人在系统钻研为高级开发做准备

android 程序员 移动开发

[ CloudWeGo 微服务实践 - 番外 ] Go 代码静态检查

baiyutang

golang 11月日更

头条Android 岗年薪45W+面经分享(技术 6面,Android开发者值得深入思考的几个问题

android 程序员 移动开发

图文DEMO并茂讲解RecyclerView滑动时回收和复用触发的时机

android 程序员 移动开发

备战秋招-阿里巴巴面试真题:-给你一个Demo-你如何快速定位ANR?

android 程序员 移动开发

备战金九银十:Android面试10+个知识点总结宝典助你通关

android 程序员 移动开发

大众点评App的短视频耗电量优化实战,通宵都要看完这个Android关键技术点

android 程序员 移动开发

太强了吧,这居然是19年双非本科开发一年的Android面经总结!开发几年的老程序员自叹不如

android 程序员 移动开发

在Android项目中接入Flutter,在Flutter使用安卓布局---草稿

android 程序员 移动开发

事务是如何影响你的系统(二)

卢卡多多

11月日更

大牛耗时一年:深入探索-Android-包体积优化,共三万字建议收藏上

android 程序员 移动开发

太难为我这个应届生了,腾讯面试了8轮,终拿下腾讯Android测发岗offer

android 程序员 移动开发

基于Android的特征X射线谱识别系统的开发,android指纹识别

android 程序员 移动开发

基本功---Litho的使用及原理剖析,10年阿里开发架构师经验分享

android 程序员 移动开发

大厂一步到位:Android-基础+Android高级,android物联网开发从入门到实战

android 程序员 移动开发

大学毕业做音视频开发,月入20K,你呢,kotlin协程面试

android 程序员 移动开发

大学计算机专业,什么水平可以进大厂?,解密Android开发常见误区

android 程序员 移动开发

大神一招搞定:ReentrantReadWriteLock-几道小小数学题就够了。

android 程序员 移动开发

图解:HTTP 范围请求,助力断点续传(1),成功入职腾讯月薪45K

android 程序员 移动开发

图解:HTTP 范围请求,助力断点续传,android游戏开发入门

android 程序员 移动开发

在-View-上使用挂起函数,app开发面试题及答案

android 程序员 移动开发

大型Bat面试知识总结分享—AMS在Android起到什么作用?简单的分析下Android的源码

android 程序员 移动开发

备战阿里面试一年半顺利通过二面,面对突如其来的疫情,让我的阿里三面搁浅ing

android 程序员 移动开发

国庆节不知道学什么?这份 Android 优秀技术文章清单请收下

android 程序员 移动开发

Android线程思考

轻口味

android 多线程 11月日更

在线等!阿里、百度一面就惨遭吊打,kotlin语言书籍

android 程序员 移动开发

坊间传言:程序员可以先在大厂镀金,以后去中小厂毫无压力

android 程序员 移动开发

时序数据库DolphinDB和TimescaleDB 性能对比测试报告_软件工程_沈鸿飞_InfoQ精选文章