從redis主從複製學習系統設計

賈智文發表於2018-11-18

今天看《redis設計與實現》,學習了redis主從複製相關的知識,學習不總結就沒有真正的提高,但也不想簡單的把書中東西進行一次謄寫,正巧最近做了很多次系統設計,下面就講講,我理解的從redis主從複製可以學習到的系統設計知識。我就從一個最簡單的快取模型開始,一步步的講述下reids設計了哪些東西,為什麼要設計這些,來更深刻的領會這些知識的使用場景。(我將講述各個設計的考慮場景,引出更多的問題,為了促進思考和避免文章冗長,將不在文中贅述

首先,我們有一臺主機和多臺從機,主機上的資料需要同步到從機上。這個時候我們有兩個方式將資料從主機同步到從機上,第一個將主機上的資料整體的發給從庫,從庫執行這些資料。第二個是將主機上的資料一條條的發給主機(大家可以瞭解下redis主從複製完全使用aof方式的問題,這個方案不做展開)。

如果每次都是整體發給從庫,那麼只有主庫讀很多寫很少的場景才勉強可以使用,否則每次都要重新生成整體資料,效能一定超差了。redis現在做了第一步優化(並非實際上的構思順序,只是為行文順序),當客戶端整體同步完成後,後續主機的命令可以通過命令傳播的方式,傳遞給從機,這樣就保證了主機和從機資料的一致。

其實進行到這一步,在某些業務場景下就已經滿足了。但是redis畢竟是個大範圍使用的中介軟體,要面臨更大的流量,更加複雜的線上環境。比如主機如果掛了怎麼辦,命令傳播階段斷開連線了怎麼辦。前者redis引入了runid,後者引入了積壓緩衝區偏移量。積壓緩衝區類似於業務系統中的本地快取,我不清楚是否給你傳送了,先記錄在快取當中。如果是我設計的話,肯定是每個從庫都需要一個對應的快取了,這樣一來主庫需要多份記錄,二來主庫需要對從庫的增加有感知,增加了系統複雜度。大家可以看下redis怎麼設計,帶著情景思考肯定可以有不同的收穫。

再說個命令傳播階段的設計細節。積壓緩衝區1,.先進先出,2.固定長度。大家想一下為什麼需要這樣?redis通過環形陣列實現了上面的兩個要求,環形陣列的實現大家可以瞭解下,redis真的是有很多設計將省記憶體進行到底。

說完了命令傳播階段,再簡單說下整體資料生成時候的一個問題。如果生成資料的時候又有新資料發來怎麼辦呢,直接發給從庫將會導致命令執行的順序不一致,難道加鎖不允許寫入嗎?redis使用了緩衝區的方式,這裡的緩衝區每個從庫對應一個,為什麼積壓緩衝區可以多個從庫共享一個呢?

最後還有個整體設計的點,redis主從庫建立連線後,主庫相當於從庫的客戶端,從庫也是主庫的客戶端,這樣主庫和從庫其實是從業務角度理解的,從redis角度講只有伺服器和客戶端。合理的抽象和封裝,可以使得架構的複雜性降低,在命令傳遞階段對於每臺伺服器而言都相當於接受命令,執行命令,不需要考慮主從的問題。

為了引發思考和不給網際網路新增更多同質化的文章,所以本文留了很多開放問題。大家可以根據下面的參考文章去解惑,掌握了其中的機理,在設計儲存高可用系統時就可以進行借鑑。如果有疑惑也歡迎留言討論。

參考書目:《redis設計與實現》

參考文章:https://mp.weixin.qq.com/s/Vxg8DIaxPjSlSFBNtTvyIg               




相關文章