Ceph 进阶系列(三):谈谈 Ceph Cache Tier (Cache Pool) 的配置 、原理 和 源码分析

从 GitHub 上 Clone Ceph 项目,我是基于 (ceph version 12.2.11 luminous 版本) 的代码来分析的

一、Cache Tier(Cache Pool)是什么?

在 Ceph 里创建 pool 时,可以设置一个 pool 为另一个 pool 的 cache 层,做缓存层的 pool 称为 cache pool (也就是 cache tier)。而真正存数据的 pool 就是我们常用的 data pool(代码里叫 base pool)。使用如下命令来创建 Cache Tier:

ceph osd tier add {data_pool} {cache_pool}

该命令行程序发送请求给 Monitor,然后由 Monitor 相关的 pool 设置上述属性值,并由 Monitor 来持久化存储该 pool 信息。**注:**一个 data pool 可以有多个 cache tier (cache pool).

另外,如何在指定的 OSD 上创建 Ceph Pool,请参考 Ceph 进阶系列(二):如何在指定的 OSD 设备上创建 pool

cache tier 相关的命令(属于 monitor command):

命令 描述
ceph osd tier add <data_pool> <cache_pool> {–force-nonempty} add the tier <tierpool> (the second one) to base pool <pool> (the first one)
ceph osd tier add-cache <data_pool> <cache_pool> <int[0-]> add a cache <tierpool> (the second one) of size <size> to existing pool <pool> (the first one)
ceph osd tier cache-mode <cache_pool> none|writeback|forward|readonly|readforward|proxy|readproxy {–yes-i-really-mean-it} specify the caching mode for cache tier <pool>
ceph osd tier remove <data_pool> <cache_pool> remove the tier <tierpool> (the second one) from base pool (the first one)
ceph osd tier remove-overlay <data_pool> remove the overlay pool for base pool <pool>
ceph osd tier rm <data_pool> <cache_pool> remove the tier <tierpool> (the second one) from base pool <pool> (the first one)
ceph osd tier rm-overlay <data_pool> remove the overlay pool for base pool <pool>
ceph osd tier set-overlay <data_pool> <overlaypool> set the overlay pool for base pool <pool> to be <overlaypool>

二、为什么要有 Cache Tier?

Cache Tier 技术目标在于:把用户访问频率高的热数据放置在高性能、小容量的存储介质中(比如 NVME SSD),把大量冷数据放置在大容量的存储介质中(比如 HDD)。Cache Tier 为用户提供的价值在于:提高热数据访问性能的同时,降低存储成本。实现这样的方法是:Cache Tier 可以让冷数据自由安全地迁移到更低层的存储介质中(data pool),这样达到节约存储成本;让热点数据自动的从低层(data pool)迁移到高层存储层(cache tier),这样达到提高访问热点数据的性能。

三、Cache Tier 的技术实现

  • 数据访问行为的追踪、统计与分析:持续追踪与统计每个数据块的存取频率,并通过定期分析,识别出存取频率高的 “热” 区块,与存取频率低的 “冷” 区块。
  • 数据迁移:以存取频率为基础,定期执行数据迁移,将热点数据块迁移到高速存储层,把较不活跃的冷数据块迁移到低速存储层。数据迁移一对象(默认为 4MB)为基本单位。

四、Cache Tier 在 Ceph 架构里的位置

Ceph 进阶系列(三):谈谈 Ceph Cache Tier (Cache Pool) 的配置 、原理 和 源码分析_第1张图片

例如,cache tier 的 read forward 模式流程如下(一共 6 种模式 writeback|forward|readonly|readforward|proxy|readproxy,每种模式的流程略有不同):

Ceph 进阶系列(三):谈谈 Ceph Cache Tier (Cache Pool) 的配置 、原理 和 源码分析_第2张图片

read proxy 模式

Ceph 进阶系列(三):谈谈 Ceph Cache Tier (Cache Pool) 的配置 、原理 和 源码分析_第3张图片

五、Cache Tier 的关键代码分析

Cache Tier 的代码分布在 Ceph 源代码的各个模块,其核心在对象的数据读写路径上。

1. 其相关的数据结构:

pool 的数据结构 pg_pool_t,它有两个变量对应相应的 cache pool 和 base pool 配置

//src/osd/osd_types.h

/*
 * pg_pool
 */
struct pg_pool_t {
...
set tiers;      ///< pools that are tiers of usint64_t tier_of;         ///< pool for which we are a tier
...
}

这两个字段用来设置 pool 的属性:
・如果当前 pool 是一个 cache pool,那么 tier_of 记录了该 cache pool 的 base pool 层。
・如果当前 pool 是 base pool,那么 tiers 就记录该 base pool 的 cache pool 层,一个 base pool 可以设置多个 cache pool 层。

2. Cache Tier 的初始化

Cache Tier 初始化有两个入口,如下所示:
・on_active:如果该 pool 已经设置为 cache pool,在该 cache pool 的所有 PG 处于 activave 状态后初始化。
・on_pool_change:当该 pool 的所有 PG 都已经处于 active 状态后,才设置该 pool 为 cache pool,那么就等待 Monitor 通知 osd map 相关信息的变化,在 on_pool_change 函数里初始化。

3**. 读写路径上的 Cache Tier 处理**

在 OSD 的正常读写路径上,如果该 pool 有 Cache Tier 设置,处理逻辑就发生了变化。如下所示:

// hot/cold tracking
  HitSetRef hit_set;        ///< currently accumulating HitSet
 
/** do_op - do an op
 * pg lock will be held (if multithreaded)
 * osd_lock NOT held.
 */
void PrimaryLogPG::do_op(OpRequestRef& op)
{
......
bool in_hit_set = false;
  if (hit_set) {
    if (obc.get()) {
      if (obc->obs.oi.soid != hobject_t() && hit_set->contains(obc->obs.oi.soid))
	in_hit_set = true;
    } else {
      if (missing_oid != hobject_t() && hit_set->contains(missing_oid))
        in_hit_set = true;
    }
    if (!op->hitset_inserted) {
      hit_set->insert(oid);
      op->hitset_inserted = true;
      if (hit_set->is_full() ||
          hit_set_start_stamp + pool.info.hit_set_period <= m->get_recv_stamp()) {
        hit_set_persist();
      }
    }
  }
 
  if (agent_state) {
    if (agent_choose_mode(false, op))
      return;
  }
 
  if (obc.get() && obc->obs.exists && obc->obs.oi.has_manifest()) {
    if (maybe_handle_manifest(op,
			       write_ordered,
			       obc))
    return;
  }
 
  if (maybe_handle_cache(op,
			 write_ordered,
			 obc,
			 r,
			 missing_oid,
			 false,
			 in_hit_set))
    return;
......

参考:《Ceph 源码分析》

转自:https://blog.csdn.net/don_chiang709/article/details/99727048

你可能感兴趣的:(Ceph)