【osd】Ceph OSD写操作失效如何处理

 OSD写操作失效如何处理

很多人对Ceph写操作的异常处理的过程还不是特别的清楚。本文就介绍Ceph如何处理异常处理的。

首先需要明确的是,Ceph的读写操作并没有超时机制。 rbd_write并没有超时机制。所有经常看到,用ceph -s 命令查看,有些 slow request请求会显示延迟 30s甚至更长的时间。

当然,osd有一个机制,会检查某个线程执行时间,如果执行时间过长,osd就会触发自杀机制(osd suicide timeout)。这个机制默认关闭。

下面就研究一下ceph如何处理写操作的异常。

正常的写流程
在OSD端正常的写操作流程中,在函数ReplicatedBackend::submit_transaction把请求加入到in_progress_ops 队列中

map<ceph_tid_t, InProgressOp> in_progress_ops;
1
该map保存了所有正在处理的请求。一个请求必须等到所有的 acting 的osd的请求都返回才能返回给客户端。

例如
pg 1.1(osd1,osd2,osd4)
client的请求先发起给osd1,osd1把请求发送给osd2和osd4,等到osd2和osd4上的请求返回给osd1,osd1才能给客户端应答。

那么,当osd2或者osd4出现crash的情况下,该请求如何处理? 甚至当osd1出现crash的情况该如何处理呢? 实际上,客户端和OSD端都根据接收到的OSDMap的变化来做相应的处理。

OSD端的处理
当一个osd发生故障或者crash时(无论何种原因),通过Heartbeat机制,Monitor会检查到该osd的状态,并把该状态通过OSDMap推送给集群中其它的节点。相应的PG在peering的过程中,会首先丢弃正在处理请求。

例如上述的例子:

当一个osd2或者osd4发生crash时,通过hearbeat等机制,该osd的状态会上报给monitor,当monitor判断该osd处于down状态,会把最新的osdmap推送给各个osd。当osd1收到该osdmap后,pg1.1发现自己的osd 列表发生了变化,就会重新发起peering过程。其会调用函数:PG::start_peering_interval, 该函数调用了ReplicatedBackend::on_change(), 该函数会把正在处理的请求从in_progress_ops中删除。

void PG::start_peering_interval(
{
     on_change(t);
}

 

参考资料

1. Ceph OSD写操作失效如何处理

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