Skip to content

2: 总体设计

Colin edited this page Mar 25, 2023 · 32 revisions

Raft 库日志存储结构

日志

  • 写日志的时候先写磁盘,后写内存 cache,读先读内存后读磁盘(内存没读到),优化。

设计原稿,可评论 https://docs.google.com/drawings/d/16GtqVtMF6p3v2B_A_mhpsgsm60oFm-837saBntPYhOk/edit?usp=sharing

ERaftKV 设计了一个双 db 结构的日志存储,在进行快照的时候我们会创建第二个 DB 进行写入,快照的时候我们会 apply 掉第一个 db 里面的所有日志,这个操作是有锁的,为了影响性能。在我们打快照的之前创建了第二个 DB 继续写入增量数据。

Raft 库选举流程

选举流程

  • 选举流程支持可选的 prevote 开启选项进行预选举
  • 新加入的节点日志没有追上前,不参与选举
  • pre_candidate 选举的请求里面任期号加一,但是节点自己的任期号不会加

设计原稿,可评论 https://docs.google.com/drawings/d/1HR_L1fYSmWy6k5mLNfn3DD3O9U6YAoNATG4haeps-g8/edit?usp=sharing

Raft 库日志复制流程

日志复制

设计原稿,可评论 https://docs.google.com/drawings/d/1G2eCE9f1JxXcs_soha79JmiMjfOs0ZTGoONzZLsW29c/edit?usp=sharing

ERaftKV 分片节点动态变更

增删节点

设计原稿,可评论 https://docs.google.com/drawings/d/1wjZW0INYzx0PjY_rl9DnMI89IMAFppOMEHGG8hdUrNc/edit?usp=sharing

ERaftKV 快照

快照流程

  • 快照过程中,不能触发新的快照请求
  • 快照可以有用户自定义触发

设计原稿,可评论 https://docs.google.com/drawings/d/1Xb0GcWWzm5SF7_gHb4kDYtCTx9AXQs8kNXYNNLsAA9Y/edit?usp=sharing

ERaftKV 集群多分片

多分片集群方案

  • 没有中心节点存储集群配置,定期在集群间进行配置广播,少一层与配置节点交互,提高性能

设计原稿,可评论 https://docs.google.com/drawings/d/15OHAKqugRBvbnQale3UJnfVzOYpp0nBJ7XvuzIhx6EA/edit?usp=sharing

ERaftKV 集群多分片进行重新分片

slot 迁移数据,可以实现 auto rebalance

slot迁移设计

  • 对源端 key 的读取,发送迁移,删除数据必须是一个原子操作(在迁移这个 key 的期间在 meta 集群存一个 lock key 的指令)。
  • 后续优化上 MVCC

设计原稿,可评论 https://docs.google.com/drawings/d/1ZIjES69DUWkkqHfRqiHPGoFltkqfP5M2BSJVsP34ByM/edit?usp=sharing

ERaftKV 对外接口以及客户端

  • 数据操作类
接口定义 说明
Put(K, V) 写入数据
Get(K) 读取数据
Del(K) 删除指定K数据
PutBatch(Ks, Vs) 写批量数据
Gets(Ks) 读取批量数据
Gets(Ks) 读取批量数据
Dels(Ks) 删除指定Ks的批量数据
  • 集群操作类
接口定义 说明
JoinCluster(SHARDGROUP LEADER ADDR) 节点加入集群
InitCluster() 初始化集群节点
AddShardGroupNode(NODE_ID, NODE_ADDR) 添加节点到分片集群
RemoveShardGroupNode(NODE_ID) 从分片集群中删除节点
NodeShutDown(NODE_ID) 指定节点退出进程
ShardGroupTransferLeader(TARGET_NODE_ID) 指定 NODE 成为 Leader
MigrateKeysTo(TARGET_NODE_IP, TARGET_NODE_PORT, SLOT_START, SLOT_END) 从当前分片迁移 SLOT_START-SLOT_END 范围的数据到目标节点