写点什么

时序数据库 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:5452754

评论

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

跟着卷卷龙一起学Camera--自动驾驶需要几个 camera

卷卷龙

ISP camera 11月月更

极客时间架构训练营模块四作业

李晨

架构

千万级学生管理系统试卷存储方案设计

π

架构实战营

Oracle sql 性能优化(一)

默默的成长

oracle 前端 11月月更

模块四 -- 作业

李某人

架构训练营 #架构训练营

week4 - 作业 - 设计千万级学生管理系统的考试试卷存储方案

in9

作业四:学生考试系统试卷储存方案

许四多

纯css爱心代码-最近超级火的打火机与公主裙中的爱心代码(简易版)

肥晨

11月月更 跳动的爱心 代码爱心 爱心代码

对象可达性状态流转分析、显式地影响软引用垃圾收集

共饮一杯无

Java 11月月更 引用类型扩展

教育的本质(57/100)

hackstoic

随机森林-用随机森林回归填补缺失值

烧灯续昼2002

Python 机器学习 算法 sklearn 11月月更

数据库系统的组成

阿泽🧸

数据库 11月月更

小白入门:什么是CURD?

wljslmz

数据库 sql crud 11月月更

Java引用类型(class、interface)用法总结详解

共饮一杯无

Java 11月月更 Java引用类型

强引用、软引用、弱引用、幻象引用有什么区别和使用场景

共饮一杯无

Java 引用类型 11月月更

HTML学习笔记(三)

lxmoe

html 前端 学习笔记 11月月更

【云原生】Nacos-TaskManager 任务管理的使用

石臻臻的杂货铺

云原生 nacos 11月月更

如何在论文中画出漂亮的插图?

Jackpop

猿创征文|点亮JAVA技术之灯(线程篇)

叶秋学长

Java 线程 教学 11月月更

设计千万级学生管理系统的考试试卷存储方案

小虎

架构训练营

Github已经54k个star的Docker,到底是什么?

Jackpop

千万学生管理系统存储架构设计--redis细化

Johnny

架构实战营

夜幕下的湖畔音乐派对,华为音乐之夜为HDC 2022划上“聚”号

最新动态

跟着卷卷龙一起学Camera--信号采样03

卷卷龙

ISP camera 11月月更

2022-11-06:给定平面上n个点,x和y坐标都是整数, 找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的。 返回最短距离,精确到小数点后面4位。

福大大架构师每日一题

算法 rust 福大大

第九期-模块五

wuli洋

python的类的定义和使用

乔乔

11月月更

跟着卷卷龙一起学Camera--信号采样04

卷卷龙

ISP camera 11月月更

从URL输入到页面展现到底发生什么?

loveX001

JavaScript

使用TSDB自动检测时序数据的异常情况

CnosDB

IoT 时序数据库 开源社区 CnosDB infra

零基础入门网络安全,收藏这篇不迷茫【2022最新】

网络安全学海

黑客 网络安全 信息安全 渗透测试 WEB安全

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