Closed Cczzzz closed 2 years ago
jraft 的主从模式是异步的,但是我阅读代码发现实际上 发送log 和收到从节点响应的处理逻辑中会抢用同一个锁。导致处理响应时不能继续发送新的请求给从节点,即使已经有了可以发送的新log。 我尝试添加log 以观察锁的影响: 在 Replicator#continueSending 1000 行
static boolean continueSending(final ThreadId id, final int errCode) { if (id == null) { //It was destroyed already return true; } long nanoTime = System.nanoTime(); final Replicator r = (Replicator) id.lock(); long num = r.getOpts().getLogManager().getLastLogIndex() - (r.nextIndex - 1); if (r == null) { return false; } double cost = (System.nanoTime() - nanoTime) / 1000D; if (num > 0 && cost > 10) { LOG.warn("lock cost time {} us , ready log is {}", cost, num); }
在3w tps 写入的情况下 可以看到对写入到耗时大概影响到 20-30 微妙,最坏可能会到达 0.1 ms
这里的锁是必要的,但是瓶颈不应该在这里。
看起来,耗时主要是 r.getOpts().getLogManager().getLastLogIndex() 吧? 另外 continueSending 通常是因为发送 log 不连续也就是吞吐较低才会被触发的,在你 3w tps 写入的情况下,这里不应该被频繁调用也不会是热点代码,理论上不影响写入耗时。
r.getOpts().getLogManager().getLastLogIndex()
continueSending
可以再看看是否有别的原因。
先关闭了,有新的发现可以再打开
jraft 的主从模式是异步的,但是我阅读代码发现实际上 发送log 和收到从节点响应的处理逻辑中会抢用同一个锁。导致处理响应时不能继续发送新的请求给从节点,即使已经有了可以发送的新log。 我尝试添加log 以观察锁的影响: 在 Replicator#continueSending 1000 行
在3w tps 写入的情况下 可以看到对写入到耗时大概影响到 20-30 微妙,最坏可能会到达 0.1 ms