分佈式mysql中間件(mycat)html
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程序員
隨着傳統的數據庫技術日趨成熟、計算機網絡技術的飛速發展和應用範圍的擴充,數據庫應用已經廣泛創建於計算機網絡之上。這時集中式數據庫系統表現出它的不足:github
(1)集中式處理,勢必形成性能瓶頸;web
(2)應用程序集中在一臺計算機上運行,一旦該計算機發生故障,則整個系統受到影響,可靠性不高;sql
(3)集中式處理引發系統的規模和配置都不夠靈活,系統的可擴充性差。
在這種形勢下,集中式數據庫將向分佈式數據庫發展。
MyCAT的誕生,要從其前身Amoeba和Cobar提及。
Amoeba(變形蟲)項目,該開源框架於2008年開始發佈一款 Amoeba for Mysql軟件。這個軟件致力於MySQL的分佈式數據庫前端代理層,它主要在應用層訪問MySQL的時候充當SQL路由功能,專一於分佈式數據庫代理層(Database Proxy)開發。座落與 Client、DB Server(s)之間,對客戶端透明。具備負載均衡、高可用性、SQL過濾、讀寫分離、可路由相關的到目標數據庫、可併發請求多臺數據庫合併結果。 經過Amoeba你可以完成多數據源的高可用、負載均衡、數據切片的功能,目前Amoeba已在不少企業的生產線上面使用。
阿里巴巴於2012年6月19日,正式對外開源的數據庫中間件Cobar,前身是早已經開源的Amoeba,不過其做者陳思儒離職去盛大以後,阿里巴巴內部考慮到Amoeba的穩定性、性能和功能支持,以及其餘因素,從新設立了一個項目組而且更換名稱爲Cobar。Cobar 是由 Alibaba 開源的 MySQL 分佈式處理中間件,它能夠在分佈式的環境下看上去像傳統數據庫同樣提供海量數據服務。
Cobar自誕生之日起, 就受到廣大程序員的追捧,可是自2013年後,幾乎沒有後續更新。在此狀況下,MyCAT應運而生,它基於阿里開源的Cobar產品而研發,Cobar的穩定性、可靠性、優秀的架構和性能,以及衆多成熟的使用案例使得MyCAT一開始就擁有一個很好的起點,站在巨人的肩膀上,MyCAT能看到更遠。目前MyCAT的最新發布版本爲1.3.0.2版本。
能夠經過git或官網下載,地址見首頁。
簡單的說,MyCAT就是:
MyCAT的目標是:低成本的將現有的單機數據庫和應用平滑遷移到「雲」端,解決數據存儲和業務規模迅速增加狀況下的數據瓶頸問題。
1
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的主從服務器的地址。
與任何一個傳統的關係型數據庫同樣,MyCAT也提供了「數據庫」的定義,並有用戶受權的功能,下面是MyCAT邏輯庫相關的一些概念:
MyCAT目前經過配置文件的方式來定義邏輯庫和相關配置:
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大配置文件的關係:
啓動前,通常須要修改JVM配置參數,打開conf/wrapper.conf文件,以下行的內容爲2G和2048,可根據本機配置狀況修改成512M或其它值。
在命令行窗口中進入MyCAT安裝解壓文件下的bin目錄,輸入以下命令可安裝(可選)、啓動和中止MyCAT,參考結果以下所示:
./mycat start 啓動 ./mycat stop 中止 ./mycat console 前臺運行 ./mycat install 添加到系統自動啓動(暫未實現) ./mycat remove 取消隨系統自動啓動(暫未實現) ./mycat restart 重啓服務 ./mycat pause 暫停 ./mycat status 查看啓動狀態
win下:直接運行startup_nowrap.bat,若是出現閃退,在cmd 命令行運行,查看出錯緣由。
安裝MySQL服務器和MySQL客戶端,筆者使用的MySQL服務器是免安裝版本:mysql-noinstall-5.1.73-winx64,MySQL客戶端是:Navicat for MySQL,免安裝版本安裝方法請參考:http://blog.csdn.net/q98842674/article/details/12094777,再也不贅述。
建立user、和pay 兩個個數據庫,並分別創建表結構。
數據的垂直切分,也能夠稱爲縱向切分。將數據庫想象成由不少個一大塊一大塊的「數據塊」(表)組成,垂直地將這些「數據塊」切開,而後把它們分散到多臺數據庫主機上面。這樣的切分方法就是垂直(縱向)的數據切分。
一個架構設計較好的應用系統,其整體功能確定是由不少個功能模塊所組成的,而每個功能模塊所須要的數據對應到數據庫中就是一個或多個表。而在架構設計中,各個功能模塊相互之間的交互點越統1、越少,系統的耦合度就越低,系統各個模塊的維護性及擴展性也就越好。這樣的系統,實現數據的垂直切分也就越容易。
垂直切分優勢:
(1)數據庫的拆分簡單明瞭,拆分規則明確;
(2)應用程序模塊清晰明確,整合容易;
(3)數據維護方便易行,容易定位。
垂直切分缺點:
(1)部分表關聯沒法在數據庫級別完成,要在程序中完成;
(2)對於訪問極其頻繁且數據量超大的表仍然存在性能瓶頸,不必定能知足要求;
(3)事務處理相對複雜;
(4)切分達到必定程度以後,擴展性會受到限制;
(5)過分切分可能會帶來系統過於複雜而難以維護。
在以下的實例中,須要將
編輯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中的配置進行填寫。
鏈接後可查看後端鏈接的三個數據庫,以下圖所示:
水平切分所指的是經過一系列的切分規則將數據水平分佈到不一樣的DB或table中,在經過相應的DB路由 或者table路由規則找到須要查詢的具體的DB或者table以進行Query操做,好比根據用戶ID將用戶表切分到多臺數據庫上。
將某個訪問極其頻繁的表再按照某個字段的某種規則來分散到多個表之中,每一個表中包含一部分數據。
例如,全部數據都是和用戶關聯的,那麼咱們就能夠根據用戶來進行水平拆分,將不一樣用戶的數據切分到不一樣的數據庫中。
如今互聯網很是火爆的web 2.0類型的網站,基本上大部分數據都可以經過會員用戶信息關聯上,可能不少核心表都很是適合經過會員ID來進行數據的水平切分。而像論壇社區討論系統,就更容易切分了,很是容易按照論壇編號來進行數據的水平切分。切分以後基本上不會出現各個庫之間的交互。
水平切分的優勢:
表關聯基本可以在數據庫端所有完成;
不會存在某些超大型數據量和高負載的表遇到瓶頸的問題;
應用程序端總體架構改動相對較少;
事務處理相對簡單;
只要切分規則可以定義好,基本上較難遇到擴展性限制。
水平切分的缺點:
切分規則相對更爲複雜,很難抽象出一個可以知足整個數據庫的切分規則;
後期數據的維護難度有所增長,人爲手工定位數據更困難;
應用系統各模塊耦合度較高,可能會對後面數據的遷移拆分形成必定的困難。
在通常的應用系統中,用戶表及其密切相關的關聯表,可根據「用戶表」(eg:t_user)中的「用戶ID」(user_id)進行水平切分,並基於MyCAT的E-R關係分片策略將其密切相關的表(eg:t_user_class_rel)也分到對應的庫中。
在建表語句參考以下:
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表';
首先配置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>
在schema.xml的文件內容中可看到t_user表指定的分片規則是rule1,須要在conf/rule.xml文件中設置rule1的規則爲根據user_id進行分片,並按照類「org.opencloudb.route.function.PartitionByLong」的規則進行分片。
該文件的參考內容以下所示:
在server.xml文件中的schemas屬性中添加test_mycat的schema。修改後的文件以下所示:
重啓MyCAT,使用MySQL客戶端鏈接後,鏈接後可在mycat數據庫下看到t_user和t_area,t_node表,以下圖所示:
在MySQL客戶端鏈接的MyCat的test_mycat數據庫的t_user表運行以下插入語句,插入2000條數據:
爲了確保數據庫產品的穩定性,不少數據庫擁有雙機熱備功能。也就是,第一臺數據庫服務器,是對外提供增刪改查業務的生產服務器;第二臺數據庫服務器,僅僅接收來自第一臺服務器的備份數據。通常來講,爲了配置方便,以及穩定性,這兩臺數據庫服務器,都用的是相同的配置。
在實際運行中,第一臺數據庫服務器的壓力,遠遠大於第二臺數據庫服務器。所以,不少人但願合理利用第二臺數據庫服務器的空閒資源。
從數據庫的基本業務來看,數據庫的操做無非就是增刪改查這4個操做。但對於「增刪改」這三個操做,若是是雙機熱備的環境中作,一臺機器作了這三個操做的某一個以後,須要當即將這個操做,同步到另外一臺服務器上。出於這個緣由,第二臺備用的服務器,就只作了查詢操做。進一步,爲了下降第一臺服務器的壓力,乾脆就把查詢操做所有丟給第二臺數據庫服務器去作,第一臺數據庫服務器就只作增刪改了。
優勢:合理利用從數據庫服務器的空閒資源。
缺點:原本第二臺數據庫服務器,是用來作熱備的,它就應該在一個壓力很是小的環境下,保證運行的穩定性。而讀寫分離,卻增長了它的壓力,也就增長了不穩定性。所以,讀寫分離,實質上是一個在資金比較缺少,但又須要保證數據安全的需求下,在雙機熱備方案上,作出的一種折中的擴展方案。
MyCAT的讀寫分離機制以下:
例如將本機做爲寫庫,10.18.96.133做爲讀庫,MyCAT的讀寫分離的配置以下:
dataHost的balance屬性設置爲:
一個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 表明全部節點都是寫入寫入,慎重開啓,多節點寫入順序爲默認寫入根據配置順序,第一個掛掉切換另外一個。
一個真實的業務系統中,每每存在大量的相似字典表的表格,它們與業務表之間可能有關係,這種關係,能夠理解爲「標籤」,而不該理解爲一般的「主從關係」,這些表基本上不多變更,能夠根據主鍵ID進行緩存,下面這張圖說明了一個典型的「標籤關係」圖:
在分片的狀況下,當業務表由於規模而進行分片之後,業務表與這些附屬的字典表之間的關聯,就成了比較棘手的問題,考慮到字典表具備如下幾個特性:
鑑於此,MyCAT定義了一種特殊的表,稱之爲「全局表」,全局表具備如下特性:
將字典表或者符合字典表特性的一些表定義爲全局表,則從另一個方面,很好的解決了數據JOIN的難題。經過全局表+基於E-R關係的分片策略,MyCAT能夠知足80%以上的企業應用開發。
在各個庫分別建立全局表(例如:t_area)的表結構,表結構保持一致,例如:
全局表配置比較簡單,不用寫Rule規則,在schema.xml中修改test_schema,添加t_area的table子元素,參考以下配置便可:
運行以下insert語句,往test_mycat的t_area表插入10條數據,以下所示:
插入後去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