天天看点

[Paper Reading] Alibaba Hologres: A Cloud-Native Service for Hybrid Serving/Analytical Processing===== 3. Storage

阅读时间:2022.07 - Storage Engine 相关部分

===== 2.3 Data Storage

Data Storage 有3个核心设计思想:

  • 存储计算分离(Decoupling of Storage/Computation)
  • 基于 tablet 的 数据layout(Tablet-based Data Layout):table & index 都拆分到 tablet 级别来进行管理
  • 分离读写路径(Separation of Reads/Writes)

===== 3. Storage

Hologres 支持 混合行列存储 以支持 HSAP 场景:

  • Row storage 面向低延迟点查
  • Column storage 面向高吞吐scan

// 从 paper 中看,这里的 「混合行列存储」是指引擎中既有行存又有列存,而并不是指一个持久化文件中是行列混存的

===== 3.1 Data Model

所有的 table 都被分组为 table group。每个 table group 被拆分为 table group shards(TGS),影响数据分布的两个配置:clustering key & distribution key

  •         distribution key:表示数据的分布策略,仅支持 hash 类型,Hash(distribution key) % shard_count。
    •         clustering key:数据在tablet的排序依据(默认为空,则按照插入顺序)。从索引的角度来讲,Hologres 仅支持一个 聚簇索引(就是基于 clustering key的索引),非聚簇索引要指向到 cluster key or row locator

Hologres 中每个table都有一个用户定义的 clustering key(默认为空)和一个unique row locator。如果 clustering key 是 unique 的,那么 row locator 就是 clustering key;否则 row locator 为 (clustering key, uniquifier)。

每个 TGS 包含每个table的 base data 以及 index data,将 base data partition & index partition 都统一看作是 tablet,tablet 有 row tablet & column tablet 两种format。

Tablet 是要求有 unique key 的:

  • 对于 base data tablet,这个key就是 row locator
  • 对于 index data,如果 index column 是 unique的,那么key就是index column;否则需要在 index column 后添加 row locator

比如一个table有两个index:一个unique index:col1,一个非unique index:col2,那么base data tablet 的 key 是 「row locator」,index1 的 key 是 「col1」,index2 的 key 是 「col2, row locator」

通过将 table 分组的方式来进行管理,用户可以将相关的table划分到一个 table group中,相关的写入操作只产生一条 wal log,降低 wal log量、消除不必要的shuffle。

===== 3.2 Table Group Shard

[Paper Reading] Alibaba Hologres: A Cloud-Native Service for Hybrid Serving/Analytical Processing===== 3. Storage

TGS 由一个 WAL Manager 和 属于该TGS的 多个tablet 组成。

每个 tablet 统一由 LSM tree 管理:

  • 每个 tablet 包括 一个 MemTable 和 一些不可变的 shard file
  • MemTable 定期flush成为一个 shard file
  • Level0 中,每个 shard file 对应一个 flushed MemTable
  • 从 Level1 开始,所有的 record 都是按照 key 有序排列的, 所有各个shard file之间是没有 overlap 的
  • Leveli+1 的 shard file 数量是 Leveli的 K 倍,每个 shard file 最大为 M

每个 tablet 维护一个 metadata file 记录 shard file 的状态(类似 RocksDB)。

每个 tablet 仅支持单并发写入 ,但是可以支持多个 reader 读取。HSAP场景对 一致性 要求不高,所以仅支持 原子写 和 RYW 隔离

===== 3.2.1 Writes in TGSs

Hologres 支持两种类型写入:single-shard write & distributed batch write,两种写入都是原子的。single-shard write 仅支持一个 shard 写入,distributed batch write 则支持大量数据导入多个TGS。

Single-shard write流程:

  1. WAL Manager 为 写入请求 分配一个 LSN,这个LSN由 timestamp & 自增id 组成
  2. 创建一个 log entry,并将其持久化
  3. 数据写入 memory table,随即对其他请求可见
  4. 按需 flush & compaction

Distributed Batch Write,使用 两阶段提交 来保证写入原子性:

  1. FE 节点作为 协调者,锁定所有需要访问的 tablet
  2. 每个 TGS 执行写入:分配 LSN、flush memory table、加载数据并将其flush成 shard file
  3. TGS 向 FE 投票、FE收集投票决定 commit or abort
  4. FE 节点释放 tablet 锁

===== 3.2.2 Reads in TGSs

Hologres 保证 RYW 隔离级别,client 总是可以看到其最后一次提交写入的 LSN。每次读取操作会包含一个 timestamp(这里应该就是最后一次写入的LSN),用来构建 LSNread。LSNread 与 record LSN 共同决定 record 是否可见。

