ATS讀小文件(內存命中)

一個資源根據其大小可能會存在多個存儲對象中。如果足夠小(連同doc結構的大小小於一個fragment的size),連同這個資源的meta信息一起存儲在一個doc中。如果比較大,第一個存儲對象保存資源的meta信息,後面跟着若干個fragment存着資源的content。這裏討論小文件讀行爲,並且內存命中,在資源第二次命中的時候纔有可能是內存命中。整個流程在主狀態機流程的入口函數是Cache::open_read,正流程如下:

wKiom1gF5DyQvrUYAACyLBd2Uqk518.png

Cache::open_read: 首先需要計算的到vol,因爲需要知道資源在哪個vol上才能確定是否存在,每個vol都是獨立存在的。獲取鎖之後運行了dir_probe函數,確定了緩存查詢的結果。獲取了dir,對CacheVC對象的key和dir進行了初始化。生成一個CacheVC對象,之後的操作都是這個CacheVC對象是事兒了。設置回調函數爲Cache::openReadStartHead,設置完回調函數會執行do_read_call,最終do_read_call返回了EVENT_RETURN,執行了事件回調函數,就是剛剛設置的Cache::openReadStartHead。


dir_probe: 通過md5值計算得到資源所在的segemnt和bucket,進而得到目標dir,如果dir是否“正確”,如果正確就認爲命中了。

CacheVC::do_read_call: 初始化doc_pos爲0。解析dir,獲取fragment大概大小(dir_approx_size)。決定是否應該存在於ssd中(dir_inssd),如果已經是從ssd中讀了,就肯定不寫了。每個vol都會對應自己的ssd,每個vol都會維護一些歷史數據用來判斷熱度相關的數據。最終執行CacheVC::handleRead,最終返回了EVENT_RETURN。


CacheVC::handleRead: 獲取偏移量(dir_get_offset)。 在內存中查詢(vol->ram_cache->get函數會根據records.config中的配置項proxy.config.cache.ram_cache.algorithm指向不同的函數)。假設內存查詢函數爲RamCacheLRU::get,詳見下面解析。內存命中的話在這個函數裏面會將內容放倒buf中,進而獲取到了doc。


RamCacheLRU::get: 判斷是否在內存中命中,如果命中了,在lru隊列中刪除並且在頭部重新插入。


CacheVC::openReadStartHead: 每次讀操作都會執行一次,獲取這個資源相關的信息,根據buf是否爲空判斷是否命中。確定一個alternate,通過判斷alternate的key是否就是doc的key來判斷這個alternate是不是要找的那個。如果是的話判斷是不是single fragment,如果滿足len = heln + total_len + 72,認爲是小文件。獲取doc_pos,即爲doc的大小與整個資源的metadata的大小的和。獲取next key(對於小文件沒必要,但是也執行了),執行begin_read,這個函數主要判斷了是否需要evacuate,由於小文件都會存在一個fragment,而此時已經都到了內存中,所以不需要考慮evacuate問題。最後將回調函數設置爲 CacheVC::openReadMain,並且執行緩存主狀態機事件回調函數 HttpCacheSM::state_cache_open_read,傳遞的參數是 CACHE_EVENT_OPEN_READ。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章