資料庫分庫分表、讀寫分離的實現原理及使用場景
為什麼要分庫分表和讀寫分離?
類似淘寶網這樣的網站,海量資料的儲存和訪問成為了系統設計的瓶頸問題,日益增長的業務資料,無疑對資料庫造成了相當大的負載,同時對於系統的穩定性和擴充套件性提出很高的要求。隨著時間和業務的發展,資料庫中的表會越來越多,表中的資料量也會越來越大,相應地,資料操作的開銷也會越來越大;另外,無論怎樣升級硬體資源,單臺伺服器的資源(CPU、磁碟、記憶體、網路IO、事務數、連線數)總是有限的,最終資料庫所能承載的資料量、資料處理能力都將遭遇瓶頸。分表、分庫和讀寫分離可以有效地減小單臺數據庫的壓力。
分庫分表的原理和實現
1.什麼是分割槽、分表、分庫
分割槽
就是把一張表的資料分成N個區塊,在邏輯上看最終只是一張表,但底層是由N個物理區塊組成的,分割槽實現比較簡單,資料庫mysql、oracle等很容易就可支援。
分表
就是把一張表按一定的規則分解成N個具有獨立儲存空間的實體表。系統讀寫時需要根據定義好的規則得到對應的字表明,然後操作它。
分庫
一旦分表,一個庫中的表會越來越多
將整個資料庫比作圖書館,一張表就是一本書。當要在一本書中查詢某項內容時,如果不分章節,查詢的效率將會下降。而同理,在資料庫中就是分割槽。
2.什麼時候考慮使用分割槽?
一張表的查詢速度已經慢到影響使用的時候。
-
sql經過優化
-
資料量大
-
表中的資料是分段的
-
對資料的操作往往只涉及一部分資料,而不是所有的資料
分割槽解決的問題
主要可以提升查詢效率
分割槽的實現方式(簡單),例如:
mysql5 開始支援分割槽功能
CREATE TABLE sales (
id INT AUTO_INCREMENT,
amount DOUBLE NOT NULL,
order_day DATETIME NOT NULL,
PRIMARY KEY(id, order_day)
) ENGINE=Innodb
PARTITION BY RANGE(YEAR(order_day)) (
PARTITION p_2010 VALUES LESS THAN (2010),
PARTITION p_2011 VALUES LESS THAN (2011),
PARTITION p_2012 VALUES LESS THAN (2012),
PARTITION p_catchall VALUES LESS THAN MAXVALUE);
3.什麼時候考慮分表?
-
一張表的查詢速度已經慢到影響使用的時候。
-
sql經過優化
-
資料量大
-
當頻繁插入或者聯合查詢時,速度變慢
4.分表解決的問題
分表後,單表的併發能力提高了,磁碟I/O效能也提高了,寫操作效率提高了
-
查詢一次的時間短了
-
資料分佈在不同的檔案,磁碟I/O效能提高
-
讀寫鎖影響的資料量變小
-
插入資料庫需要重新建立索引的資料減少
5.分表的實現方式(複雜)
需要業務系統配合遷移升級,工作量較大。
6.常見分表、分庫常用策略:
1.平均進行分配hash(object)%N(適用於簡單架構)。
2.按照權重進行分配且均勻輪詢。
3.按照業務進行分配。
4.按照一致性hash演算法進行分配(適用於叢集架構,在叢集中節點的新增和刪除不會造成資料丟失,方便資料遷移)。
7.分庫分表中介軟體
分表又分為單庫分表(表名不同)和多庫分表(表名相同),不管使用哪種策略都還需要自己去實現路由,制定路由規則等,可以考慮使用開源的分庫分表中介軟體,無侵入應用設計,例如淘寶的tddl等。
分庫分表中介軟體介紹
Cobar:
阿里巴巴B2B開發的關係型分散式系統,管理將近3000個MySQL例項。 在阿里經受住了考驗,後面由於作者的走開的原因cobar沒有人維護 了,阿里也開發了tddl替代cobar。
MyCAT:
社群愛好者在阿里cobar基礎上進行二次開發,解決了cobar當時存 在的一些問題,並且加入了許多新的功能在其中。目前MyCAT社群活 躍度很高,目前已經有一些公司在使用MyCAT。總體來說支援度比 較高,也會一直維護下去,發展到目前的版本,已經不是一個單純的MySQL代理了,它的後端可以支援MySQL, SQL Server, Oracle, DB2, PostgreSQL等主流資料庫,也支援MongoDB這種新型NoSQL方式的儲存,未來還會支援更多型別的儲存。MyCAT是一個強大的資料庫中介軟體,不僅僅可以用作讀寫分離,以及分表分庫、容災管理,而且可以用於多租戶應用開發、雲平臺基礎設施,讓你的架構具備很強的適應性和靈活性,藉助於即將釋出的MyCAT只能優化模組,系統的資料訪問瓶頸和熱點一目瞭然,根據這些統計分析資料,你可以自動或手工調整後端儲存,將不同的表隱射到不同儲存引擎上,而整個應用的程式碼一行也不用改變。MyCAT是在Cobar基礎上發展的版本,兩個顯著提高:後端由BIO改為NIO,併發量有大幅提高; 增加了對Order By, Group By, Limit等聚合功能(雖然Cobar也可以支援Order By, Group By, Limit語法,但是結果沒有進行聚合,只是簡單返回給前端,聚合功能還是需要業務系統自己完成)
sharding-JDBC:
噹噹應用框架ddframe中,從關係型資料庫模組dd-rdb中分離出來的資料庫水平分片框架,實現透明化資料庫分庫分表訪問。Sharding-JDBC是繼dubbox和elastic-job之後,ddframe系列開源的第3個專案。Sharding-JDBC直接封裝JDBC API,可以理解為增強版的JDBC驅動,舊程式碼遷移成本幾乎為零:
-
可適用於任何基於Java的ORM框架,如JPA、Hibernate、Mybatis、Spring JDBC Template或直接使用JDBC。
-
可基於任何第三方的資料庫連線池,如DBCP、C3P0、 BoneCP、Druid等。
-
理論上可支援任意實現JDBC規範的資料庫。雖然目前僅支援MySQL,但已有支援Oracle、SQLServer等資料庫的計劃。
Sharding-JDBC定位為輕量Java框架,使用客戶端直連資料庫,以jar包形式提供服務,無proxy代理層,無需額外部署,無其他依賴,DBA也無需改變原有的運維方式。Sharding-JDBC分片策略靈活,可支援等號、between、in等多維度分片,也可支援多分片鍵。SQL解析功能完善,支援聚合、分組、排序、limit、or等查詢,並支援Binding Table以及笛卡爾積表查詢。
讀寫分離的原理和實現
1、什麼是讀寫分離
讀寫分離,基本的原理是讓主資料庫處理事務性增、改、刪操作(INSERT、UPDATE、DELETE),而從資料庫處理SELECT查詢操作。資料庫複製被用來把事務性操作導致的變更同步到叢集中的從資料庫。
2、為什麼要讀寫分離呢?
因為資料庫的“寫”(寫10000條資料到oracle可能要3分鐘)操作是比較耗時的。
但是資料庫的“讀”(從oracle讀10000條資料可能只要5秒鐘)。
所以讀寫分離,解決的是,資料庫的寫入,影響了查詢的效率。
3、什麼時候要讀寫分離?
資料庫不一定要讀寫分離,如果程式使用資料庫較多時,而更新少,查詢多的情況下會考慮使用,利用資料庫 主從同步 。可以減少資料庫壓力,提高效能。當然,資料庫也有其它優化方案。memcache 或是 表折分,或是搜尋引擎。都是解決方法。
4.主從複製、讀寫分離的基本設計
在實際的生產環境中,對資料庫的讀和寫都在同一個資料庫伺服器中,是不能滿足實際需求的。無論是在安全性、高可用性還是高併發等各個方面都是完全不能滿足實際需求的。因此,通過主從複製的方式來同步資料,再通過讀寫分離來提升資料庫的併發負載能力。
一臺主、多臺從,主提供寫操作,從提供讀操作。
讀寫分離的實現:
我們只需要實現讀寫分離,主從複製資料一般由資料庫級來實現同步,當然也可以自己去實現同步,只是需要考慮的點比較多。
分庫分表、讀寫分離總結:
1.分割槽
對業務透明,分割槽只不過把存放資料的檔案分成了許多小塊,根據一定的規則把資料檔案(MYD)和索引檔案(MYI)進行了分割,分割槽後的表呢,還是一張表。
2.分表
當資料量大到一定程度的時候,都會導致處理效能的不足,這個時候就沒有辦法了,只能進行分表處理。也就是把資料庫當中資料根據按照分庫原則分到多個數據表當中,這樣,就可以把大表變成多個小表,不同的分表中資料不重複,從而提高處理效率。
3.分庫
分表和分割槽都是基於同一個資料庫裡的資料分離技巧,對資料庫效能有一定提升,但是隨著業務資料量的增加,原來所有的資料都是在一個數據庫上的,網路IO及檔案IO都集中在一個數據庫上的,因此CPU、記憶體、檔案IO、網路IO都可能會成為系統瓶頸。
當業務系統的資料容量接近或超過單臺伺服器的容量、QPS/TPS接近或超過單個數據庫例項的處理極限等此時,往往是採用垂直和水平結合的資料拆分方法,把資料服務和資料儲存分佈到多臺資料庫伺服器上。
4.讀寫分離方案
當資料庫讀遠大於寫,查詢多的情況,就可以考慮主資料負責寫操作,從資料庫負責讀操作,一主多重,從而把資料讀寫分離,最後還可以結合redis等快取來配合分擔資料的讀操作,大大的降低後端資料庫的壓力。
PS:關注360linker公眾號,加入官方社群獲取免費視訊教程、知名單位招聘資訊。交流分享IT圈學習經驗。