找回密码
 注册
查看: 1803|回复: 0

分布式存储Ceph rbd-mirror灾备同步数据

[复制链接]

1

主题

0

回帖

12

积分

管理员

积分
12
QQ
发表于 2021-12-7 13:35:36 | 显示全部楼层 |阅读模式
个人主要关注的技术领域:高性能Nginx开发、分布式缓存、分布式存储。
0 N/ a4 K5 R) k. _8 T1.说明介绍 1.1 基本原理
9 ^) r  s" X; D- n) E, mRBD Mirror原理其实和MySQL的主从同步原理非常类似,前者基于journaling,后者基于binlog,简单地说就是利用日志进行回放(replay):通过在存储系统中增加Mirror组件,采用异步复制的方式,实现异地备份。(此处的journal是指Ceph RBD的journal,而不是OSD的journal)
  v; F. J( j: k; O2 V/ h$ ^该能力利用了 RBD image 的日志特性,以确保集群间的副本崩溃一致性。镜像功能需要在同伴集群( peer clusters )中的每一个对应的 pool 上进行配置,可设定自动备份某个存储池内的所有 images 或仅备份 images 的一个特定子集。 rbd-mirror 守护进程负责从远端集群拉取 image 的更新,并写入本地集群的对应 image 中。; z$ V3 @9 K# Y
当RBD Journal功能打开后,所有的数据更新请求会先写入RBD Journal,然后后台线程再把数据从Journal区域刷新到对应的image区域。RBD journal提供了比较完整的日志记录、读取、变更通知以及日志回收和空间释放等功能,可以认为是一个分布式的日志系统。
6 l2 _6 U8 s* Y5 k. S( i  ~" P) o- |, T1.2 工作流程3 ?: M9 {  {  {5 j4 y& x$ C! T4 F
1 J8 D0 d  Z. ?; Z# Z
1、当接收到一个写入请求后,I/O会先写入主集群的Image Journal
9 S* m% \8 K* V' B. ~2、Journal写入成功后,通知客户端
8 L# N# J  G  R0 k3、客户端得到响应后,开始写入image9 E! o3 `2 [' S9 R0 i  v( _2 |
3、备份集群的mirror进程发现主集群的Journal有更新后,从主集群的Journal读取数据,写入备份集群(和上面序号一样,是因为这两个过程同时发生)
& F: p8 D( n& {' S4、备份集群写入成功后,会更新主集群Journal中的元数据,表示该I/O的Journal已经同步完成2 g" u, Z9 j4 q; C, w$ c" _
5、主集群会定期检查,删除已经写入备份集群的Journal数据。# @2 D/ u) X  K& e
以上就是一个rbd-mirror工作周期内的流程,在现有的Jewel版本中30s为一次工作周期,暂时不能改变这个周期时间。; w( W4 f" {7 d. C0 q/ D; L
1.3 优点
8 I( f- @2 f  U) v1、当副本在异地的情况下,减少了单个集群不同节点间的数据写入延时;
( ~1 n8 |: E' W2、减少本地集群或异地集群由于意外断电导致的数据丢失。, g7 U# _# O2 z! A  l1 ^
1.4 单向备份与双向备份
+ N& X" _1 B$ U" E' K- [7 d9 g双向备份:两个集群之间互相同步,两个集群都要运行rbd-mirror进程。
* C7 e  F$ e2 S( X* g单向备份:分为主集群和从集群,只在从集群运行rbd-mirror进程,主集群的修改会自动同步到从集群。& l) m; P' J+ ?+ S. s2 l6 D% D+ P8 Y
1.5 安装须知# p  ?8 ^, R8 m+ N: `) P0 d
RBD 镜像功能需要 Ceph Jewel 或更新的发行版本。
' W8 C' R6 l/ e5 m8 r目前Jewel版本只支持一对一,不支持一对多。' {5 y5 a; ~, ^% e- z9 K/ K( k
两个集群 (local和remote) 需要能够互通。8 P0 V# ]: O3 S% J' e! a1 g
RBD需要开启journal特性, 启动后会记录image的事件。
6 m( T2 s- N: A9 e* T  ?7 ~2. mirroring 模式7 d( x8 u3 y+ M- I
mirroring是基于存储池进行的peer,ceph支持两种模式的镜像,根据镜像来划分有:9 U6 c8 ?4 X) ~/ }# q' E
存储池模式3 @4 Q( E) m% r! a+ E7 K. z4 |& Z
一个存储池内的所有镜像都会进行备份" O7 b( [3 Z1 u+ a4 l5 _
镜像模式
4 Y+ R& D0 L+ Z' C只有指定的镜像才会进行备份2 i: M4 L: W( m( {; [& b6 p
2.1 存储池模式 2.1.1 创建存储池5 S; K& d: V5 P/ l7 A
创建一个用于测试的存储池:2 D9 p. S1 d# F$ {0 J6 G
#local集群% E0 v( i# M  G( ^8 [/ l2 I
ceph osd pool create test_pool 100 100 replicated --cluster= localpool 'test_pool'created2 e$ B" E& Q- N# W6 {- v
#remote集群7 u9 o8 l: L3 c7 ?- l% x
ceph osd pool create test_pool 100 100 replicated --cluster=remotepool 'test_pool'created 2.1.2 启用存储池模式3 a! w; }# v8 K- o" h7 ]9 q! T
开启存储池rbdmirror的镜像功能:5 x) y( W; a& S4 f9 l  l
#local集群. W: H" W3 w5 U& B- C
rbd mirror pool enabletest_pool pool --cluster= local' |3 C& ]) g6 _1 Y
#remote集群+ r5 ~- B) F4 m7 U- R
rbd mirror pool enabletest_pool pool --cluster=remote 2.1.3 创建RBD
) c' H- [3 ]' d  A; s+ ~主集群创建一个测试用的RBD:
. W- `9 [3 b- u* k3 a& Brbd create test_pool/test_image --size=1024 --cluster= local2.1.4 主集群开启jounaling特性6 O7 E& b" O2 b+ Z! O) Y
启动后会才会记录image的事件,才可以被rbd-mirror检测到并同步到从集群:$ c' {* }# ]/ j$ E: }
rbd feature enabletest_pool/test_image exclusive-lockrbd feature enabletest_pool/test_image journaling 2.1.5. 增加同伴集群
0 c& ]& {/ B) B, B. S把local和remote设为同伴,这个是为了让rbd-mirror进程找到它peer的集群的存储池:* S% t1 ^; W0 ~
rbd mirror pool peer add test_pool client.admin@remote --cluster= local  Z# `$ L! z6 M4 l1 d
rbd mirror pool peer add test_pool client.admin@ local--cluster=remote
- ~2 k1 I/ M/ J#如果需要删除peer 语法:
7 ~9 G# V6 n/ `5 @- Xrbd mirror pool peer remove <pool-name> <peer-uuid>8 h0 N6 M6 |! Q
查看peer的情况:
* x7 X# U5 Z9 q& erbd mirror pool info --pool=test_pool --cluster= localMode: poolPeers:UUID NAME CLIENTf0929e85-259d-450b-917e-9eb231b7e43b remote client.admin rbd mirror pool info --pool=test_pool --cluster=remoteMode: poolPeers:UUID NAME CLIENT5851ba6a-e383-4ef0-9b9d-5ae34c9518a6 localclient.admin 2.1.6 开启rbd-mirror的同步进程$ b* Y- o# h* N4 {6 {0 x
a. 先用调试模式启动进程看看情况,在remote的机器上执行" @# m1 y9 X* K  L3 o4 j0 R
#remote:4 @# Q9 ?7 {1 L. c% ^0 w7 j5 {
rbd-mirror -d --setuser ceph --setgroup ceph --cluster remote -i admin$ V7 }' f% t4 A' L2 \/ Y7 o% P
b. 如果确认没问题就用服务来控制启动
9 D; b% b% X9 C& Z% Z0 Q5 U#remote
3 U/ X6 _  \% I# F) }- uvim [url=]/usr/lib/systemd/system/ceph-rbd-mirror@.service[/url]8 R; y6 _) R  m' Z/ E& K& Q; \
#修改, H/ @/ X" Y0 X" y
Environment= CLUSTER=remote: {3 T2 m3 h% ?) D; y
c. 在remote机器上启动
; o' j4 x/ {' S: ssystemctl start ceph-rbd-mirror @adminps -ef|grep rbdceph 43251117: 59? 00: 00: 00/usr/bin/rbd-mirror -f --cluster remote --id admin --setuser ceph --setgroup ceph 2.1.7 检查同步结果
& @! I* L- K+ j% T- U! za. 查询local集群镜像的同步的状态
, m. D9 E8 ~+ [#local
* w& [) g" v- {rbd mirror image status test_pool/test_image --cluster remotetest_image: global_id: dabdbbed-7c06-4e1d-b860-8dd104509565 state: up+replaying deion: replaying, master_position=[object_number=2, tag_tid=2, entry_tid=3974], mirror_position=[object_number=3, tag_tid=2, entry_tid=2583], entries_behind_master=1391 last_update: 2017-01-22 17:54:22
  P! Z  x4 B6 Tb. 检查数据是否同步到remote集群& R, ]! j6 `$ r
#remote
$ U. X6 x3 O0 L" P: lrbd info test_pool/test_image 2.2 镜像模式 2.2.1 主集群开启jounaling特性
# R/ i# n* f, [3 s( [启动后会才会记录image的事件,才可以被rbd-mirror检测到并同步到从集群$ \7 g- o1 A' M! G& S* m
#local9 p# }+ s  t% a; x
rbd feature enabletest_pool/test_image exclusive-lockrbd feature enabletest_pool/test_image journaling 2.2.2 开启存储池的mirror的模式 #local:
5 U  q. P9 _: v2 y" lrbd mirror pool enabletest_pool image
! C: A5 N8 h4 Y1 v8 F#remote:- M" e1 o4 C' G) [+ i; U4 @
ceph osd pool create test_pool 100 100 replicated --cluster=remotepool 'rbdmirror'created rbd mirror pool enabletest_pool image 2.2.3 开启image的mirror #local
* O0 [" v% t+ ?" L6 @! i7 \. h6 Irbd mirror image enabletest_pool/test_imageMirroring enabled rbd info test_pool/test_image --cluster= localrbd image 'test_image': size 10240 MB in2560 objects order 22 (4096 kB objects) block_name_prefix: rbd_data.105774b0dc51 format: 2 features: layering, exclusive-lock, journaling flags: create_timestamp: Wed Dec 13 16:46:08 2017 journal: 105774b0dc51 mirroring state: enabled mirroring global id: 013f9e35-9d08-40fc-bf24-1e11a07a0910 mirroring primary: true2.2.4 增加同伴集群0 V0 t' a2 G5 w& T5 z0 N
把local和remote设为同伴,这个是为了让rbd-mirror进程找到它peer的集群的存储池:
6 |) ?% F- I8 f' orbd mirror pool peer add test_pool client.admin@remote --cluster= local
' a. H3 \# ]$ J6 b/ frbd mirror pool peer add test_pool client.admin@ local--cluster=remote0 R+ E  k. L& @
#如果需要删除peer 语法:6 r5 M  u5 t' o1 m
rbd mirror pool peer remove <pool-name> <peer-uuid>
* k  g4 P% x& X1 R查看peer的情况:+ \- p! E4 `: {/ P! C
rbd mirror pool info --pool=test_pool --cluster= localMode: poolPeers:UUID NAME CLIENTf0929e85-259d-450b-917e-9eb231b7e43b remote client.admin rbd mirror pool info --pool=test_pool --cluster=remoteMode: poolPeers:UUID NAME CLIENT5851ba6a-e383-4ef0-9b9d-5ae34c9518a6 localclient.admin 2.2.5 开启rbd-mirror的同步进程! C7 u0 C- _6 T/ O2 z, {
a. 先用调试模式启动进程看看情况,在remote的机器上执行
" `6 C% K5 j/ f9 i, y#remote:
8 }& P% b: g  prbd-mirror -d --setuser ceph --setgroup ceph --cluster remote -i admin
% F5 I8 a: r+ s: ~7 Bb. 如果确认没问题就用服务来控制启动% q* \2 }4 y9 n, m' f$ ?; I8 v
#remote
$ x. L- a8 j. |8 Q; z' L! ?vim [url=]/usr/lib/systemd/system/ceph-rbd-mirror@.service[/url]* P% r* p- @# b' a, I
#修改
8 W' q; d/ |9 NEnvironment= CLUSTER=remote: R# w: O0 I* {1 W
c. 在remote机器上启动, Q% z4 B/ o; M. R# s1 q' A- w
systemctl start ceph-rbd-mirror @adminps -ef|grep rbdceph 43251117: 59? 00: 00: 00/usr/bin/rbd-mirror -f --cluster remote --id admin --setuser ceph --setgroup ceph 2.2.6 检查同步结果0 r; {, m' O$ I- ?
a. 查询local集群镜像的同步的状态7 R. k+ A% J3 c3 I4 G( A( b7 {
#local
; U5 W6 ^. j. _, L* Vrbd mirror image status test_pool/test_image --cluster remotetest_image: global_id: dabdbbed-7c06-4e1d-b860-8dd104509565 state: up+replaying deion: replaying, master_position=[object_number=2, tag_tid=2, entry_tid=3974], mirror_position=[object_number=3, tag_tid=2, entry_tid=2583], entries_behind_master=1391 last_update: 2017-01-22 17:54:224 J% x3 I" u! h5 P: d! K
b. 检查数据是否同步到remote集群
1 I) L. p9 q" H#remote* m* u7 ]; }; P
rbd info test_pool/test_image 3. 测试对比报告 3.1 单主集群性能 3.1.1 rbd性能测试9 V! w* S" a) r/ H4 q( O+ A
顺序读写 //block size是4M,30个线程并发 测试结果:30线程并发,带宽:935 MB/s 平均IOPS:228.33
5 E( t! X9 n& t1 i- ?) V/ R, Urbd bench-write test_image --io-threads 30 --pool=test_pool --io-pattern seq --io-total 17199730000 --io-size 4096000elapsed: 18 ops: 4200 ops/sec: 228.33 bytes/sec: 935243763.72
4 _% Y4 K  W$ Y3 R) B随机读写 //block size是4M,30个线程并发 测试结果:30线程并发,带宽:936 MB/s 平均IOPS: 228.579 G# \* ^- O, \) t
rbd bench-write test_image --io-threads 30 --pool=test_pool --io-pattern rand --io-total 17199730000 --io-size 4096000elapsed: 18 ops: 4200 ops/sec: 228.57 bytes/sec: 936229596.77 3.2 主备集群性能 3.2.1 rbd性能测试2 B' w! j6 W8 E/ n+ e8 _# X
顺序读写 //block size是4M,30个线程并发 测试结果:30线程并发,带宽:182 MB/s 平均IOPS:44.53! ?- f3 j- C& R: n# R
rbd bench-write test_image --io-threads 30 --pool=test_pool --io-pattern seq --io-total 17199730000 --io-size 4096000elapsed: 94 ops: 4200 ops/sec: 44.53 bytes/sec: 182382108.66( d2 V; v3 V0 T
随机读写 //block size是4M,30个线程并发 测试结果:30线程并发,带宽:149 MB/s 平均IOPS: 36.50
' ]1 O- O3 T( F$ H' E. d- U" \+ Erbd bench-write test_image --io-threads 30 --pool=test_pool --io-pattern rand --io-total 17199730000 --io-size 4096000elapsed: 115 ops: 4200 ops/sec: 36.50 bytes/sec: 149499469.69 3.3 测试结果
! i) b0 u8 L) n( W: n通过测试结果,可以看出启用rbd-mirror 会导致主集群性能下降5倍多。& C- `( o7 J* @
工具 集群模式 块大小 并发数 顺序读写 随机读写. ]! a/ L, X4 I" w! s+ l* y5 E2 W' q
rbd bench-write 单主集群 4M 30 带宽:935 MB/s
3 l5 r  _' a- \" a平均IOPS:228.33
+ m' X( E' ?& U) T4 _带宽:936 MB/s
, Z  T8 M* S- v- a. @' _" f! D9 m% W9 Z平均IOPS: 228.57
8 {' L' n2 z+ }( h# Y# M4 i3 L9 _rbd bench-write 主备集群 4M 30 带宽:182 MB/s7 A( Y) Q4 I! u* p$ T, j* Z
平均IOPS:44.53
) [  [, A5 D5 X. I) y带宽:149 MB/s' U& a5 a8 O( M" k* l. a4 _% s
平均IOPS: 36.50
2 [/ r! u* S5 X& U) M/ ?4. 分析原因 4.1 journal流程
4 o3 }6 P" A7 u当RBD Journal功能打开后,所有的数据更新请求会先写入Image Journal. l, Z0 t# w' o8 k: ]; a
写入成功后,通知客户端
/ ^# w7 o2 g/ U客户端得到响应后,开始写image
& ^8 Q% }* k" b  W! e9 V* M备份集群的mirror进程发现主集群的Journal有更新后,从主集群的Journal读取数据,写入备份集群/ R2 {2 B1 u- m4 ]$ C$ k# o+ d
备份集群写入成功后,会更新主集群Journal中的元数据,表示该I/O的Journal已经同步完成
  W; R" I! Q4 B1 H4.2 优化
. s' |8 N- Y, g- _; n5 d( e3 QUse a small SSD/NVMe-backed pool for journals
. j; k9 D7 M2 C‘rbd journal pool = <fast pool name>’% m; B3 r! w& z& v: f, ]) R
Batch multiple events into a single journal append* J/ a1 k: _) m( g
‘rbd journal object flush age = <seconds>’
2 Z- E" L- G# MIncrease journal data width to match queue depth
; r& a, x1 t8 C8 g6 `* v* q5 t‘rbd journal splay width = <number of objects>’' m5 y1 p2 s, c6 M
Future work: potentially parallelize journal append + image write between write barriers& C" M5 h& \. [8 x+ w1 p* u
1. rbd journal pool 功能没实现sudo ceph daemon osd.0 config setrbd_journal_pool = test_pool3{ "error": "error setting 'rbd_journal_pool' to '= test_pool3': (38) Function not implemented"} 2. 调整参数从10-100,效果不明显rbd_journal_object_flush_age = 100rbd_journal_splay_width = 100 4.3 官方待改进 4.3.1 引入一致性组
. s8 b1 z" n( R8 f- w; Wjournaling可以看做是另一个rbd的image(一些rados对象),一般情况下,先写日志,然后返回客户端,然后被写入底层的rbd的image,出于性能考虑,这个journal可以跟它的镜像不在一个存储池当中。1 _- J+ l  Q9 P3 Z2 t; f
目前是一个image一个journal,最近应该会沿用这个策略,直到ceph引入一致性组。关于一致性组的概念就是一组卷,然后用的是一个RBD image。可以在所有的组中执行快照操作,有了一致性的保证,所有的卷就都在一致的状态。
# H+ v# V6 B, H. M# x3.当一致性组实现的时候,我们就可以用一个journal来管理所有的RBD的镜像,可以给一个已经存在image开启journal,ceph将会将你的镜像做一个快照,然后对快照做一个复制,然后开启journal,这都是后台执行的一个任务可以启用和关闭单个镜像或者存储池的mirror功能,
" ~$ m: o4 E. l如果启用了journal功能,那么每个镜像将会被复制可以使用 rbd mirror pool enable启用它。
& g  H- Z  w1 L, x; t+ e4.3.2 并行写7 s6 b, y: k" l5 d& t% o% W, i
Future work: potentially parallelize journal append + image write between write barriers
2 U9 ^; k3 J  O) O参考官方文档如下:( A; J1 }  R& l) ^3 P8 }- B
官方类似问题:https://www.spinics.net/lists/ceph-users/msg31676.html
" C+ p) J5 ^1 z' s1 b" X4.4 结论
( L- t" A/ m9 I- }- G由于核心流程就是先写日志,然后写image需要写两份的逻辑,所以导致性能就会有损失。- W0 p+ t  \( G+ \6 X
根据官方的参数优化也没有明显的效果,建议等待官方更新features。
# y6 l5 O) m5 \5 s% c& {8 q
您需要登录后才可以回帖 登录 | 注册

本版积分规则

返回首页|Archiver|手机版|小黑屋|易陆发现技术论坛 ( 蜀ICP备2026014127号-1 )

GMT+8, 2026-6-12 00:09 , Processed in 0.017950 second(s), 23 queries .

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表