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。

在Objecter::ms_dispatch里会处理osd返回的结果,对应的函数是Objecter::handle_osd_op_reply。

你可能感兴趣的:(rados写入一个文件的流程)