Cassandra执行元数据压缩任务时间过长时的处理方法

Posted on

 Translate this page into English

对于一个日常数据变化量较大的分布式存储服务集群(比如NetApp StorageGRID),其Cassandra元数据表SSTable中堆积大量过期数据是在所难免的。一般而言,当SSTable大小到达一定值时,便会自动触发元数据压缩任务,这个压缩操作会将标记为过期的key从SSTable中清理掉,进而释放可用空间。

随着数据量变化幅度的增加,有时会出现元数据压缩任务十分缓慢的情况。元数据压缩无法完成,便会影响所在节点的存储服务性能(因为压缩也会占用一定的I/O及CPU资源)。此时可以尝试通过孤立节点的方式,临时缓解元数据压缩速度。

问题现象

1. 节点的整体存储服务性能下降

2. 使用$ top命令观察到系统CPU使用率高,且主要被Java进程占用

3. 执行$ nodetool compactionstats命令可以看到多个压缩任务正在进行,类似如下情况:

$ nodetool compactionstats

Pending tasks: 6

Compaction Type     Keyspace        Table               Completed       Total           Unit    Progress
Compaction          storagegrid     s3_key_by_bucket    131822603712    1744984129313   bytes   7.55%
Compaction          storagegrid     s3_key_by_bucket    544             284528121764    bytes   0.00%
Compaction          storagegrid     s3_key_by_bucket    54411613725     367394592446    bytes   14.81%
Compaction          ilmqueue        ilm_queue           33031517        41991942        bytes   78.66%
Validation          storagegrid     object_by_uuid      242621050684    748915553843    bytes   32.40%

Active compaction remaining time: 36h,01m,26s

可以观察到Active compaction remaining time剩余时间较长。

处理方法

遇到上述情况,可以临时将问题节点孤立,以加快元数据压缩进度。

注意:此方法有一定风险造成节点的元数据同步不一致。除非元数据压缩长时间无进展,否则不建议使用。

1. SSH登陆至问题节点

2. 禁用原生通信,本地元数据暂停同步:

$ nodetool disablebinary

#注:在早期版本的Cassandra中使用的通讯协议为Thrift,在当前主流版本中已被废弃
#如果使用的是早期版本的Cassandra,需要禁用Thrift以防止节点成为元数据调度节点
$ nodetool disablethrift

3. 禁用Gossip,暂停点对点通信(同时会暂停对外元数据服务):

$ nodetool disablegossip

4. 提高元数据压缩的吞吐量限制,以加快压缩速度(Cassandra默认为16M/s):

$ nodetool setcompactionthroughput 200

5. 检查压缩任务的剩余时长是否得到缩减

状态恢复

在元数据压缩任务顺利完成后,需要将上述操作回退,以便元数据正常更新,并恢复对外服务:

$ nodetool enablebinary
$ nodetool enablegossip
$ nodetool setcompactionthroughput 16

确认Cassandra服务状态:

$ nodetool info

#从其他正常节点查询该节点状态是否为UN
$ nodetool status

END

0