|
|
一、扩容条件
/ }4 T( O# j7 u( Va. 一般可用容量达到70%,就要开始考虑进行物理扩容,部分由于部署不合理导致的问题,可通过调节pg和weight进行调整。, h1 Q; o7 C' W; T. F
; R( z: _2 P' z( e9 R3 C) y {8 Mb. 扩容时需尽可能的评估当前业务规模,因为当集群达到一定规模后,累计的数据量是十分巨大的,所以尽可能的减少迁移操作。4 v0 D# f+ A1 ~4 M O [& ]9 b
9 Q5 E# D( G& `- I
c. 通过 ceph df 查看 %USED 是否已经达到70%,并通过ceph osd df 查看osd 使用率最高的和最低的使用率。 %USED 是按照使用率最高的osd算出来的,而ceph在一个osd满的情况下(阈值一般为0.95,告警为0.85),集群就不可用了。. n# H: [7 ~1 G% _- g6 F
6 ` f3 @1 h1 A9 c例如,通过 ceph osd df | sort -k 8 查看到最低osd使用率40%,最高osd使用率为72%,误差32,这种情况很可能就是osd之间数据不均衡。
p- _) L2 L( S: R. L
, E2 t" y# ~$ C( T" R {+ R/ hd. 导出osd 的pg分布,查看到部分池的数据很少(几乎没有),但给予了1024pg,data数据量多的池在每个osd内分布的不均匀,例如在osd 1 中,总pg数为120,但data池的pg只占用60pg,其他池meta池占用30pg,但实际上meta池数据量远远少于data池。查看osd 181,发现data池pg为90,而且其容量只剩剩余2T,而osd 1剩余3.6T。从而导致可用容量按osd 181的显示,随着业务持续写入,很快就接近阈值,导致集群空间的浪费。! ]* d6 |& l! M4 _ D
! b2 K' H; W& D' C1 ?3 j
此时,应该调整池pg分布的均衡或者调节部分峰值的osd。. O3 l5 {* s6 N! C( B7 d d
0 H- w% a5 w* H; m& ^ z/ i" ee. 若pg分布均衡且数据分布均衡,则考虑 物理扩容 。
5 u9 j2 M7 f4 ~: }8 w$ }- u; Y! Y1 i' |, L. ^
二、扩容流程0 c a+ T5 y" c8 `7 p' G T
扩容的过程主要是添加osd的过程,添加完osd后,还需看情况是否调节pg,具体可查看文档后面 计算需要调节pg
3 _: K& e( a7 U4 D) f. A- v2 p& S' G5 F5 l5 u
扩容过程主要分为4步(文档有具体描述):
, d. Y+ L, _6 O3 E O8 D- t, L4 h5 [. g! h, Q8 }
(1)业务规模的评估
- c$ _3 Z# Y4 D' e6 ?1 c3 X
$ a c2 R! l5 G' Z3 d) |, D4 H" R; m(2)扩容前的准备工作(包括环境的检查,pg数的计算,pg分布的统计)9 |* D9 z, X* P. n
. \) n& @4 c# w, l1 v; r2 z
(3)扩容过程中的故障处理(mon、osd进程故障,pg状态异常故障); ~' a; }) J) i, _
8 r2 C- @" _% Z! T$ w3 f! E
(4)扩容完的收尾动作(统计pg的分布图,调节迁移的速度等)
( ?1 w) p% L1 Q( X& w/ o2 L2 O; \; q2 }0 `/ @8 n
扩容时候出现的故障主要从 现网组网 系统 集群 进程的这几个维度进行排查# i7 }* K* I! I1 D+ ~4 G
2 Q. q c$ q& b& G例如出现mon down时候,可通过mon进程所提示的err进行定位,从而转到集群的规模是否部分参数未放开限制,再到系统的内存不足或者网口负载太高,需调节系统参数,再到组网环境搭建进行排查,如交换机环路等。3 b" Q+ u6 l+ d
! s; o( `9 X' G, ^0 H
(1)由于pg不均衡或者weight权重不相等的,可以通过调节osd的pg数,或者 weight值进行初步腾出容量。
$ _% S" H# o9 r0 q; |# 调节osd weight值
' H: s- \3 c* d1 D3 @; V: s! k% Oceph osd reweight <osdname (id|osd.id)> <float[0.0-1.0]>
8 X! @6 F5 R7 ~
9 ?# n- D5 \& G2 c4 b8 E, H: r9 W* Z b
# 调节pg数目/ T8 v. w' \6 _% k/ f) r& x$ w
ceph osd pool set <poolname> pg_num|pgp_num <int> #int为最接近2的幂次方
3 D* j$ G2 D7 f! L0 S' J! R7 U8 n6 V若是由于池的pg不均衡导致,采用ceph balancer进行调整5 p: y- t" o/ t- ^ L) |
. Y2 q$ M' W9 I) |7 i+ ]- c# 查看集群得分
/ N2 p' D6 y- M" xceph balancer eval
. V3 M# A/ x: |: c* y2 f0 T9 ~0 | G; m1 G6 t& B
4 J! s) D( t) o) o- ]" J7 K# 设置均衡策略(crush-compat)
" ~$ S5 X% Y% P6 T, Eceph balancer mode <upmap/crush-compat/none>9 T3 P; i" `; h8 a$ i% a
None:表示什么都不做
" r& l. J: V1 T. _9 Z6 j8 sUpmap:通过重新映射pg来平衡pg
! |+ a$ B9 a* Dcrush-compat: 通过重新设置osd的weight值触发pg的重新分布7 h/ `0 A! d% s& X! G8 b2 W2 s
9 `- g% u! F# H9 m+ {
7 G9 Z/ F' p v! m( W6 G6 o
# 设置均衡任务
; a' {$ @( A2 f% W' j0 e3 S" ]ceph balancer optimize tune <pool_name>2 k0 t2 s8 Q, p: O! z
ceph balancer execute tune+ r( Y& V$ e$ p7 |
: p z, J9 y7 f# |1 m: b# Y
, A- J" E7 i8 ?& o/ p# 这时,在查看集群得分4 ?' l8 ~ _' ^6 B; c
ceph balancer eval
) ^$ }5 L$ A7 o(2)通过增加osd进行物理扩容: J/ O3 {. K* g8 l/ A: t5 }( \
处理流程可在web上操作,这里提供添加osd的命令
- s- q0 ? f0 ^: j6 @% L4 J+ \
3 Y3 H: S5 \! G; H) g! D, d# bluestore:
+ s) n* N/ M; L2 ~3 L9 z+ \ceph-deploy --overwrite-conf osd create node66 --data /dev/sdb --block-db /dev/sdd2 --block-wal /dev/sdd1, E: L$ D1 [7 X z: q! M
ceph-deploy --overwrite-conf osd create node66 --data /dev/sdc --block-db /dev/sde2 --block-wal /dev/sde1
& l3 E$ L: E6 M.... U6 l( Z7 Y; H0 q2 N0 b
) B4 `$ A& \% k% P. ?; Y( `1 K
T& J7 b5 E/ D' b& S7 `1 W5 r# filestore& p8 ^" |# r9 y% Q
ceph-deploy osd create --filestore --fs-type xfs --data /dev/sdb1 --journal /dev/sde1 node66ceph-deploy osd create --filestore --fs-type xfs --data /dev/sdc1 --journal /dev/sde2 node66' n" J1 W; X/ [: Z2 ?) C. p$ m* k
(3)扩容后,看情况是否需要增加pg,或者均衡池pg。pg均衡情况可通过脚本《pg均衡查询脚本》查看,脚本可私信获取。
2 a3 }! l6 A6 ^ n$ \- Vpg的计算公式:
5 q6 r n7 X7 |- @2 ^- `0 \& m6 ?0 A6 ]7 t
1、输出的值取舍到最接近的2的幂(最接近的2的幂提供了CRUSH算法效率的少量提高)- l0 y( o# Z& i, q, @
4 f' K; E: A9 v4 V0 {
2、如果最接近的2的幂比原始值低25%以上,则使用下一个更高的2的幂3 C1 E. @0 A2 q# G" C/ _
. ] o; U6 G: H! ^3、每个osd pg数目,建议值:8 z$ c/ Y0 o# q
$ c2 }. X e j: ]' N3 X% I100 如果在可预见的将来,群集OSD的数量预计不会增加。
+ h0 D0 b( H# H. u1 [ x8 m% b7 p+ {4 @( @& u/ w+ S7 T! p6 `
200 如果在可预见的将来,群集OSD的数量预计会增加(最多增加一倍)。4 c3 M" h9 ^5 p# D4 e+ u
/ m+ V- n- A$ g4 j! C8 G1 u算法:4 Y7 g7 F3 L/ N' a g2 F1 e
) k, H! t4 X. u8 c: Q* i(每个OSD的目标PG)x(OSd总数)x(数据量百分比)/ (副本数)
, w) Q6 y1 G: N+ ]$ g$ V
2 z4 J; D0 `: Kps:! N: V6 {4 c" X \
* ?- V% A _5 Y3 p2 [8 S b# j
如果以上计算的值小于(osd总数)/(副本数)的值,则该值将更新为(osd总数)/(副本数)的值。这是通过为每个池为每个OSD分配至少一个主或辅助PG来确保均匀的负载/数据分配
! Q" t9 F/ J% }* p& a! F
1 V' h% a' B( o! m; A. b数据量(普通生产环境):; \( ^# V+ G& U4 P
" W) M) J; G2 \* `' m' o
项 .rgw.root rgw.control rgw.meta rgw.log rgw.buckets.index rgw.buckets.data rgw.buckets.non-ec! g. f* f5 }6 \% E/ _9 N5 z
数据量占用率(%) 0.2 0.1 0.3 0.6 1 94.8 3
' Q8 E; C+ [, n! |三、扩容期间
2 |: n- T- Y8 o& W" M3 l$ A" |(1)观察pg的状态(相关故障处理可根据《pg异常处理》处理)* b1 F+ j$ f0 G& Y* p" ~& v+ f
Peering2 Y$ [- K: K V% c6 E8 z3 Y3 Y
peering的作用主要是在PG及其副本所在的OSD之间建立互联,并使得OSD之间就这些PG中的object及其元数据达成一致. V# U% Z! w+ ?/ E
4 L( v* P |1 O# ?. l
Remapped0 K4 K7 K# v, I5 z. t6 u: O( b
当负责维护某个PG的acting set变更时,PG需要从原来的acting set迁移至新的acting set。这个过程需要一段时间,所以在此期间,相关PG的状态便会标记为remapped9 \9 o% `5 S" l/ E
5 E6 J# w7 Y' e5 w" ]
Backfills
8 `9 T1 k _+ E当有新的OSD加入集群时,CRUSH会把现有集群内的部分PG分配给它。这些被重新分配到新OSD的PG状态便处于backfilling* p2 g5 n) k9 |
$ R8 A) H6 m3 s1 X4 f
Recovering
, v6 S' Y/ o( [( ^& \3 g* w当某个OSD因为某些原因down了,该OSD内PG的object会落后于它所对应的PG副本。而在该OSD重新up之后,该OSD中的内容) t$ G X- W& g" ^# W* o `- k
必须更新到当前状态,处于此过程中的PG状态便是recovering* L0 B o, J- h' z: `6 l
4 e* C2 f4 c4 u" A( c( wDegraded4 p- v( B0 f w W- L
当某个PG的副本数未达到规定个数时,该PG便处于degraded状态,例如: M; v+ h3 ^, M2 {4 \; Q
7 \& j- @* d" Z& `
在客户端向主OSD写入object的过程,object的副本是由主OSD负责向副本OSD写入的,直到副本OSD在创建object副本完成,并向主OSD发出完成信息前,该PG的状态都会一直处于degraded状态。又或者是某个OSD的状态变成了down,那么该OSD上的所有PG都会被标记为degraded。
) `2 l, D8 v( o! k) U; d% j! T- y$ Q, H$ V9 B- K5 i/ Y1 R( }
当Ceph因为某些原因无法找到某个PG内的一个或多个object时,该PG也会被标记为degraded状态。此时客户端不能读写找不到的对象,但是仍然能访问位于该PG内的其他object2 n3 P: [4 X% V% N p% Z* L
, _. a6 N& R( t* m
Active
% E8 S _# Q/ b8 W处于该状态意味着数据已经完好的保存到了主PG及副本PG中,并且Ceph已经完成了peering工作5 e" K6 @. c0 Q7 G
7 x4 l% V6 [$ j% B. s
Clean
% b# E4 O: k) s/ e, t7 P3 A* L当某个PG处于clean状态时,则说明对应的主OSD及副本OSD已经成功互联,并且没有偏离的PG。也意味着Ceph已经将该PG中的对象按照规定的副本数进行了复制操作 }% h" T- y! h$ v: E
2 z+ ^; Q; Q! Q V
5 v5 ^; F7 D( n5 a+ Z1 c( o
9 j. r3 ]+ p" f& g
(2)迁移参数调整
) H3 {9 z& u+ h c( d/ X) z+ W, ?$ @6 ?+ B/ H, A
数据的迁移的相关参数,可根据业务数据流量的时间分布,进行适当的调整,加快迁移:
: R! h7 C& Q3 k. G* J) |
, \2 P9 X3 P3 s# F3 w这个值存在平衡点:具体可看:https://blog.csdn.net/tony_vip/article/details/100122104% B( y; f0 h6 R9 g1 s3 [2 ~
' r9 ]2 [# j9 ^7 w: ?% {' ~思科参考值,具体视集群情况而定
0 R; o5 y5 z. Y3 a! @osd recovery max active = 3 (default : 15)
) l/ Q4 H# } l, t( @osd recovery op priority = 3 (default : 10)
4 c# q* O, I. {; y, S+ Nosd max backfills = 1 (default : 10)
( S$ J b- s( Q/ j A3 U1 f5 d0 s: [2 b
7 C) P1 E9 `: O
参数注意事项:8 z- N% \" ^1 x
osd max backfills设置为10时,假如一个pg 50G数据 需要迁移10个,那么基本是迁移500G左右的数据的时候开始删除而0 t8 `, v: e9 e5 m3 t$ a0 l) Q
backfill为1的时候,就是迁移50G,开始删除一个,迁移50G删除一个,加大backfill反而阻碍了空间的释放。
& y, _3 I$ }. B3 }8 p4 o) ?/ J9 j2 Q+ v- h
7 U: ]5 F3 G) Sosd_recovery_sleep = 0 在luminous版本已经设置成ssd是0,sata变成0.1,相当于增加了一个延时的过程
& N, f- `& N1 p& ]% N1 C* {
% A: |+ |( m6 p8 M: ]' u$ J4 m- N3 X T# m' z" K2 Q1 T5 `. z
(3)slow request
" u0 A, u, d4 S$ ]0 w/ O" A
% I. A! i* M/ j/ G* p若迁移过程中出现slow request的情况,一般为集群过载了。主要可能有以下原因导致。
$ M3 f, m* d/ i1 ]- S8 `# _/ ] n$ ?( G
/ b) W4 z( L! j4 {# ha. 池的pg数太少,导致某个池阻塞osd的情况 w, U. V& \+ X+ p
+ |1 E! r4 v7 Z7 y) ~* i通过mon log日志,获取到阻塞osd的信息:2 D# |0 s4 i H8 m" \* v
1 o8 G& G3 E! Q6 g2021-01-12 00:04:05.257239 osd.3 osd.3 172.168.30.103:6801/908686 2976 : cluster [WRN] slow request 31.493678 seconds old, received at 2021-01-12 00:03:33.763381: osd_op(client.137288303.0:1137363 7.1a 7:590
# o6 S& P) H7 t9 K7 K' Y7 X这里可以看到osd.3阻塞了,pg序号为7.1a,查看对应的池(ceph df):# i" B+ O3 p; Q. x P7 K1 V
7 a- \3 x/ e$ x" O3 A可查看到是default.rgw.log,在查看对应pg数目:
- _# | I, E' ~# o& ^5 R$ a) G* ~# c0 Q- K' s! {
ceph pg dump pgs|grep ^7.|awk '{print $1,$2}'
5 K) H3 p" @7 R% _( D" ^& P$ o环境上有80个osd,而pg只有32个,均摊到每个osd,平均一个都没有,并没有充分散列,假如维持单个osd承载10个相关pg,那么计算下来:
5 O/ ]" M0 |- x: L8 Q
5 f8 V" n! o: y1 s3 P d( O10*80/2=400 取最接近幂是512
9 _' T' T2 q* J5 g
0 v' D$ S- d0 ^! S( J/ G* x) L512*2/80=12.88 k" C6 k( k! e/ b8 T& o, Z. u- ~! a
7 `+ _+ X. C" C# Q: |& I平均每个osd上的为12.8个相关的pg,因为对象是207个,平坦下去每个pg只需要承担一个对象,平均每个osd承担不到3个对象,比现在的设置情况要好很多) }" W8 u3 W1 A, ?' v4 C w
3 c0 _/ @7 K' ^
5 t6 v/ u( T0 H) d
/ W3 g8 x8 H# Z4 B+ y9 Pb. 业务在某段时间突然触发增长
) @. i8 P& M) W9 h/ p2 @ k5 Y* \: X4 Q9 A: h$ d
例如项目在凌晨12点时,业务方进行批量删除过期文件的操作,这无疑增加扩容时候的压力,而且其中穿插着设备的批量遍历操作和ceph生命周期操作。
! W; ~4 l% A- L4 h% U
* K* L4 Z; ^) o' k( X7 Q3 p' v- T故可结合现场环境进行调节:
: D7 ]! ~- V: [. a" O5 K0 n+ |% _
a. 将ceph生命周期的迁移时间设置为:01:00 - 23:00,避开峰值时间段
$ u* ]8 N" p/ W; {7 j% j2 m; |1 P0 K3 f, e
rgw_lifecycle_work_time = 01:00-23:00
' e/ w& D: g" f+ W3 R, K4 {b. 降低backfill修复对磁盘的压力
- z: I) Q+ F" ~1 ^
& z1 z- X) P# o0 j! {( x& Tceph tell osd.* injectargs --osd_recovery_sleep_hdd 0.52 p4 ^1 K( G/ T1 m
#默认为0.1# 效果recovery: 16.1MiB/s, 6objects/s0 R- b. e! n8 s5 W
) m' @* x |7 M' x/ A) c. D
1 i! W6 G O9 d6 B- @ceph tell osd.* injectargs --osd_recovery_sleep_hdd 0.13 o% C4 ^3 X2 }. w Q* H
# 效果recovery: 82.1MiB/s, 32objects/s
7 e0 }# u4 b2 @8 S% Hc. 将池后端使用SSD代替
3 v A8 F6 ]2 B; w4 i0 d; a3 B" F* W! m6 S) k1 r0 n$ A
若集群osd数目不能抗住大量元数据的操作,可将池使用SSD进行代替,缓解SSD的更新的时延,加大并发量。
- L9 j4 L0 s7 J3 x% f; K+ ^5 z: M. a$ ^: X! @9 O' X& ]+ f" [
6 H( h( b9 r7 V9 y# M/ h! L2 ~! t3 \9 u
(4)盘容量接近阈值
7 q- y5 |' Y% {/ X7 ^* l/ v) K4 c% ^! b& q7 C a
若存在扩容不及时,导致osd的容量还未释放,逐渐逼近设置盘满的阈值0.95,此时需手动操作,将阈值高的osd进行优先迁移。. [3 Y* x8 m( d9 c+ n8 K
( r+ Q5 C# Y8 ?, z( o0 G
# 查看满盘osd 所需迁移的pg
* s w& n7 H- r5 T, o3 a0 Z' G& rceph pg dump pgs | grep <osd.x> | grep backfill_wait( f* |; q c n
主要看UP 和 ACTING 列,可通过awk 过滤出来。
4 ?% f: c) @1 }. @, ~
- ~/ t5 [( V+ ?8 R0 L迁移流程为: ACTING[0,1] —> UP[3,4] 尽量选取UP 为新加入的osd进行迁移。1 h* h1 _" o: \% G: w( c1 K& `' j
2 _% a4 V$ H$ v
尽量将 ACTING 中存在该osd 的pg进行优先迁移,同时设置该osd的backfill 为1,相当于加快迁移出去的数据,减慢迁移进来的数据。
. p) B1 `1 r) q( K) R( ]: z% w3 y3 W3 k/ x2 |( ?
ceph pg force-backfill <pg_id>ceph tell <osd.x> injectargs "--osd_max_backfills 1"/ [& A! F% O" d
7 o, F7 M% k, o! p
- ]2 b9 L; \6 E0 s7 T: \. u& _(5)迁移所需时间" e7 j. O# i1 A. G5 x
2 M$ d+ U4 F. p% j6 T# p迁移所需时间可通过下面脚本进行大致评估,ceph版本不同可能截取需要数据位置不同,需适当更改下脚本。1 B# |+ F5 W$ ]8 E3 T0 `
( E& m/ u- k3 U
#! /bin/sh
' [ C2 @9 n0 b/ vwhile ( 2>1 )
7 O7 R- v' {+ @# @- h* rdo
: c0 ?( y$ h h5 [start=`ceph -s|grep pgs|grep mis|awk '{print $2}'|cut -d / -f 1` K+ M! y9 Q" ~4 E+ q; W+ s: Q
sleep 5( n' U. j5 D! r: J: d
end=`ceph -s|grep pgs|grep mis|awk '{print $2}'|cut -d / -f 1`
1 ~/ p- O3 V( H5 x( Lspeed=$((start-end))+ ^' G# u% b2 U/ _
#echo $end9 J# k4 v. a% ?6 R5 _3 o
#echo $speed# e2 i/ o7 I$ F' B2 Y1 T
second=$((end/speed*5))5 e8 I* h( C1 q' h5 g2 c# U
hour=$(( $second/3600 )). w! i9 f- `& z% R
min=$(( ($second-${hour}*3600)/60 ))
. F1 o/ A }5 Y6 b4 `4 f. Bsec=$(( $second-${hour}*3600-${min}*60 ))
: j3 k. u8 b. l. y1 Recho 当前时间:`date`) |$ M3 k6 r9 d7 H, A( L+ ]& D+ L! H
echo 迁移剩余:$end: F+ a8 r0 V+ f
echo 迁移速度:$((speed/5))/ \7 J. `: ~8 A0 [0 s9 {
echo 迁移还需要:${hour}小时${min}分${sec}秒9 ?4 x: \9 N" z8 g
echo "-------------------------------------"& }: j- ~( A+ z+ c$ p& X/ b, R7 m2 j
done
t! J" I' v6 p" s
3 s# E# ?0 B+ I( h2 O& O0 A |
|