cache原始碼分析四 初始化與元資料同步

2021-07-31 16:38:29 字數 1923 閱讀 5395

原文:

之前我們討論過,cache的索引在trafficserver啟動時,會從磁碟載入到記憶體中。這裡有兩個問題。

問題1:記憶體中的索引被更新後,與磁碟中儲存的部分已經不一致,我們稱之為髒了,這時需要將索引寫回至磁碟中去。

問題2:設想這樣一種情況,trafficserver將索引寫回磁碟後,開始將agg_buffer中資訊寫入磁碟,未等這個過程結束,trafficserver就因為某種原因stop了,導致磁碟上儲存的索引資訊與實際儲存的內容兩者之間資訊不一致。

儲存機制這篇文章中,我們分析過cache的disklayout設計。索引維護在磁碟的directory中,其中header與footer儲存的是索引元資訊以及cache讀寫行為的資訊,而位於它們之間的就是實際索引儲存區。header與footer都是同乙個資料結構型別volheaderfooter,這個結構中與本文相關的資訊如下:

struct volheaderfooter ;

問題1分析  

cache的disklayout中可以看到有兩個directory,按照先後順序稱為a與b。trafficserver在啟動後,會不定期將記憶體中索引寫回磁碟中去。寫回過程是這樣的,首先會將header的值賦給footer,然後先寫header,再寫索引區,最後寫footer。

問:為什麼儲存兩份directory?

答:比如trafficserver啟動後,載入a至記憶體構建索引。如果只有乙份directory,那麼在寫回時,在將記憶體中索引寫回磁碟時,trafficserver由於某種原因異常退出,這時磁碟上索引就被損壞了,嚴重時導致無法修復而丟失所有資料。如果有兩份directory,那麼在寫回時,可以將索引寫回至b,這時即使出錯,那麼下次啟動時,至少還有a是可用的,雖然不可避免也會丟失一些資料。

問:為什麼需要header,footer兩次來儲存索引元資訊?

答:同上,如果寫完header,索引部分還沒寫完,trafficserver就異常退出。下次啟動時,發現header與footer資訊不一致,就可以證明這次寫回操作失敗,從而選擇另乙個directory使用。

問:每次將記憶體中索引寫回至磁碟的哪乙個部分?

答:通過header的sync_serial來區分。每次寫到磁碟上之前,都會++sync_serial,如果是偶數,寫至a,否則,寫至b。

**分析:

//當trafficserver正常退出時,會將索引寫回磁碟

sync_cache_dir_on_shutdown()              

//cachesync這個continuation會不定期被呼叫將索引寫回磁碟

cachesync::main_event()

問題2分析

trafficserver在啟動時,會將磁碟中索引載入至記憶體。當將索引讀至記憶體後,這時cache還是不能提供服務的,需要解決上次退出時可能的異常行為導致索引與儲存內容的元資訊不一致問題。

上圖是cache啟動後,索引從磁碟載入到記憶體的過程。

(1) trafficserver啟動後,首先會將a與b的header與footer讀取出來。

(2) 比較a與b的header與footer,選擇a還是b構建索引。

(3) 將索引讀入記憶體後,判斷是否讀取正確,設定元資訊等。

(4) 這是整個過程的核心。將磁碟中儲存的與索引資訊不一致的object讀取出來,根據header提供的元資訊,與每個object的元資訊進行比較。如果這個object是可用的,則更新header元資訊。最後將無效的objects的索引清空,也就是執行刪除object操作。

(5) 當recover完成後,就代表記憶體載入成功了。vol::handle_recover_write_dir更新scan資訊,執行periodic_scan,函式流程進入vol::dir_init_done,至此磁碟讀取索引至記憶體完成。

Spring MVC原始碼分析 初始化過程

1.概述 handleradapter的繼承體系 同樣的視 析器viewresolver針對不同的輸出格式也有一系列的實現類,具體可自己看。2.實現分析 以我自己的乙個web專案中spring mvc的配置為例 2.1 spring mvc初始化流程 dispatcherservlet的繼承體系如 ...

mybatis 原始碼分析之初始化

mybatis 的配置檔案解析又xmlconfigbuilder的parseconfiguration方法來完成,解析結果都存在configuration這個類中 private void parseconfiguration xnode root catch exception e 別名解析 pr...

Nginx原始碼分析3 模組初始化

直接跟 main ngx preinit modules 對模組名進行複製 ngx init cycle 講模組物件複製到cycle裡面 ngx cycle modules ngx master process cycle ngx start worker processes ngx worker ...