ceph-heartbeat2

ceph集群中的心跳机制研究2

我知道Ceph的基石是RADOS,而RADOS的含义是Reliable Autonomic Distributed Object Storage,而Autonomic(自治)的实现则依赖于Ceph中很好的故障检测机制。
下面进入正题。

Ceph在故障检测的时候有两个函数:

1
2
OSDMonitor::check_failure
OSDMonitor::prepare_failure

他们之间的关系是,prepare_failure做了一些fail前的report过程,然后再调用check_failure。

grace time

对于osd的故障判断有个grace time,相当于一个容错值,当fail time大于grace time时基本可以断定osd fail。当配置项g_conf->mon_osd_adjust_heartbeat_grace为true的时候,grace的计算有个过程,并且这个过程让人难以理解,先贴一下代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//my_grace计算
double halflife = (double)g_conf->mon_osd_laggy_halflife;
double decay_k = ::log(.5) / halflife;

// scale grace period based on historical probability of 'lagginess'
// (false positive failures due to slowness).
const osd_xinfo_t& xi = osdmap.get_xinfo(target_osd);
double decay = exp((double)failed_for * decay_k);
dout(20) << " halflife " << halflife << " decay_k " << decay_k
<< " failed_for " << failed_for << " decay " << decay << dendl;
my_grace = decay * (double)xi.laggy_interval * xi.laggy_probability;
grace += my_grace;

//peer_grace计算
assert(fi.reporters.size());
for (map<int,failure_reporter_t>::iterator p = fi.reporters.begin();
p != fi.reporters.end();
++p) {
const osd_xinfo_t& xi = osdmap.get_xinfo(p->first);
utime_t elapsed = now - xi.down_stamp;
double decay = exp((double)elapsed * decay_k);
peer_grace += decay * (double)xi.laggy_interval * xi.laggy_probability;
}
peer_grace /= (double)fi.reporters.size();
grace += peer_grace;

失效条件

重点在这里,最终check_failure的成功条件是:

1
2
3
failed_for >= grace && 
((int)fi.reporters.size() >= g_conf->mon_osd_min_down_reporters) &&
(fi.num_reports >= g_conf->mon_osd_min_down_reports)

即失效时间大于grace(g_conf中设置的值),并且reporters大于配置的reporters,reports大于配置的reports。
当这3个条件同时满足后osd会被标记为down,并输出类似如下这样的日志:
osd.3 failed 3 reports from 1 peers after 21.666000 >= grace 20

注(2018年1月13日):

以上对于Ceph 0.94.5版本,对于Ceph10.2.10 Jewel版本,mark down的机制有所不同,条件从3个变成两个了,代码如下:

1
2
if (failed_for >= grace &&
(int)reporters_by_subtree.size() >= g_conf->mon_osd_min_down_reporters)

即grace time超时,并且来自不同subtree的reporters达到了配置的数目。
相关的两个集群配置为:

1
2
mon_osd_min_down_reporters,默认2
mon_osd_reporter_subtree_level,默认为host

grace值的tradeoff

这个值可以在集群动态配置,默认是20s。如果值设置地过大,那么当集群出现节点故障时,集群的故障判断时间势必会很长,这直接导致客户端的IO相应地阻塞很长时间。如果值设置的过小也是可能会出问题的,因为分布式集群不可避免地会遇到节点之间的网络问题,当网络出现短时间的丢包或者阻塞的时候,过小的grace设置会导致集群很快认为osd down,尽管网络只是暂时的抖动。从这里可以看出来,对于分布式系统的3个状态:成功,失败和超时,其中失败和超时之间并没有严格的界限,需要我们自己去权衡。

2017年11月24日