Skip to content

Latest commit

 

History

History
66 lines (49 loc) · 3.26 KB

0. Introduction.md

File metadata and controls

66 lines (49 loc) · 3.26 KB

源码目录结构

  • raft.h/cpp:所有对外接口的定义
    • Task
    • StateMachine
    • Node:这里的 Node 只是对 NodeImpl 的 wrapper,所有的操作都是调用 NoteImpl 完成的
  • node.h/cpp:NodeImpl 的实现,apply Task、节点管理(add_peer/remove_peer/change_peer)、snapshot、vote、append_entries 等
  • replicator.h/cpp:日志复制的实现,一个 Replicator 对应一个 Follower,由 ReplicatorGroup 统一管理
  • log_manager.h/cpp:日志存储相关的实现,log 格式由 log_entry.h/cpp 定义,包括了两种 log 实现:
    • SegmentLogStorage:定义在 log.h/cpp 中,基于文件的日志实现,默认方式
    • MemoryLogStorage:定义在 memory_log.h/cpp 中,基于内存的日志实现
  • shapshot_xxx 相关:snapshot 实现,包括 SnapshotExecuto、LocalSnapshotWriter、LocalSnapshotReader、LocalSnapshotStorage 等
  • raft_service.h/cpp:RPC 服务实现,一共包括 5 个 RPC:pre_vote、request_vote、append_entries、install_snapshot、timeout_now,这里只是一些简单的处理,最终还是靠调用 Node 的接口实现的。
  • raft.proto:RPC 接口和消息格式定义
  • node_manager.h/cpp:通常来说,我们会在一个进程中运行多组 raft(即有多个 Node 实例存在),这些所有的 Node 都监听同一个 RPC 服务端口,在收到 RPC 请求后需要根据 request 消息体中的 peer_id 找到对应的 Node 实例进行调用。

异步 brpc

https://github.com/apache/incubator-brpc/blob/master/docs/cn/client.md#%E5%BC%82%E6%AD%A5%E8%AE%BF%E9%97%AE

https://github.com/apache/incubator-brpc/blob/master/docs/cn/server.md#%E5%BC%82%E6%AD%A5service

braft 的实现中,都是用的异步调用。

Closure and ClosureGuard

braft 的流程都靠异步回调来驱动,其中 Closure 就是回调函数的定义,braft 中定义了各种 Closure 用于 RPC 完成后或其他步骤完成后的回调,比如 pre_vote 完成后的回调 OnPreVoteRPCDone

Closure 定义如下,只需要继承该类并实现 Run 方法即可,而 brpc::ClosureGuard 用于调用 Run 函数:

class PROTOBUF_EXPORT Closure {
 public:
  Closure() {}
  virtual ~Closure();

  virtual void Run() = 0;

 private:
  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Closure);
};

我们以 pre_vote 为例来说明,其他流程类似。pre_vote 由 VoteTimer 超时后发起,然后调用函数 NodeImpl::pre_vote() 实现 pre_vote。

  1. NodeIMpl::pre_vote() 向其他节点发起 pre_vote RPC 请求,该调用的最后一个参数(done)类型是 OnPreVoteRPCDone
  2. 其他节点接收到 pre_vote 请求后,会调用 NodeImpl::handle_pre_vote_request() 处理该请求并返回结果
  3. 当 RPC 返回后,OnPreVoteRPCDone::Run() 函数会被回调,该函数会调用 NodeImpl::handle_pre_vote_response() 处理 pre_vote 的 response。
class RaftServiceImpl : public RaftService {
public:
    explicit RaftServiceImpl(butil::EndPoint addr)
        : _addr(addr) {}
    ~RaftServiceImpl();

    void pre_vote(google::protobuf::RpcController* controller,
                              const RequestVoteRequest* request,
                              RequestVoteResponse* response,
                              google::protobuf::Closure* done);
    // ... ...
}

bthread