最近往ceph对象存储中,灌了1年的历史数据,大概4 5千万个文件进去以后,集群开始告警,这篇文章简要的记录了排除过程。由于排除的时间跨度有点长,大部分输出都没有了,只能写下大概的过程
pg中的对象太多
ceph health detail后,会提示 pool XXX has many more objects per pg than average ,提示内容其实说的很明白了。就是说某个池里单个pg的对象太多了,如果要消除这个,要么是删掉不用的pool,或者减少其他pool中的pg数量,要么就是这个池增长。由于ceph不支持直接减少pg数量,我们选择了扩容。 请注意,调整pg数量,会导致大量的数据需要平衡,平衡过程中如果有节点挂掉,可能会导致这个池无法写入,请评估风险。
增加的方法很简单,在管理节点执行下面的语句就完了
1 | ceph osd pool set {pool-name} pg_num {pg_num} |
pg和pgp数量应该是一致的,而且最好是2的指数倍。
改完以后,噩梦就开始了,ceph -s 会提示
1 | xxxxx/yyyyy objects misplaced (52.642%) |
可以看到开始平衡了,然而默认参数下,速度极慢,1计算,会发现要好几天才能平衡完毕。
先按照网上的教程,把并发调大
1 | ceph tell 'osd.*' injectargs '--osd-recovery-max-active 4' |
会发现,恢复速度会有不小提升。然而过了半天再看,会发现又下降了回来。
真正很有效的参数是下面这个
1 | ceph tell osd.* injectargs '--osd_recovery_sleep_hdd 0' |
ceph在默认情况,ceph在恢复的间隔进行睡眠,默认0.1秒,可能是为了避免恢复造成压力,也可能是为了保护硬盘。将休眠关闭以后,恢复速度会基本达到网卡或者硬盘的性能极限。
数据平衡完毕以后,建议改回默认值
1 | ceph tell 'osd.*' injectargs '--osd-recovery-max-active 3' |
index文件过大
rehard
ceph -s 会有下面的字样
1 | 2 large objects found in pool 'xxxx.buckets.index' |
一般的做饭是直接分片,shard数量根据实际的对象数量来预估。不超过每个shard,10万个
1 | radosgw-admin reshard --bucket=xxx --num-shards=yyy |
然并卵,这样多半要失败,而且会留下垃圾数据
检查一下,bucket-name替换为实际的桶名称
radosgw-admin metadata get bucket:bucket-name
找到bucket_id字段,替换下面的id
radosgw-admin metadata get bucket.instance:bucket-name:bucket_id
num_shards就是目前实际的shard数量,如果上面的reshard失败了,这个值还会是个比较小的值。
改为后台运行
radosgw-admin reshard add –bucket=realname-images –num-shards=768
用下面的命令查询进度
1 | radosgw-admin reshard list |
查询可以看到新的bucketid,然而,ceph并不会删除老的元数据。必须自己手动清理。
删除老的元数据
首先确认下是不是真的是bucket的key太多。看看到底有多少key
1 | for i in `rados -p .default.rgw.buckets.index ls`; do echo -n "$i:"; rados -p default.rgw.buckets.index listomapkeys $i |wc -l; done > omapkeys |
先检查一下
1 | for bucket in $(radosgw-admin bucket list | jq -r .[]); do |
如果同一个桶出现一次以上,就说明还有老数据,用下面的脚本生成删除命令
1 | for bucket in $(radosgw-admin bucket list | jq -r .[]); do |
如果嫌麻烦,可以把echo去了就是直接删除,我个人还是建议手工检查一下,再人工执行删除,另外,我个人非常不建议用rados rm来删除
以为这就完了?
扫描一下
虽然对象已经删除了,但是告警是还在的。需要手动扫描一下才行,看看是哪些pg里的多
1 | for i in `ceph pg ls-by-pool default.rgw.buckets.index | tail -n +2 | awk '{print $1}'`; do echo -n "$i: "; ceph pg $i query |grep num_large_omap_objects | head -1 | awk '{print $2}'; done | grep ": 1" |
再扫描
1 | ceph pg deep-scrub 11.3c |
插曲
全部弄完以后,添加新的机器到集群中,发现新节点1启动,就会自杀,而且还有一个老节点也挂掉。搜索日志可以看到
1 | map e2579 wrongly marked me down at e2579 |
没办法,先设置ceph osd set nodown , 数据平衡了一段时间以后,发现很多pg卡在inactive。再其他osd上查看。可以看到下面的日志
1 | heartbeat_check: no reply from 10.174.100.6:6801 osd.3 ever on either front o |
然而直接telnet一切正常。最后排查
netstat -ant |sort -k4 发现没有指向某个ip的链接。 登录到指定的主机一看。原来运维把这台机器的ip设置错了,吐血。根据网上其他人的经验来看,inactive一般是selilux或者网络方面的问题