Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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

  • 分布式进程中单机内存和 RaftLog 内存没有统一考虑管理,导致分布式内存一开始就比较紧张。
  • RaftLog 模块自身做了简单的内存控制策略,但只是针对已 commit 日志做的,未 commit 的日志没有通过阻写的方式来实现完备的内存控制。
  • RaftLog 模块的内存控制与单机的内存控制产生了正反馈导致系统崩盘。极端情况下,由于内存不够,单机状态机受单机内存控制模块影响导致 apply 日志过慢,然而 RaftLog 模块的清理内存线程只能清理 applyIndex 之后的日志,这导致 RaftLog 模块的内存控制几乎失效,无法清理内存中的日志。两者的双向作用共同导致了问题的进一步恶化。
  • RaftLog 模块的后台清理内存线程默认被关闭了,导致目前只有在 commit 的时候才会去检验内存,这可能使得内存释放不及时。当然,即使有它也不能完全避免第二个问题。的时候才会去检验内存,这可能使得内存释放不及时。当然,即使有它也不能完全避免前面提到的问题。

方案

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

Leader 内存控制策略:

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

...