mycat是一個開源的數據庫中間件,其前身是阿里巴巴的cobar,主要可以實現的功能有讀寫分離,數據分片(垂直分庫,垂直分表,水平分庫,水平分表)及多數據源整合。其基本原理主要是攔截要執行的sql語句,該sql的表信息主要是邏輯表信息,依據規則進行分片分析,讀寫分析,緩存分析等等指定具體的物理表,而後將sql改寫分別發送到不一樣的數據庫上執行,而後獲取到結果進行歸併,接着就是返回結果(sharding-jdbc原理與其大體相同,思考:mycat是否有綁定功能)。mysql
server.xml: mycat的系統信息等。sql
<user name="mycatUser"> //應用程序中配置的用戶名、密碼及數據庫名稱 <property name="password">mycatUserPassword</property> <property name="schema">testdb</property> //指定的schema </user>
schema.xml: 定義邏輯表,表分片節點信息等。數據庫
<mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="testdb" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"></schema> //schema name 對應server中配置的schema name dataNode 對應下面dataNode的name <dataNode name="dn1" dataHost="host1" database="testdb"/> //database爲物理數據庫 dataHost和下面dataHost節點name保持一致 <dataHost name="host1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="hostM1" url="192.168.101:3306" user="root" password="123456"> //寫主機的地址 用戶名 及密碼 <readHost host="hostS1" url="192.168.101.102:3306" user="root" password="123456"/> //讀主機的地址 用戶名 及密碼 </writeHost> </dataHost> //dataHost中 balance的值設置不一樣的值,讀寫負載也不一樣 //balance:0 讀操做都在寫庫中 //balance:1 當有多主多從的時候,主之間互爲主從,mater1->slave1 master2->slave2 master1和master2互爲主備,select會在slave1 master2 slave2隨機調用 //balance:2 全部讀操做將會在全部數據庫中隨機執行 //balance:3 全部讀操做將會在全部讀數據庫中執行 //通常使用1或者3,1單主單從 3 多主多從 </mycat:schema>
rule.xml: 定義數據分片信息等。segmentfault
啓動在mycat bin目錄下執行:緩存
./mycat console(控制檯啓動) ./mycat start (後臺啓動)
登陸函數
維護窗口: mysql -umycat -p123456 -P 9066 -h 192.168.101.101 使用窗口: mysql -umycat -p123456 -P 8066 -h 192.168.101.101
mysql主從數據庫之間同步是基於mysql本身實現的,教程url
//dataHost中 balance的值設置不一樣的值,讀寫負載也不一樣 //balance:0 讀操做都在寫庫中 //balance:1 當有多主多從的時候,主之間互爲主從,mater1->slave1 master2->slave2 master1和master2互爲主備,select會在slave1 master2 slave2隨機調用 //balance:2 全部讀操做將會在全部數據庫中隨機執行 //balance:3 全部讀操做將會在全部讀數據庫中執行 //通常使用1或者3,1單主單從 3 多主多從
單主單從中,若是主掛了,對應業務影響就比較大了,能夠採用多主要多從,一個主有多個主的從庫,當一個主庫掛掉,主的從庫就升級爲主庫繼續提供服務,當主庫在掛掉後再從新服務就變成了運行中主的從庫,當主庫掛掉後就可能再次升級爲主庫。當balance設置爲3時候,主的從庫就能夠做爲讀取數據的從庫。.net
修改上述單主單從配置日誌
解除主從關係:code
在從庫上執行: stop slave; reset master;
修改單主單從中主的/etc/my.cnf
#在主數據庫做爲從數據庫的時候,也要進行讀取中繼日誌進行寫操做 log-slave-updates #自增字段每次自增增加量 auto-increment-increment=2 範圍:1---65535 #自增字段起始值 auto-increment-offset=1 範圍:1---65535
設置第二臺主的/etc/my.cnf
server-id=3 #serverid 不要重複 其餘同第一臺主的配置 auto-increment-increment=2 #設置同第一臺主的配置 auto-increment-offset=2 #這個要設置爲2了
第二臺從的配置同第一臺從的配置
須要修改sever-id=4
重啓服務便可
在主數據庫建立從庫訪問的用戶,執行show master status;獲取日誌名及偏移值。
GRANT REPLICATION SLAVE ON *.* TO 'slaveDB'@'%' IDENTIFIED BY '123456'
執行主從同步命令
CHANGE MASTER to MASTER_HOST='主的ip地址', MASTER_USER='主給從訪問的用戶名', MASTER_PASSWORD='主給從訪問的密碼', MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=134; #經過在主數據庫上show master status;查詢到的值
啓動slave:start slave;
執行完後,在從的數據庫上執行:
show slave status; 查看io及sql狀態,若是有錯誤能夠看到錯誤信息。
上述是設置主與從之間的配置
主與主之間還要進行設置主備:
命令同主從之間的設置,執行命令
CHANGE MASTER to MASTER_HOST='另外一臺主的ip地址', MASTER_USER='主給從訪問的用戶名', MASTER_PASSWORD='主給從訪問的密碼', MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=134;
執行後在主上執行:start slave;
經過在主數據庫上show slave status;查看io及sql執行狀態。
另一臺主做爲這臺主的從設置同上述執行命令。
到此,數據庫之間的雙主雙從設置完畢了。
下面配置mycat了:
修改schema.xml
<mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="testdb" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"></schema> //schema name 對應server中配置的schema name dataNode 對應下面dataNode的name <dataNode name="dn1" dataHost="host1" database="testdb"/> //database爲物理數據庫 dataHost和下面dataHost節點name保持一致 <dataHost name="host1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="hostM1" url="192.168.101:3306" user="root" password="123456"> //第一個寫主機的地址 用戶名 及密碼 <readHost host="hostS1" url="192.168.101.102:3306" user="root" password="123456"/> //第一個讀主機的地址 用戶名 及密碼 </writeHost> <writeHost host="hostM2" url="192.168.103:3306" user="root" password="123456"> //第二個寫主機的地址 用戶名 及密碼 <readHost host="hostS2" url="192.168.101.104:3306" user="root" password="123456"/> //第二個讀主機的地址 用戶名 及密碼 </writeHost> </dataHost> //balance設置爲1 //dataHost中 balance的值設置不一樣的值,讀寫負載也不一樣 //balance:0 讀操做都在寫庫中 //balance:1 當有多主多從的時候,主之間互爲主從,mater1->slave1 master2->slave2 master1和master2互爲主備,select會在slave1 master2 slave2隨機調用 //balance:2 全部讀操做將會在全部數據庫中隨機執行 //balance:3 全部讀操做將會在全部讀數據庫中執行 //通常使用1或者3,1單主單從 3 多主多從 //writeType 爲0表示寫操做將會在第一個writeHost中進行,若是第一個writeHost掛掉了,將會在第二個writeHost中進行 爲1表示隨機在兩個writeHost中進行,不要使用要被棄用了 //switchType 1表示自動切換 推薦使用 -1表示不自動切換 2基於mysql主從同步狀態切換 </mycat:schema>
在/usr/local/mycat/bin目錄下:重啓mycat服務 ./mycat console
修改schema.xml文件
<mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="testdb" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">//testdb schema默認dataNode 爲dn1 默認訪問主庫maindb <table name="customer" dataNode="dn2"></table> //設置customer dataNode 爲dn2 dn2中指定的數據庫爲customerdb </schema> <dataNode name="dn1" dataHost="host2" database="maindb"/> //database爲物理數據庫 dataHost和下面dataHost節點name保持一致 <dataNode name="dn2" dataHost="host1" database="customerdb"/> //垂直分庫 <dataHost name="host1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> //只有主庫,balance設置爲0 <writeHost host="hostM1" url="192.168.101:3306" user="root" password="123456"> </writeHost> </dataHost> <dataHost name="host2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat>//只有主庫,balance設置爲0 <writeHost host="hostM1" url="192.168.102:3306" user="root" password="123456"> </writeHost> </dataHost> </mycat:schema>
A.字段取餘分表: 對訂單表依據id進行取餘拆分
修改schema.xml文件
<mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="testdb" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">//testdb schema默認dataNode 爲dn1 默認訪問主庫maindb <table name="order" dataNode="dn1,dn2" rule="orderModRule"></table> //設置order表 dataNode 爲dn1和dn2 </schema> </mycat:schema>
修改rule.xml文件
<tableRule name="orderModRule"> <rule> <columns>order_id</columns> <algorithm>orderIdModFunction</algrothim> </rule> </tableRule> <function name="orderIdModFunction" class="io.mycat.rount.function.PartatiionByMod"> <count>2</count> //該數目要和dataNode保持一致 </function>
B.關聯表(相似sharding-jdbc綁定表):
修改schema.xml
<schema name="testdb" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">//testdb schema默認dataNode 爲dn1 默認訪問主庫maindb <table name="order" dataNode="dn1,dn2" rule="orderModRule"> <childTable name="order_detail" primaryKey="id" joinKey="order_id" parentKey="id"/> //order_detail表中有order_id和order表中的id關聯,primaryKey設置的是order_detail的主鍵,order_id爲order_detail表中的字段,id爲order表中的主鍵和order_id對應 </table> //設置order表 dataNode 爲dn1和dn2 <table name="address" dataNode="dn1,dn2" type="global"></table> </schema>
C.枚舉分片:依據region進行選擇dataNode
修改schema.xml
<schema name="testdb" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">//testdb schema默認dataNode 爲dn1 默認訪問主庫maindb <table name="ware_region_info" dataNode="dn1,dn2" rule="sharding_by_region"></table> </schema>
修改rule.xml
<tableRule name=「sharding_by_region」> <rule> <columns>region</columns> <algorithm>shardingByRegionFunction</algorithm> </rule> </tableRule> //指定枚舉分片函數 <function name="shardingByRegionFunction" class="io.mycat.route.function.PartitionByFileMap"> <property name="mapFile">region-partition.txt</property> <property name="type">1</property> <property name="defaultNode">0</property> </function> //columns 分片的字段 algorithm 分片函數 //mapFile 映射文件 //type : 0表明爲int型號 非0爲String //defaultNode 小於0表示不設置默認節點 大於等於0表示設置 若是遇到不認識的枚舉值就路由到默認節點
region-partition.txt文件保存在mycat conf目錄下,內容以下:
henan=0 shanghai=1
D.全局表(相似sharding-jdbc廣播表)
設置地址表在各個數據庫中都有寫入
在schema.xml文件中增長table type爲global
<table name="address" primaryKey="id" type="global" dataNode="dn1,dn2" />
E.範圍分片
schema.xml修改同枚舉分片,rule.xml以下:
<function name="rangePartitionFunction" class="io.mycat.route.function.AutoPartitionByLong"> <property name="mapFile">rangePartitionFile.txt</property> <property name="defaultNode">0</property> </function> //mapFile:表示配置文件 //defaultNode: 默認節點,0設置默認節點,大於等於0不設置默認節點
rangePartitionFile.txt文件
0-100=0 101-200=1
F.日期分片
schema.xml的修改同上
主要是rule.xml對應函數的設置
<function name="shardingByDate" class="io.mycat.route.function.PartitionByDatat> <property name="dateFormat">yyyy-MM-dd</property> <property name="sBeginDate">2020-01-01</property> <property name="sEndDate">2020-01-04</property> <property name="sPartionDay">2</property> </function> //dateFormat:日期格式 //sBeginDate:開始日期 //sEndDate:結束日期 //sPartionDay:分區天數,即默認從開始日期算起,分隔2天一個分區 //上述demo含義:2020-01-01 2020-01-02 會寫入dn1中 2020-01-03 2020-01-04 //會寫入到dn2中,若是沒有設置結束時間,按道理應該選擇dn3,可是沒有dn3因此就會報錯 //若是設置告終束時間後,到了01-05後會重新循環dn1和dn2,設置告終束時間會保證循環 //插入數據值的格式爲2020-01-01
插入sql:insert into(date) values("2020-02-10");
mycat全局序列設置有三種類型:本地文件0,數據庫設置1,時間戳2
數據庫設置:首先要在數據庫中設置全局序列表及函數等,而後在mycat修改server.xml 全局序列表方式爲數據庫設置方式(值爲1),修改sequence_db_conf.properties將設置的表指定到具體的dataNode。
其實現基本原理:將序列信息設置在數據庫中,須要序列號的時候每次去數據庫查詢,每次能夠獲取必定量的,使用完成後從新請求獲取,若是未使用完,服務宕機了,那麼一部分序列號就丟棄了。
使用haproxy+keepalived實現高可用