列存设计原理
通常事务型数据库采用行存便于支持事务和高并发读写,分析型数据库采用列存减少 IO 和便于压缩。ByConity 采用列存的方式,保证读写性能、支持事务一致性,又适用大规模的数据计算。
Data Layout
表数据物理上按 Partition Key 切分为多个 Parts 存储在统一的分布式文件系统和云存储的逻辑存储路径下,每个 Part 的大小有数据量和行数限制,计算组根据服务节点分配的策略(预先分配和实时分配)获得其对应的部分 parts。
Part Delta
Part 数据最初构建之后是一个行列混合存储的 Part 数据文件,随着 DML/数据字典/Bitmap index 等构建工作的进行 Part 存在增量数据,这部分数据可以有以下两种存储方式:
- 每次构建都会 Rewrite Part 数据
- 生成增量数据,后台异步合并成一个大的 Part 文件
方案一对整个集群的可用性可能会有一定的影响:
- 每次 DML/数据字典等构建都可能涉及到整个表 Parts 的全量 IO 操作,这个代价比较大。
- 构建时间比较长 DML 等操作会比较长的时间才能做完,对用户不友好,我们采用方案二。
Part 文件内容
part 数据分为两个部分:
一是整个 Part 包括 rows/schema/column data 在数据文件中的 Offset 等元信息,这部分信息持久化存储并被计算节点缓存
二是实际的数据信息,这部分信息包含实际的 column bin 数据/column mrk 数据/Map key bin/Map key index/数据字典数据/bitmap index 数据等,数据按元信息中的 Offset 信息在 Part 的数据文件依次存储。
Compaction
ByConity 支持将一个 part 文件拆分为多个小文件,通过配置 Part 的最大 Size 和最大行数,Compact 之后的 Part 需要满足这个限制。
ByConity 中的 Compaction 是在全局做的,与前面提高的全局的 block ID 保持一致。