Kairbon'Blog.

基于Raft协议的NoSQL数据库的设计和实现(6)-MetaServer

字数统计: 879阅读时长: 3 min
2021/05/21

基于Raft协议的NoSQL数据库的设计和实现-MetaServer

前面我们提到,Meta Server 主要有这几个功能:

  1. 管理监控所有节点。
  2. 给出交互接口。

那接下来详细介绍一下每个功能是如何实现的。

1. 监控管理Store Server功能

我们之所以要管理监控Store Server,是需要管理Store Process 的存亡,动态拉起注册一个节点或者重启原本节点,使得整个系统处于最大可用状态。因此从技术层面需要做两件事情:

1.1 实时获取更新所有节点的存活状态

这个功能我将其拆分为三个问题,首先是如何实时更新?这个我们通过心跳机制来做到。在每个节点上,我们需要配置对应Meta Server集群的地址,以每隔20ms的频率向Meta Server推送当前节点的状态。

figure 1

图一 Meta Server心跳

第二个问题是如何高可用存储节点状态数据,这个问题就比较困难了,因为Meta Server是有状态的服务,为了保证其高可用,我们采用raft的方式去使得这部分数据能够同步冗余,一旦leader节点宕机,follower节点也可以立刻服务。

第三个问题是数据结构的问题,因为Partition,node(character),shard,这些信息都是一级一级嵌套的,因此我们采用了类似zookeeper的目录式结构,但这样也会有一些问题。比如:如果我们不做冗余的索引,当我在查询某几个节点的存活状态时就需要遍历,这会导致时间开销,但如果使用索引,又会导致需要同步索引等问题增加复杂性。因此在未来,我们也将考虑将其底层改为支持sql的KV式的存储引擎。

1.2设计节点重启和加入时的策略

节点一般在以下三种情况下会需要这个策略:

  1. 节点宕机重启。
  2. 新节点加入已有的partition
  3. 新节点加入新partition

第一种情况下,我们只需要判断当心跳延时10s未发送时则判断该节点死亡,该节点下的所有shard也判为死亡。这时候就需要向节点所在服务器发送信号通知重启进程或通知管理员重启机器。而raft自带的snapshot和日志复制策略可以使得重启后的进程能够追上partition集群内其他节点的进度。

第二种情况和第一种类似,SOFA-JRAFT支持动态注册新节点到raft集群内,因此我们只需要实现相关的接口即可。partition加入新节点时,集群内部会向原来raft集群通知,然后raft集群会修改集群状态机接纳新节点,并且向新节点同步数据。

第三种情况涉及到新的partition,在我们的方案中,则需要新增一个hash环或整体进行rehash。详情参考算法篇。

2. 交互接口

client方面,一方面dmeta client要为Store Server提供支持,提供心跳上报功能,另一方面,dmeta client也要为用户提供支持,用户需要获得全局信息Global View(主要是所有shard的信息)以获取哪个Key在哪个位置,我应该把这个key发送到哪个位置,这里也会在算法篇详细讲述。

CATALOG
  1. 1. 基于Raft协议的NoSQL数据库的设计和实现-MetaServer
    1. 1.1. 1. 监控管理Store Server功能
      1. 1.1.1. 1.1 实时获取更新所有节点的存活状态
      2. 1.1.2. 1.2设计节点重启和加入时的策略
    2. 1.2. 2. 交互接口