金融市场高频数据应当如何管理——DolphinDB与pickle的性能对比测试和分析

本文提供文章标题与基础信息,并围绕DolphinDB与pickle在高频金融数据读取上的对比测试展开。

Source: https://dolphindb.cn/blogs/286

What this page covers

技能认证特训营第二期报名促销

页面顶部提供培训营报名入口,并提示限时优惠。

文章标题与基础信息

展示文章标题,并标注作者/来源与发布日期。

背景:高频金融数据规模与传统数据库/文件存储的局限

说明L1/L2高频数据规模,并讨论关系数据库、通用数据仓库/NoSQL与文件存储在该场景下的不足。

DolphinDB概述与本文测试目标

介绍DolphinDB面向高频数据的设计要点,并给出与pickle读取性能对比的结论与参考文档链接。

文章目录(外部链接)

提供指向文章各章节(如场景、环境、方法、结果与结论等)的链接目录。

测试场景和测试数据

定义两个数据集的结构与规模,并描述写入DolphinDB后的副本/占用/压缩情况,以及对比测试口径与计时拆分。

测试环境

列出硬件、网络、操作系统以及DolphinDB集群部署方式与版本信息。

测试方法

说明清缓存必要性,并给出DolphinDB查询、DolphinDB Python API与pickle读取的步骤与代码示例。

测试结果分析:基础结果表

展示两数据集在无缓存/有缓存条件下,DolphinDB数据库查询、DolphinDB Python API与pickle读取的耗时对比结果表。

DolphinDB的性能优势来源

从磁盘IO、网络传输、压缩与分布式存储、以及客户端协议等角度解释瓶颈与优化方向。

字符串对性能的影响

分析字符串字段对耗时的影响,并给出剔除字符串字段后的对比结果与SYMBOL机制说明。

多任务并发下的性能对比

对比多进程并发读取下的耗时表现,并解释瓶颈与改进方向。

库内分析的必要性

建议尽量在数据库内完成清洗与分析,以减少传输与客户端开销,并描述DolphinDB脚本语言与分析能力覆盖范围。

结论和展望

总结分布式、压缩、列式存储与协议改进带来的工程结论,并讨论网络瓶颈与数据类型设计建议。

Facts Index

