從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 <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架構裏的位置
例如,cache tier的read forward模式流程如下(一共6種模式writeback|forward|readonly|readforward|proxy|readproxy,每種模式的流程略有不同):
read proxy模式
五、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<uint64_t> 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源碼分析》