TGS 还记录一个 LSNref,表示当前 tablet 维护的最老版本 LSN。LSNref 根据用户指定的保留时间定期更新,在数据 flush & compaction 时根据 LSNref 决策 record 是否被 merge

===== 3.2.3 Distributed TGS Management

一个TGS的所有读写都在同一个 worker 节点上完成,以共享 memory table,如果 worker 节点压力过大,则会将 TGS(这里应该是 tablet?)从 worker 节点上迁走。

为了支持更高的并发,后续有计划支持 两种类型的 read replica:fully-synced replica & partially-synced replica

  • fully-synced replica:维护最新的 memory table & metadata file,支持最新的数据读取
  • Partially-synced replica:仅维护最新的 metadata file,支持已经flush到磁盘的数据读取

===== 3.3 Row Tablet

[Paper Reading] Alibaba Hologres: A Cloud-Native Service for Hybrid Serving/Analytical Processing===== 3. Storage

内存态使用一个 Masstree 来维护,按照 key 来排序。

Shard file 是一个分块结构(block-wise structure),包含两种块:data block & index block:

  • Data block 中数据按 key 排序,连续的record存储在同一个 data block 中
  • Index block 索引每个 data block 的 starting key & offset:(key, block_offset)

内存态&shard file 中的key对应的value格式为 (values_cols, del_bit, LSN):

  • values_cols:记录非key列的值 -- 这里应该只存储了变更数据,而非整行数据
  • del_bit:记录是否是删除记录
  • LSN:本次写入的LSN

Reads in Row Tablets,读请求包含 key 和 LSNread:

  • 【data skipping】同时从 MemTable & shard files 中读取数据,根据 metadata 筛选包含对应key以及LSN匹配的数据的文件
  • 【Merge on Read】并根据 LSN 顺序merge 数据,构建结果

因为这里需要 Merge on Read,所以values cols中应该存储的只是变更数据

Writes in Row Tables

  • insert & update请求 包括 key、column value、LSNwrite
  • Delete 请求 包括 key、deletion mark、LSNwrite

Row Tablet 是一个基于 LSM Tree 的 Delta Store,数据整体按照key来排序。每个数据文件都只存储了 delta 数据,所以需要 Merge on Read。

===== 3.4 Column Tablet

[Paper Reading] Alibaba Hologres: A Cloud-Native Service for Hybrid Serving/Analytical Processing===== 3. Storage

Column Tablet 由一个 column LSM tree & delete map 组成。

Column LSM tree 的value是 (value_cols, LSN):

  • value_cols:记录非 key 列的值 -- 这里应该是整行数据
  • LSN:本次写入的 LSN

数据在内存态使用 Apache Arrow 来维护,按照写入顺序排序。

在持久化文件(shard file)有三类 block:

  • Data Block:按照 key 来排序,并拆分为 row group。同一列的数据在连续的 Data Block 中存储,即每个Data Block中存储一个 row group中的一列数据,接下来的Data Block仍然存储这一列的数据,这与 Parquet 的存储格式是不同的
  • Meta Block:存储列的 metadata & 文件的 metadata
    • Column metadata:data blocks 的 offset、每个 data block 的 range、编码格式
    • File metadata:编码格式、row count、LSN & key range
  • Index Block:为了快速完成key的定位,index block中存储了row group中的第一个key

Delete map 是一个 row tablet,key是 shard file id,value存储的是 bitmap、LSN 等信息,方便快速过滤。

Reads in Column Tablet,读请求只包括 target column & LSNread:

  • 从 memory table & shard file 并行读取,根据 LSN 过滤
  • 读取出来的数据与 delete map 进行merge

与 row tablet 不同的是,column tablet 的 shard file 都可以独立的输出,而不需要和其他shard file合并。因为 delete map 可以说明哪些数据被删除了。

Writes in Column Tablet

  • Insert 请求包括key、column values、LSNwrite
  • Delete 请求包括 key 、LSNwrite,根据key快速定位目标文件以及 row number
  • Update 请求 = Delete + Insert

Column Tablet 整体是一个基于 LSM Tree 的 Delete+Insert 的结构,Delete 信息按照 file 级别存储在一个 Row Tablet中。每个数据文件中都存储了一行完整的数据。

Delete+Insert 的方案也不太能快速定位目标文件,因为L0层可能有很多 key range 包含目标key的shard file,相比于 delta store 的方案是更快的

===== 3.5 Hierarchical Cache

包括 local disk cache,block cache,row cache,用于查询加速

继续阅读