存储引擎
存储引擎主要提供以下两个功能:
- 数据的持久化
- 在保证数据正确性的前提下,用最合理的方式来组织数据,来满足不同场景的查询需求
本篇文档就来介绍 HoraeDB 中存储引擎的内部实现,读者可以参考这里面的内容,来探索如何高效使用 HoraeDB。
整体架构
HoraeDB 是一种基于 share-nothing 架构的分布式存储系统,不同服务器之间的数据相互隔离,互不影响。每一个单机中的存储引擎是 LSM(Log-structured merge-tree)的一个变种,针对时序场景做了优化,下图展示了其主要组件的运作方式:
Write Ahead Log (WAL)
一次写入请求的数据会写到两个部分:
- 内存中的 memtable
- 可持久化的 WAL
由于 memtable 不是实时持久化到底层存储系统,因此需要用 WAL 来保证 memtable 中数据的可靠性。
另一方面,由于分布式架构的设计,要求 WAL 本身是高可用的,现在 HoraeDB 中,主要有以下几种实现:
Memtable
Memtable 是一个内存的数据结构,用来保存最近写入的数据。一个表对应一个 memtable。
Memtable 默认是可读写的(称为 active),当写入达到一起阈值时,会变成只读的并且被一个新的 memtable 替换掉。只读的 memtable 会被后台线程以 SST 的形式写入到底层存储系统中,写入完成后,只读的 memtable 就可以被销毁,同时 WAL 中也可以删除对应部分的数据。
Sorted String Table(SST)
SST 是数据的持久化格式,按照表主键的顺序存放,目前 HoraeDB 采用 parquet 格式来存储。
对于 HoraeDB 来说,SST 有一个重要特性: segment_duration
,只有同一个 segment 内的 SST 才有可能进行合并操作。而且有了 segment,也方便淘汰过期的数据。
除了存放原始数据外,SST 内也会存储数据的统计信息来加速查询,比如:最大值、最小值等。
Compactor
Compactor 可以把多个小 SST 文件合并成一个,用于解决小文件数过多的问题。此外,Compactor 也会在合并时进行过期数据的删除,重复数据的去重。目前 HoraeDB 中的合并策略参考自 Cassandra,主要有两个:
Manifest
Manifest 记录表、SST 文件元信息,比如:一个 SST 内数据的最小、最大时间戳。
由于分布式架构的设计,要求 Manifest 本身是高可用的,现在 HoraeDB 中,主要有以下几种实现:
- WAL
- ObjectStore
ObjectStore
ObjectStore 是数据(即 SST)持久化的地方,一般来说各大云厂商均有对应服务,像阿里云的 OSS,AWS 的 S3。