searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Ceph块设备客户端缓存策略实现介绍

2023-07-21 01:28:26
133
0

    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一致。

0条评论
作者已关闭评论
CD
15文章数
0粉丝数
CD
15 文章 | 0 粉丝
原创

Ceph块设备客户端缓存策略实现介绍

2023-07-21 01:28:26
133
0

    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一致。

文章来自个人专栏
文章 | 订阅
0条评论
作者已关闭评论
作者已关闭评论
0
0