Ceph块设备客户端Librbd缓存默认情况下处于启用状态,并支持以下三种不同的缓存策略:write-around,write-back和write-through,其中write-around缓存策略是在O版新增的,并且作为了默认的缓存策略(原默认策略为write-back)。
除非有超过rbd缓存最大脏字节数(rbd_cache_max_dirty)的数据未写到存储集群,否则在write-around和write-back策略下,写请求在写到rbd缓存后即返回。与write-back策略不同的是,write-around策略不提供读缓存服务,因而对写请求的处理更为简单,支持更高的性能。对于write-through策略,仅当数据写入到所有副本的磁盘上时,写请求才会返回,但读请求可能来自缓存。
三者对比示意图如下:
此处需注意,Librbd的write-around策略与一般意义上的write-around策略不同,对于一般意义上的write-around策略,缓存供读请求使用,写请求则绕过缓存直接写到后端存储设备。
两者对比示意图如下:
RBD Cache在librbd/image/OpenRequest.cc的send_init_cache方法中进行初始化:
size_t max_dirty = m_image_ctx->config.template get_val<Option::size_t>("rbd_cache_max_dirty");
auto writethrough_until_flush = m_image_ctx->config.template get_val<bool>("rbd_cache_writethrough_until_flush");
auto cache_policy = m_image_ctx->config.template get_val<std::string>("rbd_cache_policy");
if (cache_policy == "writearound") {
auto cache = cache::WriteAroundObjectDispatch<I>::create(m_image_ctx, max_dirty, writethrough_until_flush);
cache->init();
} else if (cache_policy == "writethrough" || cache_policy == "writeback") {
if (cache_policy == "writethrough") {
max_dirty = 0;
}
auto cache = cache::ObjectCacherObjectDispatch<I>::create(m_image_ctx, max_dirty, writethrough_until_flush);
cache->init();
// readahead requires the object cacher cache
m_image_ctx->readahead.set_trigger_requests(m_image_ctx->config.template get_val<uint64_t>("rbd_readahead_trigger_requests"));
m_image_ctx->readahead.set_max_readahead_size(m_image_ctx->config.template get_val<Option::size_t>("rbd_readahead_max_bytes"));
}
可以看到,原有的write-back和write-through策略使用了ObjectCacherObjectDispatch对象处理缓存,两者在实现上唯一的不同是write-through策略将max_dirty值置为0,即不允许脏数据存在于缓存中,迫使写请求需在写到后端存储后才成功返回。
而新增的write-around策略使用了WriteAroundObjectDispatch对象处理缓存,与前两者有较大的区别。
通过WriteAroundObjectDispatch和WriteAroundObjectDispatch的成员变量及相关实现对比可以看到,WriteAroundObjectDispatch缓存的内容实质为I/O请求,而ObjectCacherObjectDispatch缓存的内容实质为对象内容(通过ObjectCacher管理),由于WriteAroundObjectDispatch不涉及从I/O请求到对象数据内容的处理和转换,因此在流程上简化很多。此外,在ObjectCacher管理模式中,对脏数据的处理以及对缓存数据的淘汰也更为复杂。
由于处理流程及管理模式的简化,对于write-around策略而言,写性能与write-back模式相比具备较明显的优势。由于缺少都缓存,write-around策略下读性能与未开启rbd cache一致。