Entity Attribute Value Confidence
技能认证特训营第二期报名链接https://www.qingsuyun.com/h5/e/217471/5/high
文章发布日期2021-05-18high
DolphinDB署名/来源标识DolphinDBhigh
国内全市场L1/L2历史数据数据量规模约20~50Tmedium
国内全市场L1/L2每日新增数据数据量规模约20~50G/日medium
MS SQL Server或MySQL对该数据量级的支撑能力无法支撑这样的数据量级(即便分库分表,查询性能也远远无法达到要求)low
Impala和Greenplum数据仓库、HBase等NoSQL在存储方面对该数据量级的作用可以解决该量级的存储,但对时序数据支持不友好,查询和计算存在严重不足,对Python支持有限low
常用二进制文件格式示例HDF5、Parquet、picklehigh
pickle性质作为Python对象序列化/反序列的协议非常高效low
文件存储用于高频数据缺陷大量数据冗余、版本管理困难、不提供权限控制、无法利用多个节点资源、数据关联不便、管理粒度粗、检索与查询不便等medium
DolphinDB采用的存储方式列式存储high
DolphinDB分区机制提供多种灵活的分区机制,可利用集群中每个节点资源medium
DolphinDB能力/优势(按文中列举)支持超高性能查询与计算,并提供数据管理、权限控制、并行计算、数据关联等数据库优势low
DolphinDB vs pickle(数据读取性能)提升幅度(直接使用DolphinDB数据库读取)最多可提升10倍以上medium
DolphinDB vs pickle(数据读取性能)提升幅度(使用DolphinDB Python API读取)最多有2~3倍提升medium
DolphinDB在线文档链接https://link.zhihu.com/?target=https%3A//www.dolphindb.cn/cn/help/index.htmlhigh
DolphinDB教程(Gitee)链接https://link.zhihu.com/?target=https%3A//gitee.com/dolphindb/Tutorials_CN/blob/README.mdhigh
数据集1日期范围/日期美国股市一天(2007.08.23)Level 1报价和交易数据high
数据集1列数与字符串列数共10列,其中2列是字符串类型high
数据集1行数(一天)约2亿3000万行medium
数据集1CSV文件大小9.5Ghigh
数据集1转换为pickle后大小11.8Ghigh
数据集1在DolphinDB中的表结构列定义symbol SYMBOL; date DATE; time SECOND; bid DOUBLE; ofr DOUBLE; bidsiz INT; ofrsiz INT; mode INT; ex CHAR; mmid SYMBOLhigh
数据集2日期范围中国股市3天(2019.09.10~2019.09.12)Level 2报价数据high
数据集2列数与字符串列数总共78列,其中2列是字符串类型high
数据集2行数(一天)约2170万行medium
数据集2一天CSV文件大小11.6Ghigh
数据集2转换为pickle后大小(一天)12.1Ghigh
数据集2在DolphinDB中的表结构(字段示例)列定义(表中列出)UpdateTime TIME; TradeDate DATE; Market SYMBOL; SecurityID SYMBOL; PreCloPrice DOUBLE; OpenPrice DOUBLE; HighPrice DOUBLE; LowPrice DOUBLE; LastPrice DOUBLE; TradNumber INT; TradVolume INT; Turnover DOUBLE; LocalTime TIME; TotalBidVol INT; WAvgBidPri DOUBLE; TotalAskVol INT; WAvgAskPri DOUBLE; IOPV DOUBLE; AskPrice1~10 DOUBLE; AskVolume1~10 INT; BidPrice1~10 DOUBLE; BidVolume1~10 INT; NumOrdersB1~10 INT; NumOrdersS1~10 INThigh
DolphinDB database数据副本数2high
两数据集写入DolphinDB后的磁盘占用占用空间10.6G(单份数据5.3G)high
两数据集写入DolphinDB后的压缩比压缩比约8:1medium
pickle文件(本文测试)是否采用压缩存储未采用压缩存储;测试发现pickle压缩后加载时间大幅延长medium
对比测试口径查询范围对比测试查询一天的数据high
DolphinDB Python API vs pickle 对比计时范围从客户端发出查询到接收到数据并转换成Python pandas DataFrame对象的耗时high
DolphinDB Python API查询过程步骤拆分(1)数据库查询耗时;(2)数据节点发送到API客户端时间;(3)客户端反序列化为pandas DataFrame时间high
pickle读取耗时定义计时内容使用pickle模块加载pickle数据文件所需时间high
服务器硬件(测试环境)主机型号PowerEdge R730xdhigh
服务器硬件(测试环境)CPUE5-2650 24cores 48线程high
服务器硬件(测试环境)内存512Ghigh
服务器硬件(测试环境)硬盘HDD 1.8T * 12high
测试环境网络网络类型万兆以太网high
测试环境操作系统OS版本CentOS Linux release 7.6.1810high
DolphinDB部署模式(测试)集群形态多服务器集群模式;3台服务器;每台服务器部署2个数据节点high
数据节点资源配置(测试)磁盘/内存/线程每个节点分配2个10K RPM HDD磁盘;内存使用限制32G;线程数设置16high
DolphinDB数据库(测试)副本数2high
测试客户机位置安排在其中一台服务器上high
DolphinDB服务器版本(测试)版本号1.30.0high
Python API for DolphinDB版本(测试)版本号1.30.0.4high
测试方法(清缓存)原因操作系统会缓存读写后的文件,从缓存读取会影响测试结果;每次测试前清除操作系统缓存和DolphinDB缓存,并对比有缓存性能high
清理操作系统缓存命令命令sudo sh -c "echo 1 > /proc/sys/vm/drop_caches"(可能需root用户)high
清理DolphinDB数据库缓存命令命令pnodeRun(clearAllCache)high
DolphinDB查询示例(测试代码)Level 1查询select * from loadTable("dfs://TAQ", "quotes") where TradeDate = 2007.08.23high
DolphinDB查询示例(测试代码)Level 2查询select * from loadTable("dfs://DataYesDB", "tick") where TradeDate = 2019.09.10high
DolphinDB Python API连接示例(测试代码)连接参数s.connect("192.168.1.13",22172, "admin", "123456")high
pickle测试流程(测试代码)生成pkl文件方法quotes.to_pickle("taq.pkl"); tick.to_pickle("level2.pkl")high
pickle测试流程(测试代码)读取方法pickle.load(open('taq.pkl','rb')); pickle.load(open('level2.pkl','rb'))high
读取美国股市Level 1数据集(结果表)DolphinDB 数据库查询耗时无缓存6秒;有缓存6秒high
读取美国股市Level 1数据集(结果表)DolphinDB Python API耗时无缓存38秒;有缓存35秒high
读取美国股市Level 1数据集(结果表)pickle耗时无缓存72秒;有缓存34秒high
读取中国股市Level 2数据集(结果表)DolphinDB 数据库查询耗时无缓存5秒;有缓存5秒high
读取中国股市Level 2数据集(结果表)DolphinDB Python API耗时无缓存22秒;有缓存22秒high
读取中国股市Level 2数据集(结果表)pickle耗时无缓存70秒;有缓存20秒high
DolphinDB数据库直连查询 vs pickle性能对比结论直接从DolphinDB数据库查询速度最快,超过pickle查询10倍以上medium
pickle文件读取极限性能(本文配置)吞吐范围每秒150MB~200MBmedium
读取12G pickle文件耗时约70秒medium
pickle读取瓶颈瓶颈来源磁盘IO;有操作系统缓存时性能提升,耗时主要为反序列化medium
提升pickle读取性能的方法(文中建议)方向提升存储介质吞吐量,例如改用SSD或磁盘阵列medium
DolphinDB数据库与Python API客户端采用的协议采用改良的pickle协议medium
DolphinDB数据库查询部分耗时(两数据集)耗时范围约5~6秒(无论是否有缓存)high
一天的数据量在DolphinDB数据库中数据量约8Gmedium
数据在集群中分布(一天数据)节点数与单节点数据量分三个节点存储;每个节点约2.7Gmedium
从一个节点查询需要传输的数据量(文中设定)传输数据量约5.4G(本地节点不需要网络传输)medium
万兆以太网传输约5.4G数据对应时间约5~6秒medium
DolphinDB数据库查询瓶颈(本文配置)瓶颈来源网络而非磁盘IOmedium
压缩后一天的数据量大小约1.4Gmedium
压缩数据分布与磁盘加载时间估算估算条件与结果分布于12个磁盘;每盘100mb/s吞吐量;加载一天数据磁盘时间约1.2秒medium
DolphinDB Python API的反序列化协议相对原版pickle的改进收益比原版pickle协议节约5~6秒时间medium
进一步提升DolphinDB Python API查询性能(文中建议)方向升级网络(10G到100G,第一步查询耗时可能从5~6秒缩减到2秒)或继续改良pickle协议low
数据集1(无缓存)DolphinDB Python API耗时构成反序列化占比总耗时38秒,数据库端耗时仅5~6秒,约80%时间耗费在pickle反序列化上medium
数据集1(无缓存,剔除两个字符串字段)耗时变化(DolphinDB Python API)从38秒缩短到19秒(减少一半)high
数据集1两个字符串字段耗时影响描述以20%的数据量占了50%的耗时(在该分析语境下)medium
数据集2(剔除两个字符串字段)耗时变化(DolphinDB Python API)从22秒缩减到20秒high
美国股市Level 1(去除字符串字段)读取结果DolphinDB耗时无缓存19秒;有缓存18秒high
美国股市Level 1(去除字符串字段)读取结果pickle耗时无缓存56秒;有缓存16秒high
中国股市Level 2(去除字符串字段)读取结果DolphinDB耗时无缓存20秒;有缓存20秒high
中国股市Level 2(去除字符串字段)读取结果pickle耗时无缓存66秒;有缓存18秒high
剔除字符串字段对pickle查询的影响(本文观察)效果描述有缓存情况下耗时缩短一半;无缓存情况下提升有限,原因是瓶颈在磁盘IOmedium
DolphinDB数据类型 SYMBOL用途用于优化高重复度的字符串类型数据(如股票ID、交易所名称)medium
SYMBOL类型的实现机制(文中描述)存储方式为Vector或Table配备字典存储不重复字符串,内部存储字符串在字典中的索引high
DolphinDB改用STRING类型(相对SYMBOL)性能影响性能会降低medium
pickle反序列化对SYMBOL优势的利用问题描述未充分利用SYMBOL带来的优势,存在大量Python对象多次copy,是进一步优化方向之一medium
并发测试设置数据集与方法采用数据集2;因全局锁限制,开启多个Python进程从pickle文件或DolphinDB数据库加载数据;pickle并发读取同一节点同一磁盘不同文件high
并发查询耗时(3个连接,数据集2)DolphinDB API连接本地服务器数据节点连接1 48秒;连接2 43秒;连接3 45秒high
并发查询耗时(3个连接,数据集2)DolphinDB API连接不同服务器数据节点连接1 28秒;连接2 35秒;连接3 31秒high
并发查询耗时(3个连接,数据集2)pickle连接1 220秒;连接2 222秒;连接3 219秒high
pickle并发读取耗时变化(本文解释)原因与现象耗时从70秒线性增加到约220秒;瓶颈为磁盘IO,任务从1到3耗时约变3倍medium
DolphinDB并发查询耗时增加(本文解释)连接到不同服务器数据节点耗时增加约50%(约10秒),主要原因是客户端节点网络达到瓶颈medium
DolphinDB并发查询耗时增加(本文解释)连接到同一服务器数据节点耗时增加约100%(约22秒),主要原因是客户端节点和接入数据节点网络同时达到瓶颈medium
提升DolphinDB并发多任务查询性能(文中建议)方向升级网络(万兆升级到10万兆以太网)或引入传输压缩以提升网络传输效率low
DolphinDB数据库端查询耗时占比(文中总结)占比约占整个查询耗时的20%左右(单任务与并发场景的总结表述)medium
数据集1示例(库内分析 vs 客户端分析)Python API取数后pandas分析总耗时约50秒左右low
数据集1示例(库内分析)若各节点完成统计并仅合并少量结果的总耗时约2秒左右(文中估计)low
DolphinDB脚本语言与内置函数规模内置完整的多范式脚本语言,包括千余个内置函数medium
DolphinDB库内分析能力(文中列举)支持的操作类型时间序列、面板数据、矩阵的聚合、滑动窗口分析、关联、Pivoting、机器学习等量化金融常用功能可在库内完成medium
数据库性能结论(文中结论)总体结论数据库在提供管理便利/安全/可靠优势的同时,性能上超越操作系统裸文件业已可行;得益于分布式、压缩、列式存储与应用层协议改进,磁盘IO可能不再是最先遇到的瓶颈low
高频金融数据解决方案(文中结论)对DolphinDB的定位高频数据的时序特性使得时序数据库DolphinDB成为最新且有前景的解决方案;相对pickle等文件方案,带来管理便利与性能突破及时间序列/面板处理便利low
Python API查询链路瓶颈(文中结论)瓶颈位置数据库查询耗时占很小部分,大部分时间耗费在客户端网络传输与数据序列化/反序列化(“最后一公里”)low
突破“最后一公里”瓶颈的思路(文中建议)方向采用库内分析以降低传输数据量;启用类似Apache Arrow的通用内存数据格式以降低序列化/反序列化开销low
网络瓶颈(文中展望)判断与建议随着分布式技术推进,10G网络可能更早成为瓶颈;部署高性能数据库集群时可开始考虑100G以太网low
数据压缩的重要性(文中结论)作用数据压缩可提升磁盘IO与网络IO效率,在大数据存储与传输中重要medium
字符串类型对系统性能的影响(文中结论)对数据系统性能有非常大的负面影响;对象存储导致内存不连续与分配压力;CPU效率低;长度不一致导致磁盘随机读取困难medium
数据系统设计(文中建议)字符串类型使用建议尽可能避免使用字符串类型;若重复度高,建议使用类似DolphinDB的SYMBOL类型替代medium