分佈式mysql中間件(mycat)

分佈式mysql中間件(mycat)html

 

 

分佈式mysql中間件前端

官方地址:

主站:Mycat-server@github :  https://github.com/MyCATApache/Mycat-Server.git
Mycat-web@github                :  https://github.com/MyCATApache/Mycat-Web.git
Mycat-doc@github                 :  https://github.com/MyCATApache/Mycat-doc.git

Mycat-download@github      :  https://github.com/MyCATApache/Mycat-download.git java

官網                                           : mycat.ionode

qq官方羣:106088787mysql

Mycat權威指南官方下載:http://songwie.com/attached/file/mycat_1.5.2.pdfgit

視頻資料下載:http://pan.baidu.com/s/1i4mgga5程序員

 

一、   MyCAT概述

1.1 背景

隨着傳統的數據庫技術日趨成熟、計算機網絡技術的飛速發展和應用範圍的擴充,數據庫應用已經廣泛創建於計算機網絡之上。這時集中式數據庫系統表現出它的不足:github

(1)集中式處理,勢必形成性能瓶頸;web

(2)應用程序集中在一臺計算機上運行,一旦該計算機發生故障,則整個系統受到影響,可靠性不高;sql

(3)集中式處理引發系統的規模和配置都不夠靈活,系統的可擴充性差。

在這種形勢下,集中式數據庫將向分佈式數據庫發展。

1.2 發展歷程

MyCAT的誕生,要從其前身Amoeba和Cobar提及。

Amoeba(變形蟲)項目,該開源框架於2008開始發佈一款 Amoeba for Mysql軟件。這個軟件致力於MySQL的分佈式數據庫前端代理層,它主要在應用層訪問MySQL的時候充當SQL路由功能,專一於分佈式數據庫代理層(Database Proxy)開發。座落與 Client、DB Server(s)之間,對客戶端透明。具備負載均衡、高可用性、SQL過濾、讀寫分離、可路由相關的到目標數據庫、可併發請求多臺數據庫合併結果。 經過Amoeba你可以完成多數據源的高可用、負載均衡、數據切片的功能,目前Amoeba已在不少企業的生產線上面使用。

阿里巴巴於2012619,正式對外開源的數據庫中間件Cobar,前身是早已經開源的Amoeba,不過其做者陳思儒離職去盛大以後,阿里巴巴內部考慮到Amoeba的穩定性、性能和功能支持,以及其餘因素,從新設立了一個項目組而且更換名稱爲Cobar。Cobar 是由 Alibaba 開源的 MySQL 分佈式處理中間件,它能夠在分佈式的環境下看上去像傳統數據庫同樣提供海量數據服務。

Cobar自誕生之日起, 就受到廣大程序員的追捧,可是自2013年後,幾乎沒有後續更新。在此狀況下,MyCAT應運而生,它基於阿里開源的Cobar產品而研發,Cobar的穩定性、可靠性、優秀的架構和性能,以及衆多成熟的使用案例使得MyCAT一開始就擁有一個很好的起點,站在巨人的肩膀上,MyCAT能看到更遠。目前MyCAT的最新發布版本爲1.3.0.2版本。

1.3 介紹

1.3.1 MyCat的下載方式

能夠經過git或官網下載,地址見首頁。

 

1.3.2 什麼是MyCat?

簡單的說,MyCAT就是:

  • 一個新穎的數據庫中間件產品;
  • 一個完全開源的、面向企業應用開發的「大數據庫集羣」;
  • 支持事務、ACID、能夠替代MySQL的增強版數據庫;
  • 一個能夠視爲「MySQL」集羣的企業級數據庫,用來替代昂貴的Oracle集羣;
  • 一個融合內存緩存技術、Nosql技術、HDFS大數據的新型SQL Server;
  • 結合傳統數據庫和新型分佈式數據倉庫的新一代企業級數據庫產品。

1.3.3 MyCat的目標

MyCAT的目標是:低成本的將現有的單機數據庫和應用平滑遷移到「雲」端,解決數據存儲和業務規模迅速增加狀況下的數據瓶頸問題。

