MyCat實現分庫分表讀寫分離

本文介紹了如何使用MyCat中間件來實現分庫分表、讀寫分離等功能。

1.安裝

下載地址 http://mycat.io/

下載完成解壓即可。

2.分表

2.1.使用id的范圍來分表

1、添加訪問用戶和使用的邏輯數據庫
conf/server.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
    <user name="root">
        <property name="password">root</property>
        <property name="schemas">db</property>
    </user>
</mycat:server>

2、配置邏輯數據庫的表節點、以及指定rang-long分片規則
conf/schema.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
    <!-- 配置邏輯數據庫 -->
    <schema name="db" checkSQLschema="false" sqlMaxLimit="100">
        <!-- 配置邏輯表,以及對應的子表和分片規則 -->
        <table name="tb" dataNode="dn1" primaryKey="id" subTables="tb$0-2" rule="rang-long" />
    </schema>
    <!-- 配置節點 -->
    <dataNode name="dn1" dataHost="dh1" database="db1" />
    <!-- 配置節點的地址 -->
    <dataHost name="dh1" 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="127.0.0.1:3306" user="root" password="root">
            <!-- can have multi read hosts -->
            <readHost host="hostS2" url="127.0.0.1:3306" user="root" password="root" />
        </writeHost>
    </dataHost>
</mycat:schema>

這里邏輯數據庫db下的邏輯表tb對應 127.0.0.1:3306 下物理數據庫db1下的tb0、tb1、tb2字表,這里分表的規則為根據id使用rang-long規則來分表

3、配置分片規則
conf/rule.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
    <!-- 定義rang-long規則 -->
    <tableRule name="rang-long">
        <rule>
            <columns>id</columns>
            <!-- 使用rang-long方法 -->
            <algorithm>rang-long</algorithm>
        </rule>
    </tableRule>
    <!-- 定義rang-long方法 -->
    <function name="rang-long"
        class="io.mycat.route.function.AutoPartitionByLong">
        <!-- 配置id范圍對應表規則 -->
        <property name="mapFile">autopartition-long.txt</property>
    </function>
</mycat:rule>

4、配置具體id對應的表范圍
conf/autopartition-rang.txt

# range start-end ,data node index
# K=1000,M=10000.
0-500M=0
500M-1000M=1
1000M-1500M=2

配置0-500w選擇tb$0、500w-1000w選擇tb$1、1000w-1500w選擇tb$2

4、測試

CREATE TABLE `db1`.`tb0`(  
  `id` BIGINT NOT NULL,
  `name` VARCHAR(100),
  PRIMARY KEY (`id`)
);

新建 數據庫db1以及數據表tb0、tb1、tb2、
然后連接Mycat的邏輯數據庫db,往邏輯表tb里插入3條數據,地址127.0.0.1:8066


邏輯表
INSERT INTO tb(id,NAME) VALUES(2500000,'tb0');
INSERT INTO tb(id,NAME) VALUES(7500000,'tb1');
INSERT INTO tb(id,NAME) VALUES(12500000,'tb2');
SELECT * FROM tb;

查看物理表里的數據


物理表.gif

可以看到三條數據分別進入到三個物理表,至此單庫分表已經完成。

3.分庫

3.1.根據id取模

1、添加訪問用戶和使用的邏輯數據庫
conf/server.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
    <user name="root">
        <property name="password">root</property>
        <property name="schemas">db</property>
    </user>
</mycat:server>

