Ceph rbd写入数据

本文简介rbd中数据的写入过程。

do_import(librbd::RBD &rbd, librados::IoCtx& io_ctx,
        const char *imgname, int *order, const char *path,
        int format, uint64_t features, uint64_t size,
        uint64_t stripe_unit, uint64_t stripe_count)
    >open(path, O_RDONLY) //首先打开要导入的文件
    >fstat(fd, &stat_buf) //获取该文件的元信息,主要关注size
    >do_create(rbd, io_ctx, imgname, size, order, format, features,stripe_unit, stripe_count) //为上传的文件创建一个image
    >rbd.open(io_ctx, image, imgname) //打开该image
    >read(fd, p + blklen, reqlen)) //从本地文件中读取指定长度的数据,放入到p执行的字符数组中。
    >bl.append(p, blklen) //把读取到的数据放入到bufferlist中
    >new AioImportContext(*throttle, image, bl, image_pos) //写入读取的文件到image中(在回调对象中实现) image_pos是相对于image
    >image.aio_write2(m_offset, m_bufferlist.length(), m_bufferlist,m_aio_completion, op_flags) //m_offset相对于image
        >submit_aio_write(ictx, off, len, bl.c_str(), get_aio_completion(c),op_flags) //rbd的写入提供两种写入方式:1.异步阻塞 2.异步非阻塞(两者并列)
            >ictx->aio_work_queue->queue(new C_AioWriteWQ(ictx, off, len, buf, c,op_flags)) //异步非阻塞,将写入工作放入ImageCtx::aio_work_queue队列中
            aio_work_queue是ContextWQ类的实例,该类继承于ThreadPool::PointerWQ->ThreadPool::WorkQueue_;有aio_work_queue = new ContextWQ("librbd::aio_work_queue",cct->_conf->rbd_op_thread_timeout,thread_pool_singleton);可以看出该队列中的元素会由ThreadPoolSingleton线程池中的线程来处理
            由于元素C_AioWriteWQ是一个回调对象,在处理的时候,通过调用该类的complete方法,再调用finish方法,最后调用librbd::aio_write(m_ictx, m_off, m_len, m_buf, m_comp, m_op_flags),来处理。
            >librbd::aio_write(ictx, off, len, buf, c, op_flags) //异步阻塞的调用方式
                >Striper::file_to_extents(ictx->cct, ictx->format_string,&ictx->layout, off, clip_len, 0, extents)
                    >file_to_extents(cct, object_format, layout, offset, len, trunc_size,object_extents, buffer_offset) //将读取到的数映射到相应的对象上,被映射的对象会有一组vector<ObjectExtent>, 每个OjectExtent标记image的某段范围映射到该对象上。
                        >file_to_extents(cct, object_format, layout, offset, len, trunc_size,object_extents, buffer_offset)
                        >assimilate_extents(object_extents, extents) //把不同对象的ObjectExtent,合并到同一个vector<ObjectExtent>
                >bufferlist bl;for(vector<ObjectExtent> for(ObjectExtent.buffer_extents){bl.append(buf + q->first, q->second)}) //把ObjectExtend中标记的image范围合并到一个bufferlist中。
                >ictx->write_to_cache(p->oid, bl, p->length, p->offset, req_comp, op_flags) //rbd支持Cache,该调用是使用cache方式
                    >object_cacher->writex(wr, object_set, onfinish)
                >AioWrite *req = new AioWrite(ictx, p->oid.name, p->objectno, p->offset, bl, snapc, req_comp) //禁用cache方式
                >req->send()
                    >send_pre() 
                        >send_write()
                            >add_write_ops(&m_write) //初始化Objecter::ObjectOperation对象
                            >m_ictx->data_ctx.aio_operate(m_oid, rados_completion, &m_write,m_snap_seq, m_snaps)
                                >io_ctx_impl->aio_operate(obj, (::ObjectOperation*)o->impl, c->pc,snapc, 0)
                                    >objecter->mutate(oid, oloc, *o, snap_context, ut, flags, onack, oncommit,&c->objver) //进入Objecter层
                                        >prepare_mutate_op(oid, oloc, op, snapc, mtime, flags, onack, oncommit, objver) //封装成Op
                                        >op_submit(o)
                                            >_op_submit_with_budget(op, lc, ctx_budget) //统计该Op的预算
                                                >_op_submit(op, lc) //提交Op

当rbd做写入操作时:
1.缓存要写入的数(off(in image)、len、data)
2.计算该操作落到具体哪个对象上(通过off、image size、stripe,获得对象(off(in object)、len、data))
3.将要写入的对象封装在AioWrite对象中,并进一步放入librados::ObjecterOperation的 Objecter.h/ObjectOperation中
4.通过image context进入IO context再进入objecter层,ObjectOperation转变成Op
5.计算Op对应的pg、osd,获得session,进入massenger层,通过PipeConnect.Pipe,发送到客户端。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值