一、Master-Slave架構java
二、異步日誌持久化機制數據庫
三、檢查點機制:定時持久化全量數據架構
四、引入檢查點節點併發
五、總結 & 思考異步
這篇文章,給你們來聊一個生產級的中間件系統的架構設計實踐,但願給對中間件系統感興趣的同窗一點啓發。分佈式
這個中間件系統的本質是但願可以用分佈式的方式來處理一些數據,可是具體的做用涉及到核心技術,因此這裏不能直接說明。高併發
可是他的核心思想,就是把數據分發到不少臺機器上來處理,而後須要有一臺機器來控制N多臺機器的分佈式處理,大概以下圖所示。性能
那麼既然是分佈式的處理,就確定涉及到在Master中要維護這個集羣的一些核心元數據。學習
好比說數據的分發處理是如何調度的,處理的具體過程如今什麼進度了,還有就是對集羣裏存放數據進行描述的一些核心元數據。spa
這些核心元數據確定會不斷的頻繁的修改,你們此時能夠想,不管你是基於外部的文件仍是數據庫,或者是zookeeper來存放這些元數據的話,其實都會致使他的元數據更新性能下降,由於要訪問外部依賴。
況且這種複雜的元數據其實還不必定能經過zk或者數據庫來存放,由於他多是非格式化的。
因此這裏一個核心的設計,就是將核心元數據直接存放在Master的內存裏,這樣能夠保證高併發更新元數據的時候,他的性能是極高的,並且直接基於內存來提供對外的更新服務。
若是Master部署在高配置物理機上,好比32核128GB的那種,每秒支持10萬+的請求都沒問題。
可是這裏有一個問題,假如說Master進程重啓,或者是忽然宕機了,那麼內存裏的數據不就丟失了麼?
對,因此針對這個問題,既然已經否決掉了基於外部存儲來寫入元數據,那麼這裏就能夠採起異步持久化日誌的機制,來經過異步化的方式把元數據的更新日誌寫入磁盤文件。
每次Master收到一個請求,在內存裏更新元數據以後,就須要生成一條元數據的更新日誌,把這個更新日誌須要寫入到一個內存緩衝裏去。
而後等內存緩衝滿了以後,由一個後臺線程把這裏的數據刷新到磁盤上去,以下圖。
確定會有人說,那若是一條更新日誌剛寫入緩衝區,結果Master宕機了,此時不是仍是會丟失少許數據嗎?由於還沒來得及刷入磁盤。
沒錯啊,這個爲了保證高併發請求都是由內存來處理的,你必須得用異步持久化磁盤的模式,因此必然要容忍極端宕機狀況下,可能丟失好比幾秒鐘的數據。
那麼若是是正常的Master重啓呢?
那簡單,必須先把日誌緩衝區清空刷入磁盤,而後才能正常重啓Master,保證數據都在磁盤上不會丟失。
接着重啓的時候,從磁盤上讀取更新日誌,每一條都依次回訪到內存裏,恢復出來核心元數據便可。
可是這裏又有一個問題了,那個磁盤上的日誌文件愈來愈大,由於元數據不斷的在更新,不斷在產生最新的變動日誌寫入磁盤文件。
那麼系統運行一段時間之後,每次重啓都須要從磁盤讀取歷史所有日誌,一條一條回放到內存來恢復核心元數據嗎?
不可能,因此這裏必定要配合引入檢查點機制。
也就是說,每隔一段時間,就須要開啓一個後臺線程,把內存裏的所有核心元數據序列化後寫入磁盤上的元數據文件,做爲這個時間的一個快照文件,同時清空掉日誌文件,這個叫作檢查點操做。
下次重啓,只要把元數據文件讀取出來直接反序列化後方入內存,而後把上次檢查點以後的變動日誌從日誌文件裏讀出來回放到內存裏,就能夠恢復出來完整的元數據了。
這種方式,可讓Master重啓很快,由於大部分數據都是在檢查點寫入的那個元數據文件裏。
整個過程,以下圖所示:
可是這個時候又有一個問題了。
你們能夠想一下,Master內存裏的元數據須要高併發的被人訪問和修改,同時每隔一段時間還要檢查點寫入磁盤。
那麼在檢查點過程當中,是否是須要把內存數據所有加鎖,不容許別人修改?
在加鎖的時候,把不會變更的數據寫入磁盤文件中,可是這個過程是很慢的,意味着此時別人高併發的寫入操做都須要等待覈心元數據的鎖。
由於此時別人鎖住了,你沒法加鎖去寫數據進去,這會致使系統在幾秒內出現卡頓沒法響應請求的問題。
因此此時須要在架構設計裏引入一個檢查點節點,專門負責同步Master的變動日誌。
而後在本身內存裏維護一份如出一轍的核心元數據,每隔一段時間由檢查點節點來負責將內存數據寫入磁盤,接着上傳發送給Master。
這樣作,就不須要Master本身執行檢查點的時候對本身內存數據進行加鎖了,以下圖。
在這樣的一個架構下,對Master來講,他只須要一個後臺線程負責接收Checkpoint進程定時傳送過來的元數據文件快照而後寫入本地磁盤就能夠了,徹底規避掉了對本身內存元數據的鎖衝突的問題。
總結一下這個架構設計,其實就是Master基於內存維護元數據,這樣一臺物理機能夠支撐每秒10萬+的高併發請求。
每次元數據出現更新,寫一條日誌到內存緩衝區,而後後臺線程去刷新日誌到日誌文件裏去,同時須要發送一條日誌到Checkpoint節點去。
Checkpoint節點會在本身內存裏維護一份如出一轍的元數據,而後每隔一段時間執行checkpoint檢查點寫一份元數據文件快照。
接着上傳給Master節點後清空掉他的日誌文件。而後Master節點每次重啓的時候直接讀取本地元數據文件快照,加上回放上次checkpoint以後的日誌便可。
這裏可能你們會提幾個問題,好比說Master節點忽然宕機會如何?
那很簡單,直接影響就是他內存緩衝裏的那些日誌丟了,致使少許數據丟失,這個在咱們的場景下能夠容忍。
若是Checkpoint節點宕機怎麼辦?
那沒關係,由於他以前上傳過元數據文件的快照,因此對Master而言最多就是沒法同步數據過去。
可是Master重啓,仍是能夠讀取最近一次的元數據快照,而後回放日誌便可。
等Checkpoint節點恢復了,能夠繼續接着上一次同步日誌,而後繼續執行checkpoint操做。
架構專題
因爲圖片太大上傳會不清晰,須要完整架構體系大綱的能夠加我私人技術討論羣領取資料哦,我已經打包好的架構體系大綱,免費分享給你們哦!
點擊連接加入羣聊【互聯網java高級架構536172545】:https://jq.qq.com/?_wv=1027&k=5S5wh8D
針對大綱的技術知識點,咱們也有Java高級學習的視頻資料分享,機會很少,先到先得!