baidu / braft

An industrial-grade C++ implementation of RAFT consensus algorithm based on brpc, widely used inside Baidu to build highly-available distributed systems.
Apache License 2.0
3.92k stars 876 forks source link

_append_entries_in_fly的一些困惑 #467

Open cangfengzhs opened 1 month ago

cangfengzhs commented 1 month ago
    struct FlyingAppendEntriesRpc {
        int64_t log_index;
        int entries_size;
        brpc::CallId call_id;
        FlyingAppendEntriesRpc(int64_t index, int size, brpc::CallId id)
            : log_index(index), entries_size(size), call_id(id) {}
    };

我的理解是这里的log_index代表的是每个request的first index。 那么,在on_rpc_returned

 while (!r->_append_entries_in_fly.empty() &&
           r->_append_entries_in_fly.front().log_index <= rpc_first_index) {
        r->_flying_append_entries_size -= r->_append_entries_in_fly.front().entries_size;
        r->_append_entries_in_fly.pop_front();
    }

这段代码中,小于等于当前request.first_index的所有flying request都会被清理掉。

我的疑惑是在下面的场景中会不会出现问题:

  1. 当前next_index是10
  2. send_empty_entries(hearbeat = false),此时_append_entries_in_fly中内容为[{10,0,call_1}]
  3. send_entries(),此时_append_entries_in_fly中内容为[{10,0,call_1}, {10,1,call_2}]
  4. send_empty_entries返回,在on_rpc_returned的逻辑中,while循环里(上面提到的)会将call_1和call_2的flying request全部清理掉
  5. send_entres返回,找不到call_2,直接退出。此时,11应该被ballotBox.commit,但是没有执行所以11一直都不会被apply。

请教下我哪里理解的有问题还是braft存在bug

ehds commented 1 month ago

什么情况下,在 send_empty_entries(hearbeat = false) 返回前,会发起 send_entries?

" 11应该被ballotBox.commit "

11 是指 log_index 吗?例子中是指的哪儿?

cangfengzhs commented 1 month ago

什么情况下,在 send_empty_entries(hearbeat = false) 返回前,会发起 send_entries? 这一点我还没有理太清楚,braft有保证这一点吗?

11 是指 log_index 吗?例子中是指的哪儿? 是的,11指的是log_index。就是在(3)那一步通过send_entries发送的数据,也就是_append_entries_in_fly队列中的第二个

ehds commented 1 month ago

什么情况下,在 send_empty_entries(hearbeat = false) 返回前,会发起 send_entries? 这一点我还没有理太清楚,braft有保证这一点吗?

11 是指 log_index 吗?例子中是指的哪儿? 是的,11指的是log_index。就是在(3)那一步通过send_entries发送的数据,也就是_append_entries_in_fly队列中的第二个

你可以看下 braft 代码,send_empty_entries(hearbeat = false) 主要是用于 check follower 的当前有效的 log index,所有调用这个函数之前都会清理 _append_entries_in_fly (即所有fly的rpc都会被强行取消)。 你可以 double check 下。

还有一点没看懂:

send_entries(),此时_append_entries_in_fly中内容为[{10,0,call_1}, {10,1,call_2}]

如果是发送 11 的日志为什么 nextindex 是 10?