天天看點

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的狀态,還不清楚。

繼續閱讀