rados写入一个文件的流程

简单分析下使用librados接口写入一个文件的流程,首先是librados解析配置、和集群建立链接之后,创建一个librados::IoCtx后就可以开始写入文件。入口是librados::IoCtxImpl::write_full这个方法,然后进程objecter相关的逻辑,Objecter::write_full,Objecter::write_full会把相关的请求通过add_data方法加入到 OSDOp的indata里。librados::IoCtxImpl::operate会执行刚才生成的那些op。Objecter::op_submit,然后_op_submit_with_budget,这里会通过objecter_inflight_ops、objecter_inflight_op_bytes这两个配置来进行流控。_op_submit在这个函数里会调用_calc_target来进行这个文件目标位置,注意_calc_target里会判断cache tier的情况,代码如下:

// apply tiering t->target_oid = t->base_oid; t->target_oloc = t->base_oloc; if ((t->flags & CEPH_OSD_FLAG_IGNORE_OVERLAY) == 0) { if (is_read && pi->has_read_tier()) t->target_oloc.pool = pi->read_tier; if (is_write && pi->has_write_tier()) t->target_oloc.pool = pi->write_tier; pi = osdmap->get_pg_pool(t->target_oloc.pool); if (!pi) { t->osd = -1; return RECALC_OP_TARGET_POOL_DNE; } }

最终Objecter::_send_op会把这个op的请求发送到primary的osd。
流控的逻辑是在Objecter::_op_submit_with_budget体现的:
if (!op->ctx_budgeted || (ctx_budget && (*ctx_budget == -1))) { int op_budget = _take_op_budget(op, sul); // take and pass out the budget for the first OP // in the context session if (ctx_budget && (*ctx_budget == -1)) { *ctx_budget = op_budget; } } }

上面的代码里的_take_op_budget会做流控
在Objecter::_finish_op里有调用put_op_budget,代码如下:
if (!op->ctx_budgeted && op->budgeted) put_op_budget(op);

刚才Objecter::_send_op会调用 op->session->con->send_message(m); 把请求发送到primary的osd上,message的type是CEPH_MSG_OSD_OP。
【rados写入一个文件的流程】在Objecter::ms_dispatch里会处理osd返回的结果,对应的函数是Objecter::handle_osd_op_reply。

    推荐阅读