1.3.4 MyCat的關鍵特性

  •         支持 SQL 92標準
        支持Mysql集羣,能夠做爲Proxy使用
        支持JDBC鏈接ORACLE、DB二、SQL Server,將其模擬爲MySQL  Server使用
        支持NoSQL數據庫
        支持galera for mysql集羣,percona-cluster或者mariadb cluster,提供高可用性數據分片集羣
        自動故障切換,高可用性
        支持讀寫分離,支持Mysql雙主多從,以及一主多從的模式
        支持全局表,數據自動分片到多個節點,用於高效表關聯查詢
        支持獨有的基於E-R 關係的分片策略,實現了高效的表關聯查詢
        支持一致性Hash分片,有效解決分片擴容難題
        多平臺支持,部署和實施簡單
        支持Catelet開發,相似數據庫存儲過程,用於跨分片複雜SQL的人工智能編碼實現,143行Demo完成跨分片的兩個表的JION查詢。
        支持NIO與AIO兩種網絡通訊機制,Windows下建議AIO,Linux下目前建議NIO
        支持Mysql存儲過程調用
        以插件方式支持SQL攔截和改寫
        支持自增加主鍵、支持Oracle的Sequence機制

 

1.3.5 MyCat的優點

  • 基於阿里開源的Cobar產品而研發,Cobar的穩定性、可靠性、優秀的架構和性能,以及衆多成熟的使用案例使得MyCAT一開始就擁有一個很好的起點,站在巨人的肩膀上,能看到更遠。
  • 普遍吸收業界優秀的開源項目和創新思路,將其融入到MyCAT的基因中,使得MyCAT在不少方面都領先於目前其餘一些同類的開源項目,甚至超越某些商業產品。
  • MyCAT背後有一隻強大的技術團隊,其參與者都是5年以上資深軟件工程師、架構師、DBA等,優秀的技術團隊保證了MyCAT的產品質量。
  • MyCAT並不依託於任何一個商業公司,所以不像某些開源項目,將一些重要的特性封閉在其商業產品中,使得開源項目成了一個擺設。

1

1.3.6 MyCat的長期路線

 

  • 在支持Mysql的基礎上,後端增長更多的開源數據庫和商業數據庫的支持,包括原生支持PosteSQL、FireBird等開源數據庫,以及經過JDBC等方式間接支持其餘非開源的數據庫如Oracle、DB二、SQL Server等
  • 實現更爲智能的自我調節特性,如自動統計分析SQL,自動建立和調整索引,根據數據表的讀寫頻率,自動優化緩存和備份策略等
  • 實現更全面的監控管理功能
  • 與HDFS集成,提供SQL命令,將數據庫裝入HDFS中並可以快速分析
  • 集成優秀的開源報表工具,使之具有必定的數據分析的能力

 

 

1.4 整體架構

MyCAT的架構以下圖所示:

MyCAT使用MySQL的通信協議模擬成一個MySQL服務器,並創建了完整的Schema(數據庫)、Table (數據表)、User(用戶)的邏輯模型,並將這套邏輯模型映射到後端的存儲節點DataNode(MySQL Instance)上的真實物理庫中,這樣一來,全部能使用MySQL的客戶端以及編程語言都能將MyCAT當成是MySQLServer來使用,沒必要開發新的客戶端協議。

當MyCAT收到一個客戶端發送的SQL請求時,會先對SQL進行語法分析和檢查,分析的結果用於SQL路由,SQL路由策略支持傳統的基於表格的分片字段方式進行分片,也支持獨有的基於數據庫E-R關係的分片策略,對於路由到多個數據節點(DataNode)的SQL,則會對收到的數據集進行「歸併」而後輸出到客戶端。

SQL執行的過程,簡單的說,就是把SQL經過網絡協議發送給後端的真正的數據庫上進行執行,對於MySQL Server來講,是經過MySQL網絡協議發送報文,並解析返回的結果,若SQL不涉及到多個分片節點,則直接返回結果,寫入客戶端的SOCKET流中,這個過程是非阻塞模式(NIO)。

DataNode是MyCAT的邏輯數據節點,映射到後端的某一個物理數據庫的一個Database,爲了作到系統高可用,每一個DataNode能夠配置多個引用地址(DataSource),當主DataSource被檢測爲不可用時,系統會自動切換到下一個可用的DataSource上,這裏的DataSource便可認爲是Mysql的主從服務器的地址。

1.5 邏輯庫

