ceph的數據存儲之路(12)----- cache tier 曾經有過的YY

對於cache的東西啊,我曾經在公司的項目中,有寫過cache的經歷,因此我覺得我很瞭解,在我看ceph手冊對於cache tier描述的時候,感受沒啥新鮮的東西,可是當我對應到ceph源碼級別的時候,發現本身YY的ceph cache tier不太正確。瞭解不難,深刻不易啊。閒話少說進入正題。(排版有點亂)python

1、什麼是cache tier 

在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.分佈式

2、  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實現。

3、ceph cache tier處理流程:

仍是原來的配方,正宗好涼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,說明該寫請求都會在緩存中處理。

相關文章
相關標籤/搜索