Mycat簡介
1.功能介紹
Mycat是什麼?從定義和分類來看,它是一個開源的分佈式數據庫系統,是一個實現了MySQL協議的的Server,前端用戶可以把它看作是一個數據庫代理,用MySQL客戶端工具和命令行訪問,而其後端可以用MySQL原生(Native)協議與多個MySQL服務器通信,也可以用JDBC協議與大多數主流數據庫服務器通信,其核心功能是分表分庫,即將一個大表水平分割爲N個小表,存儲在後端MySQL服務器裏或者其他數據庫裏。
2.Mycat原理
Mycat的原理中最重要的一個動詞是“攔截”,它攔截了用戶發送過來的SQL語句,首先對SQL語句做了一些特定的分析:如分
片分析、路由分析、讀寫分離分析、緩存分析等,然後將此SQL發往後端的真實數據庫,並將返回的結果做適當的處理,最終再
返回給用戶。
3.應用場景
- 單純的讀寫分離,此時配置最爲簡單,支持讀寫分離,主從切換
- 分表分庫,對於超過1000萬的表進行分片,最大支持1000億的單表分片
- 多租戶應用,每個應用一個庫,但應用程序只連接Mycat,從而不改造程序本身,實現多租戶化
- 報表系統,藉助於Mycat的分表能力,處理大規模報表的統計
- 替代Hbase,分析大數據
- 作爲海量數據實時查詢的一種簡單有效方案,比如100億條頻繁查詢的記錄需要在3秒內查詢出來結果,除了基於主鍵的查詢,還可能存在範圍查詢或其他屬性查詢,此時Mycat可能是最簡單有效的選擇
數據分片
1.垂直切分
一個數據庫由很多表的構成,每個表對應着不同的業務,垂直切分是指按照業務將表進行分類,分佈到不同的數據庫上面,這樣也就將數據或者說壓力分擔到不同的庫上面
優點
- 拆分後業務清晰,拆分規則明確。
- 系統之間整合或擴展容易。
- 數據維護簡單
缺點
- 部分業務表無法join,只能通過接口方式解決,提高了系統複雜度。
- 受每種業務不同的限制存在單庫性能瓶頸,不易數據擴展跟性能提高。
- 事務處理複雜
- 由於垂直切分是按照業務的分類將表分散到不同的庫,所以有些業務表會過於龐大,存在單庫讀寫與存儲瓶頸,所以就需要水平拆分來做解決
2.水平切分
相對於垂直拆分,水平拆分不是將表做分類,而是按照某個字段的某種規則來分散到多個庫之中,每個表中包含一部分數據。簡
單來說,我們可以將數據的水平切分理解爲是按照數據行的切分,就是將表中的某些行切分到一個數據庫,而另外的某些行又切
分到其他的數據庫中
優點
- 拆分規則抽象好,join操作基本可以數據庫做。
- 不存在單庫大數據,高併發的性能瓶頸。
- 應用端改造較少。
- 提高了系統的穩定性跟負載能力
缺點
- 拆分規則難以抽象。
- 分片事務一致性難以解決。
- 數據多次擴展難度跟維護量極大。
- 跨庫join性能較差
3.數據切分的原則
- 第一原則:能不切分儘量不要切分。
- 第二原則:如果要切分一定要選擇合適的切分規則,提前規劃好。
- 第三原則:數據切分儘量通過數據冗餘或表分組(Table Group)來降低跨庫Join的可能。
- 第四原則:由於數據庫中間件對數據Join實現的優劣難以把握,而且實現高性能難度極大,業務讀取儘量少使用多表Join。
Mycat中的基本概念
1.邏輯庫
前面一節講了數據庫中間件,通常對實際應用來說,並不需要知道中間件的存在,業務開發人員只需要知道數據庫的概念,所以
數據庫中間件可以被看做是一個或多個數據庫集羣構成的邏輯庫
<dataNode name="order_db" dataHost="mysql124" database="order_db"/>
2.邏輯表
2.1邏輯表
既然有邏輯庫,那麼就會有邏輯表,分佈式數據庫中,對應用來說,讀寫數據的表就是邏輯表。邏輯表,可以是數據切分後,分佈在一個或多個分片庫中,也可以不做數據切分,不分片,只有一個表構成。
<table name="order_customer_addr" dataNode="order_db"primaryKey="customer_addr_id"/>
2.2分片表
分片表,是指那些原有的很大數據的表,需要切分到多個數據庫的表,這樣,每個分片都有一部分數據,所有分片構成了完整的
數據。
<table name="order_master" dataNode="orderdb01,orderdb02,orderdb03,orderdb04" rule="order_master" primaryKey="order_id" autoIncrement="true"></table>
2.3 非分片表
一個數據庫中並不是所有的表都很大,某些表是可以不用進行切分的,非分片是相對分片表來說的,就是那些不需要進行數據切分的表
<table name="shipping_info" dataNode="order_db" primaryKey="ship_id"/>
2.4 ER表
關係型數據庫是基於實體關係模型(Entity-RelationshipModel)之上,通過其描述了真實世界中事物與關係,Mycat中的ER表即是來源於此。根據這一思路,提出了基於E-R關係的數據分片策略,子表的記錄與所關聯的父表記錄存放在同一個數據分片上,即子表依賴於父表,通過表分組(TableGroup)保證數據Join不會跨庫操作。
<table name="order_master" dataNode="orderdb01,orderdb02,orderdb03,orderdb04" rule="order_master" primaryKey="order_id" autoIncrement="true">
<childTable name="order_detail" joinKey="order_id" parentKey="order_id" primaryKey="order_detail_id" autoIncrement="true"/>
</table>
2.5全局表
一個真實的業務系統中,往往存在大量的類似字典表的表,這些表基本上很少變動
全局表特性
- 變動不頻繁
- 數據量總體變化不大
- 數據規模不大,很少有超過數十萬條記錄
<table name="region_info" dataNode="order_db,product_db,customer_db" primaryKey="region_id" type="global"/>
2.6 分片節點
數據切分後,一個大表被分到不同的分片數據庫上面,每個表分片所在的數據庫就是分片節點(dataNode)。
<dataNode name="orderdb04" dataHost="mysql125" database="orderdb04"/>
2.7 節點主機
數據切分後,每個分片節點(dataNode)不一定都會獨佔一臺機器,同一機器上面可以有多個分片數據庫,這樣一個或多個分片節點(dataNode)所在的機器就是節點主機(dataHost),爲了規避單節點主機併發數限制,儘量將讀寫壓力高的分片節點(dataNode)均衡的放在不同的節點主機(dataHost).
<dataHost balance="3" maxCon="1000" minCon="10" name="mysql123" writeType="0" switchType="1" dbType="mysql" dbDriver="native">
<heartbeat>select user()</heartbeat>
<writeHost host="192.168.56.123" url="192.168.56.123:3306" password="123456" user="im_mycat"/>
</dataHost>
2.8 分片規則
前面講了數據切分,一個大表被分成若干個分片表,就需要一定的規則,這樣按照某種業務規則把數據分到某個分片的規則就是
分片規則,數據切分選擇合適的分片規則非常重要,將極大的避免後續數據處理的難度。
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
<tableRule name="order_master">
<rule>
<columns>customer_id</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<property name="count">4</property>
</function>
</mycat:rule>
2.9 全局序列
數據切分後,原有的關係數據庫中的主鍵約束在分佈式條件下將無法使用,因此需要引入外部機制保證數據唯一性標識,這種保證全局性的數據唯一標識的機制就是全局序列號(sequence)
<property name="sequnceHandlerType">0</property>
# sequnceHandlerType 配置爲0 表示使用本地文件讀取。
<property name="sequnceHandlerType">1</property>
# sequnceHandlerType 配置爲1 表示從數據庫表中讀取。
<property name="sequnceHandlerType">2</property>
# sequnceHandlerType 配置爲2表示時間戳方式。