目錄
一、數據庫性能瓶頸及其解決方案
性能瓶頸
- 數據庫連接數達到機器性能的瓶頸
- 表數據量過大,有些查詢命中不了索引從而導致全表掃描
- 硬件資源本身的QPS(每秒的查詢請求個數)和TPS(每秒的事務請求個數)的瓶頸
解決方案
- sql優化(避免多次查詢,利用好索引)
- 緩存(redis,es)
- 建好索引(根據查詢實際需求來建立索引)
- 讀寫分離
區別讀、寫多數據源方式進行數據的存儲和加載。數據的存儲(增刪改)一般指定寫數據源,數據的讀取查詢指定讀數據源(讀寫分離會基於主從複製)
解決的問題:
1. 解決了數據庫連接瓶頸
2. 釋放了硬件資源限制(QPS\TPS) - 分庫分表
對數據的庫表進行拆分,用分片的方式對數據進行管理
1. 垂直拆分
解決問題
(1)解決了數據庫連接瓶頸
(2)釋放了硬件資源限制(QPS\TPS)
2. 水平拆分
解決問題
(1)表數據量大的問題 存儲空間也解決了
(2)解決了數據庫連接瓶頸
(3)釋放了硬件資源限制(QPS\TPS)
二、MyCat的名詞概念
邏輯庫
對實際應用來說,並不需要知道中間件的存在,業務開發人員只需要知道數據庫的概念,所以數據庫中間件可以被看做是一個或多個數據庫集羣構成的邏輯庫。如圖一中,在MYCAT服務區中的db_user庫,只是邏輯上存在的數據庫,真正的數據來源還是來源MYSQL服務區中的兩臺實際的Mysql db實例。在Mycat中邏輯庫在{MYCAT_HOME}/conf/schema.xml 用<schema> 標籤定義。
邏輯表
既然有邏輯庫,肯定將會存在邏輯表,分佈式數據庫中,對應用來說,讀寫數據的表就是邏輯表。邏輯表的數據來源,可以是數據進行切分後,分佈在一個或多個分片庫中,針對不同的數據分佈和管理特點,我們將邏輯表又分爲 分片表、全局表、ER表、非分片表。在schema.xml使用<table>標籤對邏輯表進行定義。
分片表
是指那些原有的很大數據的表,需要切分到多個表,這樣,每個分片都有表的一部分數據,所有分片數據的合集構成了完整的表數據,如圖一種中MYCAT服務區的users表即是分片表,通過userID字段取模的方式進行數據的水平切分。如圖中用戶(users)表
分片規則
將大數據的表,切分到多個數據分片的策略。如圖中 rule="mod-userID-long",名字爲mod-userID-long引用的詳細規則,將在MYCAT的rule.xml中({MYCAT_HOME}/conf/rule.xml)中進行定義,具體定義規則如圖
分片規則Mycat中內置了很多種,比如 按時間、按自定義數字範圍、十進制取模、程序指定,字符串Hash,一致性Hash等等,總體可將這些分片規則分爲離散型和連續型兩種分片規則。離散型分片規則數據分佈均衡,對數據的處理併發能力強,但是對於分片的擴縮容存在較大的挑戰。連續性分片數據分佈較集中,更符合業務特性,但是對數據的處理併發能力受限數據的分佈,分片的擴縮容有更好的支持。
全局表
一個真實的業務系統中,往往存在大量的類似數據字典表的表,數據字典表具有以下幾個特性:
- 數據變動不頻繁
- 數據規模不大,數據量在十萬以內
- 存在跟其他表(特別是分片表)有一點的關聯查詢要求
未了解決表與表的join查詢,Mycat提倡大家將具有上訴特點的表通過數據冗餘的方式(全局表的定義)進行解決,即所有的分片都有一份數據的拷貝。通過MYCAT對這樣的表進行數據的操作時,數據的修改,新增,刪除時,所有的分片數據都將受到影響。
ER表
關係型數據庫是基於實體關係模型(Entity-Relationship Model)之上,通過其描述了真實世界中事物與關係,Mycat 中的 ER 表即是來源於此。根據這一思路,提出了基於 E-R 關係的數據分片策略,子表的記錄與所關聯的父表記錄存放在同一個數據分片上,即子表依賴於父表,通過表分組(Table Group)保證數據 Join 不會跨庫操作,如文中的案例,用戶表是分片表,用戶地址表與用戶表之間存在一對多的關係,若通過分片規則,將用戶表中的張三分在了分片1,則最好的數據存儲方式是將張三的用戶地址信息跟隨張三一起分配在分片1中。這樣一種表分組的設計方式是解決跨分片數據 join 的一種很好的思路,也是數據切分規劃的重要一條規則。ER表中在schema.xml中使用<childTable>標籤進行描述和定義,如圖
非分片表
一個數據庫中並不是所有的表都很大,某些表是可以不用進行切分的,非分片是相對分片表來說的,就是那些不需要進行數據切分的表。在schema.xml中具體的定義,可參見圖
分片節點
大數據表進行數據切分後,每個表分片所在的數據庫就是分片節點,狹義的理解可以認爲一個DB實例就是一個節點,在schema.xml中使用<dataNode>進行分片節點的定義如圖
節點主機
數據切分後,每個分片節點(dataNode)不一定都會獨佔一臺機器,同一機器上面可以有多個分片數據庫,這樣一個或多個分片節點(dataNode)所在的機器就是節點主機,爲了規避單節點主機併發數限制,儘量將讀寫壓力高的分片節點(dataNode)均衡的放在不同的節點主機。在schema.xml中使用<dataHost>進行分片節點的定義如圖
三、MySQL的主從複製
就是一種主備模式的數據庫應用,主庫(master)數據與備庫(slave)數據完全一致,實現數據的多重備份,保證數據的安全。
MySQL主從複製原理
- 從庫生成兩個線程,一個I/O線程,一個SQL線程;
- i/o線程去請求主庫 的binlog,並將得到的binlog日誌寫到relay log(中繼日誌) 文件中;
- 主庫會生成一個 log dump 線程,用來給從庫 i/o線程傳binlog;
- SQL 線程,會讀取relay log文件中的日誌,並解析成具體操作,來實現主從的操作一致,而最終數據一致;
四、MyCat的應用場景分析
應用場景1:MyCat讀寫分離(負載均衡)、主從自動切換
目前有大量MyCat的生產實踐案例是屬於簡單的讀寫分離類型的,大多數讀寫分離的案例是同時支持高可用性的,即MyCat+MySQL主從複製的集羣,並開啓MyCat的讀寫分離功能,這種場景需求下,MyCat是最爲簡單並且功能最爲豐富的一類Proxy,正常情況下,配置文件也最爲簡單。
需要注意的是:
主從複製是mysql自己實現的,mycat只是代理插件,它本身不能實現主從複製,只能實現了讀寫分離、主從切換、分庫分表功能
具體的相關配置流程參考:https://www.cnblogs.com/kevingrace/p/9365840.html
應用場景2:MyCat分庫分表
MyCat分表分庫原理
MyCat裏面通過定義路由規則來實現分片表(路由規則裏面會定義分片字段,以及分片算法)。分片算法有多種,你所說的hash是其中一種,還有取模、按範圍分片等等。在MyCat裏面,會對所有傳遞的sql語句做路由處理(路由處理的依據就是表是否分片,如果分片,那麼需要依據分片字段和對應的分片算法來判斷sql應該傳遞到哪一個、或者哪幾個、又或者全部節點去執行)
MyCat分片選擇總結
- 根據業務數據的特性合理選擇分片規則
- 善用全局表、ER關係表解決join操作
- 用好primaryKey讓你的性能起飛
MyCat適用於哪些場景
數據量大到單機hold不住,而又不希望調整架構切換爲NoSQL數據庫,這個場景下可以考慮適用MyCat。當然,使用前也應該做規劃,哪些表需要分片等等。另外MyCat對跨庫join的支持不是很好,在使用MyCat的時候要注意規避這種場景
MyCat聯表查詢問題
- 用好ER表
- 善用全局表
- 使用註解
/*!mycat:catlet=io.mycat.catlets.ShareJoin */
select * from users u,employee em on u.phoneNum=em.phoneNum where u.phoneNum ='12345456454';
具體的相關配置流程參考:https://www.cnblogs.com/kevingrace/p/9365840.html