ATS讀大文件(命中)

大文件存儲結構和小文件完全不同,小文件佔一個fragment就夠了,大文件佔若干個fragment。大文件第一個分片是doc只存一些信息數據,包括http頭,資源的content存在於後面若干個fragment中,默認每個fragment佔1048576字節,在proxy.config.cache.target_fragment_size中可以改。一個fragment中有72個字節是doc,剩下的是資源的content。ats會先讀第一個fragment,然後以循環的方式讀取若干個fragment,直到客戶端得到了需要的所有數據。

wKioL1ga9xLSFYbSAAPvh3sQl3M637.png

Cache::open_read: 計算的到vol。運行了dir_probe函數,確定了緩存查詢的結果。獲取了dir,對CacheVC對象的key和dir進行了初始化。生成一個CacheVC對象,之後的操作都是這個CacheVC對象是事兒了。設置回調函數爲Cache::openReadStartHead,設置完回調函數會執行do_read_call。

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

CacheVC::handleRead: 獲取偏移量(dir_get_offset)。 在內存中查詢(vol->ram_cache->get函數會根據records.config中的配置項proxy.config.cache.ram_cache.algorithm指向不同的函數)。如果查詢沒有命中,生成一個iobufferdata buf(可以理解爲內存中開了一塊空間),生成一個char*變量指向buf的data。將磁盤中的內容memcpy到內存中。會有兩種情況,一種是ramhit會執行CacheVC::handleReadDone,另一種是memhit,直接執行CacheVC::openReadStartHead,區別不大,這裏討論memhit情況。將回調函數POP掉,POP之後的回調函數變爲在Cache::open_read設置的Cache::openReadStartHead,最終返回EVENT_RETURN一直向上直到Cache::open_read

CacheVC::openReadStartHead: 函數確定了是大文件還是小文件。挑選了一個alternate,將選定的alternate的key賦值給Cache::key,判斷alternate的key和doc->key是否相等。由於大文件的doc只存了一些信息,所以alternate的key和第一個存content的fragment的doc->key。函數最後將buf賦值爲NULL,之後將回調函數設置爲CacheVC::openReadStartEarliest並且執行。

CacheVC::openReadStartEarliest: 如果hit狀態,一般會執行兩次。但是如果出於正在下載狀態,這個函數會執行若干次,但是獲取鎖不會成功。按照順序來講,CacheVC::openReadStartHead已經獲取到了第一個存儲content的fragment的key。通過dir_probe函數根據key得到earliest_dir。

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

CacheVC::handleRead: 獲取偏移量(dir_get_offset)。 在內存中查詢(vol->ram_cache->get函數會根據records.config中的配置項proxy.config.cache.ram_cache.algorithm指向不同的函數)。將回調函數設置爲CacheVC::handleReadDone,返回EVENT_CONT一直向上給Cache::open_read,事件結束

CacheVC::handleReadDone: 將回調函數POP掉,之後回調函數變爲CacheVC::openReadStartEarliest,之後執行回調函數。

CacheVC::openReadStartEarliest: 這次之行時buf已經不是NULL了,計算next_key,設置回調函數爲CacheVC::openReadMain並且執行。

CacheVC::openReadMain: 判斷客戶端請求的range最開始的位置位於哪個fragment,調整offset和doc_pos到合適的位置,offset是整個響應的offset不包含doc所佔的72字節,doc_pos是單個fragment的postion包括72字節。這個函數會進入若干次,直到東西全都發完了。最後一次執行的時候,根據CacheVC::openReadStartEarliest計算得到的key,通過dir_probe的到對應的dir,設置回調函數爲CacheVC::openReadReadDone,執行CacheVC::do_read_call,最後返回EVENT_CONT。到這裏就進入了一個循環,一片一片的讀文件發文件,直到請求結束。

CacheVC::handleReadDone: 進入循環之後這個函數由事件出發,將回調函數POP掉之後的回調函數變爲CacheVC::openReadReadDone,執行回調函數。

CacheVC::openReadReadDone: fragment數量加1,計算next_key。將回調函數設置爲CacheVC::openReadMain並且執行。


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