這篇文章主要介紹Ceph中RGW是如何向底層OSD發(fā)送Message的,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
成都創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),沾益企業(yè)網(wǎng)站建設(shè),沾益品牌網(wǎng)站建設(shè),網(wǎng)站定制,沾益網(wǎng)站建設(shè)報價,網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,沾益網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學習、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網(wǎng)站。
在src/cls/rgw/cls_rgw_client.cc
可以看到如下函數(shù):
int cls_rgw_lc_set_entry(IoCtx& io_ctx, string& oid, pair& 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; }
繼續(xù)跟蹤io_ctx.exec()
這個函數(shù)調(diào)用, 在src/librados/librados.cc
可以查看到相應(yīng)的函數(shù)實現(xiàn)如下:
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); }
繼續(xù)跟蹤io_ctx_impl->exec()
這個函數(shù)調(diào)用,在librados/IoCtxImpl.cc
中看到如下實現(xiàn):
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()此函數(shù)將該操作封裝成OSDOp,放入ObjectOperation對象的vector集合中。 在最后的operate_read(oid, &rd, &outbl)
函數(shù)中發(fā)起讀寫請求操作:
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, &r); 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)
可以分解為一下三個步驟:
創(chuàng)建一個Op實例,數(shù)據(jù)結(jié)構(gòu)變成了Objecter::Op
Objecter::Op *objecter_op = objecter->prepare_read_op(oid, oloc, *o, snap_seq, pbl, flags, onack, &ver);
操作提交到objecter層,操作對象類型變?yōu)?code>Objecter::Op, 函數(shù)實現(xiàn)在osdc/Objecter.cc
:
objecter->op_submit(objecter_op)
繼續(xù)調(diào)用ceph_tid_t Objecter::_op_submit()
函數(shù),函數(shù)實現(xiàn)在osdc/Objecter.cc
: 省略了部分代碼,重點關(guān)注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)
就是我們要關(guān)注的重點了. 從這里開始就會用到網(wǎng)絡(luò)層提供的各種操作將消息,也就是這里的op
發(fā)送出去. 這里可以看成是調(diào)用網(wǎng)絡(luò)層的一個起點.
下面的代碼就和網(wǎng)絡(luò)層有關(guān)系了。
在網(wǎng)絡(luò)層中,需要注意的是類Messenger是核心的數(shù)據(jù)結(jié)構(gòu)。同時也是個抽象基類,在Firefly版本中,由于網(wǎng)絡(luò)通信類型只實現(xiàn)了SimpleMessenger這一單一類型。在后面,就會看到SimpleMessenger是繼承自Messenger類,很多方法最終都是調(diào)用的是SimpleMessenger(在此也可以體會到多態(tài)思想)。 首先,看一下Objecter類的聲明(其他部分已省略):
class Objecter : public md_config_obs_t { ........... public: Messenger *messenger; ........ }
在這個類中聲明了messenger
. 從ceph_tid_t Objecter::_op_submit(Op *op)
中可以看到,最后調(diào)用了send_op()
函數(shù)。 這個函數(shù)末尾:
messenger->send_message(m, op->session->con);
可以看出,需要發(fā)送的消息是: m
。 發(fā)送到哪里去呢? 通過**op->session->con
**可以獲取到相應(yīng)的連接。
以上是“Ceph中RGW是如何向底層OSD發(fā)送Message的”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!