對於cache的東西啊,我曾經在公司的項目中,有寫過cache的經歷,因此我覺得我很瞭解,在我看ceph手冊對於cache tier描述的時候,感受沒啥新鮮的東西,可是當我對應到ceph源碼級別的時候,發現本身YY的ceph cache tier不太正確。瞭解不難,深刻不易啊。閒話少說進入正題。(排版有點亂)python
在ceph的手冊裏http://docs.ceph.com/docs/master/rados/operations/cache-tiering/ 中對 cache tiering 進行了描述。算法
分佈式的集羣通常都是採用廉價的pc搭建,這些pc一般使用的是傳統的機械硬盤,因此在磁盤的訪問速度上有必定的限制,沒有理想的iops數據。當去優化一個系統的IO性能時,最早想到的就是添加cache,熱數據在cache被訪問到,縮短數據的訪問延時。Cache 通常會有 memory 或者ssd來作,考慮到價格和安全性,通常都是採用ssd做爲cache。尤爲實在隨機io上,若是隨機io所有放在ssd上,等數據冷卻,將數據合併後,再刷入機械硬盤中,提高系統的io性能。(原本是想給你們看一下ssd和機械盤的性能測試結果的,可是測試數據是公司的不能放出來,本身測試的數據找不到了。。。。)。c#
對於ceph而言,怎麼利用ssd做爲普通磁盤的cache的,從手冊中可知,先建立一個機械硬盤的pool,叫作storage tier,而後再建立一個使用ssd的pool ,叫作cache tier,把cache tier放在 storage tier之上。以下圖:緩存
當客戶端訪問操做數據時,優先讀寫cache tier數據(固然要根據cache mode來決定),若是數據在storage tier 則會提高到cache tier中,在cache tier中 會有請求命中算法、緩存刷寫算法、緩存淘汰算法等的實現,將熱數據提高到cache tier中,將冷數據下放到storage tier中。安全
這就是通常的緩存技術實現,可是對於ceph來說一個分佈式的存儲怎麼來實現這個cache tier,實現起來是否是和文檔同樣的呢?讓咱們一塊兒來探祕 cache tier.分佈式
一、cache tier 是基於pool的。這裏值得注意的是cache pool 對應storage pool,不是ssd磁盤對應機械硬盤的,因此在cache tier和storage tier之間移動數據 是兩個pool之間數據的移動,數據可能在不一樣地點的設備上移動。函數
二、cache mode有四種:writeback、forward、readonly、readforward、readproxy模式,這裏每種模式都來解釋下:性能
---a、writeback 模式:寫操做,當請求到達cache成,完成寫操做後,直接返回給客戶端應答。後面由cache的agent線程負責將數據寫入storage tier。讀操做看是否命中緩存,若是命中直接在緩存讀,沒有命中能夠redirect到storage tier訪問。測試
---b、forward模式:全部的請求都redirct到storage tier 訪問。優化
---c、readonly模式:寫請求直接redirct到storage tier訪問,讀請求命中則直接處理,沒有命中須要提高storage tier到cache tier中,完成請求,下次再讀取直接命中緩存。
---d、readforward模式:讀請求都redirect到storage tier中,寫請求採用writeback模式。
---e、readproxy模式:讀請求發送給cache tier,cache tier去base pool中讀取,在cache tier得到object後,本身不保存,直接發送給客戶端,寫請求採用writeback模式。
三、cache的flush、evict算法,都是根據時間前後來的。這裏有一些值得去改進的地方。
四、cache的agent 是應該根據pg的狀況來實現,和pg的恢復流程同樣,一個是recovery,一個是agent,可是最終放在了osd實現。
仍是原來的配方,正宗好涼cha。。。。說一大堆理論,也不如從代碼入手,那咱們就先從代碼的流程來說講 cache tier,而後再分析cache tier的問題,最後以爲哪裏能夠完善的,但願和你們進行討論。
手冊裏 已經教會你們怎麼來使用這個cache tier的,不知道的自行回去修習,否則怕後面看不懂,那這裏再手把手走一下?
我用的是實驗環境,也沒有ssd盤,直接在普通盤上建立一個cachepool,咱們只是看一下cache tier的處理流程,因此影響不大。
1.1ceph 實驗環境,可參考http://www.javashuo.com/article/p-fzxvobqg-hq.html。一個mon,3個osd。
1.2建立cache pool,這裏爲了方便跟蹤代碼,因此建立的cachepool 只有8個pg。
這裏本來有一個rbd pool是建立ceph默認,而後再新建立一個cache tier的 pool,新的pool名字直接叫作cachepool。如今咱們有兩個pool 一個是rbd,一個cachepool。
1.3 添加cachepool 爲rbd的tier,這裏直接使用add-cache 命令,該命令是其餘幾個命令集合的形式,用起來快速一點,採用默認項。可是後面要接一個緩存大小的設置,這裏使用200M的大小。
./ceph osd tier add-cache rbd cachepool 209715200
而後查看pool的詳細信息
Pool 0 就是名字爲rbd的pool,這裏有兩個重要指標 read_tier 1 write_tier 1,這裏的1指的是pool 1. Pool 1就是剛剛建立的cachepool,在看看pool1 的設置,tier_of 爲0 是指pool1是pool0的tier,還有一個重要的要說cache_mode,默認建立的就是write_back模式的緩存,最後一個bloom 過濾器,緩存命中的算法,忘了是什麼的人,能夠搜一下。
代碼裏去搜一下add-cache的實現就能夠知道了,命令會發送給osdminitor,在osd minitor中處理。
前面一些對pool的檢查代碼就不說了,這裏是主要的代碼,這部分代碼比較簡單能夠一代而過就行了。總之就是將tier的關係添加到兩個pool裏,而後pool的信息會推送到全部的節點上。
6496:獲取base pool信息
6497:獲取cache pool 信息
6498:檢查是pool tier的關係。
6502:將cache pool 添加到base pool 的tiers集合中。
6503:將base pool的read_tier write_tier都設置爲cachepool。這個頗有用。
6506:設置cache pool的緩存模式,默認爲write_back,能夠手動設置其餘模式。
6507~6511:就是和緩存 flush、evict相關的參數了。後面的講flush和evict的時候會分析具體的參數。
到這裏 已經設置好了 base pool和cache pool的tier關係了。那麼就存在一個問題了,客戶端要寫一個object,這個object確定是指向base pool的,怎麼將object先寫入到cache pool的?
1.4 測試讀寫請求,看請求如何從base pool轉向到cache pool。
測試 代碼,建立一個myimage的rbd,而後向rbd寫入數據。
root@cephmon:~/ceph/ceph-0.94.2/src# cat ../python/create_rbd.py #!/usr/bin/env python import sys,rados,rbd def connectceph(): cluster = rados.Rados(conffile = '/root/ceph/ceph-0.94.2/src/ceph.conf') cluster.connect() ioctx = cluster.open_ioctx('rbd') rbd_inst = rbd.RBD() size = 1*1024**3 #4 GiB rbd_inst.create(ioctx,'myimage',size) image = rbd.Image(ioctx,'myimage') data = 'foo'* 200 image.write(data,0) image.close() ioctx.close() cluster.shutdown() if __name__ == "__main__": connectceph() root@cephmon:~/ceph/ceph-0.94.2/src#
客戶端的調用流程就不細說了,前面的blog也有講過,這裏咱們挑重點的說。在客戶端想ceph集羣發送寫請求的時候,必定會先拿到pool的相關信息,而後根據pool的信息再通過crush算法,得知數據副本所在的位置,而後把數據發送到對應的osd上。這裏比較重要的就是計算crush算法,由於crush算法會決定你發送到那些osd上。
跟蹤 客戶端代碼:…/src/osdc/Objecter.cc 中Objecter::_calc_target,撿重要的說,
2513:判斷是否須要檢查 存在cache tiering。
2516:若是是讀請求,而且該pool存在read_tier。這個read_tier就是上面說的在osd monitor設置過的,指向cache pool。
2517:若是是讀請求,則將target_oloc.pool 設置爲read_tier。
2519:判斷是寫請求,而且該pool存在write_tier。這個值也是在osd minitor中設置過的的,指向cache pool。
2518:若是是寫請求,則將target_oloc.pool 設置爲write_tier。
這裏重要的是設置了target_oloc.pool,原本這個值是指向base pool的,可是因爲設置了add-cache 命令,這裏target_oloc.pool指向了cache pool。當相面使用target進行crush計算的時候,就能計算出cache pool中對應的object存儲的osd。將請求發送到對應osd上。
1.5 cache pool的請求處理。決定請求是否緩存命中,或者redirect處理。
osd先接收到客戶端發送來的請求,而後調用ReplicatedPG:: do_request() >>>>> ReplicatedPG::do_op () 中處理,這都是正常的一個pool 處理請求的流程,在do_op中來看看不一樣於其餘普通pool的處理。
固然也在裏面挑重要的說:
1623:判斷下,當在對應的object 目錄下找不到對應的object,是否須要建立object的context。若是是寫請求須要建立,若是是讀請求則不須要建立。
1625:根據接收到的msg恢復出 原始的oid(這個oid的信息仍然指向base pool,在1629中設置,可是當前處理的pg是cache pool的pg)。
1638:根據oid ,而後在cachepool中建立對應的head信息。Head和oid的區別在於一個指向了cache pool一個指向了base pool。查找head的context信息,若是是寫操做沒有找到head context,則會爲head建立一個context,若是是讀操做則沒有則失敗,有則返回正確。當讀操做的時候,且查找context失敗,則missing_oid會指向head信息。
目前獲得的幾個信息整理下,oid(原始的object id)、missing_oid(在cache pool中不存在的oid信息),r(獲取object context 失敗錯誤碼),obc(object 的context信息)。繼續下面的代碼:
1680:當讀操做時候,讀的object 再也不當前的cache pool中,有可能被evict 或者該object還沒寫入到cache中,可是該object曾經在操做過。
1681:判斷是否有hit_set 集合,該集合是用來統計pg中被操做過的object,不管是否命中過緩存。
1683:若是是讀操做,且要讀的object在當前的cachepool中不存在,可是在hit_set中記錄了該object 剛被訪問過。
1684:若是剛剛一樣也被訪問過,則記錄in_hit_set標記。(必定的時間內被訪問屢次)
1686:統計此次的訪問操做object。
1688:若是這hit_set 滿了,或者時間間隔到了,則須要持久化這個hit_set信息。
1691:hit_set信息持久化。
1695:若是這個pg存在agent_state
1697:這裏判斷緩存的flush、evict等操做,後面細說。Flush閾值、evict閾值的判斷。只要不直接return,則不影響正常流程。
這裏有兩個重要的事情重申下,一個是hit_set集合,一個是flush、evict等操做觸發。
繼續下面代碼:
1706:判斷msg中flags不須要 ignore cache的時候,則進行maybe_handle_cache(),若是maybe_handle_cache 處理成功了則直接return,不然繼續進行後面的操做。
這個後面的操做就是基本的操做,若是讀的話,則直接讀本osd,若是寫的話,就分發到其餘replicate osd上。
細看maybe_handle_cache作了什麼,由於他影響了正常的處理流程。
ReplicatedPG::maybe_handle_cache()流程解析:
1971:函數入參解析,op就是當前須要處理的請求,write_ordered 是否爲寫指令,obc 是object context,r是find_object_context 處理後的錯誤碼,missing_oid以前介紹過,must_promote 是否要從base pool提高到cache pool,in_hit_set是否在近期剛訪問過。
1979:判斷該pool 若是不是cachepool 或者pool沒有設置緩存模式,則認爲不是緩存pool直接return false。普通pool或者cachepool未設置緩存模式,都直接返回。
2008:好不起眼的一個判斷,讓人們彷彿忘了他的存在,但他確實坑爹同樣的存在,爲了表達它的重要性,你加個註釋好麼! 這個判斷就是爲了判斷該object是否在cache pool中是否命中。若是在cachepool中命中,則直接return false,而後在do_op中會直接操做cache pool後面的流程。這裏有個小問題,他沒區分是cache模式 和op的操做因素,表示疑問,這部分後面也會有log進行證實。
2012:若是op沒能命中cache pool則,則獲取op中object的oloc信息,該信息記錄了object所在的pool,如今它還指向base pool。
2015:若是設定了直接須要promote操做,則直接promote操做就能夠了。這裏再說一下promote_object(),是將base pool中對應的object拷貝到cache pool中,而後再處理op。這裏只須要記住 promote_object()就是將object從base pool中拷貝到cache pool中便可。
2021:判斷cachepool是否能夠進行代理讀 proxy_read。默認是能夠的,這個屬性是後續版本加入的,ceph比較靠前的版本是沒有的。
1.5.1 writeback模式:
2026:判斷緩存模式
2028:若是是writeback模式,若是在未命中的狀況下,writeback模式如何處理。
2029:若是如今cache已經滿了,須要所有的evict。
2031:若是是讀操做,能夠proxy_read的直接do_proxy_read(),不然do_cache_redirect()直接轉向到base pool中。
2046:若是是寫操做,添加到waiting_for_cache_not_full等待隊列,緩存evict後會從新處理該op。
下面就是若是cache 在非full狀況下的處理:
2050:若是是寫請求的狀況
2052:則須要從base pool 提高object到cache pool中。
2056:剩下後面的狀況就都是讀操做了,這裏判斷是否能夠proxyread,若是能夠則直接do_proxy_read()。
2061:若是這object是block住的,則不能進行操做。
在writeback模式下,讀操做未命中時,min_read_recency_for_promote 該值默認狀況下爲1,這個在ceph osd pool ls detail 時也能看到。默認走了case1。若是近期訪問過,說明object比較熱,能夠提高到cache 中,若是能夠proxy read則在上面已經do_proxy_read(),若是不能夠proxy_read,則直接do_cache_redirect()。最後break ,return。
1.5.2 forward模式:
Forward模式就是把全部的請求都轉向給base pool。
2135:若是是forward模式
2136:直接調用do_cache_redirect()直接告訴客戶端,將請求轉給base pool。
1.5.3 readonly 模式:
2139:case 當cache 的mode是readonly模式。
2141:若是不存在obc 而且沒有建立,說明是讀操做。在readonly模式時,讀操做未命中的狀況下須要promote_object()。將object從base pool 提高到cache pool。
2148:若是未命中,可是find obc成功了,說明是未命中的寫操做,因此r爲0
2150:若是寫操做未命中,在readonly模式下須要調用do_cache_redirect 將寫操做轉向到base pool。
1.5.4 readforward 模式:
2157:case 當cache 的mode是readforward模式。
2159:判斷是不是寫操做
2161:若是pg存在agent_state,而且evict_mode是full模式,表示cache中的object都要evict。
2165:若是是evict full模式 ,就須要添加到等待隊列中,等待evict完成,而後再處理。
2174:若是不是evict full 模式,則須要promote_object()。
2179:若是是讀操做,則直接轉向到base pool。直接調用do_cache_redirect()
1.5.5 readproxy 模式:
2182:case 當cache 的mode是readproxy模式。
2184:判斷是不是寫操做
2186:若是pg存在agent_state,而且evict_mode是full模式,表示cache中的object都要evict。
2190:若是是evict full模式 ,就須要添加到等待隊列中,等待evict完成,而後再處理。
2197:若是不是evict full 模式,則須要promote_object()。
2202:若是是讀操做,則使用代理讀do_proxy_read()。
目前有幾個地方尚未細說的,promote_object(),do_cache_direct(),do_proxy_read()的操做。這幾個代碼比較簡單,稍微熟悉就能看明白。
總結:
流程看着確實不復雜,可以捋順關鍵點便可。
一、使用命令add-cache 能夠將一個cachepool做爲base pool的tier。這時會設置pool的信息,在pool裏面記錄了cache pool和base pool的關係。
二、客戶端在獲取pool信息的時候可知,目標base pool存在一個tier,叫作cache pool,那麼操做base pool的請求都會發送給cache pool。
三、請求達到cache pool中時,做爲tier的pool會有一些特別的處理maybe_cache_handle,具體的流程以下圖:
a、會判斷操做的object是否在cache pool中命中,若是命中,則直接在cache pool中處理,和在普通pool的請求同樣處理。後續會有agent線程將緩存髒數據刷寫到base pool中。
b、沒有命中緩存的狀況下,纔會去判斷緩存模式。若是命中緩存,無論是什麼模式都會在cache pool中處理。下面的處理都是未命中緩存的狀況。
c、判斷是不是writeback模式,讀操做,若是能夠proxy_read,那就直接do_proxy_read讀取數據便可,不能夠proxy_read 就使用do_cache_redirect,告訴客戶端去base pool中讀取。寫操做,若是當前是evict_full模式,說明如今緩存中已經達到了閾值,須要等待緩存淘汰一些object,在完成寫操做,目前放在等待隊列中等待,若是不是evict_full模式,則須要從base pool中promote對應的object到cache pool中,promote結束後繼續處理本次的寫操做。
d、判斷是不是forward模式。在forward模式下,再也不在cachepool中處理請求,會告訴客戶端將請求所有發送到base pool中。
e、判斷是否是readonly模式。寫操做會告訴客戶端直接想base pool寫便可,若是是讀操做,則會從base pool中promote該object。
f、判斷是否是readforward模式。該模式讀操做所有都告訴客戶端直接去base pool中讀取便可,寫操做按着writeback模式處理。
g、判斷是否是readproxy模式。該模式讀操做都採用cachepool的proxy read方法,寫操做按着writeback模式處理。
h、這裏在解釋一下這幾個操做以下圖:
綠框:客戶端請求cache pool,cache pool告訴客戶端你應該去base pool中請求,客戶端收到應答後,再次發送請求到base pool中請求數據,由base pool告訴客戶端請求完成。
藍框:客戶端發送讀請求到cache pool,可是未命中,則cache pool本身會發送請求到base pool中,獲取數據後,由cache pool將數據發送給客戶端,完成讀請求。可是值得注意的是,雖然cache pool讀取到了該object,但不會保存在cache pool中,下次請求仍然須要從新向basepool請求。
紫框:當客戶端發送請求到cache pool中,可是cache pool未命中,cache pool會選擇將該ojbect從base pool中提高到cache pool中,而後在cache pool進行讀寫操做,操做完成後告知客戶端請求完成,在cache pool會緩存該object,下次直接在cache中處理,和proxy_read存在的區別。
一個cache 重要不是他的數據處理流程,還有他的緩存flush策略、evict策略。下一節來細說一下cache的flush、evict如何來處理的。對本篇博客存在疑問的,歡迎批評指正。
對了,最後還有個疑問要說明下。就是你在writeback模式下,若是你的寫操做命中緩存,則在cache pool中處理便可,可是readonly模式下,寫操做也命中緩存,也會在cachepool中進行處理。並且在代碼註釋中寫到OSDMinitor.cc中有這麼一個註釋
6351:readonly模式下,寫操做會轉向給base pool。可是在實際狀況下抓取日誌不是這樣的。
日誌的抓取,在ReplicatedPG::do_op中找到maybe_handle_cache的調用處,
在1706以前添加一句,打印msg 的flags。表示要進入到了maybe_handle_cache().打印內容例如:」XYJdo_op maybe_handle_cache mesg->flags:4194321 IGNORE_CACHE:32768」
在1710:以後添加一句「XYJdo_opmaybe_handle_cache false」,若是日誌中出現這句說明 命中緩存,直接在緩存中處理。
目的,要查看 writeback模式下,若是寫操做命中緩存,會不會打印出上面的的輸出「XYJdo_opmaybe_handle_cache false」,若是在readonly模式下,無論寫操做是否命中都應該轉向給base pool,若是打印」 XYJdo_opmaybe_handle_cache false」,說明在readonly模式下緩存依然會處理寫操做。
從新編譯代碼,啓動實驗環境,第一次設置爲writeback模式:獲取日誌以下:
Line 402: 14:27:51.260842 20 osd.1 pg_epoch: 13 pg[1.0] XYJdo_op maybe_handle_cache mesg->flags:4194321 IGNORE_CACHE:32768 Line 403: 14:27:51.260860 10 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cache ,write:0 ,r:-2 ,,missing_oidfea29050/myimage.rbd/head//1 ,obc:0 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 404: 14:27:51.260875 25 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cache (no obc) missing_oid fea29050/myimage.rbd/head//1 must_promote 0 in_hit_set 0 Line 405: 14:27:51.260895 20 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cache,write back:can_proxy_read,do_proxy_read Line 418: 14:27:51.261328 20 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cachewrite_back:min_read_recency_for_promote=1 in_hit_set:0 ,can_proxy_read1 Line 470: 14:27:51.270061 20 osd.1 pg_epoch: 13 pg[1.4] XYJdo_op maybe_handle_cache mesg->flags:4194340 IGNORE_CACHE:32768 Line 471: 14:27:51.270068 10 osd.1 pg_epoch: 13 pg[1.4] maybe_handle_cache ,write:1 ,r:0 ,,missing_oid0//0//-1 ,obc:0x4f774b0 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 472: 14:27:51.270090 25 osd.1 pg_epoch: 13 pg[1.4] maybe_handle_cache 30a98c1c/rbd_directory/head//1(0'0 unknown.0.0:0 wrlock_by=unknown.0.0:0 s 0 uv 0) DNE missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 498: 14:27:51.270616 20 osd.1 pg_epoch: 13 pg[1.4] maybe_handle_cachewrite back : may_write:1 ,write_ordered1 ,hit_set:0x7fca6410baa0 Line 580: 14:27:51.273533 20 osd.1 pg_epoch: 13 pg[1.4] XYJdo_op maybe_handle_cache mesg->flags:4194340 IGNORE_CACHE:32768 Line 582: 14:27:51.273541 10 osd.1 pg_epoch: 13 pg[1.4] maybe_handle_cache ,write:1 ,r:0 ,,missing_oid0//0//-1 ,obc:0x4f774b0 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 583: 14:27:51.273550 25 osd.1 pg_epoch: 13 pg[1.4] maybe_handle_cache 30a98c1c/rbd_directory/head//1(13'1 osd.1.0:1 wrlock_by=unknown.0.0:0 whiteout s 0 uv 0) exists missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 584: 14:27:51.273562 20 osd.1 pg_epoch: 13 pg[1.4] maybe_handle_cacheobc.get() && obc->obs.exists Line 585: 14:27:51.273571 20 osd.1 pg_epoch: 13 pg[1.4] XYJdo_opmaybe_handle_cache false Line 673: 14:27:51.330255 20 osd.1 pg_epoch: 13 pg[1.4] XYJdo_op maybe_handle_cache mesg->flags:4194340 IGNORE_CACHE:32768 Line 674: 14:27:51.330263 10 osd.1 pg_epoch: 13 pg[1.4] maybe_handle_cache ,write:1 ,r:0 ,,missing_oid0//0//-1 ,obc:0x4f774b0 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 675: 14:27:51.330273 25 osd.1 pg_epoch: 13 pg[1.4] maybe_handle_cache 30a98c1c/rbd_directory/head//1(13'1 osd.1.0:1 wrlock_by=unknown.0.0:0 whiteout s 0 uv 0) exists missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 676: 14:27:51.330284 20 osd.1 pg_epoch: 13 pg[1.4] maybe_handle_cacheobc.get() && obc->obs.exists Line 677: 14:27:51.330292 20 osd.1 pg_epoch: 13 pg[1.4] XYJdo_opmaybe_handle_cache false Line 835: 14:27:51.353307 20 osd.1 pg_epoch: 13 pg[1.0] XYJdo_op maybe_handle_cache mesg->flags:4194340 IGNORE_CACHE:32768 Line 836: 14:27:51.353314 10 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cache ,write:1 ,r:0 ,,missing_oid0//0//-1 ,obc:0x4fbb2d0 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 837: 14:27:51.353323 25 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cache fea29050/myimage.rbd/head//1(0'0 unknown.0.0:0 wrlock_by=unknown.0.0:0 s 0 uv 0) DNE missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 863: 14:27:51.353488 20 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cachewrite back : may_write:1 ,write_ordered1 ,hit_set:0x7fca400d9ec0 Line 948: 14:27:51.356037 20 osd.1 pg_epoch: 13 pg[1.0] XYJdo_op maybe_handle_cache mesg->flags:4194340 IGNORE_CACHE:32768 Line 949: 14:27:51.356045 10 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cache ,write:1 ,r:0 ,,missing_oid0//0//-1 ,obc:0x4fbb2d0 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 950: 14:27:51.356054 25 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cache fea29050/myimage.rbd/head//1(13'1 osd.1.0:3 wrlock_by=unknown.0.0:0 whiteout s 0 uv 0) exists missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 951: 14:27:51.356065 20 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cacheobc.get() && obc->obs.exists Line 952: 14:27:51.356072 20 osd.1 pg_epoch: 13 pg[1.0] XYJdo_opmaybe_handle_cache false Line 1144: 14:27:51.418723 20 osd.1 pg_epoch: 13 pg[1.0] XYJdo_op maybe_handle_cache mesg->flags:4194321 IGNORE_CACHE:32768 Line 1145: 14:27:51.418731 10 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cache ,write:0 ,r:0 ,,missing_oid0//0//-1 ,obc:0x4fbb2d0 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 1146: 14:27:51.418739 25 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cache fea29050/myimage.rbd/head//1(13'2 client.4120.0:4 wrlock_by=unknown.0.0:0 dirty|data_digest s 112 uv 2 dd 679cf5ea) exists missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 1147: 14:27:51.418750 20 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cacheobc.get() && obc->obs.exists Line 1148: 14:27:51.418756 20 osd.1 pg_epoch: 13 pg[1.0] XYJdo_opmaybe_handle_cache false Line 1182: 14:27:51.419938 20 osd.1 pg_epoch: 13 pg[1.0] XYJdo_op maybe_handle_cache mesg->flags:4194340 IGNORE_CACHE:32768 Line 1183: 14:27:51.419945 10 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cache ,write:1 ,r:0 ,,missing_oid0//0//-1 ,obc:0x4fbb2d0 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 1184: 14:27:51.419954 25 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cache fea29050/myimage.rbd/head//1(13'2 client.4120.0:4 wrlock_by=unknown.0.0:0 dirty|data_digest s 112 uv 2 dd 679cf5ea) exists missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 1185: 14:27:51.419965 20 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cacheobc.get() && obc->obs.exists Line 1186: 14:27:51.419972 20 osd.1 pg_epoch: 13 pg[1.0] XYJdo_opmaybe_handle_cache false Line 1327: 14:27:51.446803 20 osd.1 pg_epoch: 13 pg[1.0] XYJdo_op maybe_handle_cache mesg->flags:4194321 IGNORE_CACHE:32768 Line 1328: 14:27:51.446810 10 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cache ,write:0 ,r:0 ,,missing_oid0//0//-1 ,obc:0x4fbb2d0 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 1329: 14:27:51.446819 25 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cache fea29050/myimage.rbd/head//1(13'3 client.4120.0:6 wrlock_by=unknown.0.0:0 dirty|data_digest s 112 uv 2 dd 679cf5ea) exists missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 1330: 14:27:51.446829 20 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cacheobc.get() && obc->obs.exists Line 1331: 14:27:51.446836 20 osd.1 pg_epoch: 13 pg[1.0] XYJdo_opmaybe_handle_cache false Line 1367: 14:27:51.447919 20 osd.1 pg_epoch: 13 pg[1.0] XYJdo_op maybe_handle_cache mesg->flags:4194321 IGNORE_CACHE:32768 Line 1368: 14:27:51.447926 10 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cache ,write:0 ,r:0 ,,missing_oid0//0//-1 ,obc:0x4fbb2d0 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 1369: 14:27:51.447935 25 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cache fea29050/myimage.rbd/head//1(13'3 client.4120.0:6 wrlock_by=unknown.0.0:0 dirty|data_digest s 112 uv 2 dd 679cf5ea) exists missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 1370: 14:27:51.447945 20 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cacheobc.get() && obc->obs.exists Line 1371: 14:27:51.447952 20 osd.1 pg_epoch: 13 pg[1.0] XYJdo_opmaybe_handle_cache false Line 1412: 14:27:51.449095 20 osd.1 pg_epoch: 13 pg[1.0] XYJdo_op maybe_handle_cache mesg->flags:4194321 IGNORE_CACHE:32768 Line 1413: 14:27:51.449102 10 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cache ,write:0 ,r:0 ,,missing_oid0//0//-1 ,obc:0x4fbb2d0 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 1414: 14:27:51.449110 25 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cache fea29050/myimage.rbd/head//1(13'3 client.4120.0:6 wrlock_by=unknown.0.0:0 dirty|data_digest s 112 uv 2 dd 679cf5ea) exists missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 1415: 14:27:51.449120 20 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cacheobc.get() && obc->obs.exists Line 1416: 14:27:51.449127 20 osd.1 pg_epoch: 13 pg[1.0] XYJdo_opmaybe_handle_cache false Line 1469: 14:27:51.450942 20 osd.1 pg_epoch: 13 pg[1.7] XYJdo_op maybe_handle_cache mesg->flags:4194341 IGNORE_CACHE:32768 Line 1470: 14:27:51.450949 10 osd.1 pg_epoch: 13 pg[1.7] maybe_handle_cache ,write:1 ,r:0 ,,missing_oid0//0//-1 ,obc:0x4e8a700 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 1471: 14:27:51.450957 25 osd.1 pg_epoch: 13 pg[1.7] maybe_handle_cache a9d57427/rb.0.1018.2ae8944a.000000000000/head//1(0'0 unknown.0.0:0 wrlock_by=unknown.0.0:0 s 0 uv 0) DNE missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 1497: 14:27:51.451280 20 osd.1 pg_epoch: 13 pg[1.7] maybe_handle_cachewrite back : may_write:1 ,write_ordered1 ,hit_set:0x7fca4004ac40 Line 1635: 14:27:51.453780 20 osd.1 pg_epoch: 13 pg[1.7] XYJdo_op maybe_handle_cache mesg->flags:4194341 IGNORE_CACHE:32768 Line 1636: 14:27:51.453787 10 osd.1 pg_epoch: 13 pg[1.7] maybe_handle_cache ,write:1 ,r:0 ,,missing_oid0//0//-1 ,obc:0x4e8a700 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 1637: 14:27:51.453796 25 osd.1 pg_epoch: 13 pg[1.7] maybe_handle_cache a9d57427/rb.0.1018.2ae8944a.000000000000/head//1(13'1 osd.1.0:6 wrlock_by=unknown.0.0:0 whiteout s 0 uv 0) exists missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 1638: 14:27:51.453806 20 osd.1 pg_epoch: 13 pg[1.7] maybe_handle_cacheobc.get() && obc->obs.exists Line 1639: 14:27:51.453813 20 osd.1 pg_epoch: 13 pg[1.7] XYJdo_opmaybe_handle_cache false Line 1838: 14:27:51.499268 20 osd.1 pg_epoch: 13 pg[1.0] XYJdo_op maybe_handle_cache mesg->flags:4194340 IGNORE_CACHE:32768 Line 1839: 14:27:51.499276 10 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cache ,write:1 ,r:0 ,,missing_oid0//0//-1 ,obc:0x4fbb2d0 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 1840: 14:27:51.499284 25 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cache fea29050/myimage.rbd/head//1(13'3 client.4120.0:6 wrlock_by=unknown.0.0:0 dirty|data_digest s 112 uv 2 dd 679cf5ea) exists missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 1841: 14:27:51.499294 20 osd.1 pg_epoch: 13 pg[1.0] maybe_handle_cacheobc.get() && obc->obs.exists Line 1842: 14:27:51.499301 20 osd.1 pg_epoch: 13 pg[1.0] XYJdo_opmaybe_handle_cache false
清理環境,從新啓動環境,第二次設置爲readonly模式:獲取日誌以下:
Line 502: 14:42:02.383097 20 osd.1 pg_epoch: 15 pg[1.0] XYJdo_op maybe_handle_cache mesg->flags:4194321 IGNORE_CACHE:32768 Line 503: 14:42:02.383117 10 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache ,write:0 ,r:-2 ,,missing_oidfea29050/myimage.rbd/head//1 ,obc:0 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 504: 14:42:02.383132 25 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache (no obc) missing_oid fea29050/myimage.rbd/head//1 must_promote 0 in_hit_set 0 Line 505: 14:42:02.383150 20 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cacheREADONLY Line 506: 14:42:02.383156 20 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cacheREADONLY:!obc.get() && r == -ENOENT,promote_object() Line 632: 14:42:02.389038 20 osd.1 pg_epoch: 15 pg[1.0] XYJdo_op maybe_handle_cache mesg->flags:4194321 IGNORE_CACHE:32768 Line 633: 14:42:02.389047 10 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache ,write:0 ,r:0 ,,missing_oid0//0//-1 ,obc:0x3d72450 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 634: 14:42:02.389056 25 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache fea29050/myimage.rbd/head//1(15'1 osd.1.0:1 wrlock_by=unknown.0.0:0 whiteout s 0 uv 0) exists missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 635: 14:42:02.389068 20 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache obc.get() && obc->obs.exists Line 636: 14:42:02.389078 20 osd.1 pg_epoch: 15 pg[1.0] XYJdo_opmaybe_handle_cache false Line 731: 14:42:02.444435 20 osd.1 pg_epoch: 15 pg[1.0] XYJdo_op maybe_handle_cache mesg->flags:4194321 IGNORE_CACHE:32768 Line 732: 14:42:02.444443 10 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache ,write:0 ,r:0 ,,missing_oid0//0//-1 ,obc:0x3d72450 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 733: 14:42:02.444452 25 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache fea29050/myimage.rbd/head//1(15'1 osd.1.0:1 wrlock_by=unknown.0.0:0 whiteout s 0 uv 0) exists missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 734: 14:42:02.444463 20 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache obc.get() && obc->obs.exists Line 735: 14:42:02.444470 20 osd.1 pg_epoch: 15 pg[1.0] XYJdo_opmaybe_handle_cache false Line 837: 14:42:02.474868 20 osd.1 pg_epoch: 15 pg[1.4] XYJdo_op maybe_handle_cache mesg->flags:4194340 IGNORE_CACHE:32768 Line 838: 14:42:02.474874 10 osd.1 pg_epoch: 15 pg[1.4] maybe_handle_cache ,write:1 ,r:0 ,,missing_oid0//0//-1 ,obc:0x3e30290 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 839: 14:42:02.474882 25 osd.1 pg_epoch: 15 pg[1.4] maybe_handle_cache 30a98c1c/rbd_directory/head//1(0'0 unknown.0.0:0 wrlock_by=unknown.0.0:0 s 0 uv 0) DNE missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 840: 14:42:02.474892 20 osd.1 pg_epoch: 15 pg[1.4] maybe_handle_cacheREADONLY Line 841: 14:42:02.474899 20 osd.1 pg_epoch: 15 pg[1.4] maybe_handle_cacheREADONLY!r,r:0 Line 929: 14:42:02.494897 20 osd.1 pg_epoch: 15 pg[1.0] XYJdo_op maybe_handle_cache mesg->flags:4194340 IGNORE_CACHE:32768 Line 930: 14:42:02.494905 10 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache ,write:1 ,r:0 ,,missing_oid0//0//-1 ,obc:0x3d72450 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 931: 14:42:02.494914 25 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache fea29050/myimage.rbd/head//1(15'1 osd.1.0:1 wrlock_by=unknown.0.0:0 whiteout s 0 uv 0) exists missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 932: 14:42:02.494925 20 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache obc.get() && obc->obs.exists Line 933: 14:42:02.494932 20 osd.1 pg_epoch: 15 pg[1.0] XYJdo_opmaybe_handle_cache false Line 1062: 14:42:02.534420 20 osd.1 pg_epoch: 15 pg[1.0] XYJdo_op maybe_handle_cache mesg->flags:4194321 IGNORE_CACHE:32768 Line 1063: 14:42:02.534428 10 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache ,write:0 ,r:0 ,,missing_oid0//0//-1 ,obc:0x3d72450 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 1064: 14:42:02.534437 25 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache fea29050/myimage.rbd/head//1(15'2 client.4121.0:5 wrlock_by=unknown.0.0:0 dirty|data_digest s 112 uv 2 dd 35515d2f) exists missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 1065: 14:42:02.534448 20 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache obc.get() && obc->obs.exists Line 1066: 14:42:02.534455 20 osd.1 pg_epoch: 15 pg[1.0] XYJdo_opmaybe_handle_cache false Line 1100: 14:42:02.535924 20 osd.1 pg_epoch: 15 pg[1.0] XYJdo_op maybe_handle_cache mesg->flags:4194340 IGNORE_CACHE:32768 Line 1101: 14:42:02.535932 10 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache ,write:1 ,r:0 ,,missing_oid0//0//-1 ,obc:0x3d72450 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 1102: 14:42:02.535940 25 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache fea29050/myimage.rbd/head//1(15'2 client.4121.0:5 wrlock_by=unknown.0.0:0 dirty|data_digest s 112 uv 2 dd 35515d2f) exists missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 1103: 14:42:02.535950 20 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache obc.get() && obc->obs.exists Line 1104: 14:42:02.535957 20 osd.1 pg_epoch: 15 pg[1.0] XYJdo_opmaybe_handle_cache false Line 1245: 14:42:02.565499 20 osd.1 pg_epoch: 15 pg[1.0] XYJdo_op maybe_handle_cache mesg->flags:4194321 IGNORE_CACHE:32768 Line 1246: 14:42:02.565507 10 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache ,write:0 ,r:0 ,,missing_oid0//0//-1 ,obc:0x3d72450 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 1247: 14:42:02.565515 25 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache fea29050/myimage.rbd/head//1(15'3 client.4121.0:7 wrlock_by=unknown.0.0:0 dirty|data_digest s 112 uv 2 dd 35515d2f) exists missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 1248: 14:42:02.565525 20 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache obc.get() && obc->obs.exists Line 1249: 14:42:02.565532 20 osd.1 pg_epoch: 15 pg[1.0] XYJdo_opmaybe_handle_cache false Line 1285: 14:42:02.566794 20 osd.1 pg_epoch: 15 pg[1.0] XYJdo_op maybe_handle_cache mesg->flags:4194321 IGNORE_CACHE:32768 Line 1286: 14:42:02.566802 10 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache ,write:0 ,r:0 ,,missing_oid0//0//-1 ,obc:0x3d72450 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 1287: 14:42:02.566813 25 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache fea29050/myimage.rbd/head//1(15'3 client.4121.0:7 wrlock_by=unknown.0.0:0 dirty|data_digest s 112 uv 2 dd 35515d2f) exists missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 1288: 14:42:02.566823 20 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache obc.get() && obc->obs.exists Line 1289: 14:42:02.566830 20 osd.1 pg_epoch: 15 pg[1.0] XYJdo_opmaybe_handle_cache false Line 1330: 14:42:02.568110 20 osd.1 pg_epoch: 15 pg[1.0] XYJdo_op maybe_handle_cache mesg->flags:4194321 IGNORE_CACHE:32768 Line 1331: 14:42:02.568117 10 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache ,write:0 ,r:0 ,,missing_oid0//0//-1 ,obc:0x3d72450 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 1332: 14:42:02.568126 25 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache fea29050/myimage.rbd/head//1(15'3 client.4121.0:7 wrlock_by=unknown.0.0:0 dirty|data_digest s 112 uv 2 dd 35515d2f) exists missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 1333: 14:42:02.568136 20 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache obc.get() && obc->obs.exists Line 1334: 14:42:02.568143 20 osd.1 pg_epoch: 15 pg[1.0] XYJdo_opmaybe_handle_cache false Line 1387: 14:42:02.570163 20 osd.1 pg_epoch: 15 pg[1.4] XYJdo_op maybe_handle_cache mesg->flags:4194341 IGNORE_CACHE:32768 Line 1388: 14:42:02.570170 10 osd.1 pg_epoch: 15 pg[1.4] maybe_handle_cache ,write:1 ,r:0 ,,missing_oid0//0//-1 ,obc:0x3da8090 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 1389: 14:42:02.570179 25 osd.1 pg_epoch: 15 pg[1.4] maybe_handle_cache 9105892c/rb.0.1019.238e1f29.000000000000/head//1(0'0 unknown.0.0:0 wrlock_by=unknown.0.0:0 s 0 uv 0) DNE missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 1390: 14:42:02.570190 20 osd.1 pg_epoch: 15 pg[1.4] maybe_handle_cacheREADONLY Line 1391: 14:42:02.570196 20 osd.1 pg_epoch: 15 pg[1.4] maybe_handle_cacheREADONLY!r,r:0 Line 1484: 14:42:02.587054 20 osd.1 pg_epoch: 15 pg[1.0] XYJdo_op maybe_handle_cache mesg->flags:4194340 IGNORE_CACHE:32768 Line 1485: 14:42:02.587063 10 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache ,write:1 ,r:0 ,,missing_oid0//0//-1 ,obc:0x3d72450 ,in_hit_set:0 ,pool.info.min_read_recency_for_promote:1 Line 1486: 14:42:02.587072 25 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache fea29050/myimage.rbd/head//1(15'3 client.4121.0:7 wrlock_by=unknown.0.0:0 dirty|data_digest s 112 uv 2 dd 35515d2f) exists missing_oid 0//0//-1 must_promote 0 in_hit_set 0 Line 1487: 14:42:02.587083 20 osd.1 pg_epoch: 15 pg[1.0] maybe_handle_cache obc.get() && obc->obs.exists Line 1488: 14:42:02.587090 20 osd.1 pg_epoch: 15 pg[1.0] XYJdo_opmaybe_handle_cache false
查看日誌,無論是writeback模式仍是readonly模式,在命中緩存時都會打印」 maybe_handle_cache obc.get() && obc->obs.exists」 這句。從日誌來看,在寫操做的時候,若是命中緩存,後面都會接一句XYJdo_opmaybe_handle_cache false,說明該寫請求都會在緩存中處理。