Ceph源码解析:读写流程(5)

目前的资源统计一下,写请求可以根据目标主osd,去查找或者建立一个OSDSession,这个OSDSession中会有一个管理数据通道的Pipe结构,然后这个结构中存在一个发送消息的处理线程writer,这个线程会保持与目标osd的socket通信。

12. 建立并且获取到了这些资源,这时再回到_op_submit 函数中

ceph_tid_t Objecter::_op_submit(Op *op, RWLock::Context& lc) {     check_for_latest_map = _calc_target(&op->target, &op->last_force_resend); //---a    int r = _get_session(op->target.osd, &s, lc);  //---b    _session_op_assign(s, op); //----c    MOSDOp *m = _prepare_osd_op(op); //-----d    _send_op(op, m); //----e }

---c,将当前的op请求与这个session进行绑定,在后面发送请求的时候能知道使用哪一个session进行发送。

--d,将op转化为MOSDop,后面会以MOSDOp为对象进行处理的。

---e,_send_op 会根据之前建立的通信通道,将这个MOSDOp发送出去。_send_op 中调用op->session->con->send_message(m),这个方法会调用SimpleMessager-> send_message(m), 再调用_send_message(),再调用submit_message().在submit_message会找到之前的pipe,然后调用pipe->send方法,最后通过pipe->writer的线程发送到目标osd。

自此,客户就等待osd处理完成返回结果了。

151617_dNP0_2460844

1.看左上角的rados结构,首先创建io环境,创建rados信息,将配置文件中的数据结构化到rados中。

2.根据rados创建一个radosclient的客户端结构,该结构包括了三个重要的模块,finiser 回调处理线程、Messager消息处理结构、Objector数据处理结构。最后的数据都是要封装成消息 通过Messager发送给目标的osd。

3.根据pool的信息与radosclient进行创建一个ioctx,这里面包好了pool相关的信息,然后获得这些信息后在数据处理时会用到。

4.紧接着会复制这个ioctx到imagectx中,变成data_ioctx与md_ioctx数据处理通道,最后将imagectx封装到image结构当中。之后所有的写操作都会通过这个image进行。顺着image的结构可以找到前面创建并且可以使用的数据结构。

5.通过最右上角的image进行读写操作,当读写操作的对象为image时,这个image会开始处理请求,然后这个请求经过处理拆分成object对象的请求。拆分后会交给objector进行处理查找目标osd,当然这里使用的就是crush算法,找到目标osd的集合与主osd。

6.将请求op封装成MOSDOp消息���然后交给SimpleMessager处理,SimpleMessager会尝试在已有的osd_session中查找,如果没有找到对应的session,则会重新创建一个OSDSession,并且为这个OSDSession创建一个数据通道pipe,把数据通道保存在SimpleMessager中,可以下次使用。

7.pipe 会与目标osd建立Socket通信通道,pipe会有专门的写线程writer来负责socket通信。在线程writer中会先连接目标ip,建立通信。消息从SimpleMessager收到后会保存到pipe的outq队列中,writer线程另外的一个用途就是监视这个outq队列,当队列中存在消息等待发送时,会就将消息写入socket,发送给目标OSD。

8. 等待OSD将数据消息处理完成之后,就是进行回调,反馈执行结果,然后一步步的将结果告知调用者。

四、Ceph读流程

OSD端读消息分发流程

image

OSD端读操作处理流程

image

总体流程图:

4ac886ce405a7e638b2979b693802a8e

int read(inodeno_t ino,
            file_layout_t *layout,
            snapid_t snap,
            uint64_t offset,
            uint64_t len,
            bufferlist *bl,  // ptr to data
            int flags,
            Context *onfinish,
            int op_flags = 0)    --------------------------------Filer.h

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/bccb0f79f96239680a8dd2c94f779512.html