ceph rados ls命令卡死不返回

在测试ceph故障时,发现如果osd节点故障,那么 rados ls命令将长时间hang住,一直不返回。
测试是这样进行的,

  1. 搭建一个由1个monitor, 3个OSD组成的集群。
  2. 创建一个pool tp, size=3,
  3. 关闭osd2, osd3
  4. 运行命令rados -p tp ls ,会发现命令一直不返回。

从ceph的bug库里面看到一个类似的记录: http://tracker.ceph.com/issues/14992 。这个bug得到的解释认为这是正常的,pool里面rbd_directory映射到的3个OSD都down掉了,所以rados ls命令不返回。然而有几点疑惑的是,1) pool里面并没有创建过rbd_directory对象 2) 测试中并没有把3个OSD都关掉,仍然有1个OSD是活动的。

对测试过程进行进一步分析,发现:

  1. 当3个OSD状态都OK时,rbd_directory映射到的OSD是这样的:
# ceph osd map tp  rbd_directory
osdmap e107 pool 'tp' (3) object 'rbd_directory' -> pg 3.30a98c1c (3.4) -> up ([3,2,1], p3) acting ([3,2,1], p3)
  1. 关闭OSD3后,rbd_directory映射到的OSD是这样的:
# ceph osd map tp  rbd_directory
osdmap e121 pool 'tp' (3) object 'rbd_directory' -> pg 3.30a98c1c (3.4) -> up ([2,1], p2) acting ([2,1], p2)

此时运行rados -p tp ls 仍然能得到返回值。

  1. 继续关闭OSD2后,rbd_directory映射到的OSD是这样的:
# ceph osd map tp  rbd_directory
osdmap e123 pool 'tp' (3) object 'rbd_directory' -> pg 3.30a98c1c (3.4) -> up ([1], p1) acting ([1], p1)

然而rados -p tp ls 就Hang住不返回任何响应了。上面官方bug网站的解释显然不能完全解释我现在遇到的情况,这里显然还有一个acting osd。

分析

打开client端的log(在/etc/ceph/ceph.conf里面增加debug objecter = 20/20打开Log), 对Log进行分析,发现了hang住前进行了的操作和hang住的位置如下:

client.154225.objecter list_nobjects pool_id 3 pool_snap_seq -2 max_entries 1024 list_context 0x55aa8af8f1d0 onfinish 0x55aa8aeefed0 current_pg 0 pos MIN

client.154225.objecter _calc_target  raw pgid 3.0 -> actual 3.0 acting [1] primary 1
client.154225.objecter _get_session s=0x55aa8af90f90 osd=1 3


client.154225.objecter  response.entries.size 0, response.entries , handle 3:20000000::::head, tentative new pos 3:20000000::::head
client.154225.objecter list_nobjects pool_id 3 pool_snap_seq -2 max_entries 1024 list_context 0x55aa8af8f1d0 onfinish 0x55aa8aeefed0 current_pg 0 pos 3:20000000::::head


client.154225.objecter _calc_target  raw pgid 3.4 -> actual 3.4 acting [1] primary 1
client.154225.objecter _get_session s=0x55aa8af90f90 osd=1 4

client.154225.objecter  response.entries.size 0, response.entries , handle 3:40000000::::head, tentative new pos 3:40000000::::head
client.154225.objecter list_nobjects pool_id 3 pool_snap_seq -2 max_entries 1024 list_context 0x55aa8af8f1d0 onfinish 0x55aa8aeefed0 current_pg 4 pos 3:40000000::::head

client.154225.objecter _calc_target  raw pgid 3.2 -> actual 3.2 acting [1] primary 1
client.154225.objecter _get_session s=0x55aa8af90f90 osd=1 4

client.154225.objecter  response.entries.size 1, response.entries objA, handle 3:60000000::::head, tentative new pos 3:60000000::::head
client.154225.objecter list_nobjects pool_id 3 pool_snap_seq -2 max_entries 1024 list_context 0x55aa8af8f1d0 onfinish 0x55aa8aeefed0 current_pg 2 pos 3:60000000::::head

client.154225.objecter _calc_target  raw pgid 3.6 -> actual 3.6 acting [] primary -1
client.154225.objecter _get_session osd=-1 returning homeless
client.154225.objecter _maybe_request_map subscribing (onetime) to next osd map

从日志看其实已经成功list了好几个pg, 只是当操作到pg 3.6时进行不下去。从最后的日志看,

_calc_target  raw pgid 3.6 -> actual 3.6 acting [] primary -1
_get_session osd=-1 returning homeless

无法找到pg 3.6的acting set, 因此后面的get_session也无法获得一个连接以进行操作。

进一步追踪,发现问题出在_pg_to_raw_osds函数的返回结果。对于pg 3.6, 这个函数返回的raw osd列表只有{2}, 不像其他的几个pg,raw osd列表里面都有{1, 2}。因为目前2是down的状态,所以pg 3.6就没有acting osd了。接下来继续看为什么会这样。

ceph -s 看集群状态,发现一个奇怪的现象,osd 2处于down/in的状态。这就解释了为什么osd 2能被选中到raw osd列表。

只是为什么osd 2一直长期处于down/in的状态,还不清楚。

你可能感兴趣的:(ceph,存储技术)