补丁太多了的话,加起来大小可能会比最终的版本更大。
在 Ceph 里面,osdmap 是一个很重要的数据。比如说,
-
集群的拓扑
-
集群里每个数据池的 crush 规则,甚至还有
-
一个屏蔽列表,集群会拒绝向在列表里面的客户端提供服务
但是正因为 osdmap 包含了太多信息,在集群里面传递完整的 osdmap
会耗费很多带宽,而且编解码完整版本的 osdmap 也加大了对 CPU
的压力。为了缓解这个压力,我们选择仅仅发送变化的那部分。在 monitor
上,每次 osdmap 有变化,我们不仅仅保存了最新完整版本的
osdmap,也会保存它的增量部分 — 我们用专门的对象保存这个部分,即
OSDMap::Incremental
,有时候干脆叫它 inc
map。所以当客户端找 monitor 要 osdmap
的时候,也会告诉对方自己手里面 osdmap 的版本 m
,如果
monitor 的最新版 osdmap 的版本是 n
,那么它就会把
m..n
的所有 inc map 都发给客户端。
但是有时候也会适得其反,因为积少成多,要是有很多的 inc
map,为了发送这些 inc map,对 monitor
甚至客户端,累加起来的开销和发送一个完整 osdmap
比起来可能会更高。而且,需要注意的是,Monitor::ms_dispatch()
是在一个全局大锁里面执行的。很多其他操作也需要这个锁。所以我们应该尽量避免长时间地持有它,否则会造成很高的延迟。
要解决这个问题,有下面几个思路:
-
在 monitor 一侧
-
减少 monitor 对 osdmap 的更新频次。primary osd 会根据情况要求产生 pgtemp,但是 monitor 也可以主动地批次生成 pgtemp。
-
分期分批地发送 inc map。这样可以缓解因为长时间占用全局锁造成的延迟。
-
-
在 osd 一侧
-
减少 osd 对 osdmap 的请求。如果 osd 发现自己落后太多,就直接找 monitor 要完整的最新版 osdmap。而不是要求获得增量版本。减轻 monitor 的负担。
-
但是 n
版的 osdmap 是不是真的能替代 m
版
osdmap 加上中间的 m..n
的 inc map 呢?