Ceph Pool 迁移

laurentbarbe

你可能已经遇到过将所有对象从一个池迁移到另一个池的情况,特别是为了更改无法在池上修改的参数。例如,要从复制池迁移到 EC 池,更改 EC 配置文件,或减少 PG 的数量……根据池的内容(RBD、对象)、大小等,有不同的方法。

简单的方法

最简单和最安全的方法是使用“rados cppool”命令复制所有对象。但是,它需要在复制期间对池具有只读访问权限。

例如,要迁移到 EC 池

1
2
3
4
5
pool=testpool
ceph osd pool create $pool.new 4096 4096 erasure default
rados cppool $pool $pool.new
ceph osd pool rename $pool $pool.old
ceph osd pool rename $pool.new $pool

但它并非在所有情况下都有效。例如,对于 EC 池:“复制池 testpool => newpool 时出错:(95) 操作不受支持”。

使用缓存层

必须谨慎使用,在生产集群中使用之前进行测试。它适用于我的需求,但我不能说它在所有情况下都有效。

我发现这种方法很有趣,因为它允许透明操作,减少停机时间并避免复制所有数据。原理很简单:使用缓存层,但顺序相反。

一开始,我们有两个池:当前的“testpool”和新的“newpool”

设置缓存层

将现有池配置为缓存池

1
2
ceph osd tier add newpool testpool --force-nonempty
ceph osd tier cache-mode testpool forward

ceph osd dump 中,你应该看到类似这样的内容

--> pool 58 'testpool' replicated size 3 .... tier_of 80 

现在,所有新对象都将在 newpool 上创建

现在我们可以强制将所有对象移动到 newpool

1
rados -p testpool cache-flush-evict-all

将所有客户端切换到新的池

(你也可以更早地执行此步骤。例如,在创建缓存池之后。)在所有数据被刷新到新池之前,你需要指定一个叠加来搜索旧池上的对象

1
ceph osd tier set-overlay newpool testpool

ceph osd dump 中,你应该看到类似这样的内容

--> pool 80 'newpool' replicated size 3 .... tiers 58 read_tier 58 write_tier 58

使用叠加,所有操作都将转发到旧的 testpool

现在你可以将所有客户端切换到访问新池上的对象。

完成

当所有数据迁移完成后,你可以删除叠加和旧的“缓存”池

1
2
ceph osd tier remove-overlay newpool
ceph osd tier remove newpool testpool

正在使用的对象

在驱逐期间,你可能会遇到一些错误

....
rb.0.59189e.2ae8944a.000000000001   
rb.0.59189e.2ae8944a.000000000023   
rb.0.59189e.2ae8944a.000000000006   
testrbd.rbd 
failed to evict testrbd.rbd: (16) Device or resource busy
rb.0.59189e.2ae8944a.000000000000   
rb.0.59189e.2ae8944a.000000000026   
...

列出对象上的监视器可以提供帮助

1
2
rados -p testpool listwatchers testrbd.rbd
watcher=10.20.6.39:0/3318181122 client.5520194 cookie=1

使用 Rados 导出/导入

为此,你需要使用一个临时本地目录。

1
2
3
4
5
6
7
8
9
10
11
12
13
rados export --create testpool tmp_dir
[exported]     rb.0.4975.2ae8944a.000000002391
[exported]     rb.0.4975.2ae8944a.000000004abc
[exported]     rb.0.4975.2ae8944a.0000000018ce
...

rados import tmp_dir newpool

# Stop All IO
# And redo a sync of modified objects

rados export --workers 5 testpool tmp_dir
rados import --workers 5 tmp_dir newpool