故事背景
线上有3台Cassandra组成的小集群,随着数据增长,硬盘使用量达到了90%以上,急需扩容。
于是,就查文档,按文档一步步添加新节点,来增加集群规模。
但是,看文档就像看新闻联播,一切都很美好,可实操起来就干啥啥不行,走哪哪是坑。
于是,就有了这篇笔记,把踩坑过程做个记录,希望能帮到深陷泥潭的小伙伴。
第一关:新节点安装配置
按照文档安装、配置新节点。
文档:https://docs.datastax.com/en/cassandra/2.1/cassandra/operations/ops_add_node_to_cluster_t.html
第二关:清空垃圾数据
按照文档启动新节点后,数据同步到20G左右,就会停滞不前,之后再也没动静。
看下日志:
tail -1000 $CASSANDRA_HOME/logs/debug.log
发现有同步到某个表时,有WARN日志。
删除了新节点的data,重来一遍,发现还是一样的情况。
实验过修改Cassandra内存,仍然没有解决问题,况且,其他更大的表都能同步成功,于是怀疑是不是这个表本身有问题呢?
与业务方沟通后,得知这些都是很久不用的,早已废弃,而且数据是从2.1.x的Cassandra迁移过来的,可能存在兼容问题,所以直接干掉!
这样,就跳过了这个WARN,可以继续向下同步了。
如果,你也有这种已经废弃的垃圾数据,建议先删除,再进行同步,避免一些莫名其妙的问题。
删除数据方式:
- CQL:DROP TABLE tablename
- 手动删除每个节点对应的数据目录
第三关:资源优化
由于数据量很大,同步过程会对集群带来很大的负载,所以尽可能关闭或限制一些功能,避免对线上业务造成影响。
- 关闭压缩
$CASSANDRA_HOME/bin/nodetool disableautocompaction
$CASSANDRA_HOME/bin/nodetool stop COMPACTION
所有节点都关闭,包括新节点(新节点启动后关闭)。
- 限制流量
$CASSANDRA_HOME/bin/nodetool setstreamthroughput 32
所有节点都限制。
如果不限制,可能带宽全被数据同步给占用完了,就无法保障线上业务能及时响应了。
这取决于业务情况,如果无所谓,可以不限制。
32的单位是mbps,表示限制某节点用于数据同步的带宽为32mbps,可以根据自己的网络情况设置相应的值。
第四关:Session超时
有些表文件非常大,约60G,按照32mbps带宽估算,传输速度为4m/s,大约需要4.267小时才能完成。
这种情况下,查看日志,会收到一个WARN:
Remote peer xx.xx.xx.xx failed stream session
这是因为session超时了。
需要修改cassandra.ymal文件的streaming_socket_timeout_in_ms值。
默认值是3600000,即1小时,改成172800000(48小时),保证时间足够传输完所有数据。
第五关:飞一会儿
如果同步过程中有WARN,基本上已经失败了,可以停掉重来了。
当把所有WARN都解决后,就耐心等待,让它飞一会儿。
最好用网络工具监控下流量,时刻监控新节点的网络流入量是否正常。
如果用nodetool status查看状态,可能变化很慢,不要慌,只要传输流量正常,日志没有报WARN,基本就没问题。
以我们的情况为例,1T数据,没有限制网络流量的情况下,足足同步了30多小时,status才从UJ变为UN。
尾声:
查看集群状态
$CASSANDRA_HOME/bin/nodetool status
如果所有节点都变成UN,那么恭喜,新节点成功加入了。
接下来就是一些收尾工作了。
之前关闭了自动压缩,现在重新开启:
$CASSANDRA_HOME/bin/nodetool enableautocompaction
新增了节点,应该分担一部分数据压力,原节点数据量应该会减少,但是查看原节点磁盘使用量,发现并没有减少,需要手动清理一下:
$CASSANDRA_HOME/bin/nodetool cleanup
原节点每个都要执行一下,这个也比较费时,放后台跑着就行了。
总结:
虽然过程总遇到很多坑,但总结起来,解决办法无非做到以下几点
- 看日志,找错误、警告,并想办法解决掉
- 监控流量、进程,确保任务没有死掉
- 意志坚定、死磕到底
注意:
每次重来,一定要把新节点的数据目录清空,否则可能导致数据丢失、损坏。切记!