You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Next »

现象

三节点三副本分布式执行写入,稳定运行 15 天后出现了 OOM。


Unable to render Jira issues macro, execution error.

分析

通过对日志和内存 dump 的分析,发现分布式 RaftLogManager 中的内存缓存超出了阈值。在探究内存缓存超出阈值的原因时,发现主要有以下三个问题:

  • 分布式进程中单机内存和 RaftLog 内存没有统一考虑管理,导致分布式内存一开始就比较紧张。
  • RaftLog 模块自身做了简单的内存控制策略,但只是针对已 commit 日志做的,未 commit 的日志没有通过阻写的方式来实现完备的内存控制。
  • RaftLog 模块的后台清理内存线程默认被关闭了,导致目前只有在 commit 的时候才会去检验内存,这可能使得内存释放不及时。当然,即使有它也不能完全避免第二个问题。

方案

需要在分布式进程中将单机内存和 RaftLog 内存统一管理并配备极端情况阻写的内存控制策略,此外还可默认开启后台的内存清理线程以提高容错性。

Leader 内存控制策略:

  • 当前有太多超过未提交的日志时,参照单机内存控制阻塞写入一段时间。

Follower 内存控制策略:

  • Leader 采用 dispatcher 模式(单独启一个线程)进行同步,对于每一个 Follower,如果其未 catchup,则先向其同步之前的日志再发送之后的日志,同时在发送日志时直接使用 RaftLogManager 的日志即可,不用提前 build request,此处可以参照 pipeline 的优化。
  • Follower 在遇到本地 applyIndex 与 Leader 的 commitIndex 相差过大时,可以暂时拒绝 leader 的写入,直到本地 applyIndex 跟上为止。 


  • No labels