2、配置邏輯數據庫的表節點、以及指定mod-long分片規則
conf/schema.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
    <!-- 配置邏輯數據庫 -->
    <schema name="db" checkSQLschema="false" sqlMaxLimit="100">
        <!-- 配置邏輯表,以及對應的子表和分片規則 -->
        <table name="tb" dataNode="dn1,dn2" primaryKey="id" rule="mod-long" />
    </schema>
    <!-- 配置節點 -->
    <dataNode name="dn1" dataHost="dh1" database="db1" />
    <dataNode name="dn2" dataHost="dh2" database="db2" />
    <!-- 配置節點的地址 -->
    <dataHost name="dh1" 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="127.0.0.1:3306" user="root" password="root">
            <!-- can have multi read hosts -->
            <readHost host="hostS2" url="127.0.0.1:3306" user="root" password="root" />
        </writeHost>
    </dataHost>
    <dataHost name="dh2" 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="127.0.0.1:3306" user="root" password="root">
            <!-- can have multi read hosts -->
            <readHost host="hostS2" url="127.0.0.1:3306" user="root" password="root" />
        </writeHost>
    </dataHost>
</mycat:schema>

這里邏輯數據庫db下的邏輯表tb對應 127.0.0.1:3306 下物理數據庫db1下和db2里的tb表,這里分庫的規則為根據id使用mod-long規則來分表

3、配置mod-long分片規則
conf/rule.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
    <tableRule name="mod-long">
        <rule>
            <columns>id</columns>
            <algorithm>mod-long</algorithm>
        </rule>
    </tableRule>
    <function name="mod-long" class="io.mycat.route.function.PartitionByMod">
        <!-- how many data nodes -->
        <property name="count">2</property>
    </function>
</mycat:rule>

4.測試

INSERT INTO tb(id,NAME) VALUES(1,'db1.tb');
INSERT INTO tb(id,NAME) VALUES(2,'db2.tb');
物理數據庫

4.讀寫分離

1、添加訪問用戶和使用的邏輯數據庫
conf/server.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
    <user name="root">
        <property name="password">root</property>
        <property name="schemas">db</property>
    </user>
</mycat:server>

2、配置邏輯數據庫的表節點、以及指定mod-long分片規則
conf/schema.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
    <!-- 配置邏輯數據庫 -->
    <schema name="db" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1,dn2">
    </schema>
    <!-- 配置節點 -->
    <dataNode name="dn1" dataHost="dh1" database="db1" />
    <!-- 配置節點的地址 -->
    <dataHost name="dh1" maxCon="1000" minCon="10" balance="3"
              writeType="0" dbType="mysql" dbDriver="native" switchType="-1"  slaveThreshold="100">
        <heartbeat>select user()</heartbeat>
        <!-- can have multi write hosts -->
        <writeHost host="hostM1" url="127.0.0.1:3306" user="root" password="root">
            <!-- can have multi read hosts -->
            <readHost host="hostS2" url="127.0.0.1:3307" user="root" password="root" />
        </writeHost>
    </dataHost>
</mycat:schema>

這里邏輯數據庫db對應127.0.0.1:3306 和 127.0.0.1:3307 下的db1數據庫,其中3306負責寫,3307負責讀,3307作為3306的從庫。
這里面,有兩個參數需要注意,balance和 switchType。

其中,balance指的負載均衡類型,目前的取值有4種:

  1. balance="0", 不開啟讀寫分離機制,所有讀操作都發送到當前可用的writeHost上。
  2. balance="1",全部的readHost與stand by writeHost參與select語句的負載均衡,簡單的說,當雙主雙從模式(M1->S1,M2->S2,并且M1與 M2互為主備),正常情況下,M2,S1,S2都參與select語句的負載均衡。
  3. balance="2",所有讀操作都隨機的在writeHost、readhost上分發。
  4. balance="3",所有讀請求隨機的分發到wiriterHost對應的readhost執行,writerHost不負擔讀壓力

switchType指的是切換的模式,目前的取值也有4種:

  1. switchType='-1' 表示不自動切換
  2. switchType='1' 默認值,表示自動切換
  3. switchType='2' 基于MySQL主從同步的狀態決定是否切換,心跳語句為 show slave status
  4. switchType='3'基于MySQL galary cluster的切換機制(適合集群)(1.4.1),心跳語句為 show status like 'wsrep%'。

參考:
MyCAT實現MySQL的讀寫分離

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。