一、基本概念
概念一:單庫
概念二:分片
分片解決「數據量太大」這一問題,也就是通常說的「水平切分」。
一旦引入分片,勢必面臨「數據路由」的新問題,數據到底要訪問哪個庫。路由規則通常有3種方法:
(1)範圍:range
優點:簡單,容易擴展。
缺點:各庫壓力不均(新號段更活躍)。
(2)哈希:hash
優點:簡單,數據均衡,負載均勻。
缺點:遷移麻煩(2庫擴3庫數據要遷移)。
(3)統一路由服務:router-config-server
優點:靈活性強,業務與路由算法解耦。
缺點:每次訪問資料庫前多一次查詢。
大部分網際網路公司採用的方案二:哈希路由。
概念三:分組
分組解決「可用性,性能提升」這一問題,分組通常通過主從複製的方式實現。
網際網路公司資料庫實際軟體架構是「既分片,又分組」:
資料庫軟體架構,究竟設計些什麼呢,至少要考慮以下四點:
二、如何保證數據的可用性?
解決可用性問題的思路是:冗餘。
如何保證站點的可用性?冗餘站點。
如何保證服務的可用性?冗餘服務。
如何保證數據的可用性?冗餘數據。
數據的冗餘,會帶來一個副作用:一致性問題。
如何保證資料庫「讀」高可用?
冗餘讀庫。
冗餘讀庫帶來什麼副作用?
讀寫有延時,數據可能不一致。
上圖是很多網際網路公司mysql的架構,寫仍然是單點,不能保證寫高可用。
如何保證資料庫「寫」高可用?
冗餘寫庫。
採用雙主互備的方式,可以冗餘寫庫。
冗餘寫庫帶來什麼副作用?
雙寫同步,數據可能衝突(例如「自增id」同步衝突)。
如何解決同步衝突,有兩種常見解決方案:
(1)兩個寫庫使用不同的初始值,相同的步長來增加id:1寫庫的id為0,2,4,6...;2寫庫的id為1,3,5,7…;
(2)不使用數據的id,業務層自己生成唯一的id,保證數據不衝突;
阿里雲的RDS服務號稱寫高可用,是如何實現的呢?
他們採用的就是類似於「雙主同步」的方式(不再有從庫了)。
仍是雙主,但只有一個主提供讀寫服務,另一個主是「shadow-master」,只用來保證高可用,平時不提供服務。
master掛了,shadow-master頂上,虛IP漂移,對業務層透明,不需要人工介入。
這種方式的好處:
(1)讀寫沒有延時,無一致性問題;
(2)讀寫高可用;
不足是:
(1)不能通過加從庫的方式擴展讀性能;
(2)資源利用率為50%,一臺冗餘主沒有提供服務;
畫外音:所以,高可用RDS還挺貴的。
三、如何擴展讀性能?
提高讀性能的方式大致有三種,第一種是增加索引。
這種方式不展開,要提到的一點是,不同的庫可以建立不同的索引。
如上圖:
(1)寫庫不建立索引;
(2)線上讀庫建立線上訪問索引,例如uid;
(3)線下讀庫建立線下訪問索引,例如time;
第二種擴充讀性能的方式是,增加從庫。
這種方法大家用的比較多,存在兩個缺點:
(1)從庫越多,同步越慢;
(2)同步越慢,數據不一致窗口越大;
第三種增加系統讀性能的方式是,增加緩存。
常見的緩存架構如下:
(1)上遊是業務應用;
(2)下遊是主庫,從庫(讀寫分離),緩存;
如果系統架構實施了服務化:
(1)上遊是業務應用;
(2)中間是服務;
(3)下遊是主庫,從庫,緩存;
業務層不直接面向db和cache,服務層屏蔽了底層db、cache的複雜性。
不管採用主從的方式擴展讀性能,還是緩存的方式擴展讀性能,數據都要複製多份(主+從,db+cache),一定會引發一致性問題。
四、如何保證一致性?
主從資料庫的一致性,通常有兩種解決方案:
(1)中間件
如果某一個key有寫操作,在不一致時間窗口內,中間件會將這個key的讀操作也路由到主庫上。
(2)強制讀主
「雙主高可用」的架構,主從一致性的問題能夠大大緩解。
第二類不一致,是db與緩存間的不一致。
這一類不一致,《緩存架構,一篇足夠?》裡有非常詳細的敘述,本文不再展開。
另外建議,所有允許cache miss的業務場景,緩存中的KEY都設置一個超時時間,這樣即使出現不一致,有機會得到自修復。
五、如何保障資料庫的擴展性?
秒級成倍資料庫擴容:
《億級數據DB秒級平滑擴容》
如果不是成倍擴容:
《100億數據平滑數據遷移,不影響服務》
也可能,是要對欄位進行擴展:
《1萬屬性,100億數據,架構設計?》
這些方案,都有相關文章展開寫過,本文不再贅述。
資料庫軟體架構,到底要設計些什麼?
希望對大家系統性理解資料庫軟體架構有幫助。
架構師之路-分享可落地技術
相關推薦:
《回表查詢?索引覆蓋?| 1分鐘系列》新出爐
《優化工具,迅猛定位低效SQL | 1分鐘系列》
《資料庫允許空值(null)是悲劇的開始 | 1分鐘系列》
《兩類非常隱蔽的全表掃描 | 一分鐘系列》