问题
默认情况下,ceph的生产环境的对象存储bucket是强烈建议关掉动态reshard的,实际上也是这样,在集群建设初期就为zone设置默认的shard值,然后在使用过程中,如果有需要再进行手工的reahrd去改变shard的值。
由于bucket reshard操作执行时间较长,在执行过程中(命令行前台执行)如果发生网络中断或者不小心Ctrl+C进行了中断,就会导致一系列现场无法清理,不能继续进行reshard。
举例
首先挑选一个bucket:
1 | "bucket": "CS3-bench-bucket-z0QmTpWrYu_w1y", |
接下来,对其做reshard:
1 | [test1@mon-1 ~]$ radosgw-admin bucket reshard --bucket=CS3-bench-bucket-z0QmTpWrYu_w1y --num-shards=7999 |
实测,即便使用bucket reshard add,操作也会在前台执行。
此时如果网络断开了,或者Ctrl+C中断,或者其他问题导致的命令行前台断开,都会导致reshard的现场无法清理,例如尝试cancel这个操作
1 | [test1@mon-1 ~]$ radosgw-admin reshard cancel --bucket=CS3-bench-bucket-z0QmTpWrYu_w1y |
或者重新进行reshard:
1 | [test1@mon-1 ~]$ radosgw-admin bucket reshard --bucket=CS3-bench-bucket-z0QmTpWrYu_w1y --num-shards=7999 |
这是因为reshard退出后没有对bucket的相关状态和信息做重置清理,那么思路上,就要手工清理了。
查了一圈,没有什么好办法,有个maillist的老哥倒是遇到了,但是他删除bucket了事……还是靠自己吧。
首先是根据重新reshard时产生的报错信息进行代码的定位:
1 | if (bucket_info.reshard_status != CLS_RGW_RESHARD_NOT_RESHARDING) { |
显然,bucket info中保存了当前bucket的状态,如果状态为reshard中,就不能再reshard了。
解决
根据reshard的原理,清理它产生的残留现场需要看几个地方:
- .log存储池中reshard命名空间存放的reshard的信息,也就是cancel时提示的无法删除的oid
- .meta存储池中的新bucket的信息,因为要重启reshard,已经产生了的新bucket就没有存在的必要了
- .index存储池中新的bucket的shard数据,reshard开始时会一次性产生足够的shard,需要都删掉。
- bucket info的相关信息清理,不清理就不能重启reshard
首先是log池中的信息,在reshard过程中,集群会在这个池的reshard命名空间创建一些对象:
1 | [test1@mon-1 ~]$ rados -p tanwjzone1.rgw.log ls --namespace reshard |
如果有对应bucket的object,就用rados命令删掉(实际测试发现有的bucket有创建对应的object,有的bucket没有)
接下来是meta池中的信息,根据bucket名字直接查找:
1 | [test1@mon-1 ~]$ rados -p tanwjzone1.rgw.meta ls --all|grep 'Yu_w1y' |
可见452041308.1为后缀的对象就是new bucket的相关数据,可以用rados直接删掉。
还有index中残留的新bucket的shard信息,使用新的bucket id进行过滤
1 | [test1@mon-1 ~]$ rados -p tanwjzone1.rgw.index ls|grep 'c0ed785b-1870-4077-9feb-41ced8f29013.452041308.1' -c |
这些也要删掉。
最后是bucket info中的信息,首先要获取bucket的bucket info,注意是用原来bucket的id:
1 | [test1@mon-1 ~]$ radosgw-admin metadata get bucket.instance:CS3-bench-bucket-z0QmTpWrYu_w1y:c0ed785b-1870-4077-9feb-41ced8f29013.277247706.112 |
可以看到在reshard_status字段显示为1,表示正在做reshard,new_bucket_instance_id则记录了新bucket的id。
修改方法就是将上述内容写到文件中,然后将reshard_status置为0,new_bucket_instance_id置空,然后重新导入:
1 | [test1@mon-1 ~]$ radosgw-admin metadata put bucket.instance:CS3-bench-bucket-z0QmTpWrYu_w1y:c0ed785b-1870-4077-9feb-41ced8f29013.277247706.112 < newinfo |
完成后,重新进行reshard即可:
1 | [test1@mon-1 ~]# radosgw-admin bucket reshard --bucket=CS3-bench-bucket-z0QmTpWrYu_w1y --num-shards=7999 |
注意到,重新做reshard会重新生成bucket id,与上次reshard产生的bucket是不相同的。
总结
整个问题的处理过程,我个人觉得,手动执行reshard这个功能设计上是不太合理的,当然,想不发生中断最好的办法就是nohup放后台跑,避免一些问题,但是发生中途的问题导致reshard不能继续下去,后面又不能快速重启reshard,或者自行清理这些残留的东西,这里就是设计上的缺陷。
以上,希望对大家有所帮助。
- 本文作者: 奋斗的松鼠
- 本文链接: http://www.strugglesquirrel.com/2026/09/29/对bucket手动reshard时中途断开的处理/
- 版权声明: 本博客所有文章除特别声明外,创作版权均为作者个人所有,未经允许禁止转载!