存了50TB!巨能“装”的量化数据存储方案

文章讨论了从日线级别数据的HDF5存储升级到处理高频交易的Tick级数据时,如何采用PyArrow和Parquet进行高效大数据存储。作者介绍了PyArrow的基本概念,包括列存储、RecordBatch和Table,以及Parquet的优势,如RLE压缩和数据页压缩。文章还展示了如何构建和操作1分钟行情数据集,以及如何使用PyArrow进行数据读写和查询优化。

R50
在上一篇笔记中,我们指出,如果我们只在日线级别上存储行情数据和因子,HDF5 无论如何都是够用了。即使是在存储了 40 年分钟线的单个股数据集上,查询时间也只花了 0.2 秒 – 这个速度已经足够快了,如果我们不需要在分钟级别上进行横截面数据查询的话。

但是,如果个人交易者确实有条件(网速和硬件)做高频交易,处理 tick 级和 level 2 的数据将是必要的。如此一来,我们处理数据的规模就达到了TB级别,但我们还想保持查询时间在毫秒级。或者,您确实需要在分钟级别上进行横截面数据查询,这些场景下,HDF5 就难堪大任了。


现在我们得拜托 pyarrow + parquet 了。它们本来就是大数据解决方案之一。本文的标题是存了 50TB。博主并没有这个存储设施进行实验。但这一数字并非杜撰:

!!! tip level 2 数据有多大?
据 dolphin(一种高效的时序数据库)的报告,A 股的 level 2 数据达到了一天 10GB 的数据量。

pyarrow

要介绍 pyarrow,我们先得从 Apache Arrow 说起。Apache Arrow 定义了一种与开发语言无关的列存储(内存中)格式,以便在 CPU/GPU 上高效地执行数据读取和分析任务。

pyarrow 是 Apache Arrow 库的一个 python 实现。Apache Arrow 还有 R, Java 等多种其它实现。但是, Pyarrow 是 Apache Arrow 实现中的头等公民,许多先进的功能都率先在这里实现了,然后才是 R 等其它语言。


Pyarrow 支持从 3.8 到 3.11 的 Python 版本。我们使用下面的命令来安装它:

pip install pyarrow

Parquet

parquet 是一种数据存储格式。在大数据存储语境下,我们还常常看到 feather 这种格式。两者的区别是,parquet 提供了 RLE 压缩,字典编码(与 pandas 中的 category 替换类似)和数据页压缩。因此,在读写速度上要慢于 feather,但更省磁盘空间。

基本概念

pyarrow 中最基本的概念主要有:

  1. array – 它是一列同构的数据,但通常允许出现 None。
  2. 一系列等长的 arry 实例构成 Record Batch。batch 可以像 array 一样进行切片
  3. 在 batch 之上,还有 Table 的概念。table 由一些列构成,每一列都是一个 ChunkedArray。

接下来我们还要接触到 schema 的概念,这将在后面结合示例进行说明。


pyarrow 的主要功能:

  1. 提供各种 I/O 接口 (memory and IO interfaces),比如与常见的其它格式,比如 CSV, dataframe, S3, minio,本地文件等之间的读写转换。
  2. 为数据提供表格(tabluar datasets)化的视图和相关操作。
  3. 提供基础函数 (compute Functions),如 group, 聚合查询,join 操作,查询操作(表达式,参照 pandas)。

上述功能分类中,括号中的英文也正对应着 Arrow 的文档,以便大家在需要时查询。

行情数据存储方案

尽管我们介绍 pyarrow + parquet 是为了存储 level 2 的数据,但我手头并没有相应的 level 2 数据源,所以,也无法做出可实际运行的示例。因此,我们将通过构造 1 分钟行情的数据集来演示如何通过 pyarrow 来写入、增加和查询数据。

我们把每一天所有证券品种的 1 分钟行情放在同一个文件中,所有的分钟线都放在 1m 目录下。这里我们没有使用 partition,但在实际应用中,我们要考虑按年进行分钟线的 patition。对 level 2 的数据,可能要按月或者周进行 partition。

另一方面,每个 parquet 文件的大小最好在 20M 和 2GB 之间,所以,对于分钟线以上级别的数据,可以考虑按周或者更大的尺度写入一个文件。


这是磁盘文件结构示例:

/tmp/pyarrow
├── 1d
├── 1m
│   ├── 2023-12-27.parquet
│   ├── 2023-12-28.parquet
│   └── 2023-12-29.parquet
└── factors

首先,我们定义存储字段:

import pyarrow as pa

schema = pa.schema([
        ("symbol", pa.string(
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

量化风云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值