先表達幾個概念
分組架構是最常見的一主多從,主從同步,讀寫分離資料庫架構
主和從構成的資料庫集群稱為「組」。
分組有什麼特點?同乙個組裡的資料庫集群:
1、主從之間通過binlog進行資料同步
2、多個例項資料庫結構完全相同
3、多個例項儲存的資料也完全相同,本質上是將資料進行複製
分組架構究竟解決什麼問題?
大部分網際網路業務讀多寫少,資料庫的讀往往最先成為效能瓶頸,如果希望:
1、線性提公升資料庫讀效能
2、通過消除讀寫鎖衝突提公升資料庫寫效能
3、通過冗餘從庫實現資料的「讀高可用」
此時可以使用分組架構,需要注意的是,分組架構中,資料庫的主庫依然是寫單點。
一句話總結,分組解決的是「資料庫讀高併發量高」問題,所實施的架構設計。
分片架構是大夥常說的水平切分(sharding)資料庫架構,
分片後,多個資料庫例項也會構成乙個資料庫集群。
水平切分,到底是分庫還是分表?
答:建議分庫,而不是分表,因為:
1、分表依然公用乙個資料庫檔案,仍然有磁碟io的競爭(如果跨庫分表部分表無法join,只能通過介面聚合方式解決,提公升了開發的複雜度。
分布式事處理複雜)
2、分庫能夠很容易的將資料遷移到不同資料庫例項,甚至資料庫機器上,擴充套件性更好
不過依然存在單錶資料量過大的問題
水平切分,用什麼演算法?
常見的水平切分演算法有「範圍法」和「雜湊法」
雜湊法的不足是擴容麻煩,如果容量不夠,要增加乙個庫,重新hash可能會導致資料遷移,如何平滑的進行資料遷移,是乙個需要解決的問題
範圍法的不足是資料量不均、請求量不均
水平切分優點
1、不存在單庫資料量過大、高併發的效能瓶頸,提公升系統穩定性和負載能力。
2、應用端改造較小,不需要拆分業務模組。
水平切分缺點
1、跨分片的事務一致性難以保證
2、跨庫的join關聯查詢效能較差
3、資料多次擴充套件維度和維護量極大。
分庫分表帶來的問題
1、join操作
水平分表後,雖然物理上分散在多個表中,如果需要與其它表進行join查詢,需要在業務**或者資料庫中介軟體中進行多次join查詢,然後將結果合併。
2、count()操作
水平分表後,某些場景下需要將這些表當作乙個表來處理,那麼count()顯得沒有那麼容易 了。
3、order by 操作
分表後,資料分散到多個表中,排序操作無法在資料庫中完成,只能由業務**或資料中介軟體分別查詢每個子表中的資料,然後彙總進行排序。
分片架構究竟解決什麼問題?
大部分網際網路業務資料量很大,單庫容量容易成為瓶頸,此時通過分片可以:
1、線性提公升資料庫寫效能,需要注意的是,分組架構是不能線性提公升資料庫寫效能的
2、降低單庫資料容量
除了水平切分,垂直切分也是一類常見的資料庫架構設計,垂直切分一般和業務結合比較緊密。
垂直切分解決什麼問題?
垂直切分即可以降低單庫的資料量,還可以降低磁碟io從而提公升吞吐量,但它與業務結合比較緊密,並不是所有業務都能夠進行垂直切分的。
如果通過userid分表,對於非uid屬性上的查詢需求
【索引表法】
思路:uid能直接定位到庫,login_name不能直接定位到庫,如果通過login_name能查詢到uid,問題解決
解決方案:
建立乙個索引表記錄login_name->uid的對映關係
用login_name來訪問時,先通過索引表查詢到uid,再定位相應的庫
索引表屬性較少,可以容納非常多資料,一般不需要分庫
如果資料量過大,可以通過login_name來分庫
潛在不足:多一次資料庫查詢,效能下降一倍
【快取對映法】
思路:訪問索引表效能較低,把對映關係放在快取裡效能更佳
解決方案:
login_name查詢先到cache中查詢uid,再根據uid定位資料庫
假設cache miss,採用掃全庫法獲取login_name對應的uid,放入cache
login_name到uid的對映關係不會變化,對映關係一旦放入快取,不會更改,無需淘汰,快取命中率超高
如果資料量過大,可以通過login_name進行cache水平切分
潛在不足:多一次cache查詢
【login_name生成uid】
思路:不進行遠端查詢,由login_name直接得到uid
解決方案:
在使用者註冊時,設計函式login_name生成uid,uid=f(login_name),按uid分庫插入資料
用login_name來訪問時,先通過函式計算出uid,即uid=f(login_name)再來一遍,由uid路由到對應庫
潛在不足:該函式設計需要非常講究技巧,有uid生成衝突風險
【login_name基因融入uid】
思路:不能用login_name生成uid,可以從login_name抽取「基因」,融入uid中
假設分8庫,採用uid%8路由,潛台詞是,uid的最後3個bit決定這條資料落在哪個庫上,這3個bit就是所謂的「基因」。
解決方案:
在使用者註冊時,設計函式login_name生成3bit基因,
login_name_gene=f(login_name),如上圖粉色部分
同時,生成61bit的全域性唯一id,作為使用者的標識,如上圖綠色部分
接著把3bit的login_name_gene也作為uid的一部分,如上圖屎黃色部分
生成64bit的uid,由id和login_name_gene拼裝而成,並按照uid分庫插入資料
用login_name來訪問時,先通過函式由login_name再次復原3bit基因,login_name_gene=f(login_name),通過login_name_gene%8直接定位到庫
1、停機方案
2、平滑遷移-追日誌法,重放日誌,遷移的過程中資料變化,需要資料追平後切庫
3、平滑遷移-雙寫法
博文鏈結
資料庫分庫分表
1 基本思想之什麼是分庫分表?從字面上簡單理解,就是把原本儲存於乙個庫的資料分塊儲存到多個庫上,把原本儲存於乙個表的資料分塊儲存到多個表上。2 基本思想之為什麼要分庫分表?資料庫中的資料量不一定是可控的,在未進行分庫分表的情況下,隨著時間和業務的發展,庫中的表會越來越多,表中的資料量也會越來越大,相...
資料庫分庫 分表
分庫的優點是 實現簡單,庫與庫之間界限分明,便於維護,缺點是不利於頻繁跨庫操作,單錶資料量大的問題解決不了。分表的優點是 能解決分庫的不足點,但是缺點卻恰恰是分庫的優點,分表實現起來比較複雜,特別是分表規則的劃分,程式的編寫,以及後期的 資料庫拆分移植維護。實際應用中,一般網際網路企業的路線都是先分...
資料庫分庫分表
簡單了解資料庫分庫分表,以及資料庫的分片 什麼是分庫分表 原本儲存於乙個庫的資料分塊儲存到多個庫上,把原本儲存於乙個表的資料分塊儲存在到多個表上 為什麼分庫分表 當一張表的資料達到幾千萬時,你查詢一次所花的時間會變多,如果有聯合查詢的花,我想啃根會死在那。分表的目的就在於此,減少資料庫的負擔,縮短查...