注意
本文档适用于 Ceph 开发版本。
RADOS客户端协议
这非常不完整,但总得开始 somewhere。
基础知识
请求是MOSDOp消息。回复是MOSDOpReply消息。
对象请求针对的是hobject_t,它包括一个池、哈希值、对象名、放置键(通常是空的)和快照ID。
哈希值是一个32位哈希值,通常通过哈希对象名生成。但是,hobject_t可以任意构造,具有任何哈希值和名称。请注意,在MOSDOp中,这些组件分布在几个字段中,而不是逻辑地组合在一个实际的hobject_t成员中(主要是历史原因)。
请求也可以针对一个PG。在这种情况下,值匹配特定的PG,对象名为空,并且(希望)请求中的操作是PG操作。ps值匹配
无论如何,请求最终针对一个PG,要么通过显式pgid,要么通过将哈希值折叠到池中当前的PG数量上。客户端将请求发送给相关PG的主节点。
每个请求都被分配一个唯一的tid。
重发
如果发生连接中断,客户端将重发任何未完成的请求。
任何时候PG映射发生变化,主节点发生变化,客户端都有责任重发请求。请注意,尽管从OSD的角度来看可能会有间隔变化(触发PG对等),但如果主节点没有变化,客户端就不必重发。
有几个例外情况:
OSDMap中的pg_pool_t有一个last_force_op_resend字段。如果这个字段发生变化,客户端被迫重发任何未完成的请求。(例如,当分层调整时会发生这种情况。)
有些请求在PG间隔变化时会被重发,如pg_interval_t的is_new_interval()定义(这是OSD中对等使用的相同标准)。任何 PG interval change, as defined by pg_interval_t’s is_new_interval() (the same criteria used by peering in the OSD).
如果PAUSE OSDMap标志被设置和取消。
每次将请求发送给OSD时,尝试字段都会递增。第一次是0,下一次是1,以此类推。attempt field is incremented. The first time it is 0, the next 1, etc.
指数退避
通常情况下,OSD会将其无法立即处理的任何请求排队在内存中,直到它可以处理为止。这可能会成为一个问题,因为OSD限制了传入消息消耗的总RAM量:如果消息数量或字节数的任一阈值达到,新的消息将不会从网络套接字中读取,导致网络中的背压。
然而,在某些情况下,OSD知道或预期某个PG或对象在一段时间内不可用,并且不想通过排队请求来消耗内存。在这些情况下,它可以向客户端发送一个MOSDBackoff消息。
一个退避请求有四个属性:
操作码(块、取消块或确认块)
id,在此会话中分配的唯一ID
hobject_t开始
hobject_t结束
有两种类型的退避:一个PG退避将阻塞客户端针对整个PG的所有请求,如哈希/hobject_t空间中的范围[begin,end)所述,而一个object退避将阻塞客户端针对单个对象的所有请求(begin == end)。
当客户端收到一个块退避消息时,它现在负责firefly 发布。Firefly 将延迟至少另一个冲刺,以便我们可以对新代码进行一些操作经验,并进行一些额外的测试,然后再承诺长期支持。发送任何请求,这些请求描述了退避中定义的hobject_t。退避在退避被清除(通过“取消块”消息)或OSD会话关闭之前仍然有效。立即向OSD发送一个9f7c9f: ack_blockack_block消息以确认收到退避。
当收到取消时,它将引用客户端之前阻塞的特定ID。但是,取消描述的范围可能小于原始范围,因为PG可能在OSD上分裂。取消应该only取消取消消息中指定的范围。任何在取消请求范围内 falling 的请求都将重新检查,如果没有任何其他已安装的退避适用,则重新发送。
在OSD上,退避也在哈希空间的范围内进行跟踪,并且存在于三种状态中:
new
已确认
删除中
新安装的退避设置为new,并向客户端发送消息。当收到ack-block消息时,它变为已确认状态。OSD可能会处理来自客户端的其他消息,这些消息在new状态下被退避覆盖,但一旦退避被已确认确认,它应该永远不会看到被阻塞的请求,除非有错误。
如果OSD想要删除处于已确认状态的退避,它可以简单地删除它并通知客户端。如果退避处于new状态,它必须将其移动到删除中状态,并继续使用它来丢弃客户端请求,直到收到ack-block消息,此时它最终可以被删除。这是为了保持OSD处理的操作顺序。
由 Ceph 基金会带给您
Ceph 文档是一个社区资源,由非盈利的 Ceph 基金会资助和托管Ceph Foundation. 如果您想支持这一点和我们的其他工作,请考虑加入现在加入.