【osd】ceph读写流程

 概述

OSD是RADOS集群的基本存储单元。

PG(placement group)从名字可理解为放置策略组,它是对象的集合,该集合里的所有对象都具有相同的放置策略:对象的副本都分布在相同的OSD列表上。一个对象只能属于一个PG,一个PG对应于放置在其上的OSD列表。一个OSD上可以分布多个PG。处理来自客户端的读写请求是PG的基本功能。

Pool是整个集群层面定义的一个逻辑的存储池,它规定了数据冗余的类型以及对应的副本分布策略。目前实现了两种pool类型:replicated类型和Erasure Code类型。一个pool由多个PG构成。

 

读写流程

读写流程大致分为以下几个阶段:

  1. 客户端基于对象标识中的32位哈希值,通过stable_mod找到存储池中承载该对象的PGID,然后使用该PGID作为CRUSH输入,找到对应PG当前Primary所在的OSD并发送读写请求。
  2. OSD收到客户端发送的读写请求,将其封装为一个op,并基于其携带的PGID将其转发至对应的PG。
  3. PG收到op后,完成一些列检查,所有条件均满足后,开始真正执行op。
  4. 如果op只包含读操作,那么直接执行同步读(对应多副本)或者异步读(对应纠删码),等待读操作完成后由Primary向客户端应答。
  5. 如果op包含写操作,则由Primary基于op生成一个针对原始对象操作的PG事务,然后将其提交至PGBackend,由后者按照备份策略转化为每个副本真正需要执行的本地事务,并进行分发。当Primary收到所有副本的写入完成应答之后,对应op执行完成,由Primary向客户端回应写入完成。

对象寻址

对象寻址参考client写操作部分

消息接收与分发

读写请求都是从OSD::ms_fast_dispatch开始,它是接收读写消息message的入口。

 

消息出队处理

 

do_request

主要进行PG级别的检查,处理流程:

 

 

do_op

主要进行对象级别的检查和一些上下文的准备工作。处理流程:

 

 

execute_ctx

 

 

prerare_transaction操作主要分为三个阶段:

  1. 通过do_osd_ops生成原始op对应的PG事务。
  2. 如果op针对head对象操作通过make_writeable检查是否需要预先执行克隆操作。
  3. 通过finish_ctx生成操作原始对象的日志,并更新对象的OI和SS属性。

do_osd_ops:

对于读操作,在do_osd_ops()->do_read()中,如果是同步读直接调用pgbackend->objects_read_sync进行读操作。如果是异步读,先将op添加到pending_async_reads中,然后在execute_ctx()检测pending_async_reads队列时执行读操作。

写操作步骤如下:

 

 

make_writeable:

如果op针对head对象操作,通过make_writeable检查是否需要预先执行克隆操作。

 

 

finish_ctx:

PG事务的内存版本已经准备完毕,此时可以生成原始对象的操作日志,并更新对象上下文中OI与SS属性。

 

参考资料

1. ceph读写流程

posted @ 2021-12-10 10:21  苏格拉底的落泪  阅读(1812)  评论(0编辑  收藏  举报