ceph灾备之cephfs snapshot mirror和rsync对比
背景
最近要做ceph集群之间的灾备功能,主要讨论文件存储,因为ceph集群容量越来越大,接入的业务也越来越多,一旦出现故障,恢复时间都是小时级(根据经验每年都会出现几次这种事故),对于核心业务无法接受,最近搭建了一套集群做灾备,对cephfs数据的同步进行调研
cephfs同步方案
- cephfs snapshot mirror
- inotify+rsync
cephfs snapshot mirror
cephfs数据同步由cephfs-mirror守护进程管理,pacific以及之后的版本支持,详细说明见官方文档。
测试集群环境如下:
集群名称 | ceph版本 | osd | MDS |
---|---|---|---|
local集群 | 16.2.5 | 2个1T的HDD,组成两副本 | 1主1备 |
remote集群 | 16.2.5 | 2个1T的HDD,组成两副本 | 1主1备 |
创建用户
local端用户
通过cephadm启动的cephfs-mirror进程,会自动创建用户,不需要单独创建
local$ ceph orch apply cephfs-mirror #ceph orch apply cephfs-mirror --placement=<placement-spec>
remote端用户
官方提供的ceph fs authorize <fs_name> client.mirror_remote / rwps 还需要赋mgr权限,所以直接使用以下命令:
remote$ ceph auth get-or-create client.mirror_remote mon 'allow r fsname=cephfs' mds 'allow rwps fsname=cephfs' osd 'allow rw tag cephfs data=cephfs' mgr 'allow *'
local和remote同步配置
remote端
- mgr是能mirror
remote$ ceph mgr module enable mirroring
- 创建peer的启动配置
使用Bootstrap Peers管理比较方便,否则要在local端维护remote的ceph集群配置
remote$ ceph fs snapshot mirror peer_bootstrap create FILE_SYSTEM_NAME CLIENT_NAME SITE_NAME
remote$ ceph fs snapshot mirror peer_bootstrap create cephfs client.mirror_remote remote-site
{"token":
"eyJmc2lkIjogIjBkZjE3MjE3LWRmY2QtNDAzMC05MDc5LTM2Nzk4NTVkNDJlZiIsICJmaWxlc3lzdGVtIjogImJhY2t1cF9mcyIsICJ1c2VyIjo
gImNsaWVudC5taXJyb3JfcGVlcl9ib290c3RyYXAiLCAic2l0ZV9uYW1lIjogInNpdGUtcmVtb3RlIiwgImtleSI6ICJBUUFhcDBCZ0xtRmpOeEF
BVnNyZXozai9Y}
local端
- mgr使能mirror
local$ ceph mgr module enable mirroring
- cephfs开启mirror
ceph fs snapshot mirror enable <fs_name>
#关闭使用ceph fs snapshot mirror disable <fs_name>
3.添加peer端
把remote端创建的token导入到local
local$ ceph fs snapshot mirror peer_bootstrap import cephfs
eyJmc2lkIjogIjBkZjE3MjE3LWRmY2QtNDAzMC05MDc5LTM2Nzk4NTVkNDJlZiIsICJmaWxlc3lzdGVtIjogImJhY2t1cF9mcyIsICJ1c2VyIjog
ImNsaWVudC5taXJyb3JfcGVlcl9ib290c3RyYXAiLCAic2l0ZV9uYW1lIjo
#如果取消添加对端 执行 ceph fs snapshot mirror peer_remove FILE_SYSTEM_NAME PEER_UUID
查看peer端状态
查看添加的remote信息
local$ ceph fs snapshot mirror peer_list cephfs
{"e5ecb883-097d-492d-b026-a585d1d7da79": {"client_name": "client.mirror_remote", "site_name": "remote-site",
"fs_name": "cephfs", "mon_host": "[v2:10.0.211.54:3300/0,v1:10.0.211.54:6789/0] [v2:10.0.210.56:3300/0,v1:
10.0.210.56:6789/0] [v2:10.0.210.65:3300/0,v1:10.0.210.65:6789/0]"}}
添加同步目录
上述步骤完成后就可以开始配置同步的目录了
local$ ceph fs snapshot mirror add <fs_name> <path>
查看状态
- mirror进程的状态
local$ ceph fs snapshot mirror daemon status <fs_name>
- 同步的状态
#通过help可以看到有两条查看同步状态的命令
local$ ceph --admin-daemon /path/to/mirror/daemon/admin/socket help
:
local$ ceph --admin-daemon /var/run/ceph/cephfs-mirror.asok fs mirror status filesystem-name@filesystem-id
local$ ceph --admin-daemon /var/run/ceph/cephfs-mirror.asok fs mirror peer status filesystem-name@filesystem-id peer-uuid
:
#查看镜像状态
local$ ceph --admin-daemon /var/run/ceph/cephfs-mirror.asok fs mirror status cephfs@360
#查看往remote端同步的状态
local$ ceph --admin-daemon /var/run/ceph/cephfs-mirror.asok fs mirror peer status cephfs@360 a2dc7784-e7a1-4723-
b103-03ee8d8768f8
开始同步
上述配置完成后还不能同步目录,因为cephfs snapshot mirror同步的是snap,因此需要创建snap才能够同步,snap的创建有两种方式:
- 使用官方的scheduled snapshots,每隔一定周期创建一个snap,cephfs mirror自动扫描最新的snapshot开始同步
- 手动在同步的目录下创建文件夹,如当前mirror同步配置的目录是/test_sync,则cd /test_sync/.snap/snap_test,cephfs-mirror默认10秒扫描一次,如果扫描到snap_test为最新的snapshot,开始同步。这种方式不用等调度,可以快速验证同步机制。cephfs mirror是根据local和remote的snapid判断是否为最新,详细原理可以参考cephfs mirror同步工具源码
inotify+rsync
inotify+rsync是从客户端角度的同步方案,rsync可以全量和增量同步数据,结合inotify获取当前变更的文件进行同步,减少无效的目录扫描,由于rsync是很成熟的方案,这里不再详细介绍
测试结论
- cephfs snapshot mirror同步10MB以下的文件时性能比直接写入remote的性能差,性能损耗50%左右,把10MB作为分割点应该和测试环境有关,但是可以确认的是同步4k、64k等的小文件性能会有很大的损耗。10MB以上的大文件的同步和直接写入性能相当。
- 此外基于快照的同步因两次快照的间隔会出现数据丢失的问题,如果使用schedule
snap的方式管理,粒度最小是1h,做灾备要允许丢至少1h的数据。 - 在测试过程中对cephfs mirror的源码进行了解,cephfs mirror是基于libcephfs进行快照同步,通过扫描快照中的文件进行同步,对于文件数比较多的目录会对mds会造成很大的压力,甚至导致锁住文件影响正常业务读写。
总结和思考
从测试结果来看mirror的同步适用场景比较局限,大文件、允许丢失一段时间的数据、文件数比较小的场景比较适合。通过以上的测试对比,最终还是选择inotify+rsync做数据同步。但是有两个问题需要继续调研解决的:
- 无论cephfs mirror还是rsync都是对目录的扫描,如果cephfs目录小文件达到几十万上百万个,一次扫描下来会导致文件锁死的隐患影响业务性能,如果在ceph侧做文件数限制比较困难,因为每个业务都要调整自己的读写模式,局限性太大。当然,如果文件数不多,这也就不是问题了
- 增量更新都是基于文件的,如果1G的文件更新了数据,同步的时候是整个文件,业务频繁更新会产生大量的同步带宽,占用无效资源。目前还没有发现有工具能解决这个问题,当前的解决方案是通过拉长同步时间线的方式,比如把更新调整为10分钟内更新一次,无论这10分钟更新多少次或更新10次之后再更新等等,具体方案要结合业务场景制定;或有什么办法能够知道文件更新了哪些数据,这样只需要更新这部分数据即可,还需要调研。
以上是对cephfs snapshot mirror和rsync的测试思考,如果有哪位大佬有更好的方案,或在以上测试结论中有疑问的地方,还请多多指教,一起探讨。
参考
cephfs-mirroring
snap-schedule
source code cephfs_mirror
rsync
inotify-tools