與任何一個傳統的關係型數據庫同樣,MyCAT也提供了「數據庫」的定義,並有用戶受權的功能,下面是MyCAT邏輯庫相關的一些概念:

  • schema:邏輯庫,與MySQL中的Database(數據庫)對應,一個邏輯庫中定義了所包括的Table。
  • table:表,即物理數據庫中存儲的某一張表,與傳統數據庫不一樣,這裏的表格須要聲明其所存儲的邏輯數據節點DataNode,這是經過表格的分片規則定義來實現的,table能夠定義其所屬的「子表(childTable)」,子表的分片依賴於與「父表」的具體分片地址,簡單的說,就是屬於父表裏某一條記錄A的子表的全部記錄都與A存儲在同一個分片上。
  • 分片規則:是一個字段與函數的捆綁定義,根據這個字段的取值來返回所在存儲的分片(DataNode)的序號,每一個表格能夠定義一個分片規則,分片規則能夠靈活擴展,默認提供了基於數字的分片規則,字符串的分片規則等。
  • dataNode: MyCAT的邏輯數據節點,是存放table的具體物理節點,也稱之爲分片節點,經過DataSource來關聯到後端某個具體數據庫上,通常來講,爲了高可用性,每一個DataNode都設置兩個DataSource,一主一從,當主節點宕機,系統自動切換到從節點。
  • dataHost:定義某個物理庫的訪問地址,用於捆綁到dataNode上。

 MyCAT目前經過配置文件的方式來定義邏輯庫和相關配置:

  • MYCAT_HOME/conf/schema.xml中定義邏輯庫,表、分片節點等內容;
  • MYCAT_HOME/conf/rule.xml中定義分片規則;
  • MYCAT_HOME/conf/server.xml中定義用戶以及系統相關變量,如端口等。下圖給出了MyCAT 一個可能的邏輯庫到物理庫(MySQL的完整映射關係),能夠看出其強大的分片能力以及靈活的Mysql集羣整合能力。           

二、   基本使用教程

2.1 下載和安裝

         MyCAT使用Java開發,由於用到了JDK 7的部分功能,因此在使用前請確保安裝了JDK 7.0,並設置了正確的Java環境變量(可在命令行窗口輸入:「java –version」獲知是否安裝成功,以及獲取JDK的版本)。  

 

         安裝完成後,須要添加MYCAT_HOME環境變量,值對應MyCAT安裝的根目錄。

目錄說明見下表所示:

 

--bin  啓動目錄
--conf 配置文件存放配置文件:
      --server.xml:是Mycat服務器參數調整和用戶受權的配置文件。
      --schema.xml:是邏輯庫定義和表以及分片定義的配置文件。
      --rule.xml:  是分片規則的配置文件,分片規則的具體一些參數信息單獨存放爲文件,也在這個目錄下,配置文件修改須要重啓MyCAT。
      --log4j.xml: 日誌存放在logs/log中,天天一個文件,日誌的配置是在conf/log4j.xml中,根據本身的須要能夠調整輸出級別爲debug                           debug級別下,會輸出更多的信息,方便排查問題。
      --autopartition-long.txt,partition-hash-int.txt,sequence_conf.properties,
                    sequence_db_conf.properties 分片相關的id分片規則配置文件
      --lib	    MyCAT自身的jar包或依賴的jar包的存放目錄。
      --logs        MyCAT日誌的存放目錄。日誌存放在logs/log中,天天一個文件

 

下面圖簡單描述了最重要的3大配置文件的關係:

 

 

2.2 啓動和中止

         啓動前,通常須要修改JVM配置參數,打開conf/wrapper.conf文件,以下行的內容爲2G和2048,可根據本機配置狀況修改成512M或其它值。

wrapper.java.additional.5=-XX:MaxDirectMemorySize=512M
wrapper.java.additional.6=-Dcom.sun.management.jmxremote
wrapper.java.additional.7=-Dcom.sun.management.jmxremote.port=1984
wrapper.java.additional.8=-Dcom.sun.management.jmxremote.authenticate=false
wrapper.java.additional.9=-Dcom.sun.management.jmxremote.ssl=false

# Initial Java Heap Size (in MB)
#wrapper.java.initmemory=3
wrapper.java.initmemory=512

# Maximum Java Heap Size (in MB)
#wrapper.java.maxmemory=64
wrapper.java.maxmemory=512

     在命令行窗口中進入MyCAT安裝解壓文件下的bin目錄,輸入以下命令可安裝(可選)、啓動和中止MyCAT,參考結果以下所示:

 

