資料訪問層的設計和實現(分散式系統七)
(1)如何對外提供資料訪問層的功能
資料訪問層就是方便應用進行資料讀寫訪問的抽象層,在該層上解決各個應用通用的訪問資料庫的問題。
上圖顯示了三種方式,第一種是為使用者提供專有API,不過不推薦,通用性很差。第二種是通用的方式,java應用中一般是通過JDBC方式訪問資料庫,資料庫自身可以作為一個JDBC實現,也就是暴露出JDBC的介面給應用。第三種是基於ORM或類ORM介面方式。
2.按照資料層流程的順序看資料層設計
(1)sql解析階段處理
主要考慮兩個問題,一是sql支援程度,是否需要支援所有的sql,要根據具體場景來決定,二是支援多少sql方言。
(2)規則處理階段
a、採用固定雜湊演算法作為規則
固定雜湊的方式,根據某個欄位(例如使用者id)取模,然後將資料分散到不同的資料庫和表中,除了根據id取模,還經常根據時間維度。
一致性雜湊所帶來的最大變化就是把節點對應的雜湊值變為了一個範圍,而不再是離散的。在一致性雜湊中,我們會把整個雜湊值的範圍定義的非常大,然後把這個範圍分配給現有節點,如果有節點加入,那麼這個新節點會從原有的某個節點上分管一部分範圍的雜湊值;如果有節點退出,這個節點原來管理的雜湊值會給它的下一個節點來管理。假設雜湊值範圍從0到100,共有4個節點,那麼他們管理的範圍就變成[0,25],[25,50],[50,75],[75,100],如果第二個節點退出,那麼剩下節點管理的範圍就變成[0,25],[25,75),[75,100],若是在第二個和第三個節點增加一個,就變成0,25),[25,50),[50,63),[63,75),[75,100],減少一個節點時,只有一個節點受影響,它要承擔原來自己的和減去節點的工作,壓力明顯比其他節點要高。一致性雜湊的優勢就不明顯了。所以引入了虛擬節點,4個物理節點可以變成很多虛擬節點,如果有一個物理節點加入,就會響應加入很多虛擬節點,這些新的虛擬節點相對均勻插入整個雜湊環上,如果減少一個物理節點,對應很多虛擬節點就會失效,這樣會有很多剩餘的虛擬節點來承擔之前虛擬節點的工作,對物理節點來說,增加的負載是相對均衡的。
(3)sql改寫
如果我們分庫時按照賣家id來分,可以保證同一個賣家的商品在一個數據庫中,但是要根據商品id來查詢就比較麻煩了,因為只有商品id不能確定這個商品是在哪個資料庫中,還需要賣家id或其他標誌才能確定。為什麼要修改sql呢?
資料表從原來單庫單表變成了多庫多表,這些分佈在不同資料庫中的表的結構一樣,但是表名未必一模一樣,如果把原來的表分佈在多庫且每個庫都只有一個表的話,那麼這些表是可以同名的,若干單庫中不止一個表,那就不能用同樣的名字,如User表分庫分表後命名為user_1,user_2。在命名錶示需要作出一個選擇,不同庫中的表名是否要一樣?如果每個表的名字是唯一的,看起來似乎不太優雅,但可以避免很多誤操作,另外表名唯一在進行路由和資料遷移時比較便利。
除修改表名,sql中用到的索引名,在分庫分表時也要進行修改,需要從邏輯上的名字變成對應資料庫中物理的名字。
(4)如何選擇資料來源
user經歷分庫分表後,都會給分庫後的庫提供備庫,也就是原來一個數據庫變成一個數據庫的矩陣了。分庫是把資料分到了不同的資料分組中,我們決定了資料分組後,還要決定訪問分組中的哪個庫。
4、讀寫分離的挑戰的應對
(1)資料結構相同,多從庫對應一主庫
比較優雅解決方式是基於資料庫的日誌來進行資料的複製。
(2)主備庫分庫方式不同的資料複製
一般情況進行的是對稱的複製,也就是映象,但是也會有一些進行非對稱複製,非對稱複製是源資料和目標資料不是映象關係,也就是源資料庫和目標資料庫是不同的實現。
一個是根據買家id進行分庫,把所以買家訂單分到4個庫中,保證一個買家查詢自己的交易使都是在一個數據庫上的,不過賣家的查詢就可能跨多個庫,我們可以做一組備庫,按照賣家id進行分庫,這樣賣家就可以從備庫上查詢自己的訂單都是在同一個資料庫中了,這就是非對稱複製,需要控制資料的分發,而不是進行簡單的映象複製。
(3)如何進行資料平滑遷移
在遷移過程中可能又會有資料的變化,可以考慮的方案是,在開始進行資料遷移時,記錄增量的日誌,在遷移結束後,再對增量的變化進行處理,最後,可以把要被遷移的資料的寫暫停,保證增量日誌都是處理完畢後,在切換規則,放開所有的寫,完成遷移工作。