数据库的架构演进
? ??關系型數據庫本身比較容易成為系統瓶頸,單機存儲容量、連接數、處理能力都有限。當單表的數據量增加以后,由于查詢維度較多,即升級硬件、升級網絡、優化SQL索引,做很多操作時性能仍下降嚴重。此時需要考慮調整數據庫的架構了。
1、主從復制,讀寫分離
2、分區
3、分表
4、常見分區分表的規則策略
5、分庫
6、分庫/分表后面臨的問題
7、什么時候考慮切分
1、主從復制,讀寫分離
? ??MySQL的主從復制解決了數據庫的讀寫分離,并很好的提升了讀的性能。
? ? ? ? ? ?
? ??
? ? 但是,主從復制也帶來其他一系列性能瓶頸問題:寫入無法擴展、寫入無法緩存、復制延時、鎖表率上升、表變大,緩存率下降等,此時需要考慮進行數據庫分區了。
2、分區
? ? 分區就是把一張表的數據分成N個區塊,在邏輯上看最終只是一張表,但底層是由N個物理區塊組成的。數據分區是一種物理數據庫的設計技術,它的目的是為了在特定的SQL操作中減少數據讀寫的總量以縮減響應時間。分區并不是生成新的數據表,而是將表的數據均衡分攤到不同的硬盤,系統或是不同服務器存儲介子中,實際上還是一張表。另外,分區可以做到將表的數據均衡到不同的地方,提高數據檢索的效率,降低數據庫的頻繁IO壓力值。
1.1 什么時候考慮分區
-
一張表的查詢速度已經慢到影響使用
-
sql經過優化
-
已經添加主從復制
-
數據量大
-
表中的數據是分段的
-
對數據的操作往往只涉及一部分數據,而不是所有的數據
1.2?水平分區
? ??這種形式分區是對表的行進行分區,通過這樣的方式不同分組里面的物理列分割的數據集得以組合,從而進行個體分割(單分區)或集體分割(1個或多個分區)。所有在表中定義的列在每個數據集中都能找到,所以表的特性依然得以保持。
1.3?垂直分區
? ??這種分區方式一般來說是通過對表的垂直劃分來減少目標表的寬度,使某些特定的列被劃分到特定的分區,每個分區都包含了其中的列所對應的行。
3、分表
? ? 分表就是把一張表按一定的規則分解成N個具有獨立存儲空間的實體表。系統讀寫時需要根據定義好的規則得到對應的字表明,然后操作它。
3.1 垂直分表
? ? 垂直分表是基于數據庫中的"列"進行,某個表字段較多,可以新建一張擴展表,將不經常用或字段長度較大的字段拆分出去到擴展表中。在字段很多的情況下(例 如一個大表有100多個字段),通過"大表拆小表",更便于開發與維護,也能避免跨頁問題,MySQL底層是通過數據頁存儲的,一條記錄占用空間過大會導 致跨頁,造成額外的性能開銷。另外數據庫以行為單位將數據加載到內存中,這樣表中字段長度較短且訪問頻率較高,內存能加載更多的數據,命中率更高,減少了 磁盤IO,從而提升了數據庫性能。? ??
3.2 水平分表
? ??當一個應用難以再細粒度的垂直切分,或切分后數據量行數巨大,存在單庫讀寫、存儲性能瓶頸,這時候就需要進行水平切分了。水平分表根據表內數據內在的邏輯關系,將同一個表按不同的條件分散到多個多個表中,每個表中只包含一部分數據,從而使得單個表的數據量變小。
4、常見分區分表的規則策略
- Range(范圍)
- Hash(哈希)
- 按照時間拆分
- Hash之后按照分表個數取模
- 在認證庫中保存數據庫配置,就是建立一個DB,這個DB單獨保存user_id到DB的映射關系
5、分庫
? ??隨著數據量增加也許單臺DB的存儲空間不夠,隨著查詢量的增加單臺數據庫服務器已經沒辦法支撐。這個時候可以再對數據庫進行水平區分。
4.1 垂直分庫
? ??垂直分庫就是根據業務耦合性,將關聯度低的不同表存儲在不同的數據庫。做法與大系統拆分為多個小系統類似,按業務分類進行獨立劃分。與"微服務治理"的做法相似,每個微服務使用單獨的一個數據庫。
4.2 分庫分表
? ? 根據表內數據內在的邏輯關系,將同一個表按不同的條件分散到多個數據庫中,每個表中只包含一部分數據,從而使得單個表的數據量變小,達到分布式的效果。? ? ? ??
6、分庫/分表后面臨的問題
(1)事務的支持,分庫分表,就變成了分布式事務,分布式事務處理復雜;
(2)join時跨庫,跨表的問題,只能通過接口聚合方式解決,提升了開發的復雜度;
(3)分庫分表,讀寫分離使用了分布式,分布式為了保證強一致性,必然帶來延遲,導致性能降低,系統的復雜度變高;
7、什么時候考慮切分
(1)能不切分盡量不要切分
? ? 并不是所有表都需要進行切分,主要還是看數據的增長速度。切分后會在某種程度上提升業務的復雜度,數據庫除了承載數據的存儲和查詢外,協助業務更好的實現需求也是其重要工作之一。不到萬不得已不用輕易使用分庫分表這個大招,避免"過度設計"和"過早優化"。分庫分表之前,不要為分而分,先盡力去做力所能及的事情,例如:升級硬件、升級網絡、讀寫分離、索引優化等等。當數據量達到單表的瓶頸時候,再考慮分庫分表。
(2)數據量過大,正常運維影響業務訪問
? ? 這里說的運維,指:
- 對數據庫備份,如果單表太大,備份時需要大量的磁盤IO和網絡IO。例如1T的數據,網絡傳輸占50MB時候,需要20000秒才能傳輸完畢,整個過程的風險都是比較高的
- 對一個很大的表進行DDL修改時,MySQL會鎖住全表,這個時間會很長,這段時間業務不能訪問此表,影響很大。如果使用pt- online-schema-change,使用過程中會創建觸發器和影子表,也需要很長的時間。在此操作過程中,都算為風險時間。將數據表拆分,總量減 少,有助于降低這個風險。
- 大表會經常訪問與更新,就更有可能出現鎖等待。將數據切分,用空間換時間,變相降低訪問壓力
(3)隨著業務發展,需要對某些字段垂直拆分
(4)數據量快速增長
? ? 隨著業務的快速發展,單表中的數據量會持續增長,當性能接近瓶頸時,就需要考慮水平切分,做分庫分表了。此時一定要選擇合適的切分規則,提前預估好數據容量。
(5)安全性和可用性
? ? 雞蛋不要放在一個籃子里。在業務層面上垂直切分,將不相關的業務的數據庫分隔,因為每個業務的數據量、訪問量都不同,不能因為一個業務把數據庫搞掛而牽連到其他業務。利用水平切分,當一個數據庫出現問題時,不會影響到100%的用戶,每個庫只承擔業務的一部分數據,這樣整體的可用性就能提高。
總結
- 上一篇: zbrush导入obj模型不显示_ZBr
- 下一篇: Linux浏览器拉起应用程序