./mycat start 啓動
./mycat stop 中止
./mycat console 前臺運行
./mycat install 添加到系統自動啓動(暫未實現)
./mycat remove 取消隨系統自動啓動(暫未實現)
./mycat restart 重啓服務
./mycat pause 暫停
./mycat status 查看啓動狀態
win下:直接運行startup_nowrap.bat,若是出現閃退,在cmd 命令行運行,查看出錯緣由。 

 

 

2.3 簡單使用教程

2.3.1 安裝MySQL以及客戶端

         安裝MySQL服務器和MySQL客戶端,筆者使用的MySQL服務器是免安裝版本:mysql-noinstall-5.1.73-winx64,MySQL客戶端是:Navicat for MySQL,免安裝版本安裝方法請參考:http://blog.csdn.net/q98842674/article/details/12094777,再也不贅述。

2.3.2 建立數據庫和表

         建立user、和pay 兩個個數據庫,並分別創建表結構。

2.3.3 垂直切分

2.3.3.1 垂直切分定義

數據的垂直切分,也能夠稱爲縱向切分。將數據庫想象成由不少個一大塊一大塊的「數據塊」(表)組成,垂直地將這些「數據塊」切開,而後把它們分散到多臺數據庫主機上面。這樣的切分方法就是垂直(縱向)的數據切分。

一個架構設計較好的應用系統,其整體功能確定是由不少個功能模塊所組成的,而每個功能模塊所須要的數據對應到數據庫中就是一個或多個表。而在架構設計中,各個功能模塊相互之間的交互點越統1、越少,系統的耦合度就越低,系統各個模塊的維護性及擴展性也就越好。這樣的系統,實現數據的垂直切分也就越容易。

2.3.3.2 優缺點

垂直切分優勢:

(1)數據庫的拆分簡單明瞭,拆分規則明確;

(2)應用程序模塊清晰明確,整合容易;

(3)數據維護方便易行,容易定位。

垂直切分缺點:

(1)部分表關聯沒法在數據庫級別完成,要在程序中完成;

(2)對於訪問極其頻繁且數據量超大的表仍然存在性能瓶頸,不必定能知足要求;

(3)事務處理相對複雜;

(4)切分達到必定程度以後,擴展性會受到限制;

(5)過分切分可能會帶來系統過於複雜而難以維護。

2.3.3.3 垂直切分實現

在以下的實例中,須要將

編輯MYCAT_HOME/conf/schema.xml文件,修改dataHost和schema對應的鏈接信息,user,pay 垂直切分後的配置以下所示:

 

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/">
    <schema name="user" checkSQLschema="false" sqlMaxLimit="100" dataNode="user" />
    <schema name="pay"  checkSQLschema="false" sqlMaxLimit="100" dataNode="pay" />

    <dataNode name="user" dataHost="host" database="user" />
    <dataNode name="pay" dataHost="host" database="pay" />

    <dataHost name="host" maxCon="1000" minCon="10" balance="0"
       writeType="0" dbType="mysql" dbDriver="native">
       <heartbeat>select 1</heartbeat>
       <!-- can have multi write hosts -->
       <writeHost host="hostM1" url="192.168.0.2:3306" user="root" password="root" />
       <writeHost host="hostM2" url="192.168.0.3:3306" user="root" password="root" />
    </dataHost>
</mycat:schema>

 

 

 

注意:writeHost/readHost中的location,user,password的值須要根據實際的MySQL的鏈接信息進行修改。

查看conf/server.xml文件,該文件是Mycat服務器參數調整和用戶受權的配置文件,默認的MyCat的數據庫鏈接的用戶名/密碼爲mycat/mycat,文件內容參考以下:<?xml version="1.0" encoding="UTF-8"?>

 

<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://org.opencloudb/">
	<system>
		<property name="defaultSqlParser">druidparser</property>

	</system>
	<user name="mycat">
		<property name="password">mycat</property>
		<property name="schemas">user,pay</property>
	</user>

</mycat:server>

 

 

上述文件中的schemas屬性須要配置對應的schema(在schema.xml)中進行配置。

重啓MyCAT,使用MySQL客戶端鏈接MyCAT,須要注意的是,默認數據端口爲8066,管理端口爲9066,在MySQL客戶端鏈接MyCAT時,注意填寫端口爲8066,用戶名/密碼根據server.xml中的配置進行填寫。

         鏈接後可查看後端鏈接的三個數據庫,以下圖所示:

2.3.4 水平分庫

2.3.4.1 水平切分定義

