之前說過主從複製,現在說下我是如何基於mycat搭建讀寫分離的(這裏是搭建一個基本模型)
首先下載一個mycat的鏡像,然後準備要掛載的文件,然後啓動就ok了。
mycat目錄如下
sequence_conf.properties
TB_USER.HISIDS=
TB_USER.MINID=1
TB_USER.MAXID=20000
TB_USER.CURID=1
rule.xml=配置分片規則(當然我這裏不需要,我只是基於主庫複製寫,從庫複製讀的sql查詢分配)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
<tableRule name="userrule">
<rule>
<columns>id</columns>
<algorithm>func1</algorithm>
</rule>
</tableRule>
<tableRule name="categoryrule">
<rule>
<columns>id</columns>
<algorithm>jump-consistent-hash</algorithm>
</rule>
</tableRule>
<function name="murmur"
class="io.mycat.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="crc32slot"
class="io.mycat.route.function.PartitionByCRC32PreSlot">
<property name="count">2</property><!-- 要分片的數據庫節點數量,必須指定,否則沒法分片 -->
</function>
<function name="hash-int"
class="io.mycat.route.function.PartitionByFileMap">
<property name="mapFile">partition-hash-int.txt</property>
</function>
<function name="rang-long"
class="io.mycat.route.function.AutoPartitionByLong">
<property name="mapFile">autopartition-long.txt</property>
</function>
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
<!-- how many data nodes -->
<property name="count">4</property>
</function>
<function name="func1" class="io.mycat.route.function.PartitionByLong">
<property name="partitionCount">8</property>
<property name="partitionLength">128</property>
</function>
<function name="latestMonth"
class="io.mycat.route.function.LatestMonthPartion">
<property name="splitOneDay">24</property>
</function>
<function name="partbymonth"
class="io.mycat.route.function.PartitionByMonth">
<property name="dateFormat">yyyy-MM-dd</property>
<property name="sBeginDate">2015-01-01</property>
</function>
<function name="rang-mod" class="io.mycat.route.function.PartitionByRangeMod">
<property name="mapFile">partition-range-mod.txt</property>
</function>
<function name="jump-consistent-hash" class="io.mycat.route.function.PartitionByJumpConsistentHash">
<property name="totalBuckets">4</property>
</function>
</mycat:rule>
tableRule=
name : schema.xml中table標籤中對應的rule屬性,也就是配置表的分片規則
columns : 是表的切分字段
algorithm : 是規則對應的切分規則,對應function標籤的name屬性
function = 配置是分片規則的配置
name : 切分規則的名稱,對應tableRule標籤的algorithm屬性
class : 是切分規則對應的切分類,寫死,需要哪種規則則配置哪種
property : 標籤是切分規則對應的不同屬性,不同的切分規則配置不同
server.xml=用戶信息配置(連接mycat的配置)sequnceHandlerType代表意思如下(默認爲0,我這裏就沒有寫上去)
0 : 使用本地方式作爲數據庫自增,設置 sequence_conf.properties配置文件
GLOBAL.HISIDS=
GLOBAL.MINID=10001 最小值
GLOBAL.MAXID=20000 最大值
GLOBAL.CURID=10000 當前值
1 : 使用的是本地數據庫的方式,需要在一個分節點創建MYCAT_SEQUENCE表和存儲過程,其中MYCAT_SEQUENCE必須爲大寫
2 : 自動生成64爲的時間戳,設置配置sequence_db_conf.properties,指定sequence相關配置在哪個節點上
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<property name="useSqlStat">0</property> <!-- 1爲開啓實時統計、0爲關閉 -->
<property name="useGlobleTableCheck">0</property> <!-- 1爲開啓全加班一致性檢測、0爲關閉 -->
</system>
<user name="root">
<property name="password">root</property>
<property name="schemas">test</property> #mycat邏輯庫,對應schemas.xml裏schema標籤的name屬性,多個邏輯庫用逗號隔開
</user>
</mycat:server>
schema.xml=配置邏輯數據(關鍵地方,這裏會要你提供真實要連接的數據庫名和連接地址密碼等)
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="test" checkSQLschema="false" dataNode="dn1">
#爲了說明時候方便,複製代碼時請刪除<table name="tb_user" primaryKey="id" autoIncrement="true" #dataNode="dn1,dn2,dn3,dn4" rule="userrule" />
</schema>
<dataNode name="dn1" dataHost="localhost1" database="cvc_training_enterprise" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="3"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="120.24.5.**:32778" user="main"
password="***">
<readHost host="hostS2" url="120.24.5.**:32779" user="main" password="***" />
</writeHost>
</dataHost>
</mycat:schema>
schema : 是實際邏輯庫的配置,多個schema代表多個邏輯庫
table : 是邏輯表的配置(我這裏不配置這個,因爲我不用進行數據表分片,如果配置了,就需要給出分片規則)
name : 代表表名(真實表名)
primaryKey : 主鍵
autoIncrement : 開啓自動增長,不使用自動增長就不要加
dataNode : 代表表對應的分片,Mycat默認採用分庫方式,也就是一個表映射到不同的庫上,對應dataNode標籤的name,多個 用 逗號隔開,就是schema標籤下面的dataNode標籤中的name對應的值
rule代表表要採用的數據切分方式,名稱對應到rule.xml中tableRule標籤的name屬性,如果要分片必須配置
dataNode : 是邏輯庫對應的分片,如果配置多個分片只需要多個dataNode即可
name : dataNode的名
dataHost : 是實際的物理庫配置地址,可以配置多主主從等其他配置,對應dataHost標籤的name屬性
database : 映射實際的物理庫名稱,根據你自己的情況改動
dataHost : 配置物理庫分片映射
balance : 讀的負載均衡類型
balance=“0” : 不開啓讀寫分離機制,所有讀操作都發送到當前可用的writeHost上
balance=“1” : 全部的readHost與stand by writeHost參與select語句的負載均衡,簡單的說,當雙主雙從模式(M1->S1,M2->S2,並且M1與 M2互爲主備),正常情況下,M2,S1,S2都參與select語句的負載均衡
balance=“2” : 所有讀操作都隨機的在writeHost、readhost上分發
balance=“3” : 所有讀請求隨機的分發到wiriterHost對應的readhost執行,writerHost不負擔讀壓力注意,只在 1.4 及其以後版本有
writeType : 寫的負載均衡類型
writeType=“0” : 所有寫操作發送到配置的第一個 writeHost,第一個掛了切到還生存的第二個 ,writeHost,重新啓動後已切換後的爲準,切換記錄在配置文件中:dnindex.properties
writeType=“1” : 所有寫操作都隨機的發送到配置的 writeHost,1.5 以後廢棄不推薦
switchType : 切換的模式
switchType="-1" : 表示不自動切換
switchType=“1” : 默認值,表示自動切換
switchType=“2” : 基於MySQL主從同步的狀態決定是否切換,心跳語句爲 show slave status;
switchType=“3” : 基於MySQL galary cluster的切換機制(適合集羣)心跳語句爲 show status like ‘wsrep%’;
writeHost : 邏輯主機(dataHost)對應的後端的物理主機映射.mysql主
readHost : mysql從
接下來就是創建對應容器,記住要去暴露自己的8066和9066端口我是阿里雲的直接是去配出入規則
docker run --name mycat -v /home/docker-compose/mycat/schema.xml:/usr/local/mycat/conf/schema.xml -v /home/docker-compose/mycat/rule.xml:/usr/local/mycat/conf/rule.xml -v /home/docker-compose/mycat/server.xml:/usr/local/mycat/conf/server.xml -v /home/docker-compose/mycat/sequence_conf.properties:/usr/local/mycat/conf/sequence_conf.properties --privileged=true -p 8066:8066 -p 9066:9066 -e MYSQL_ROOT_PASSWORD=root -d longhronshens/mycat-docker
啓動完成可以使用navicat進行測試或者直接進入docker容器中進行測試
提供一個測試思路,你要測試是否有實現你的代理,寫主讀從,首先你要明白你直接進入從庫容器寫一條數據主庫是不會跟着生成一條數據(這個是之前就配置主從複製決定的),那麼你通過mycat寫一條數據查看是否從庫生成了就能看出是否有代理寫操作了,接下來你不經過mycat往從庫中某一表寫一條數據,在通過mycat去讀,主庫去讀,從庫去讀(該表全部數據)在觀察他們的主鍵直增的變化,mycat和從庫都以讀到數據而且主鍵都大於主庫1則可以證明讀都是通過從庫