Store

1.架构图

存储架构

存储类负责管理整个存储系统,该系统由两层存储引擎组成:上层是 Engine,下层是 RawEngine。 Engine 和 RawEngine 都是抽象接口类,可以有多个实现,如 RocksEngine、RaftKvEngine、MemEngine 等。

RawEngine 是底层引擎,充当封装器,也可以有多个实现。 引擎内部可以包含 RawEngine。

  • RaftKvEngine 是基于 Raft 的分布式存储引擎,用于生产环境。

  • RocksEngine 是一个具有单一副本的单节点存储引擎,既可用于生产环境,也可用于测试环境。

  • MemEngine 是一个基于内存的存储引擎,主要用于测试。

  • RawRocksEngine 是 RocksDB 的直接封装器,封装了 RocksDB 的实现细节,并为上层提供了易于使用的接口。

2.存储流程

这里使用Key/Value内存存储,由于Key/Value是一个二进制字节数组,因此直接用std::string存储不是很合适。您可以使用RocksDB的Slice类来表示它,这可以减少数据传输过程中的数据复制。

  • KvPUT

KvPut

  • KvGet

KvGet

3.元数据管理

StoreServerMeta: 管理存储节点的状态,无需持久化,可在存储节点启动时从配置文件中获取。

存储区域元信息(StoreRegionMeta): 管理存储节点上的所有区域元信息,这些信息需要持久保存并定期报告给协调器。

  • 持久化

    • key: META_REGION_{region_id}

    • value: pb协议pb::common::Region序列化

    • 只保留最新版本

    • 当region状态有变化时立即持久化

    • region 的版本由 epoch field表示。 当region 的状态发生变化时,epoch 也会发生变化、并且单调增加。

*StoreMetaManager:*管理store所有的元数据,包括StoreServerMeta和StoreRegionMeta。

4.实施过程

  • 创建 Table/Region Create Table

  1. 验证是否可以创建分区。

    • epoch==0&&state=NEW && NotExist(region)

    • Region是否合法。

    • 节点包含当前存储节点。

  2. 保存 Region元数据

  3. 创建 Raft Peers。

  4. 初始化 Raft Peer。

  5. 添加到 Raft 节点管理器。

  6. 更新 Region状态。

  7. 如果是Raft leader,通知coordinator

注释:

Region 应该有两个状态,一个是与Region 相对应的 Peer 的状态(Region-Peer-State),另一个是Region 的状态(Region-State)。 Region-State 由 Coordinator 维护,Region-Peer-State 由 Store 维护。

  • Delete Table/Region Delete Table

  1. 验证是否可以销毁Region 。

  2. 更新Region 元数据。

  3. 准备销毁该Region。

  4. 从 Raft 节点管理器中移除。

  5. 关闭 Raft 节点。

  6. 更新Region 元数据。

  7. 通知 Coordinator.

注释: Coordinator 只有在收到半数以上Store 的成功删除确认后,才会认为表格删除成功。

  • Store 初始化:

    1. 初始化配置文件。

    2. 初始化服务日志。

    3. 验证Coordinator 是否存在且有效。

    4. 首先读取本地文件,初始化服务 ID。 如果不存在,则从Coordinator中获取。

    5. 初始化从Coordinator获取的当前服务节点的region 。

    6. 初始化存储引擎。

    7. 初始化 StoreService。