水平切分所指的是經過一系列的切分規則將數據水平分佈到不一樣的DB或table中,在經過相應的DB路由 或者table路由規則找到須要查詢的具體的DB或者table以進行Query操做,好比根據用戶ID將用戶表切分到多臺數據庫上。

將某個訪問極其頻繁的表再按照某個字段的某種規則來分散到多個表之中,每一個表中包含一部分數據。

例如,全部數據都是和用戶關聯的,那麼咱們就能夠根據用戶來進行水平拆分,將不一樣用戶的數據切分到不一樣的數據庫中。

如今互聯網很是火爆的web 2.0類型的網站,基本上大部分數據都可以經過會員用戶信息關聯上,可能不少核心表都很是適合經過會員ID來進行數據的水平切分。而像論壇社區討論系統,就更容易切分了,很是容易按照論壇編號來進行數據的水平切分。切分以後基本上不會出現各個庫之間的交互。

2.3.4.2 優缺點

水平切分的優勢:

    表關聯基本可以在數據庫端所有完成;
    不會存在某些超大型數據量和高負載的表遇到瓶頸的問題;
    應用程序端總體架構改動相對較少;
    事務處理相對簡單;
    只要切分規則可以定義好,基本上較難遇到擴展性限制。
水平切分的缺點:
    切分規則相對更爲複雜,很難抽象出一個可以知足整個數據庫的切分規則;
    後期數據的維護難度有所增長,人爲手工定位數據更困難;
        應用系統各模塊耦合度較高,可能會對後面數據的遷移拆分形成必定的困難。

 

2.3.4.3 水平切分實現

在通常的應用系統中,用戶表及其密切相關的關聯表,可根據「用戶表」(eg:t_user)中的「用戶ID」(user_id)進行水平切分,並基於MyCAT的E-R關係分片策略將其密切相關的表(eg:t_user_class_rel)也分到對應的庫中。

(1)建立庫,表結構

         在建表語句參考以下:

CREATE DATABASE IF NOT EXISTS `mycat_node1`  ;

