資料庫架構設計還經常遇到哪些問題
不知不覺,資料庫水平切分的系列文章已經走過半年,很感謝朋友們一路的陪伴,也感謝gitchat這個平臺,能夠把自己曾經實踐過的水平切分架構方案,梳理總結和沉澱,系統的記錄成文字,和大家一起分享。
本文是這個專題的最後一講,在設定這個專題之初,就已經想好,這一講的內容了:
-
一部分,總結:特別擔心大家沒有完整的訂閱這一系列文章,無法系統的看到全貌,特地留了一篇總結性質的文章,把1-5篇的知識點系統性的回顧。
-
一部分,挖坑:網際網路資料庫架構,水平切分只是其中的一部分,除此之外,還會遇到很多問題,而這些問題並不是一篇文章就能講清楚的,如果未來有緣,再和大家深入交流探討。
一、《前言:資料庫水平切分通用實踐》
-
資料庫分組架構的概念,特點,解決的問題域,最佳實踐。
-
資料庫分片架構的概念,特點,解決的問題域,最佳實踐。
-
資料庫垂直拆分的概念,特點,解決的問題域,最佳實踐。
二、《從使用者中心開始,聊“單KEY”類業務資料庫水平切分架構實踐》
水平切分方式
-
範圍法
-
雜湊法
水平切分後碰到的問題
- 通過uid屬性查詢能直接定位到庫,通過非uid屬性查詢不能定位到庫。
非uid屬性查詢的典型業務
-
使用者側,前臺訪問,單條記錄的查詢,訪問量較大,服務需要高可用,並且對一致性的要求較高。
-
運營側,後臺訪問,根據產品、運營需求,訪問模式各異,基本上是批量分頁的查詢,由於是內部系統,訪問量很低,對可用性的要求不高,對一致性的要求也沒這麼嚴格。
使用者側與運營側架構設計思路
-
針對使用者側,應該採用“建立非uid屬性到uid的對映關係”的架構方案。
-
針對運營側,應該採用“前臺與後臺分離”的架構方案。
使用者前臺側,“建立非uid屬性到uid的對映關係”最佳實踐
-
索引表法:資料庫中記錄login_name->uid的對映關係。
-
快取對映法:快取中記錄login_name->uid的對映關係。
-
login_name生成uid。
-
login_name基因融入uid。
運營後臺側,“前臺與後臺分離”最佳實踐
-
前臺、後臺系統web/service/db分離解耦,避免後臺低效查詢引發前臺查詢抖動。
-
可以採用資料冗餘的設計方式。
-
可以採用“外接索引”(例如ES搜尋系統)或者“大資料處理”(例如HIVE)來滿足後臺變態的查詢需求。
三、《從帖子中心開始,聊“1對多”類業務資料庫水平切分架構實踐》
“1對多”類業務,在架構上,採用元資料與索引資料分離的架構設計方法
-
帖子服務,元資料滿足uid和tid的查詢需求。
-
搜尋服務,索引資料滿足複雜搜尋尋求。
對於元資料的儲存,在資料量較大的情況下,有三種常見的切分方法:
-
tid切分法,按照tid分庫,同一個使用者釋出的帖子落在不同的庫上,通過 - uid來查詢要遍歷所有庫。
-
uid切分法,按照uid分庫,同一個使用者釋出的帖子落在同一個庫上,需要通過索引表或者快取來記錄tid與uid的對映關係,通過tid來查詢時,先查到uid,再通過uid定位庫。
-
基因法,按照uid分庫,在生成tid里加入uid上的分庫基因,保證通過uid和tid都能直接定位到庫。
四、《從好友關係開始,聊“多對多”類業務資料庫水平切分架構實踐》
好友業務是一個典型的多對多關係,又分為強好友與弱好友
資料冗餘是一個常見的多對多業務資料水平切分實踐
冗餘資料的常見三種方案
-
服務同步冗餘
-
服務非同步冗餘
-
線下非同步冗餘
資料冗餘會帶來一致性問題,高吞吐網際網路業務,要想完全保證事務一致性很難,常見的實踐是最終一致性
最終一致性的常見實踐是,儘快找到不一致,並修復資料,常見三種方案
-
線下全量掃描法
-
線下增量掃描法
-
線上實時檢測法
五、《從訂單中心開始,聊“多KEY”類業務資料庫水平切分架構實踐》
任何複雜難題的解決,都是一個化繁為簡,逐步擊破的過程。
對於像訂單中心一樣複雜的“多key”類業務,在資料量較大,需要對資料庫進行水平切分時,對於後臺需求,採用“前臺與後臺分離”的架構設計方法:
-
前臺、後臺系統web/service/db分離解耦,避免後臺低效查詢引發前臺查詢抖動。
-
採用前臺與後臺資料冗餘的設計方式,分別滿足兩側的需求。
-
採用“外接索引”(例如ES搜尋系統)或者“大資料處理”(例如HIVE)來滿足後臺變態的查詢需求。
對於前臺需求,化繁為簡的設計思路,將“多key”類業務,分解為“1對多”類業務和“多對多”類業務分別解決:
-
使用“基因法”,解決“1對多”分庫需求:使用
buyer_uid
分庫,在oid中加入分庫基因,同時滿足oid和buyer_uid
上的查詢需求。 -
使用“資料冗餘法”,解決“多對多”分庫需求:使用
buyer_uid
和seller_uid
來分別分庫,冗餘資料,滿足buyer_uid
和seller_uid
上的查詢需求。 -
如果
oid/buyer_uid/seller_uid
同時存在,可以使用上述兩種方案的綜合方案,來解決“多key”業務的資料庫水平切分難題。
六、資料庫架構設計其他問題
上述1-5篇文章,僅僅只是展開描述了“水平切分”這一個話題,在資料庫架構設計過程中,除了水平切分,至少還會遇到這樣一些問題:
-
可用性:不管是主庫例項,還是從庫例項,如果資料庫例項掛了,如何不影響資料的讀和寫。
-
讀效能:網際網路業務大多是讀多寫少的業務,如果提升資料庫的讀效能是架構設計中必須考慮的問題。
-
一致性:資料一旦冗餘,就可能出現一致性問題,如何解決主庫與從庫之間的不一致,如何解決資料庫與快取之間的不一致,也是需要重點設計的。
-
擴充套件性:如何在不停服務的情況下擴充資料表的屬性,實施資料遷移,實施儲存引擎的切換,架構設計上都是十分有講究的。
-
分散式SQL語句:單庫情況下,所有SQL語句的執行都沒問題問題,一旦實施了水平切分,如何實現SQL的集函式,分頁,非patition key上的查詢都成了大問題。