久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

Ceph中RGW是如何向底層OSD發送Message的

166次閱讀
沒有評論

共計 3196 個字符,預計需要花費 8 分鐘才能閱讀完成。

這篇文章主要介紹 Ceph 中 RGW 是如何向底層 OSD 發送 Message 的,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

1. Librados 的讀寫流程

在 src/cls/rgw/cls_rgw_client.cc 可以看到如下函數:

int cls_rgw_lc_set_entry(IoCtx  io_ctx, string  oid, pair string, int  entry)
 bufferlist in, out;
 cls_rgw_lc_set_entry_op call;
 call.entry = entry;
 ::encode(call, in);
 int r = io_ctx.exec(oid,  rgw ,  lc_set_entry , in, out);
 return r;
}

繼續跟蹤 io_ctx.exec() 這個函數調用, 在 src/librados/librados.cc 可以查看到相應的函數實現如下:

int librados::IoCtx::exec(const std::string  oid, const char *cls, const char *method,
 bufferlist  inbl, bufferlist  outbl)
 object_t obj(oid);
 return io_ctx_impl- exec(obj, cls, method, inbl, outbl);
}

繼續跟蹤 io_ctx_impl- exec() 這個函數調用,在 librados/IoCtxImpl.cc 中看到如下實現:

int librados::IoCtxImpl::exec(const object_t  oid, 
 const char *cls, const char *method,
 bufferlist  inbl, bufferlist  outbl)
 ::ObjectOperation rd;
 prepare_assert_ops(rd);
 rd.call(cls, method, inbl);
 return operate_read(oid,  rd,  outbl);
}

rd.call() 此函數將該操作封裝成 OSDOp,放入 ObjectOperation 對象的 vector 集合中。在最后的 operate_read(oid, rd, outbl) 函數中發起讀寫請求操作:

int librados::IoCtxImpl::operate_read(const object_t  oid, 
 ::ObjectOperation *o,
 bufferlist *pbl,
 int flags)
 if (!o- size())
 return 0;
 Mutex mylock( IoCtxImpl::operate_read::mylock 
 Cond cond;
 bool done;
 int r;
 version_t ver; 
 Context *onack = new C_SafeCond( mylock,  cond,  done,   
 int op = o- ops[0].op.op;
 ldout(client- cct, 10)   ceph_osd_op_name(op)     oid=    oid     nspace=    oloc.nspace   dendl;
 Objecter::Op *objecter_op = objecter- prepare_read_op(oid, oloc,
 *o, snap_seq, pbl, flags,
 onack,  ver);
 lock- Lock();
 objecter- op_submit(objecter_op);
 lock- Unlock();
 mylock.Lock();
 while (!done)
 cond.Wait(mylock);
 mylock.Unlock();
 ldout(client- cct, 10)    Objecter returned from  
   ceph_osd_op_name(op)     r=    r   dendl;
 set_sync_op_version(ver);
 return r;
}

需要說明的是 operate_read(oid, rd, outbl) 可以分解為一下三個步驟:

創建一個 Op 實例, 數據結構變成了 Objecter::Op

Objecter::Op *objecter_op = objecter- prepare_read_op(oid, oloc,
 *o, snap_seq, pbl, flags,
 onack,  ver);

操作提交到 objecter 層,操作對象類型變為 Objecter::Op, 函數實現在 osdc/Objecter.cc:

objecter- op_submit(objecter_op)

繼續調用 ceph_tid_t Objecter::_op_submit() 函數,函數實現在 osdc/Objecter.cc:省略了部分代碼,重點關注 send_op(op)

ceph_tid_t Objecter::_op_submit(Op *op) 
 // pick tid if we haven t got one yet
 if (op- tid == ceph_tid_t(0)) {
 ceph_tid_t mytid = ++last_tid;
 op- tid = mytid;
 }
 assert(client_inc  = 0);
 // pick target
 num_homeless_ops++; // initially; recalc_op_target() will decrement if it finds a target
 int r = recalc_op_target(op);
 bool check_for_latest_map = (r == RECALC_OP_TARGET_POOL_DNE);
 ............
 else if (op- session) { send_op(op);
 } 
 .............
 }

這里的 send_op(op) 就是我們要關注的重點了. 從這里開始就會用到網絡層提供的各種操作將消息, 也就是這里的 op 發送出去. 這里可以看成是調用網絡層的一個起點.

下面的代碼就和網絡層有關系了。

2. 發送消息的過程。

在網絡層中,需要注意的是類 Messenger 是核心的數據結構。同時也是個抽象基類,在 Firefly 版本中,由于網絡通信類型只實現了 SimpleMessenger 這一單一類型。在后面,就會看到 SimpleMessenger 是繼承自 Messenger 類,很多方法最終都是調用的是 SimpleMessenger(在此也可以體會到多態思想)。首先,看一下 Objecter 類的聲明 (其他部分已省略):

class Objecter : public md_config_obs_t {
 ...........
 public:
 Messenger *messenger;
 ........
}

在這個類中聲明了 messenger. 從 ceph_tid_t Objecter::_op_submit(Op *op) 中可以看到,最后調用了 send_op() 函數。這個函數末尾:

messenger- send_message(m, op- session- con);

可以看出,需要發送的消息是: m。發送到哪里去呢?通過 **op- session- con** 可以獲取到相應的連接。

以上是“Ceph 中 RGW 是如何向底層 OSD 發送 Message 的”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注丸趣 TV 行業資訊頻道!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-16發表,共計3196字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 鹤壁市| 道真| 平遥县| 大英县| 仪征市| 六安市| 普陀区| 图们市| 昌江| 临高县| 郸城县| 土默特左旗| 鄂托克前旗| 滦平县| 平度市| 同仁县| 通化县| 竹山县| 县级市| 绩溪县| 抚州市| 阆中市| 石河子市| 阳曲县| 岢岚县| 涡阳县| 鄂尔多斯市| 兴义市| 沐川县| 诏安县| 贺兰县| 巴南区| 万安县| 顺义区| 土默特右旗| 阿巴嘎旗| 门源| 安丘市| 子洲县| 广饶县| 黄龙县|