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。
推荐阅读
- 20161126|20161126|一个简单的建立阅读笔记档案方法
- 赌个一生一世,敢不敢(5)
- 泰国房地产将真正进入一个全新时代
- 6-Python中raw字符串与多行字符串
- 再来一个二十岁人生
- 读书清单(《一个人的朝圣》)
- 无声深处
- 厨房咏叹调
- 路边的小花
- 猫猫音乐推荐,高进《有太多人》,请珍惜身边每一个拥抱和眼神!