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.99k stars 886 forks source link

arm64 架构 leader 创建的 replicator 有概率不再发送日志给 follower #473

Closed lengmoXXL closed 3 weeks ago

lengmoXXL commented 2 months ago

版本:v1.1.2 架构:arm64

现象: 在 3 个节点组成的 group 里,在运行一段时间(1天或者2天)后,其中一个 follower 的 index 落后 leader 且不再更新

初步调查结果:

  1. 出现问题后,leader 只会发送 heartbeat 给对应的 follower,而不再发送带有日志的 AppendEntries rpc
  2. 通过添加日志发现,leader 的两个 replicator 在发送完日志后,调用 log_manager->wait 等待新的日志,等待完成后,一个 replicator 的回调没有被调用,另一个 replicator 的回调被调用了两次,导致后续不再发送 AppendEntries

image

关于添加日志的逻辑: image image

  1. 根据上面的日志看,问题可能出在 log manager 的 _wait_map flatmap 上?

想问下,这个问题有什么进一步调查的方向吗?

lengmoXXL commented 2 months ago

后面又加了一些日志,看起来 wake_up_waiter 函数里拿到的两个 wait meta 的指针是一样的。

[2024-09-18 19:55:09.569939]    [INFO]  [92718] [external/com_github_brpc_braft/src/braft/log_manager.cpp:920]  :wakeup_all_waiter: {17160979: 0xfffdde802d28, 8800387989505,17160980: 0xfffdde802d28, 8800387989505}

https://github.com/apache/brpc/pull/2156 有没有可能跟这个问题有关?

lengmoXXL commented 2 months ago

butil::get_object 使用了 thread_local 变量,如果两次 butil::get_object/return_object 之前有 bthread 切换(例如调用 bthread_start_urgent)就会有问题

lengmoXXL commented 2 months ago

image 应该是这里有问题。

ehds commented 2 months ago

brpc 是使用什么版本呢?

lengmoXXL commented 2 months ago

brpc 是使用什么版本呢?

brpc 使用的是这个 commit:b3a948c9dca29632b3367529488e070852e31f11 gcc 版本:7.3

lengmoXXL commented 3 weeks ago

加上 -fno-gcse, -fno-cse-follow-jumps, -fno-move-loop-invariants 这几个编译参数可以解决。看起来使用高版本的编译器也不会有这个问题。