/**
  user 用戶表
*/ 
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
 `user_id` int(11) NOT NULL COMMENT '用戶ID',
 `receive_address` varchar(256) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '收貨地址',
 `create_time` datetime NOT NULL,
 `province_code` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,
 PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='用戶信息表';
 
 /**
  `t_area` 全局表
*/
CREATE TABLE `t_area` (
 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
 `caller` varchar(16) CHARACTER SET utf8 DEFAULT NULL COMMENT '調用方系統表示',
 `province_code` varchar(10) CHARACTER SET utf8 NOT NULL COMMENT '省份編碼',
 `area_code` varchar(10) CHARACTER SET utf8 NOT NULL COMMENT '區域編碼',
 `area_name` varchar(100) CHARACTER SET utf8 DEFAULT NULL COMMENT '區域名稱',
 `parent_area_code` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '父區域編碼',
 `create_time` datetime NOT NULL COMMENT '建立時間',
 `modify_time` datetime DEFAULT NULL COMMENT '修改時間',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3792 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

 /**
  user 節點測試表
*/ 
 DROP TABLE IF EXISTS `t_node`;
CREATE TABLE `t_node` (
 `vid` int(11) NOT NULL COMMENT 'ID',
 `user_id` int(11) NOT NULL COMMENT '用戶ID',
 `note` varchar(256) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'note',
 `create_time` datetime NOT NULL,
 PRIMARY KEY (`vid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='note表';

 

 

 

(2)配置schema.xml文件

首先配置schema.xml文件,添加mycat_node1數據庫的dataNode設置,並添加t_user和t_area表的schema設置,本次配置了雙主,讀寫分離配置,

同一個表多個分片的配置能夠用dataNode="dn$1-100" 通配方式。

修改後的schema.xml文件內容以下所示:

 

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/">

<schema name="mycat" checkSQLschema="true" sqlMaxLimit="100">
<table name="t_user" primaryKey="user_id" dataNode="dn1,dn2" rule="rule1" />
        <table name="t_node" primaryKey="vid" autoIncrement="true" dataNode="dn1,dn2" rule="rule1" />
<table name="t_area" type="global" primaryKey="ID" dataNode="dn1,dn2" />

</schema>

<dataNode name="dn1" dataHost="jdbchost" database="mycat_node1" />
<dataNode name="dn2" dataHost="jdbchost2" database="mycat_node1" />

<dataHost name="jdbchost" maxCon="500" minCon="10" balance="0"
       writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select 1</heartbeat>
<writeHost host="maste1" url="192.168.0.1:3306" user="root" password="root">
  <!-- <readHost host="readshard" url="192.168.0.2:3306" user="root" password="root"/> -->
</writeHost>
<writeHost host="maste2" url="192.168.0.3:3306" user="root" password="root">
  <!-- <readHost host="readshard" url="192.168.0.4:3306" user="root" password="root"/> -->
</writeHost>

</dataHost>
<!-- -->
<dataHost name="jdbchost2" maxCon="500" minCon="10" balance="0"
       writeType="0" dbType="mysql" dbDriver="native">
<heartbeat>select 1</heartbeat>
<writeHost host="maste1" url="192.168.0.5:3306" user="root" password="root">
  <!-- <readHost host="readshard" url="192.168.0.6:3306" user="root" password="root"/> -->
</writeHost>
<writeHost host="maste2" url="192.168.0.6:3307" user="root" password="root">
  <!-- <readHost host="readshard" url="192.168.0.8:3306" user="root" password="root"/> -->
</writeHost>
</writeHost>
</dataHost>

</mycat:schema>

 

(3)配置rule.xml文件

在schema.xml的文件內容中可看到t_user表指定的分片規則是rule1,須要在conf/rule.xml文件中設置rule1的規則爲根據user_id進行分片,並按照類「org.opencloudb.route.function.PartitionByLong」的規則進行分片。

         該文件的參考內容以下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://org.opencloudb/"> 
 <tableRule name="rule1">
    <rule>
      <columns>user_id</columns>
      <algorithm>func1</algorithm>
    </rule>
 </tableRule>

 <function name="func1" class="org.opencloudb.route.function.PartitionByLong">
    <property name="partitionCount">2</property>
    <property name="partitionLength">512</property>
 </function>
</mycat:rule>

 

(4)配置server.xml文件

         在server.xml文件中的schemas屬性中添加test_mycat的schema。修改後的文件以下所示:

<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://org.opencloudb/">
    <system>
        <property name="sequnceHandlerType">0</property> 
    </system>
    <user name="mycat">
       <property name="password">mycat</property>
       <property name="schemas">mycat</property>
    </user>
</mycat:server>

 

(5)水平切分測試

         重啓MyCAT,使用MySQL客戶端鏈接後,鏈接後可在mycat數據庫下看到t_user和t_area,t_node表,以下圖所示:

         在MySQL客戶端鏈接的MyCat的test_mycat數據庫的t_user表運行以下插入語句,插入2000條數據:

INSERT INTO `t_user` VALUES ('1', '廣州市越秀區廣州大道中599號', '2014-07-17 10:53:15', 'GD');
INSERT INTO `t_user` VALUES ('2', '廣州市越秀區廣州大道中599號', '2014-07-17 10:53:17', 'GD');
INSERT INTO `t_user` VALUES ('3', '廣州市越秀區廣州大道中599號', '2014-07-17 10:53:17', 'GD');
INSERT INTO `t_user` VALUES ('4', '廣州市越秀區廣州大道中599號', '2014-07-17 10:53:17', 'GD');
INSERT INTO `t_user` VALUES ('5', '廣州市越秀區廣州大道中599號', '2014-07-17 10:53:17', 'GD');
……
INSERT INTO `t_user` VALUES (2000, '廣州市越秀區廣州大道中599號', '2014-07-17 10:54:37', 'GD');

2.3.5 讀寫分離

2.3.5.1 讀寫分離定義

爲了確保數據庫產品的穩定性,不少數據庫擁有雙機熱備功能。也就是,第一臺數據庫服務器,是對外提供增刪改查業務的生產服務器;第二臺數據庫服務器,僅僅接收來自第一臺服務器的備份數據。通常來講,爲了配置方便,以及穩定性,這兩臺數據庫服務器,都用的是相同的配置。

在實際運行中,第一臺數據庫服務器的壓力,遠遠大於第二臺數據庫服務器。所以,不少人但願合理利用第二臺數據庫服務器的空閒資源。

從數據庫的基本業務來看,數據庫的操做無非就是增刪改查這4個操做。但對於「增刪改」這三個操做,若是是雙機熱備的環境中作,一臺機器作了這三個操做的某一個以後,須要當即將這個操做,同步到另外一臺服務器上。出於這個緣由,第二臺備用的服務器,就只作了查詢操做。進一步,爲了下降第一臺服務器的壓力,乾脆就把查詢操做所有丟給第二臺數據庫服務器去作,第一臺數據庫服務器就只作增刪改了。

2.3.5.2 優缺點

優勢:合理利用從數據庫服務器的空閒資源。

缺點:原本第二臺數據庫服務器,是用來作熱備的,它就應該在一個壓力很是小的環境下,保證運行的穩定性。而讀寫分離,卻增長了它的壓力,也就增長了不穩定性。所以,讀寫分離,實質上是一個在資金比較缺少,但又須要保證數據安全的需求下,在雙機熱備方案上,作出的一種折中的擴展方案。

2.3.5.3 讀寫分離實現

MyCAT的讀寫分離機制以下:

  • 事務內的SQL,所有走寫節點,除非某個select語句以註釋/*balance*/開頭
  • 自動提交的select語句會走讀節點,並在全部可用讀節點中間隨機負載均衡
  • 當某個主節點宕機,則其所有讀節點都再也不被使用,由於此時,同步失敗,數據已經不是最新的,MyCAT會採用另一個主節點所對應的所有讀節點來實現select負載均衡。
  • 當全部主節點都失敗,則爲了系統高可用性,自動提交的全部select語句仍將提交到所有存活的讀節點上執行,此時系統的不少頁面仍是能出來數據,只是用戶修改或提交會失敗。

例如將本機做爲寫庫,10.18.96.133做爲讀庫,MyCAT的讀寫分離的配置以下:

<dataHost name="testhost" maxCon="1000" minCon="10" balance="1"
       writeType="0" dbType="mysql" dbDriver="native">
       <heartbeat>select user()</heartbeat>
       <!-- can have multi write hosts -->
       <writeHost host="hostM1" url="localhost:3306" user="root" password="">
           <readHost host="hostM2" url="10.18.96.133:3306" user="test" password="test" />
       </writeHost>
</dataHost>

dataHost的balance屬性設置爲:

  • 0,不開啓讀寫分離機制
  • 1,所有的readHost與stand by writeHost參與select語句的負載均衡,簡單的說,當雙主雙從模式(M1->S1,M2->S2,而且M1與 M2互爲主備),正常狀況下,M2,S1,S2都參與select語句的負載均衡。
  • 2,全部的readHost與writeHost都參與select語句的負載均衡,也就是說,當系統的寫操做壓力不大的狀況下,全部主機均可以承擔負載均衡。

一個dataHost元素,代表進行了數據同步的一組數據庫,DBA須要保證這一組數據庫服務器是進行了數據同步複製的。writeHost至關於Master DB Server,而其下的readHost則是與從數據庫同步的Slave DB Server。當dataHost配置了多個writeHost的時候,任何一個writeHost宕機,Mycat 都會自動檢測出來,並嘗試切換到下一個可用的writeHost。

在沒有配置數據同步複製的狀況下,重啓後進行測試,可以使用MySQL客戶端直接鏈接讀庫,插入幾條數據後,使用MySQL客戶端鏈接MyCat,運行select語句驗證是否在讀庫上執行。

多主,多讀寫分離參考:

其中分爲dn1,dn2兩個分片,每一個分片有兩個寫入,寫入之間開啓mysql開啓2進制複製,mycat會從當前可用的寫入host隨機獲取一個寫入,mycat在任什麼時候候   只會單點寫入。若是要開啓讀寫分離在放開註釋read配置,balance=1或2。

writeType=1 表明全部節點都是寫入寫入,慎重開啓,多節點寫入順序爲默認寫入根據配置順序,第一個掛掉切換另外一個。

 

 

2.3.6 全局表

2.3.6.1 全局表定義

一個真實的業務系統中,每每存在大量的相似字典表的表格,它們與業務表之間可能有關係,這種關係,能夠理解爲「標籤」,而不該理解爲一般的「主從關係」,這些表基本上不多變更,能夠根據主鍵ID進行緩存,下面這張圖說明了一個典型的「標籤關係」圖:

 

         在分片的狀況下,當業務表由於規模而進行分片之後,業務表與這些附屬的字典表之間的關聯,就成了比較棘手的問題,考慮到字典表具備如下幾個特性:

  • 變更不頻繁;
  • 數據量整體變化不大;
  • 數據規模不大,不多有超過數十萬條記錄。

鑑於此,MyCAT定義了一種特殊的表,稱之爲「全局表」,全局表具備如下特性:

  • 全局表的插入、更新操做會實時在全部節點上執行,保持各個分片的數據一致性
  • 全局表的查詢操做,只從一個節點獲取
  • 全局表能夠跟任何一個表進行JOIN操做

將字典表或者符合字典表特性的一些表定義爲全局表,則從另一個方面,很好的解決了數據JOIN的難題。經過全局表+基於E-R關係的分片策略,MyCAT能夠知足80%以上的企業應用開發。

2.3.6.2 全局表實現

(1)建立表結構

         在各個庫分別建立全局表(例如:t_area)的表結構,表結構保持一致,例如:

DROP TABLE IF EXISTS `t_area`;
CREATE TABLE `t_area` (
 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
 `caller` varchar(16) CHARACTER SET utf8 DEFAULT NULL COMMENT '調用方系統表示',
 `province_code` varchar(10) CHARACTER SET utf8 NOT NULL COMMENT '省份編碼',
 `area_code` varchar(10) CHARACTER SET utf8 NOT NULL COMMENT '區域編碼',
 `area_name` varchar(100) CHARACTER SET utf8 DEFAULT NULL COMMENT '區域名稱',
 `parent_area_code` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '父區域編碼',
 `create_time` datetime NOT NULL COMMENT '建立時間',
 `modify_time` datetime DEFAULT NULL COMMENT '修改時間',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3792 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

 

(2)配置schema.xml

全局表配置比較簡單,不用寫Rule規則,在schema.xml中修改test_schema,添加t_area的table子元素,參考以下配置便可:

<schema name="test_mycat" checkSQLschema="false" sqlMaxLimit="100">
       <!-- auto sharding by id (long) -->
       <table name="t_user" dataNode="dn1,dn2" rule="rule1">
           <childTable name="t_user_class_rel" primaryKey="id" joinKey="user_id" parentKey="user_id" />
       </table>
       <table name="t_area" primaryKey="id" type="global" dataNode="dn1,dn2" />
</schema>

 

(3)全局表測試

         運行以下insert語句,往test_mycat的t_area表插入10條數據,以下所示:

INSERT INTO `t_area` VALUES ('100', 'test', 'ZX', '1', '全國', '0', '2012-09-25 08:30:23', null);
INSERT INTO `t_area` VALUES ('101', 'test', 'BJ', '110000', '北京市', '1', '2012-09-25 08:30:23', null);
INSERT INTO `t_area` VALUES ('102', 'test', 'BJ', '110100', '市轄區', '110000', '2012-09-25 08:30:23', null);
INSERT INTO `t_area` VALUES ('103', 'test', 'BJ', '110101', '東城區', '110100', '2012-09-25 08:30:23', null);
INSERT INTO `t_area` VALUES ('104', 'test', 'BJ', '110102', '西城區', '110100', '2012-09-25 08:30:23', null);
INSERT INTO `t_area` VALUES ('105', 'test', 'BJ', '110103', '崇文區', '110100', '2012-09-25 08:30:23', null);
INSERT INTO `t_area` VALUES ('106', 'test', 'BJ', '110104', '宣武區', '110100', '2012-09-25 08:30:23', null);
INSERT INTO `t_area` VALUES ('107', 'test', 'BJ', '110105', '朝陽區', '110100', '2012-09-25 08:30:23', null);
INSERT INTO `t_area` VALUES ('108', 'test', 'BJ', '110106', '豐臺區', '110100', '2012-09-25 08:30:23', null);
INSERT INTO `t_area` VALUES ('109', 'test', 'BJ', '110107', '石景山區', '110100', '2012-09-25 08:30:23', null);

插入後去dn1,dn2分片中查找,可看到這2個分片中的t_area表都被插入10條數據。執行select語句能返回t_area表的對應記錄,執行update和delete語句能對應對全局表相關的分片中的記錄進行更新和刪除操做。

三、   參考文檔

《MyCat inAction中文版》

 

 

 

 

 

四、   地址

主站:Mycat-server@github :  https://github.com/MyCATApache/Mycat-Server.git
Mycat-web@github              :  https://github.com/MyCATApache/Mycat-Web.git
Mycat-doc@github               :  https://github.com/MyCATApache/Mycat-doc.git
Mycat-download@github     :  https://github.com/MyCATApache/Mycat-download.git 

qq官方羣:106088787

相關文章
相關標籤/搜索