緩存池簡介
緩存池原理
ceph的緩存分層特性是在ceph的F版當中正式發布的。所謂的緩存分層其實就是在更快的磁盤(通常是ssd)上創建一個存儲池。然后將這個存儲池放置在常規的復制池或者糾刪碼池的前端充當緩存。這樣所有的客戶端I/O操作都首先由緩存池處理,之后再將數據寫回到現有的數據存儲池中,使得客戶端能夠在緩存池上享受更好的性能,而最終數據還是寫回到常規池中。
一般來說,緩存池會被構建在更昂貴的或者說速度更快的ssd盤上,這樣才能提供更好的I/O性能。而緩存池后端的存儲池則由普通的hdd盤組成。在這種類型的設置中,客戶端將I/O請求提交至緩存池,不管是讀還是寫操作,它的請求都能立即獲得響應。速度更快的緩存層為客戶端請求提供響應。一段時間后,緩存層將所有數據再寫回后端的存儲存,以便它可以緩存來自客戶端的新請求。在緩存層和數據層之間的數據遷移都是自動觸發且對客戶端透明的。
緩存池的工作模式
緩存池能以以下兩種模式進行配置:
-
writeback模式:當緩存池配置為writeback模式時,客戶端將數據寫至緩存池,然后立即接收寫入確認。緩存池基於我們為其設置的flushing/evicting策略,將數據從緩存池遷移至后端存儲池,並最終由緩存代理將其從緩存層中刪除。處理來自客戶端的讀操作時,首先由緩存分層代理將數據從存儲層遷移至緩存層,然后再將其返回給客戶端。只到數據變得不再活躍或者成為冷數據時,再將其從緩存池中刪除。
-
read-only模式:當緩存池配置為read-only模式時,它只適用於處理客戶端的讀操作。客戶端的寫操作不涉及緩存分層,所有的客戶端寫都在存儲層上完成。在處理來自客戶端的讀操作時,緩存分層代理將請求的數據從存儲層復制到緩存層。緩存池基於我們為其配置的策略,將不活躍的對象從緩存池中刪除。這種方法非常適合多個客戶端需要讀取大量類似數據的場景。
配置緩存池
1. 創建一個緩存池
假設我們已經有了一個基於ssd的crush_rule
,我們創建一個存儲池,使用該crush rule即可。關於如何創建一個基於ssd的crush_rule
,可直接參考《crushmap磁盤智能分組》。
下面是創建一個基於ssd的存儲池的示例:
# 假設ssd_rule即基於ssd的cursh_rule
ceph osd create pool cache 64 64 ssd_rule
2. 設置緩存層
# 將上面創建的cache池綁定至存儲池的前端,cephfs_data即為我們的后端存儲池
ceph osd tier add cephfs_data cache
# 設置緩存模式為writeback
ceph osd tier cache-mode cache writeback
# 將所有客戶端請求從標准池引導至緩存池
ceph osd tier set-overlay cephfs_data cache
此時,我們分別查看存儲池和緩存池的詳情,可以看到相關的緩存配置信息:
root@ceph:~# ceph osd dump |egrep 'cephfs_data|cache'
pool 2 'cephfs_data' replicated size 3 min_size 1 crush_rule 0 object_hash rjenkins pg_num 128 pgp_num 128 last_change 3079 lfor 3079/3079 flags hashpspool tiers 4 read_tier 4 write_tier 4 stripe_width 0 application cephfs
pool 4 'cache' replicated size 3 min_size 1 crush_rule 1 object_hash rjenkins pg_num 64 pgp_num 64 last_change 3100 lfor 3079/3079 flags hashpspool,incomplete_clones tier_of 2 cache_mode writeback target_bytes 1099511627776 hit_set bloom{false_positive_probability: 0.05, target_size: 0, seed: 0} 0s x0 decay_rate 0 search_last_n 0 stripe_width 0
3. 緩存層相關參數說明
- 對於生產環境的部署,目前只能使用bloom filters數據結構(看官方文檔的意思,好像目前只支持這一種filter):
ceph osd pool set cache hit_set_type bloom
- 設置當緩存池中的數據達到多少個字節或者多少個對象時,緩存分層代理就開始從緩存池刷新對象至后端存儲池並驅逐:
# 當緩存池中的數據量達到1TB時開始刷盤並驅逐
ceph osd pool set cache target_max_bytes 1099511627776
# 當緩存池中的對象個數達到100萬時開始刷盤並驅逐
ceph osd pool set cache target_max_objects 10000000
- 定義緩存層將對象刷至存儲層或者驅逐的時間:
ceph osd pool set cache cache_min_flush_age 600
ceph osd pool set cache cache_min_evict_age 600
- 定義當緩存池中的臟對象(被修改過的對象)占比達到多少時,緩存分層代理開始將object從緩存層刷至存儲層:
# 當臟對象占比達到10%時開始刷盤
ceph osd pool set cache cache_target_dirty_ratio 0.4
# 當臟對象占比達到60%時開始高速刷盤
cache_target_dirty_high_ratio: 0.6
- 當緩存池的使用量達到其總量的一定百分比時,緩存分層代理將驅逐對象以維護可用容量(達到該限制時,就認為緩存池滿了),此時會將未修改的(干凈的)對象刷盤:
ceph osd pool set cache cache_target_full_ratio 0.8
4. 測試緩存池
配置好緩存池以后,我們可以先將其驅逐對象的最小時間設置為60s:
ceph osd pool set cache cache_min_evict_age 60
ceph osd pool set cache cache_min_flush_age 60
然后,我們往存儲池中寫一個數據
rados -p cephfs_data put test /tmp/test.txt
查看存儲池,這時應該無法查看到該數據,查看緩存池,則可以看到數據存儲在緩存池中:
rados -p cephfs_data ls |grep test
rados -p cache ls |grep test
等60s之后,數據刷盤,此時即可在存儲池中看到該數據,則緩存池中,該數據即被驅逐。
刪除緩存池
需要說明的是,根據緩存池類型的不同,刪除緩存池的方法也不同。
1. 刪除read-only緩存池
由於只讀緩存不具有修改的數據,因此可以直接禁用並刪除它,而不會丟失任何最近對緩存中的對象的更改。
- 將緩存模式個性為none以禁用緩存:
ceph osd tier cache-mode cache none
- 刪除緩存池:
# 解除綁定
ceph osd tier remove cephfs_data cache
2. 刪除writeback緩存池
由於回寫緩存可能具有修改的數據,所以必須采取措施以確保在禁用和刪除緩存前,不丟失緩存中對象的最近的任何更改。
- 將緩存模式更改為轉發,以便新的和修改的對象刷新至后端存儲池:
ceph osd tier cache-mode cache forward
- 查看緩存池以確保所有的對象都被刷新(這可能需要點時間):
rados -p cache ls
- 如果緩存池中仍然有對象,也可以手動刷新:
rados -p cache cache-flush-evict-all
- 刪除覆蓋層,以使客戶端不再將流量引導至緩存:
ceph osd tier remove-overlay cephfs_data
- 解除存儲池與緩存池的綁定:
ceph osd tier remove cephfs_data cache
參考: https://blog.csdn.net/weixin_34364135/article/details/87528549