sofastack / sofa-jraft

A production-grade java implementation of RAFT consensus algorithm.
https://www.sofastack.tech/projects/sofa-jraft/
Apache License 2.0
3.52k stars 1.12k forks source link

ReadIndex frequently times out. #1103

Closed ye-xiaowei closed 2 months ago

ye-xiaowei commented 2 months ago

Your question

read index 总是超时 Status[ETIMEDOUT<1010>: read-index request timeout]

Your scenes

3个节点一个follower节点掉线,这个时候发向leader的readIndex总是超时

Your advice

看堆栈像是卡在了 ThreadId.lock 上,因为一个节点掉线导致长时间建立连接并且持有锁?

在 continueSending 的时候也会持有锁

是否可以改成 在readIndex的时候异步的发送心跳,这样就不会影响发向正常节点的心跳了。

for (final PeerId peer : peers) {
    if (peer.equals(this.serverId)) {
        continue;
    }
   // 下面用一个线程来执行
    this.replicatorGroup.sendHeartbeat(peer, heartbeatDone);
}

Environment

fengjiachun commented 2 months ago

是否可以改成 在readIndex的时候异步的发送心跳

不行的,如果有阻塞,会逐步 block 住所有可用线程的,没办法从根本解决问题。

这里有个判断,对于没创建连接的,会快速失败并异步建连,不应该有阻塞的。你用的什么版本?

另外,看堆栈,这是魔改过的 jraft?

ye-xiaowei commented 2 months ago

我在排查为什么会timeout的时候自己加了很多日志所以行数可能对不上,版本是1.3.13.

看图片2,堆栈中checkConnection之后 park?

我打印日志的时候发现readIndex在从发送到一个掉线的节点,到发送到正常的节点相差5s,这个时候早已timeout了。然后会打印

A timeout read-index response finally returned: Status[OK]

fengjiachun commented 2 months ago

不仅仅是日志行数对不上的问题,比如 com.galaxybase 是什么?

看图片2,堆栈中checkConnection之后 park?

看不到具体代码行数,不过是 ConcurrentHashMap 里面的锁吧?这里 bolt rpc 建连也是异步的 (我的意思是想说你再抓一把线程栈可能没有这个 wait 了)

至少从现在的信息里是看不到哪里 block 的,建议用 arthas 试试能不能找到 block 在哪了

ye-xiaowei commented 2 months ago

嗯嗯