一、目標
使用mycat部署分片枚舉。
什麼叫分片枚舉?分片枚舉有什麼用處?
分片枚舉:是mycat水平分表的一種形式,它可以按照指定的規則將表的數據分發到不同的數據庫,最終以減輕單臺msyql服務器的壓力。
二、平臺
[[email protected] ~]# uname -a
Linux client 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
[[email protected] ~]# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
Mycat-server-1.6.7.5-test-20200303154735-linux.tar.gz
三、實驗拓撲
主機名 ip 所裝必須的軟件 角色
mycat31 192.168.73.31 java1.8及以上,mycat1.6.7.5,mysql5.7 mycat服務器、mysql庫xkahn的部分表存儲地
mycat32 192.168.73.32 mysql5.7 mysql庫xkahn的部分表存儲地
四、說明
本次不再重複以前做過的操作了,寫個博客真累,又沒人點贊支持。關於基礎知識課參考之前的帖子
五、部署mycat分片枚舉
1.(mycat31上執行)修改配置文件/usr/local/mycat/conf/server.xml中的默認啓動賬號從root改爲爲mycat
(這裏的賬號mycat是mycat的管理賬號,而非linux系統上的賬號。)
cp /usr/local/mycat/conf/server.xml{,.bak}
sed -i 's/name="root"/name="mycat"/g' /usr/local/mycat/conf/server.xml
註釋:
<user name="mycat" ----->定義mycat的管理賬號叫mycat(即登錄mycat管理程序的賬號,而非linux系統賬號)
<property name="password">123456 ----->定義mycat的管理賬號的密碼
<property name="schemas">TESTDB ----->定義mycat的邏輯數據庫名,這裏需要和schema.xml中的<schema name="TESTDB"保持一致。
2.(mycat31上執行)修改配置文件/usr/local/mycat/conf/schema.xml
cat > /usr/local/mycat/conf/schema.xml <<EOF
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
<table name="teacher" dataNode="dn2"></table>
<table name="student" dataNode="dn1,dn2" rule="mod_rule">
<childTable name="student_record" primaryKey="xid" joinKey="student_id" parentKey="xid" />
</table>
<table name="xuser" dataNode="dn1,dn2" type="global"></table>
<table name="grade" dataNode="dn1,dn2" rule="sharding_by_intfile"></table>
</schema>
<dataNode name="dn1" dataHost="host1" database="xkahn" />
<dataNode name="dn2" dataHost="host2" database="xkahn" />
<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.73.31:3306" user="root"
password="123123">
</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>
<writeHost host="hostM1" url="192.168.73.32:3306" user="root"
password="123123">
</writeHost>
</dataHost>
</mycat:schema>
EOF
相比之前做的又多了本次的分片枚舉參數<table name="grade" dataNode="dn1,dn2" rule="sharding_by_intfile"></table>,#分片枚舉:表名叫grade被切分到dn1,dn2兩臺服務器,切分的規則用./rule.xml中的sharding_by_intfile規則。
3.(mycat31上執行)修改配置文件rule.xml
cp /usr/local/mycat/conf/rule.xml{,.bak}
vim /usr/local/mycat/conf/rule.xml
3-1.(mycat31上執行)添加自定義規則
在<mycat:rule xmlns:mycat="http://io.mycat/">的下面添加7行內容(包含最後一行空白行)
<tableRule name="sharding_by_intfile">
<rule>
<columns>course</columns>
<algorithm>hash-int</algorithm>
</rule>
</tableRule>
註釋,這裏定義分片規則叫sharding_by_intfile,分片依靠的列叫course(在schema.xml中有定義它的表名叫grade),分片的方法用hash-int(下面會有介紹)
3-2.(mycat31上執行)修改系統預定義的算法hash-int。
原本的hash-int方法是這樣寫的
<function name="hash-int"
class="io.mycat.route.function.PartitionByFileMap">
<property name="mapFile">partition-hash-int.txt</property>
</function>
修改爲
<function name="hash-int"
class="io.mycat.route.function.PartitionByFileMap">
<property name="mapFile">partition-hash-int.txt</property>
<property name="type">1</property>
<property name="defaultNode">0</property>
</function>
註釋:
分片用的系統類是io.mycat.route.function.PartitionByFileMap;
分片枚舉規則文件是./partition-hash-int.txt;
規則文件中要用來做枚舉分片的字段類型<property name="type">1</property>,0代表int類型,1代表string類型。
規則文件中沒有指定的字段存放在哪個服務器<property name="defaultNode">0</property>,0代表編程語言的第一個(服務器),若改成了1,那就說明沒有指定枚舉規則的數據就放到schema.xml中的第二臺mysql服務器上。
3-3.還是上一段完整的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://io.mycat/">
<tableRule name="sharding_by_intfile">
<rule>
<columns>course</columns>
<algorithm>hash-int</algorithm>
</rule>
</tableRule>
<tableRule name="mod_rule">
<rule>
<columns>xid</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
<tableRule name="rule1">
<rule>
<columns>id</columns>
<algorithm>func1</algorithm>
</rule>
</tableRule>
<tableRule name="sharding-by-date">
<rule>
<columns>createTime</columns>
<algorithm>partbyday</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="crc32slot">
<rule>
<columns>id</columns>
<algorithm>crc32slot</algorithm>
</rule>
</tableRule>
<tableRule name="sharding-by-month">
<rule>
<columns>create_time</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="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>
<property name="type">1</property>
<property name="defaultNode">0</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">2</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="partbyday"
class="io.mycat.route.function.PartitionByDate">
<property name="dateFormat">yyyy-MM-dd</property>
<property name="sNaturalDay">0</property>
<property name="sBeginDate">2014-01-01</property>
<property name="sEndDate">2014-01-31</property>
<property name="sPartionDay">10</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">3</property>
</function>
</mycat:rule>
4.(mycat31上執行)修改分片枚舉規則文件partition-hash-int.txt
cp /usr/local/mycat/conf/partition-hash-int.txt{,.bak}
cat > /usr/local/mycat/conf/partition-hash-int.txt <<EOF
language=0
math=1
EOF
註釋:這就是分片枚舉的規則了。
language指的是數據庫(xkahn)中本次的分片枚舉表(grade)中的字段course的一個值叫language(語文)
math同上,這個數據庫course字段值表示數學。
language=0 ------->讓語文成績放到第0臺服務器(實際的schema.xml中定義的第一臺服務器)
math=1 --------->讓數學成績放到第1臺服務器(實際的schema.xml中定義的第二臺服務器)
那其他成績呢?問的好,剛纔在<3.2>中有說明了<function name="hash-int" defaultNode的值是0代表第一臺服務器就是默認的其他科目成績的存放地。
5.小結
是不是有點亂?捋一捋?那就捋一捋。
1.首先mycat定製規則要從schema.xml中開始
2.schema.xml中定義了此次的枚舉分片<table name="grade" dataNode="dn1,dn2" rule="sharding_by_intfile"></table>,grade是表名,該表被分到了dn1和dn2兩臺服務器,規則用的名字叫sharding_by_intfile。
3.那麼規則sharding_by_intfile都是放在了規則配置文件./rule.xml中。
4.rule.xml中就增加一個sharding_by_intfile的規則,而它的規則中指定(表grade)列叫course。同時還指定了分片方法叫hash-int
5.在rule.xml中的後部分就有定義hash-int分片方法<function name="hash-int"
6.在分片方法中有定義了具體的分片枚舉的配置文件叫partition-hash-int.txt,這個文件中指定了具體按照什麼樣的枚舉去分表,同時還指定了該字段course的字段類型爲string(<property name="type">1</property>),同時還聲明瞭,假定分片枚舉配置文件partition-hash-int.txt中若沒定義的course的值的時候,該值應當存放在mycat的第一個節點服務器上(<property name="defaultNode">0</property>)
7.而具體的分片枚舉配置文件partition-hash-int.txt就指定了凡是course值等於語文(language)的就放到第0臺服務器(實際的mycati的第一個節點服務器)上,凡是course值等於數學(math)的都放到第1臺服務器(實際的mycati的第二個節點服務器)上。
六、往mycat的分片枚舉表裏灌入數據(mycat31上執行)
1.開一個新終端用於啓動mycat
cd /usr/local/mycat/bin
./mycat console
2.再開一個新的終端,並啓動mycat的數據管理平臺
mysql -umycat -p123456 -h 10.100.100.31 -P 8066
use TESTDB;
3..在mycat數據管理平臺創建mycat中建立本次的分片枚舉的表
create table grade(xid int(10) not null unique primary key,student_id int(10) not null,course varchar(100) not null,grade float(5,2),note varchar(500));
4.在mycat數據管理平臺上往分片枚舉的表grade裏灌入測試數據
insert into grade(xid,student_id,course,grade,note) values (1,1,"language",95.5,"語文玖拾伍點五分");
insert into grade(xid,student_id,course,grade,note) values (2,1,"math",92.5,"玖拾貳點五分92.5");
insert into grade(xid,student_id,course,grade,note) values (3,2,"language",60,"及格60");
insert into grade(xid,student_id,course,grade,note) values (4,2,"math",35,"忒差了35");
insert into grade(xid,student_id,course,grade,note) values (5,1,"sport",100,"體育100");
insert into grade(xid,student_id,course,grade,note) values (6,2,"sport",99,"體育99");
insert into grade(xid,student_id,course,grade,note) values (7,1,"music",80,"音樂80分");
insert into grade(xid,student_id,course,grade,note) values (8,2,"music",88,"音樂88分");
5.在mycat數據管理平臺上查詢數據是否正常
select * from grade;
七、檢驗分片枚舉
1.分別登陸兩臺mysql服務器,查看grade表裏的數據是否是按照語文(language)和數學(math)去分到了各自自定的服務器上的數據庫上了。
select * from grade;
2.同時看看體育和音樂成績的值都放到了哪個服務器上了
3.還可以回去修改rule.xml中的<property name="defaultNode">0</property>的值改爲1,即將默認的值存放到第二臺節點服務器上。然後再重啓mycat,再插入一些其他科目的數據進去,看看成績是不是跑到了第二臺服務器上了。
下圖可能跟本次試驗有點差別,因爲是用的其他電腦做的測試,剛纔開始<property name="defaultNode">的值我設置的是1,本次寫博客的時候又改成了0。如果看不懂本劇說的,完全可以忽略這兩行廢話。
----------------------END----------------2020年3月24日23:35:52-------------------------------------
寫帖子真心的累,純寫帖子+截圖,1個小時都算快的了,一般1個小時不可能寫完。網上的帖子不是這有坑,就是那有陷阱,像保安這樣完美的乾貨技術貼不多。
若是感覺對你有用,隨意贊助下,彌補一下我這顆快崩潰的心。
-------------------最後送上一碗雞湯:要拿執着將那苦逼的命運枷鎖打破----------------------------------------