傳統關系型資料庫的分布式開發通常需要自己做,不僅耗時耗力而且效果不是很理想,當想快速搭建時,最初想到的是看有沒有第三方,網上牛人還是很多的,做得比較好的其中之一Mycat,它是開源的分布式資料庫系統,解決資料庫的負載均衡,主備複制,讀寫分離,簡單來說就是你隻管直接與mycat通訊,至于分離什麼的交給它裡面自己做,其它啥都不用操心。
至于什麼是MyCat有什麼優勢,可以看看官網介紹 Mycat 資料庫分庫分表中間件 。

上圖是MyCat架構圖。
MyCat可以與HAProxy使用實作高可用資料庫叢集,更深入的内容自己去查,本章隻詳講從0開始使用MyCat 基礎篇,至少能先跑起來。
一、下載下傳
本次運作環境為windows,Linux下更好吧,然後資料庫用mysql,需要java環境,下載下傳jdk8
jdk安裝配置
1. 首先去oracle官網下載下傳并安裝jdk8,添加環境變量,JAVA_HOME設定為D:\Java\jdk1.8
2. CLASSPATH設定為.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar
3. path系統變量追加%JAVA_HOME%\bin;
安裝Mysql,需要注意的是資料庫,表,字段的編碼都采用utf8吧,否則插入的中文顯示為亂碼,具體解決方法網上查一查,去試一試。
下載下傳MyCat,http://dl.mycat.io/ 選擇最新的版本下載下傳。(下圖可以看到還有其它前面需要的資源都可以從這裡下載下傳)
二、配置
下載下傳解壓後就要先配置MyCat了,(這裡不是exe檔案,沒有安裝,配置好後直接運作startup_nowrap.bat)
打開mycat\conf裡面的startup_nowrap.bat 為了降低資源占用,mycat的jvm設定在startup_nowrap.bat 可以清楚看到如下配置:
“%JAVA_CMD%” -server -Xms1G -Xmx2G -XX:MaxPermSize=64M -XX:+AggressiveOpts -XX:MaxDirectMemorySize=1G -DMYCAT_HOME=%MYCAT_HOME% -cp “..\conf;..\lib*” io.mycat.MycatStartup
這裡将-Xms1G改成-Xms512M,-Xmx2G改成-Xmx1024M,儲存後重新啟動即可。
添加Windows環境變量,MYCAT_HOME設定為安裝目錄D:\MycatServer1.5
修改wrapper.conf檔案裡的改成wrapper.java.command=D:\jdk1.8\bin\java.exe
三、連接配接MySQL
Mycat綁定MySQL 啟動的配置
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中,每天一個檔案
具體什麼意思後面慢慢看。
先解決主配置,server.xml配置檔案配置通路使用者及權限, 修改高亮處資訊,其中mycat、user為通路mycat的使用者,TESTDB為mycat虛拟的資料庫,供上層應用通路。
<user name="mycat">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
<!-- 表級 DML 權限設定 -->
<!--
<privileges check="false">
<schema name="TESTDB" dml="0110" >
<table name="tb01" dml="0000"></table>
<table name="tb02" dml="1111"></table>
</schema>
</privileges>
-->
</user>
<user name="user">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property>
</user>
mycat的資料庫配置是在schema.xml中配置,這部分不太好了解,精簡了一下,主要分schema、dataNode、dataHost三個主要配置。
<scheme>節點定義了mycat的虛拟資料庫為TESTDB,下面借用園友的說明:
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/" >
<!--在這一行參數裡面,schema name定義了可以在MyCAT前端顯示的邏輯資料庫的名字,checkSQLschema這個參數為False的時候,表明MyCAT會自動忽略掉表名前的資料庫名,比如說mydatabase1.test1,會被當做test1;sqlMaxLimit指定了SQL語句傳回的行數限制-->
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
<!-- 主鍵範圍規則 -->
<!-- 這一行代表在MyCAT前端會顯示哪些表名,類似幾行都代表一樣的意思,這裡強調的是表,而MyCAT并不會在配置檔案裡面定義表結構,如果在前端使用show create table ,MyCAT會顯示正常的表結構資訊,觀察Debug日志,可以看到,MyCAT把指令分發給了dn1代表的資料庫,然後把dn1的查詢結果傳回給了前端 可以判斷,類似的資料庫級别的一些查詢指令,有可能是單獨分發給某個節點,然後再把某個節點的資訊傳回給前端。
dataNode的意義很簡單,這個邏輯表的資料存儲在後端的哪幾個資料庫裡面rule代表的是這個邏輯表students的具體切分政策,目前MyCAT隻支援按照某一個特殊列,遵循一些特殊的規則來切分,如取模,枚舉等,具體的留給之後細說
-->
<table name="travelrecord" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
<table name="company" primaryKey="ID" dataNode="dn3,dn2,dn1" rule="mod-long"/>
<table name="goods" primaryKey="ID" type="global" dataNode="dn1,dn2" />
<!--求模分片随機規則 -->
<table name="hotnews" primaryKey="ID" dataNode="dn1,dn2,dn3"
rule="mod-long" />
<table name="employee" primaryKey="ID" dataNode="dn1,dn2"
rule="sharding-by-intfile" />
<table name="customer" primaryKey="ID" dataNode="dn1,dn2"
rule="sharding-by-intfile">
<!--
childtable我在測試中并沒有實際用起來不過在MyCAT的設計文檔裡面有提到,childtable是一種依賴于父表的結構,
這意味着,childtable的joinkey會按照父表的parentKey的政策一起切分,當父表與子表進行連接配接,
且連接配接條件是childtable.joinKey=parenttable.parentKey時,不會進行跨庫的連接配接.
-->
<childTable name="orders" primaryKey="ID" joinKey="customer_id"
parentKey="id">
<childTable name="order_items" joinKey="order_id"
parentKey="id" />
</childTable>
<childTable name="customer_addr" primaryKey="ID" joinKey="customer_id"
parentKey="id" />
</table>
<!-- 全局表是自動克隆到所有定義的資料節點,這樣可以與拆分節點的任何表連接配接查詢,是在同一個資料節點-->
<table name="news_table" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3" />
</schema>
<dataNode name="dn1" dataHost="localhost1" database="TESTDB1" />
<dataNode name="dn2" dataHost="localhost1" database="TESTDB2" />
<dataNode name="dn3" dataHost="localhost1" database="TESTDB3" />
<!--
dataHost配置的是實際的後端資料庫叢集,大部分參數簡單易懂,這裡就不一個個介紹了,隻介紹比較重要的兩個參數,writeType和balance.
-->
<!-- writeType和balance是用來控制後端叢集的讀寫分離的關鍵參數,這裡我用了雙主雙從的叢集配置
這裡的測試過程比較麻煩,是以直接貼結論:
1.balance=0時,讀操作都在localhost上(localhost失敗時,後端直接失敗)
2.balance=1時,讀操作會随機分散在localhost1和兩個readhost上面(localhost失敗時,寫操作會在localhost1,如果localhost1再失敗,則無法進行寫操作)
3.balance=2時,寫操作會在localhost上,讀操作會随機分散在localhost1,localhost1和兩個readhost上面(同上)
4.writeType=0時,寫操作會在localhost上,如果localhost失敗,會自動切換到localhost1,localhost恢複以後并不會切換回localhost進行寫操作
5.writeType=1時,寫操作會随機分布在localhost和localhost1上,單點失敗并不會影響叢集的寫操作,但是後端的從庫會無法從挂掉的主庫擷取更新,會在讀資料的時候出現資料不一緻
舉例:localhost失敗了,寫操作會在localhost1上面進行,localhost1的主從正常運作,但是localhost的從庫無法從localhost擷取更新,localhost的從庫于其他庫出現資料不一緻
-->
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<!-- can have multi write hosts -->
<writeHost host="hostM1" url="localhost:3306" user="root"
password="123456">
<!-- can have multi read hosts -->
<!--<readHost host="hostS2" url="192.168.1.200:3306" user="root" password="xxx" />-->
</writeHost>
</dataHost>
</mycat:schema>
以上配置注意高亮部分,配置的是每個dn對應哪個實體伺服器裡面哪個實體庫(此處隻有本機,是以都綁定到本機localhost,再添加3個不同的資料庫TESTDB1\TESTDB2\TESTDB3,手動都添加要測試的表,若有多餘的伺服器可以将ip替換掉測試),詳細的内容參考文中的注釋。
經過實驗 goods表:在mycat的TESTDB的虛拟表goods中添加一行記錄會在 TESTDB1和TESTDB2中的表goods同步添加一行記錄。
hotnews表:在mycat的TESTDB的虛拟表hotnews中添加的一行記錄會随機插入 TESTDB1、TESTDB2、TESTDB3的其中一個庫中的hotnews表。
其它表的測試你們自己試試。
這就是分片,靠的是分片規則,下面就來看rule。
(每個資料庫中相同的表要手工提前生成表結構,否則會提示找不到此表,操作mycat時它并不能自動同步實體資料庫生成,可能有方法,現在還沒深入了解)
rule.xml配置檔案,可以先不管。
<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License. - You
may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0
- - Unless required by applicable law or agreed to in writing, software -
distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the
License for the specific language governing permissions and - limitations
under the License. -->
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://org.opencloudb/">
<tableRule name="rule1">
<rule>
<columns>id</columns>
<algorithm>func1</algorithm>
</rule>
</tableRule>
<tableRule name="rule2">
<rule>
<columns>user_id</columns>
<algorithm>func1</algorithm>
</rule>
</tableRule>
<tableRule name="sharding-by-intfile">
<rule>
<columns>sharding_id</columns>
<algorithm>hash-int</algorithm>
</rule>
</tableRule>
<tableRule name="auto-sharding-long">
<rule>
<columns>id</columns>
<algorithm>rang-long</algorithm>
</rule>
</tableRule>
<tableRule name="mod-long">
<rule>
<columns>id</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
<tableRule name="sharding-by-murmur">
<rule>
<columns>id</columns>
<algorithm>murmur</algorithm>
</rule>
</tableRule>
<tableRule name="sharding-by-month">
<rule>
<columns>create_date</columns>
<algorithm>partbymonth</algorithm>
</rule>
</tableRule>
<tableRule name="latest-month-calldate">
<rule>
<columns>calldate</columns>
<algorithm>latestMonth</algorithm>
</rule>
</tableRule>
<tableRule name="auto-sharding-rang-mod">
<rule>
<columns>id</columns>
<algorithm>rang-mod</algorithm>
</rule>
</tableRule>
<tableRule name="jch">
<rule>
<columns>id</columns>
<algorithm>jump-consistent-hash</algorithm>
</rule>
</tableRule>
<function name="murmur"
class="org.opencloudb.route.function.PartitionByMurmurHash">
<property name="seed">0</property><!-- 預設是0 -->
<property name="count">2</property><!-- 要分片的資料庫節點數量,必須指定,否則沒法分片 -->
<property name="virtualBucketTimes">160</property><!-- 一個實際的資料庫節點被映射為這麼多虛拟節點,預設是160倍,也就是虛拟節點數是實體節點數的160倍 -->
<!-- <property name="weightMapFile">weightMapFile</property> 節點的權重,沒有指定權重的節點預設是1。以properties檔案的格式填寫,以從0開始到count-1的整數值也就是節點索引為key,以節點權重值為值。所有權重值必須是正整數,否則以1代替 -->
<!-- <property name="bucketMapPath">/etc/mycat/bucketMapPath</property>
用于測試時觀察各實體節點與虛拟節點的分布情況,如果指定了這個屬性,會把虛拟節點的murmur hash值與實體節點的映射按行輸出到這個檔案,沒有預設值,如果不指定,就不會輸出任何東西 -->
</function>
<function name="hash-int"
class="org.opencloudb.route.function.PartitionByFileMap">
<property name="mapFile">partition-hash-int.txt</property>
</function>
<function name="rang-long"
class="org.opencloudb.route.function.AutoPartitionByLong">
<property name="mapFile">autopartition-long.txt</property>
</function>
<function name="mod-long" class="org.opencloudb.route.function.PartitionByMod">
<!-- how many data nodes -->
<property name="count">3</property>
</function>
<function name="func1" class="org.opencloudb.route.function.PartitionByLong">
<property name="partitionCount">8</property>
<property name="partitionLength">128</property>
</function>
<function name="latestMonth"
class="org.opencloudb.route.function.LatestMonthPartion">
<property name="splitOneDay">24</property>
</function>
<function name="partbymonth"
class="org.opencloudb.route.function.PartitionByMonth">
<property name="dateFormat">yyyy-MM-dd</property>
<property name="sBeginDate">2015-01-01</property>
</function>
<function name="rang-mod" class="org.opencloudb.route.function.PartitionByRangeMod">
<property name="mapFile">partition-range-mod.txt</property>
</function>
<function name="jump-consistent-hash" class="org.opencloudb.route.function.PartitionByJumpConsistentHash">
<property name="totalBuckets">3</property>
</function>
</mycat:rule>
四、運作
用管理者權限運作startup_nowrap.bat啟動MyCat。
若出現上面的問題,檢查java的環境是否正确和mycat的環境配置。
啟動成功後會出現:
#如果啟動失敗,請修改D:\mycat\bin\startup_nowrap.bat檔案中的以下參數。預設占用記憶體為2G
D:\dev-bin\mycat\bin>"C:\Program Files (x86)\Java\jdk1.7.0_13/bin/java" -server -Xms512m -Xmx512m -XX:MaxPermSize=64M -XX:+AggressiveOpts -XX:MaxDirectMemorySize=768m -DMYCAT_HOME=D:\
p "..\conf;..\lib\*" io.mycat.MycatStartup
然後dos中會不停的出現心跳檢測,有錯誤資訊可去mycat\logs中檢視日志。
注意:如日志中出現192.168.xxx not connected 等資訊,請允許對應的mysql遠端通路,且先提前獨自檢查mysql都能正确通路。
使用navicat連接配接mycat,操作方式和連接配接實體mysql庫一緻,使用者mycat,密碼123456,端口8066
連接配接成功後,将看到TESTDB資料庫和hotnews等資料表
在hotnews表中添加一些資料,儲存
執行select * from hotnews 檢視操作,然後去TESTDB1、TESTDB2、TESTDB3中查詢hotnews表
MyCat中TESTDB是中間件邏輯資料庫,MySQL中的testdb、testdb2、testdb3是真實的資料庫。
在mycat中添加資料時若提示testdb2.hotnews不存在,則要手動在testdb2中添加相同表結構。
添加完後,可以看到hotnews記錄在三個testdb、testdb2、testdb3中是均衡随機插入的。
而goods在testdb、testdb2中是一樣的。
至此可以配置出MyCat了,敬請期待下篇 net下如何使用。
作者:歡醉
公衆号【一個碼農的日常】 技術群:319931204 1号群: 437802986 2号群: 340250479
出處:http://zhangs1986.cnblogs.com/
碼雲:https://gitee.com/huanzui
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。
Top