MyCat簡介

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表示時間戳方式。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章