一次ceph心跳机制异常的处理

部署使用ceph集群的时候遇到一个状况,在大规模集群的时候,有节点网络或者osd异常时,mon迟迟不把该异常的osd标down,一直等待900s后mon发现该节点的osd一直没有更新pgmap才把异常的osd标down,并更新osdmap扩散出去。

现象:部署使用ceph集群的时候遇到一个状况,在大规模集群的时候,有节点网络或者osd异常时,mon迟迟不把该异常的osd标down,一直等待900s后mon发现该节点的osd一直没有更新pgmap才把异常的osd标down,并更新osdmap扩散出去。但这个900s内,客户端IO仍是会一直往异常的osd上去下发,致使io超时,并进一步影响上次的业务。网络

缘由分析:性能

咱们在mon的日志里面也看到了和异常osd创建心跳的其余osd向mon报告该osd的异常,但mon确实在短期内没有这些osd标down。查看了一些相关网络和书籍的资料后,才发现了问题。
首先咱们关注osd配置中几个相关的配置项:
(1)osd_heartbeat_min_peers:10
(2)mon_osd_min_down_reporters:2
(3)mon_osd_min_down_reporters_ratio:0.5
以上参数的之均可以在ceph集群节点上执行ceph daemon osd.x config show查看(x是你的集群osd的id)。
问题出现的缘由是什么呢?
问题现场的集群部署时每一个osd会随机选取10个peer osd来做为创建心跳的对象,但在ceph的机制中,这个10个osd不必定保证可以所有分散在不一样的节点上。故在有osd异常的时候,向mon报该osd down的reporter有几率不知足ratio=0.5,即reporter数量未过集群存储host数量的一半,这样异常osd就没法经过osd之间的心跳报活机制快速标down,直到900s后mon发现这个osd pgmap一直不更新才识别到异常(另外一种机制,能够看作是给osd心跳保活机制作最后的保险),并经过osdmap扩散出来。而这个900s对于上层业务来讲,每每是不可接受的。
但这个现象对于小规模集群几乎不会出现,好比以一个3节点ceph集群为例:
一次ceph心跳机制异常的处理一次ceph心跳机制异常的处理
若是与其余节点osd创建的peer数量小于了osd_heartbeat_min_peers,那么osd会继续选择与本身较近的osd创建心跳链接(即便是和本身位于同一个节点上。)
对于osd心跳机制,网上有人总结过几点要求:
(1)及时:创建心跳的osd能够在秒级发现其余osd的异常并上报monitor,monitor在几分钟内把该osd标down下线
(2)适当的压力:不要觉得peer越多越好,特别是如今实际应用场景中osd监听和发送心跳报文的网络链路都是和public network以及cluster network共用的,心跳链接创建过多会极大影响系统的性能。Mon有单独与osd维持心跳的方式,但ceph经过osd之间的心跳保活,将这种压力分散到各个osd上,极大减少了中心节点mon的压力。
一次ceph心跳机制异常的处理一次ceph心跳机制异常的处理
(3)容忍网络抖动:mon收集到osd的汇报以后,会通过周期的等待几个条件,而不是贸然把osd标down。这些条件有目标osd的实效时间大于经过固定量osd_heartbeat_grace和历史网络条件肯定的阈值,以及上报的主机数是否达到min_reporters和min_reporters_ratio,以及在必定时间内,失效汇报没有被源报告者取消掉等。
(4)扩散机制:2种实现,mon主动扩散osdmap,还有一种惰性的是osd和client本身来取。为了让异常信息及时让client和其余osd感知到,通常是前一种实现比较好。3d

总结和启示:日志

2个方向能够作出改变。
(1)对于原有机制中取集群存储节点数量的0.5做为min_reporter_ratio明显不合理,应该采用的是这个osd与多少host上的osd创建心跳(取host数量),那就由0.5*创建心跳的host总数来做为判断依据。
(2)一些场景下,咱们会本身定义一些数据存放的逻辑区域,经过对crush的层级结构的利用,例如在一个ceph集群中定义多个逻辑区域,一个数据的分片或者副本只存在于一个逻辑区域中,那相关osd创建心跳链接的范围就须要相应精简和准确。对象

如今ceph实现的osd心跳机制仍是会有不少问题,不知道后面会不会有新的机制替换当前机制,让咱们拭目以待。blog

相关文章
相关标签/搜索