Open jackjoesh opened 2 years ago
LogManagerImpl里的logsInMemory是否有内存泄露风险? 重现原因: 1 如果follower重启后,需要append log的非常多,比如几亿条(某些原因leader长时间没有snapshot),那logsInMemory里就会添加很多到内存里 2 而在NodeImpl的handleAppendEntriesRequest逻辑里,是用JRaft-LogManager-Disruptor队列的空间大小来判断是否足够接收log的,不会去判断logsInMemory内存空间是否足够 3 logsInMemory的清理需要等到状态机apply或者打snapshot的时候,相当于收到log到apply这段时间内,内存是无法清理的,且apply速度一般不会那么快。
实测下来,大概logsInMemory只需要缓存36万个segment,内存占用就可以突破13GB,会内存泄露。内存dump如下:
out of memory日志: 2022-06-05 16:04:52 [JRaft-LogManager-Disruptor-0] ERROR LogExceptionHandler:64 - Handle LogManagerImpl disruptor event error, event is com.alipay.sofa.jraft.storage.impl.LogManagerImpl$StableClosureEvent@7d4d317b java.lang.OutOfMemoryError: Java heap space
是否应该考虑加入对logsInMemory空间限制的保护?
确实存在这样的风险,需要加一个硬性限制,或者软性限制(比如交换到堆外空间等),降低内存和 gc 压力。
请问调小JRaft-LogManager-Disruptor队列的空间大小会缓解吗 @killme2008
LogManagerImpl里的logsInMemory是否有内存泄露风险? 重现原因: 1 如果follower重启后,需要append log的非常多,比如几亿条(某些原因leader长时间没有snapshot),那logsInMemory里就会添加很多到内存里 2 而在NodeImpl的handleAppendEntriesRequest逻辑里,是用JRaft-LogManager-Disruptor队列的空间大小来判断是否足够接收log的,不会去判断logsInMemory内存空间是否足够 3 logsInMemory的清理需要等到状态机apply或者打snapshot的时候,相当于收到log到apply这段时间内,内存是无法清理的,且apply速度一般不会那么快。
实测下来,大概logsInMemory只需要缓存36万个segment,内存占用就可以突破13GB,会内存泄露。内存dump如下:
out of memory日志: 2022-06-05 16:04:52 [JRaft-LogManager-Disruptor-0] ERROR LogExceptionHandler:64 - Handle LogManagerImpl disruptor event error, event is com.alipay.sofa.jraft.storage.impl.LogManagerImpl$StableClosureEvent@7d4d317b java.lang.OutOfMemoryError: Java heap space
是否应该考虑加入对logsInMemory空间限制的保护?