本文主要讲述一个初始状态为active+clean了ceph集群,从OSDmap及PGMap的视角观察一个OSD从(in + up)状态到(in + down)状态,再到(out + down)状态这一过程的变化,并结合OSD的日志信息以期对PG peering过程有一个初步的了解。
1. 集群环境介绍
当前我们有如下9个OSD组成的ceph集群:
# ceph osd tree
ID WEIGHT TYPE NAME UP/DOWN REWEIGHT PRIMARY-AFFINITY
-10 1.34998 failure-domain sata-00
-9 1.34998 replica-domain replica-0
-8 0.44998 host-domain host-group-0-rack-01
-2 0.44998 host node7-1
2 0.14999 osd.2 up 1.00000 1.00000
0 0.14999 osd.0 up 1.00000 1.00000
1 0.14999 osd.1 up 1.00000 1.00000
-11 0.45000 host-domain host-group-0-rack-02
-4 0.45000 host node7-2
3 0.14999 osd.3 up 1.00000 1.00000
4 0.14999 osd.4 up 1.00000 1.00000
5 0.14999 osd.5 up 1.00000 1.00000
-12 0.45000 host-domain host-group-0-rack-03
-6 0.45000 host node7-3
6 0.14999 osd.6 up 1.00000 1.00000
7 0.14999 osd.7 up 1.00000 1.00000
8 0.14999 osd.8 up 1.00000 1.00000
-1 1.34998 root default
-3 0.44998 rack rack-01
-2 0.44998 host node7-1
2 0.14999 osd.2 up 1.00000 1.00000
0 0.14999 osd.0 up 1.00000 1.00000
1 0.14999 osd.1 up 1.00000 1.00000
-5 0.45000 rack rack-02
-4 0.45000 host node7-2
3 0.14999 osd.3 up 1.00000 1.00000
4 0.14999 osd.4 up 1.00000 1.00000
5 0.14999 osd.5 up 1.00000 1.00000
-7 0.45000 rack rack-03
-6 0.45000 host node7-3
6 0.14999 osd.6 up 1.00000 1.00000
7 0.14999 osd.7 up 1.00000 1.00000
8 0.14999 osd.8 up 1.00000 1.00000
# ceph -s
cluster 5341b139-15dc-4c68-925a-179797d894d3
health HEALTH_OK
monmap e3: 3 mons at {node7-1=10.17.155.113:6789/0,node7-2=10.17.155.114:6789/0,node7-3=10.17.155.115:6789/0}
election epoch 24440, quorum 0,1,2 node7-1,node7-2,node7-3
osdmap e2222: 9 osds: 9 up, 9 in
flags sortbitwise,require_jewel_osds
pgmap v5839062: 632 pgs, 15 pools, 206 GB data, 5860 objects
76122 MB used, 225 GB / 299 GB avail
632 active+clean
集群的初始状态为active+clean
状态,PG的个数有632个。当前osdmap的版本为e2222
,pgmap的版本为v5839062
。
另外所采用的crush如下:
之后我们在集群的三台主机上创建本次数据抓取工作目录:
# mkdir workdir
# cd workdir
1) 获取初始状态下的osdmap
在node7-1主机上,通过如下命令获取出当前状态的osdmap信息:
上面看到当前的osdmap的版本号为2222
,总共有9个osd,都处于up + in
状态。
2) 获取初始状态下的pgmap
使用如下命令获取初始状态的pgmap信息:
上面pgmap的版本号为5839062
。
接着通过如下命令获得osd.0
上的PG个数(结果为139):
# ceph pg ls-by-osd 0
查看ceph数目目录下的current文件夹,发现其中的_head
文件的个数也刚好是139:
# pwd
/var/lib/ceph/osd/ceph-0/current
# ls -al | grep _head | wc -l
139
然后我们再获取以osd.0
作为主OSD的PG个数(结果为68):
# ceph pg ls-by-primary 0 | awk '{print $1}'
pg_stat
11.4
13.4
13.9
13.d
14.3
14.5
14.8
14.d
18.2
18.4
19.2
20.3
21.1
22.e
22.21
22.2c
22.3a
22.44
22.4a
22.65
22.6b
22.73
22.79
22.92
22.96
22.a2
22.a4
22.a7
22.c4
22.ca
22.cb
22.ce
22.d7
22.e2
22.ec
22.f1
23.b
23.d
23.1e
23.26
23.30
23.37
23.38
23.61
23.72
23.75
23.76
23.79
23.7a
23.7b
23.7e
23.89
23.96
23.a1
23.a7
23.ae
23.bb
23.be
23.cb
23.cf
23.d2
23.d6
23.d7
23.e0
23.e4
23.ea
23.fa
24.5
3) 修改OSD3的日志打印级别
首先执行如下命令查看当前osd3的日志打印级别:
# ceph daemon osd.3 config show | grep debug_osd
"debug_osd": "0\/5",
# ceph daemon osd.3 config show | grep debug_monc
"debug_monc": "0\/10",
接着执行如下命令更改打印级别:
# ceph daemon osd.3 config set debug_osd 30/30
{
"success": ""
}
# ceph daemon osd.3 config set debug_monc 30/30
{
"success": ""
}
# ceph daemon osd.3 config show | grep debug_osd
"debug_osd": "30\/30",
# ceph daemon osd.3 config show | grep debug_monc
"debug_monc": "30\/30",
可以看到当前已经修改成功。我们再检查一下osd.3的日志,以确保日志级别已经修改成功。
4) 修改osd0的日志打印级别
同上,我们也修改osd0的日志打印级别:
# ceph daemon osd.0 config set debug_osd 30/30
{
"success": ""
}
# ceph daemon osd.0 config set debug_monc 30/30
{
"success": ""
}
# ceph daemon osd.0 config show | grep debug_osd
"debug_osd": "30\/30",
# ceph daemon osd.0 config show | grep debug_monc
"debug_monc": "30\/30",
4) 修改mon的日志打印级别
首先执行如下命令查看当前mon的leader:
# ceph mon_status
{"name":"node7-1","rank":0,"state":"leader","election_epoch":24434,"quorum":[0,1,2],"outside_quorum":[],"extra_probe_peers":[],"sync_provider":[],"monmap":{"epoch":3,"fsid":"5341b139-15dc-4c68-925a-179797d894d3","modified":"2018-05-11 17:10:27.830117","created":"2018-05-11 14:31:17.538703","mons":[{"rank":0,"name":"node7-1","addr":"10.17.155.113:6789\/0"},{"rank":1,"name":"node7-2","addr":"10.17.155.114:6789\/0"},{"rank":2,"name":"node7-3","addr":"10.17.155.115:6789\/0"}]}}
这里我们看到leader是node7-1
,因此这里我们先查看该monitor的日志级别:
# ceph daemon mon.node7-1 config show | grep debug_mon
"debug_mon": "1\/5",
"debug_monc": "0\/10",
接着执行如下命令更改monitor的日志打印级别:
# ceph daemon mon.node7-1 config set debug_mon 30/30
{
"success": ""
}
可以看到当前已经修改成功。我们再检查一下mon.node7-1的日志,以确保日志级别已经修改成功。
2. 准备阶段
在我们完成上面的日志级别的调整后,我们重定向相关日志:
1) 重定向osd.0日志
我们将osd.0的日志重定向到一个新文件中(osd0_watch.txt):
2) 重定向osd.3日志
我们将osd.3的日志重定向到一个新的文件中(osd3_watch.txt):
3) 重定向mon.node7-1日志
我们将mon.node7-1的日志重定向到一个新的文件中(mon-node7-1.txt):
3. osd.0处于(in+down)状态
1) 关闭osd.0,并观察集群状态
执行如下命令手动关闭osd.0
,并观察集群状态:
# systemctl stop ceph-osd@0
# ceph -s
cluster 5341b139-15dc-4c68-925a-179797d894d3
health HEALTH_ERR
17 pgs are stuck inactive for more than 300 seconds
119 pgs degraded
20 pgs peering
17 pgs stuck inactive
133 pgs stuck unclean
119 pgs undersized
recovery 1169/11720 objects degraded (9.974%)
1/9 in osds are down
monmap e3: 3 mons at {node7-1=10.17.155.113:6789/0,node7-2=10.17.155.114:6789/0,node7-3=10.17.155.115:6789/0}
election epoch 24440, quorum 0,1,2 node7-1,node7-2,node7-3
osdmap e2225: 9 osds: 8 up, 9 in; 139 remapped pgs
flags sortbitwise,require_jewel_osds
pgmap v5839107: 632 pgs, 15 pools, 206 GB data, 5860 objects
76124 MB used, 225 GB / 299 GB avail
1169/11720 objects degraded (9.974%)
493 active+clean
119 active+undersized+degraded
20 peering
recovery io 0 B/s, 5 keys/s, 0 objects/s
可以看到停止osd.0之后,集群马上出现HEALTH_ERR
状态。接着再执行ceph -w
命令:
# ceph -w
cluster 5341b139-15dc-4c68-925a-179797d894d3
health HEALTH_WARN
139 pgs degraded
133 pgs stuck unclean
139 pgs undersized
recovery 1301/11720 objects degraded (11.101%)
1/9 in osds are down
monmap e3: 3 mons at {node7-1=10.17.155.113:6789/0,node7-2=10.17.155.114:6789/0,node7-3=10.17.155.115:6789/0}
election epoch 24440, quorum 0,1,2 node7-1,node7-2,node7-3
osdmap e2225: 9 osds: 8 up, 9 in; 139 remapped pgs
flags sortbitwise,require_jewel_osds
pgmap v5839112: 632 pgs, 15 pools, 206 GB data, 5860 objects
76124 MB used, 225 GB / 299 GB avail
1301/11720 objects degraded (11.101%)
493 active+clean
139 active+undersized+degraded
2020-09-11 14:05:32.824053 mon.0 [INF] pgmap v5839112: 632 pgs: 139 active+undersized+degraded, 493 active+clean; 206 GB data, 76124 MB used, 225 GB / 299 GB avail; 1301/11720 objects degraded (11.101%)
2020-09-11 14:05:37.849532 mon.0 [INF] HEALTH_WARN; 139 pgs degraded; 133 pgs stuck unclean; 139 pgs undersized; recovery 1301/11720 objects degraded (11.101%); 1/9 in osds are down
2020-09-11 14:06:37.850136 mon.0 [INF] HEALTH_WARN; 139 pgs degraded; 135 pgs stuck unclean; 139 pgs undersized; recovery 1301/11720 objects degraded (11.101%); 1/9 in osds are down
可以看到这个时候集群状态变为HEALTH_WARN
状态,其中处于degraded
状态的PG个数是139,这刚好就是osd.0上PG的个数。
2) 导出集群当前osdmap及pgmap信息
接着我们马上执行如下命令导出当前的osdmap及pgmap信息:
3. osd.0处于(out+down)状态
1) 查看ceph集群状态
在osd.0停止约5分钟
后,monitor会将osd.0标记为out状态:
# ceph -w
cluster 5341b139-15dc-4c68-925a-179797d894d3
health HEALTH_WARN
1 pgs backfill_wait
76 pgs degraded
5 pgs recovering
70 pgs recovery_wait
76 pgs stuck unclean
1 pgs undersized
recovery 2462/11720 objects degraded (21.007%)
monmap e3: 3 mons at {node7-1=10.17.155.113:6789/0,node7-2=10.17.155.114:6789/0,node7-3=10.17.155.115:6789/0}
election epoch 24440, quorum 0,1,2 node7-1,node7-2,node7-3
osdmap e2231: 9 osds: 8 up, 8 in; 1 remapped pgs
flags sortbitwise,require_jewel_osds
pgmap v5839147: 632 pgs, 15 pools, 206 GB data, 5860 objects
72034 MB used, 196 GB / 266 GB avail
2462/11720 objects degraded (21.007%)
556 active+clean
70 active+recovery_wait+degraded
5 active+recovering+degraded
1 active+undersized+degraded+remapped+wait_backfill
recovery io 25022 kB/s, 25 objects/s
2020-09-11 14:10:18.902675 mon.0 [INF] osd.0 out (down for 300.095972)
2020-09-11 14:10:18.942928 mon.0 [INF] osdmap e2226: 9 osds: 8 up, 8 in
2020-09-11 14:10:18.961850 mon.0 [INF] pgmap v5839131: 632 pgs: 139 active+undersized+degraded, 493 active+clean; 206 GB data, 70540 MB used, 197 GB / 266 GB avail; 1301/11720 objects degraded (11.101%)
2020-09-11 14:10:19.967084 mon.0 [INF] osdmap e2227: 9 osds: 8 up, 8 in
2020-09-11 14:10:19.973245 osd.7 [INF] 17.0 starting backfill to osd.2 from (0'0,0'0] MAX to 1745'17827
2020-09-11 14:10:19.988115 mon.0 [INF] pgmap v5839132: 632 pgs: 139 active+undersized+degraded, 493 active+clean; 206 GB data, 70540 MB used, 197 GB / 266 GB avail; 1301/11720 objects degraded (11.101%)
2020-09-11 14:10:21.004820 mon.0 [INF] osdmap e2228: 9 osds: 8 up, 8 in
2020-09-11 14:10:21.042746 mon.0 [INF] pgmap v5839134: 632 pgs: 1 active+undersized+degraded+remapped+wait_backfill, 2 active+undersized+remapped, 2 active+undersized+degraded+remapped+backfilling, 60 peering, 74 active+undersized+degraded, 493 active+clean; 206 GB data, 70540 MB used, 197 GB / 266 GB avail; 743/11720 objects degraded (6.340%); 0 B/s, 1603 keys/s, 43 objects/s recovering
2020-09-11 14:10:19.971030 osd.8 [INF] 14.5 starting backfill to osd.2 from (0'0,0'0] MAX to 2222'235208
2020-09-11 14:10:22.047015 mon.0 [INF] osdmap e2229: 9 osds: 8 up, 8 in
2020-09-11 14:10:22.099375 mon.0 [INF] pgmap v5839136: 632 pgs: 4 active+recovery_wait+degraded, 2 active+recovering+degraded, 15 activating, 1 active+undersized+degraded+remapped+wait_backfill, 1 active+undersized+remapped, 3 active+undersized+degraded+remapped+backfilling, 61 peering, 17 active+undersized+degraded, 31 activating+degraded, 497 active+clean; 206 GB data, 70541 MB used, 197 GB / 266 GB avail; 351/11720 objects degraded (2.995%)
2020-09-11 14:10:19.967348 osd.5 [INF] 14.3 starting backfill to osd.2 from (0'0,0'0] MAX to 2222'417838
2020-09-11 14:10:19.975356 osd.5 [INF] 14.d starting backfill to osd.2 from (0'0,0'0] MAX to 2222'321710
2020-09-11 14:10:19.975419 osd.5 [INF] 14.8 starting backfill to osd.3 from (0'0,0'0] MAX to 2222'230561
2020-09-11 14:10:19.976943 osd.5 [INF] 14.8 starting backfill to osd.7 from (0'0,0'0] MAX to 2222'230561
2020-09-11 14:10:20.025833 osd.3 [INF] 15.5 starting backfill to osd.1 from (0'0,0'0] MAX to 2225'9330365
2020-09-11 14:10:23.142904 mon.0 [INF] osdmap e2230: 9 osds: 8 up, 8 in
2020-09-11 14:10:23.201075 mon.0 [INF] pgmap v5839138: 632 pgs: 5 active+recovery_wait+degraded, 3 active+recovering+degraded, 21 activating, 1 active+undersized+degraded+remapped+wait_backfill, 1 active+undersized+remapped, 3 active+undersized+degraded+remapped+backfilling, 61 peering, 39 activating+degraded, 498 active+clean; 206 GB data, 70541 MB used, 197 GB / 266 GB avail; 311/11720 objects degraded (2.654%)
2020-09-11 14:10:24.173223 mon.0 [INF] osdmap e2231: 9 osds: 8 up, 8 in
2020-09-11 14:10:24.192977 mon.0 [INF] pgmap v5839139: 632 pgs: 5 active+recovery_wait+degraded, 3 active+recovering+degraded, 21 activating, 1 active+undersized+degraded+remapped+wait_backfill, 1 active+undersized+remapped, 3 active+undersized+degraded+remapped+backfilling, 61 peering, 39 activating+degraded, 498 active+clean; 206 GB data, 70541 MB used, 197 GB / 266 GB avail; 311/11720 objects degraded (2.654%)
这个过期时间可以通过如下命令查出:
# ceph daemon mon.node7-2 config show | grep mon_osd_down_out_interval
"mon_osd_down_out_interval": "300",
再仔细观察ceph集群状态,可以发现开始出现recovering
的动作。
接着使用ceph osd tree
命令查看:
# ceph osd tree
ID WEIGHT TYPE NAME UP/DOWN REWEIGHT PRIMARY-AFFINITY
-10 1.34998 failure-domain sata-00
-9 1.34998 replica-domain replica-0
-8 0.44998 host-domain host-group-0-rack-01
-2 0.44998 host node7-1
2 0.14999 osd.2 up 1.00000 1.00000
0 0.14999 osd.0 down 0 1.00000
1 0.14999 osd.1 up 1.00000 1.00000
-11 0.45000 host-domain host-group-0-rack-02
-4 0.45000 host node7-2
3 0.14999 osd.3 up 1.00000 1.00000
4 0.14999 osd.4 up 1.00000 1.00000
5 0.14999 osd.5 up 1.00000 1.00000
-12 0.45000 host-domain host-group-0-rack-03
-6 0.45000 host node7-3
6 0.14999 osd.6 up 1.00000 1.00000
7 0.14999 osd.7 up 1.00000 1.00000
8 0.14999 osd.8 up 1.00000 1.00000
-1 1.34998 root default
-3 0.44998 rack rack-01
-2 0.44998 host node7-1
2 0.14999 osd.2 up 1.00000 1.00000
0 0.14999 osd.0 down 0 1.00000
1 0.14999 osd.1 up 1.00000 1.00000
-5 0.45000 rack rack-02
-4 0.45000 host node7-2
3 0.14999 osd.3 up 1.00000 1.00000
4 0.14999 osd.4 up 1.00000 1.00000
5 0.14999 osd.5 up 1.00000 1.00000
-7 0.45000 rack rack-03
-6 0.45000 host node7-3
6 0.14999 osd.6 up 1.00000 1.00000
7 0.14999 osd.7 up 1.00000 1.00000
8 0.14999 osd.8 up 1.00000 1.00000
可以看到osd.0的权重也降为0了。
2) 重新导出osdmap及pgmap
在osd.0停止后大约第8分钟,我们再导出osdmap及pgmap:
4. osdmap对比分析
1) active+clean
状态与in+down
状态osdmap对比
从上面我们可以看到首先是osdmap的epoch值发生了变动,由2222
变成了2225
。然后再是osdmap显示osd.0
上的139个PG产生了pg_temp。
2) in+down
状态与out+down
状态osdmap对比
从上面我们可以看到首先是osdmap的epoch值发生了变动,由2225
变成了2231
,并且此时pg_temp已经消失。
5. pgmap对比分析
这里我们主要是对pgmap立面的pg_stat
、up
、up_primary
、acting
、acting_primary
这几列比较感兴趣,下面我们分别对前面保存的pgmap_active_clean.txt、pgmap_in_down.txt、pgmap_out_down.txt做如下处理:
1) active+clean
状态与in+down
状态pgmap对比
上面我们看到受影响的行数刚好就是存在于osd.0上pg的个数139
。
2) in+down
状态与out+down
状态pgmap对比
可以看到,在osd.0
out之后,PG进行了重新的映射。
6. 过程分析
下面我们结合上面抓取到的osd3_watch.txt、monitor日志及上面的osdmap、pgmap信息,来分析一下osd0从in+active
到in+down
再到out+down
这一过程当中,ceph集群究竟执行了哪些操作,从而窥探出ceph的整体工作原理。
6.1 in+down状态下osdmap中出现的pg_temp
在上面in+down
状态下,我们通过对比osdmap,发现出现了139个pg_temp, 对于这一点我们感觉到十分疑惑。这里我们先来看一下网上相关文章对临时PG
的说明:
假设一个PG的acting set为[0,1,2]列表。此时如果osd0出现故障,导致CRUSH算法重新分配该PG的acting set为[3,1,2]。此时osd3为该PG的主OSD,但是osd3为新加入的OSD,并不能负担该PG上的读操作。所以PG向Monitor申请一个临时的PG,osd1为临时的主OSD,这时up set变为[1,3,2],acting set依然为[3,1,2],导致acting set和up set不同。当osd3完成Backfill过程之后,临时PG被取消,该PG的up set修复为acting set,此时acting set和up set都为[3,1,2]列表。
通过上面的描述,我们可以认为acting set
是实际进行服务的一个映射,但是假如说该映射的primary osd当前并不能正常提供服务的话,那么此时就需要申请一个临时PG
。查询Ceph源代码,发现如下函数会申请pg_temp:
choose_acting()函数会在两个地方被调用:
因为这里我们的PG的副本数设置的是两副本,因此对于那些映射为[0,3]或[3,0]的PG,在osd0停止后的in+down
阶段,只有可能是osd3申请了临时PG,所以我们这里跟踪osd3_watch.txt日志信息。通过仔细跟踪osd3_watch.txt日志信息,并未发现osd3使用choose_acting()函数对所有与osd0、osd3相关的PG进行临时PG
申请。
另一方面,由于osd0被我们使用systemctl stop ceph-osd@0
命令停止,按理说处于degraded状态下的139个PG中,只有68个PG的主OSD是osd0,因而在acting set不能正常提供服务的情况下,最多也只有68个PG会申请pg temp。
那在in+down
状态下osdmap中的139个pg_temp是如何而来的呢?如下是我们结合Monitor日志分析结果:
1) osd0端
osd0接收到关闭信号,后调用shutdown()函数:
在shutdown()函数中调用prepare_to_stop()函数向Monitor发送MOSDMarkMeDown
消息:
2) Monitor端
在Monitor端(src/mon/Monitor.cc),Monitor类继承自Dispatcher,因此可以分发消息:
这里来自OSD的消息会调用OSDMonitor的dispatch来进行处理:
之后调用prepare_update()来进行处理:
这里我们看到了实际的对于MOSDMarkMeDown消息的处理函数prepare_mark_me_down()函数:
如上,在函数中构造了一个proposal: C_AckMarkedDown,然后插入到waiting_for_finished_proposal列表中,准备对提议进行表决。因为Paxos需要对每一个提议进行持久化,因此这里会调用:
跟踪到这里,我们发现osdmap中的pg_temp原来是由maybe_prime_pg_temp()来生成的:
上面调用prime_pg_temp()来完成osdmap中的pg_temp的构建。
6.2 osdmap从active+clean
时的e2222变成in+down
时的e2225
在active+clean
状态时,我们查看到osdmap的版本号为e2222,但是到了in+down
状态时,我们查看到osdmap的版本号变为了e2225。这中间到底发生了一个什么样的过程呢? 下面我们结合在Monitor上面抓取到的日志mon-node7-1.txt
来进行分析。
执行如下命令导出e2222到e2225的osdmap:
1) osdmap从e2222变为e2223
osd0在接收到关闭信号后,在OSDService::prepare_to_stop()函数中向OSDMonitor发送MOSDMarkMeDown消息。在OSDMonitor接收到MOSDMarkDown消息后,生成一个proposal来进行表决,其中proposal的内容为: e2223版本的osdmap。在该proposal表决通过之后,就形成了一个权威的e2223
版本的osdmap,并正式标记osd0处于DOWN状态(此时此时我们查询ceph集群状态则为HEALTH_WARN),然后OSDMonitor正式对外发布该版本的osdmap。
执行如下命令对比osdmap e2222和e2223:
可以看到osdmap e2222与e2223相比,变化主要有两点:
-
osd0的状态由up状态变为down状态
-
为osd0上的所有PG都生成了一个pg_temp
注: osdmap发生变化,也同时会触发对pgmap的检查,导致pgmap也发生改变,接着触发检查是否需要创建新的PG等操作。
在上面osdmap e2223成功发布后,OSD、PGMonitor等接收到新版本的osdmap,就会触发相应的动作。这里我们介绍一下PGMonitor的大概执行路径。PGMonitor会逐个检查集群中的各个OSD,看是否需要向其发送创建pg的请求;接着检查那些处于down状态的PG,并更新对应PG的状态为stale,形成新的PGmap版本:
2020-09-11 14:05:19.834895 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 check_down_pgs last_osdmap_epoch 2223
2020-09-11 14:05:19.835145 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.65 stale (acting_primary 0)
2020-09-11 14:05:19.835167 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.61 stale (acting_primary 0)
2020-09-11 14:05:19.835192 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.4a stale (acting_primary 0)
2020-09-11 14:05:19.835203 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.44 stale (acting_primary 0)
2020-09-11 14:05:19.835216 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.3a stale (acting_primary 0)
2020-09-11 14:05:19.835222 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.38 stale (acting_primary 0)
2020-09-11 14:05:19.835228 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.37 stale (acting_primary 0)
2020-09-11 14:05:19.835237 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.30 stale (acting_primary 0)
2020-09-11 14:05:19.835244 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.2c stale (acting_primary 0)
2020-09-11 14:05:19.835253 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.26 stale (acting_primary 0)
2020-09-11 14:05:19.835261 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.21 stale (acting_primary 0)
2020-09-11 14:05:19.835270 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 14.d stale (acting_primary 0)
2020-09-11 14:05:19.835276 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 13.d stale (acting_primary 0)
2020-09-11 14:05:19.835284 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 14.8 stale (acting_primary 0)
2020-09-11 14:05:19.835313 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 13.9 stale (acting_primary 0)
2020-09-11 14:05:19.835336 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 14.3 stale (acting_primary 0)
2020-09-11 14:05:19.835347 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 11.4 stale (acting_primary 0)
2020-09-11 14:05:19.835358 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 13.4 stale (acting_primary 0)
2020-09-11 14:05:19.835363 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.1e stale (acting_primary 0)
2020-09-11 14:05:19.835371 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 14.5 stale (acting_primary 0)
2020-09-11 14:05:19.835381 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 18.2 stale (acting_primary 0)
2020-09-11 14:05:19.835389 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 19.2 stale (acting_primary 0)
2020-09-11 14:05:19.835401 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 21.1 stale (acting_primary 0)
2020-09-11 14:05:19.835411 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 18.4 stale (acting_primary 0)
2020-09-11 14:05:19.835419 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 20.3 stale (acting_primary 0)
2020-09-11 14:05:19.835428 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.6b stale (acting_primary 0)
2020-09-11 14:05:19.835437 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.72 stale (acting_primary 0)
2020-09-11 14:05:19.835441 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.73 stale (acting_primary 0)
2020-09-11 14:05:19.835446 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.75 stale (acting_primary 0)
2020-09-11 14:05:19.835452 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.76 stale (acting_primary 0)
2020-09-11 14:05:19.835456 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.79 stale (acting_primary 0)
2020-09-11 14:05:19.835461 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.79 stale (acting_primary 0)
2020-09-11 14:05:19.835465 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.7b stale (acting_primary 0)
2020-09-11 14:05:19.835470 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.7a stale (acting_primary 0)
2020-09-11 14:05:19.835476 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.7e stale (acting_primary 0)
2020-09-11 14:05:19.835489 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.89 stale (acting_primary 0)
2020-09-11 14:05:19.835501 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.92 stale (acting_primary 0)
2020-09-11 14:05:19.835508 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.96 stale (acting_primary 0)
2020-09-11 14:05:19.835512 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.96 stale (acting_primary 0)
2020-09-11 14:05:19.835524 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.b stale (acting_primary 0)
2020-09-11 14:05:19.835529 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.a1 stale (acting_primary 0)
2020-09-11 14:05:19.835535 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.a2 stale (acting_primary 0)
2020-09-11 14:05:19.835541 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.a4 stale (acting_primary 0)
2020-09-11 14:05:19.835546 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.a7 stale (acting_primary 0)
2020-09-11 14:05:19.835551 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.a7 stale (acting_primary 0)
2020-09-11 14:05:19.835560 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.ae stale (acting_primary 0)
2020-09-11 14:05:19.835565 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 24.5 stale (acting_primary 0)
2020-09-11 14:05:19.835577 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.bb stale (acting_primary 0)
2020-09-11 14:05:19.835586 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.be stale (acting_primary 0)
2020-09-11 14:05:19.835592 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.d stale (acting_primary 0)
2020-09-11 14:05:19.835600 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.c4 stale (acting_primary 0)
2020-09-11 14:05:19.835608 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.cb stale (acting_primary 0)
2020-09-11 14:05:19.835613 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.ca stale (acting_primary 0)
2020-09-11 14:05:19.835618 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.cb stale (acting_primary 0)
2020-09-11 14:05:19.835622 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.cf stale (acting_primary 0)
2020-09-11 14:05:19.835627 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.ce stale (acting_primary 0)
2020-09-11 14:05:19.835636 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.d2 stale (acting_primary 0)
2020-09-11 14:05:19.835642 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.d7 stale (acting_primary 0)
2020-09-11 14:05:19.835647 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.d6 stale (acting_primary 0)
2020-09-11 14:05:19.835652 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.d7 stale (acting_primary 0)
2020-09-11 14:05:19.835663 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.e stale (acting_primary 0)
2020-09-11 14:05:19.835669 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.e0 stale (acting_primary 0)
2020-09-11 14:05:19.835675 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.e2 stale (acting_primary 0)
2020-09-11 14:05:19.835696 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.e4 stale (acting_primary 0)
2020-09-11 14:05:19.835705 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.ea stale (acting_primary 0)
2020-09-11 14:05:19.835711 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.ec stale (acting_primary 0)
2020-09-11 14:05:19.835720 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 22.f1 stale (acting_primary 0)
2020-09-11 14:05:19.835731 7f8f9533c700 10 mon.node7-1@0(leader).pg v5839103 marking pg 23.fa stale (acting_primary 0)
上面刚好是所有以osd0作为主OSD的PG。
2) osdmap从e2223变为e2224
执行如下命令对比这两个版本的osdmap:
从上面可以看到,这两个版本的osdmap的变化主要是相应osd的up_thru发生了改变。
在OSD端,申请up_thru是通过如下函数来进行的:
在OSDMonitor端,如下是其处理流程:
接下来我们来看对MSG_OSD_ALIVE
的处理:
如果该请求可以在本阶段完成,直接返回true,否则返回false。这里如果所请求的osd的up_thru已经大于m->want,那么直接将对应的osdmap返回给OSD即可。否则需要下一步的处理。
可以看到这里直接生成一个proposal,提交表决,表决通过后将响应返回给OSD。
3) osdmap从e2224变为e2225
执行如下命令对比这两个版本的osdmap:
上面我们看到,osdmap的变化也是up_thru发生了更改。
6.2 osdmap从in+down
时的e2225变成active+clean
时的e2231
在e2225时,osd0处于down状态已经达到了5分钟,然后OSDMonitor自动将osd0标记为out状态,触发新的peering操作。这里我们将这一过程中的osdmap dump出来:
1) osdmap从e2225变为e2226
执行如下命令对比这两个版本的osdmap:
可以看到,osdmap的变化仅仅是osd.0的状态由down+in变为down+out。
2) osdmap从e2226变为e2227
执行如下命令对比这两个版本的osdmap:
从上面我们可以看到,osd3、osd4、osd5、osd6、osd7、osd8的up_thru都发生了改变,同时删除了与osd0相关的pg_temp。
3) osdmap从e2227变为e2228
执行如下命令对比这两个版本的osdmap:
从上面我们可以看到,osd.1~osd.8的up_thru都发生了改变,同时剩下的3个pg_temp也进行了删除。
4) osdmap从e2228到e2229
执行如下命令对比这两个版本的osdmap:
5) osdmap从e2229到e2230
执行如下命令对比这两个版本的osdmap:
6) osdmap从e2230到e2231
执行如下命令对比这两个版本的osdmap:
6.3 osd端工作流程
这里我们通过osd3的日志osd3_watch.txt
来分析一下OSD端的工作流程。
OSD3通过OSD::ms_dispatch()函数接收到OSDMonitor发送过来的新版本的osdmap(e2223),触发调用OSD::handle_osd_map()调用:
在osdmap成功保存到硬盘之后,回调C_OnMapCommit()函数:
在_committed_osd_maps()中consume_map()是一个关键的核心函数,起到触发相关PG的Peering过程。通常会在如下两种情况下触发PG的peering过程:
关于第一种情况,我们在《OSD启动流程》相关文章中已有说明,这里我们主要介绍一下第二种情形。
1) consume_map()函数
consume_map()会向所有PG发送一个NullEvt事件,接着将自己(PG)添加到对应OSD的peering_wq
中。
注:在osd3_watch.txt日志中,有大量类似于如下的打印信息
2020-09-11 14:05:19.127331 7fba49ec6700 7 osd.3 2223 consume_map version 2223
2020-09-11 14:05:19.129777 7fba49ec6700 30 osd.3 pg_epoch: 2222 pg[22.2c( empty local-les=2222 n=0 ec=155 les/c/f 2222/2222/0 2220/2221/2221) [0,3] r=1 lpr=2222 pi=2207-2220/5 crt=0’0 active] lock
2020-09-11 14:05:19.129793 7fba49ec6700 10 osd.3 pg_epoch: 2222 pg[22.2c( empty local-les=2222 n=0 ec=155 les/c/f 2222/2222/0 2220/2221/2221) [0,3] r=1 lpr=2222 pi=2207-2220/5 crt=0’0 active] null
这些打印信息就是来自于上面的pg->lock()
2) process_peering_events()函数
OSD对应的osd_tp
会检查peering_wq是否为空,如果不为空,触发调用process_peering_events():
在process_peering_events()函数中调用advance_pg()完成PG OSDMap的追赶。
3) advance_pg()函数
在advance_pg()中,for循环逐步完成PG对osdmap的追赶。里面涉及到的两个比较关键的函数是pg->handle_advance_map()以及pg->handle_activate_map(),下面我们分别介绍。
4) handle_advance_map()函数
在handle_advance_map()函数中会发起一个AdvMap事件,并调用recovery_state来进行处理。我们搜索AdvMap事件,发现在如下状态下都可接受该事件:
-
Reset状态
-
Started状态
-
WaitActingChange状态
-
Peering状态
-
Active状态
-
GetLog状态
-
Incomplete状态
之后我们在查看各个状态的react()处理函数,发现基本上都是会触发Peering操作。例如:
Active状态下收到AdvMap事件后,先进行一些其他的前置操作,之后调用forward_event()将事件交由父状态机处理。结合状态机转换图,Active状态机的父状态机为Started:
上面我们可以看到,如果需要重启进行Peering的话,那么就会转到Reset状态。
5) handle_activate_map()函数
handle_activate_map()函数会向recovery_state投递一个ActMap事件,并进行处理。我们搜索ActMap事件,发现在如下状态下都可接受该事件:
-
Reset状态
-
Primary状态
-
Active状态
-
ReplicaActive状态
-
Stray状态
-
WaitUpThru状态
之后我们在查看各个状态的react()处理函数,发现基本上都是调用pg->take_waiters()向OSD投递一些因peering而延后的事件,即这些事件需要等待peering完成之后来处理。例如:
Active状态下收到ActMap事件后,检查PG是否处于clean状态,如果不是,则将自己加入到recovery队列等待恢复(注: peering完成后,PG并不一定处于clean状态)。之后再调用forward_event()将事件交由父状态机处理。结合状态机转换图,Active状态的父状态为Primary:
在Primary::react()中对于ActMap主要是处理一些Peering完成后的事件。
实际上,有上面4)、5)的分析,我们发现,AdvMap
主要用于触发Peering过程,通常到PG::start_peering_interval()就结束;而ActMap
主要用于触发处理Peering完成后的一些事件。AdvMap是Advance OSDMap的缩写,而ActMap是Activate OSDMap的缩写,在处理actmap事件时都会调用pg->take_waiters()来等待相关的请求处理完成。
到这里,整个Peering的触发过程,我们基本上有了一个比较清晰的了解,而关于Peering的一些细节问题,我们会在后续相关的章节中继续讲解。