High Latency Optimize

背景现象

近期在客户现场 Cassandra 三节点高可用集群中某一节点在启动时需要半小时左右的时间,启动时日志停在 Initializing system.paxos ,需要半小时后日志才能继续滚动,程序才继续启动,但是整个启动过程中没有存在异常和报错。日志如下:

INFO  [main] 2023-10-25 10:59:48,533 ColumnFamilyStore.java:430 - Initializing system.IndexInfo
INFO  [main] 2023-10-25 10:59:49,254 ColumnFamilyStore.java:430 - Initializing system.batches
INFO  [main] 2023-10-25 10:59:49,259 ColumnFamilyStore.java:430 - Initializing system.paxos

# debug 日志如下
DEBUG [main] 2023-10-25 10:59:48,533 DiskBoundaryManager.java:53 - Refreshing disk boundary cache for system.paxos
DEBUG [main] 2023-10-25 10:59:48,533 DiskBoundaryManager.java:92 - Got local ranges [] (ringVersion = 0)
DEBUG [main] 2023-10-25 10:59:48,533 DiskBoundaryManager.java:56 - Updating boundaries from null to DiskBoundaries{directories=[DataDirectory{location=/data/cassandra_data/data}], positions=null, ringVersion=0, directoriesVersion=0} for system.paxos

重启几次之后,发现启动时间长短不一,但也基本需要接近半小时左右才能完全启动。在启动过程中机器负载正常,内存使用也正常,swap 也已关闭。检测磁盘在启动过程中只有大量读请求,但也在合理范围之内,排查过程中 iostat 工具无法显示磁盘利用率情况,因此无法判断磁盘是否有异常,但还是怀疑是磁盘问题。

排查解决

由于启动时停在上述日志位置,于是想通过上述日志查询有无相关问题。然而却发现一个类似文章,内容也是关于磁盘问题,但却是 Cassandra 关于针对 JBOD 而做的优化,大致意思当存在大量 tokens 时,Cassandra 加载并计算 token 范围时产生明显延迟。

于是根据解决方案启动时在 jvm 配置文件 jvm.options 中增加参数如下参数绕过启动时加载磁盘边界和阻止系统分割 token 范围。

-Dcassandra.split_sstables_by_token_range=false

增加了上述配置之后再次启动 Cassandra ,观察日志依然停在上述位置,等了不到 5 分钟直到 Cassandra 启动完成。通过上述优化确实在性能底下的磁盘上也有不错的改善,将启动延时从 30 分钟降到 5 分钟内,但问题依然没有解决,但也可以继续确认是跟硬盘有关。

后续再继续排查系统是否存在其他问题一起导致此现象时,猜测到可能某块磁盘已经存在异常(坏块)而导致的上述问题,因使用的是虚拟化创建的虚机,所以想将 Cassandra 数据移动备份并迁移时却发现,几十兆的数据在备份时也出现了卡住了的现象,这时才断定磁盘已经出现问题了。

最后在一段时间之后虚拟化平台果然报警其中一块磁盘已经离线,到此此问题也基本定位到原因。但是也确定一个优化方式,在 JBOD 磁盘或磁盘性能低下时通过增加 -Dcassandra.split_sstables_by_token_range=false jvm 参数确实在暂时无法解决磁盘问题时能大大改善 Cassandra 启动的效率。

Infee Fang
Infee Fang
互联网二手搬砖工