天天看點

使用MyCat單庫分表實戰詳解場景實作配置真實伺服器資訊配置路由規則配置MyCat服務資訊啟動測試

場景

比如一個大型集團公司,有一張表record儲存了交易記錄資訊。該表資料量很大,但是查詢、更新時基本都是按子公司來操作。

那麼可以按子公司編号進行分表。例如子公司編号1的交易記錄存儲到record_1表,同理子公司編号為2的交易記錄儲存到record_2中…

實作

在mysql中建立資料庫執行個體dbcompany,并建立record0-record3,共4張表,代碼如下

CREATE TABLE `record_0` (
  `id` int(11) NOT NULL,
  `companyid` int(11) DEFAULT NULL COMMENT '子公司編号',
  `info` varchar(255) DEFAULT NULL COMMENT '業務資訊',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
           

CREATE TABLE

</span>record_1<span class="token punctuation">

(

</span>id<span class="token punctuation">

int(11) NOT NULL,

</span>companyid<span class="token punctuation">

int(11) DEFAULT NULL COMMENT ‘子公司編号’,

</span>info<span class="token punctuation">

varchar(255) DEFAULT NULL COMMENT ‘業務資訊’,

PRIMARY KEY (

</span>id<span class="token punctuation">

)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE

</span>record_2<span class="token punctuation">

(

</span>id<span class="token punctuation">

int(11) NOT NULL,

</span>companyid<span class="token punctuation">

int(11) DEFAULT NULL COMMENT ‘子公司編号’,

</span>info<span class="token punctuation">

varchar(255) DEFAULT NULL COMMENT ‘業務資訊’,

PRIMARY KEY (

</span>id<span class="token punctuation">

)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE

</span>record_3<span class="token punctuation">

(

</span>id<span class="token punctuation">

int(11) NOT NULL,

</span>companyid<span class="token punctuation">

int(11) DEFAULT NULL COMMENT ‘子公司編号’,

</span>info<span class="token punctuation">

varchar(255) DEFAULT NULL COMMENT ‘業務資訊’,

PRIMARY KEY (

</span>id<span class="token punctuation">

)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

配置真實伺服器資訊

通過修改conf/schema.xml,來配置真實伺服器的資訊,并為資料庫劃分節點,指定資料表所在的節點。

注意關鍵資訊為

subTables="record_$0-3"

rule="rule-record"

,通過規則分片後,資料會落入record_0至record_3中。

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
  <!-- name為邏輯資料庫名 -->
  <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
    <!-- 配置對應表名、子表名、對應資料庫、規則名 -->
    <table name="record" subTables="record_$0-3" dataNode="dn1" rule="rule-record" />
  </schema>
  <!-- 真實資料庫名 -->
  <dataNode name="dn1" dataHost="localhost1" database="dbcompany" />
  <!-- 配置實體資料庫連接配接資訊 -->
  <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
    <heartbeat>select user()</heartbeat>
    <writeHost host="hostM1" url="127.0.0.1:3306" user="root" password="[email protected]"/>
  </dataHost>
</mycat:schema>
           

配置路由規則

在schema.xml中我們已經制定了record表存儲的節點,且設定了路由規則的名稱rule-record,然後我們設定該規則具體的政策。

修改conf/role.xml,配置規則如下,注意我們是按

companyid列

來進行規則應用的。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:rule SYSTEM "rule.dtd">
<mycat:rule xmlns:mycat="http://io.mycat/">
  <!-- 規則 -->
  <tableRule name="rule-record">
    <rule>
      <!-- 規則應用的列 -->
      <columns>companyid</columns>
      <algorithm>mod-long</algorithm>
    </rule>
  </tableRule>
  <function name="mod-long" class="io.mycat.route.function.PartitionByMod">
    <!-- 此處設定有多少個子表即可 -->
    <property name="count">4</property>
  </function>
</mycat:rule>
           

配置MyCat服務資訊

通過上面兩個配置檔案,我們已指定了庫、表、分表路由規則,下面我們将其通過MyCat暴露出來,讓用戶端進行通路。

通過修改conf/server.xml配置MyCat對外服務資訊,主要就是使用者名、密碼、以及上面指定的抽象資料庫名稱TESTDB。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
  <!-- system部分采用預設即可 -->
  <system>
    <property name="nonePasswordLogin">0</property>    <!-- 0為需要密碼登陸、1為不需要密碼登陸 ,預設為0,設定為1則需要指定預設賬戶-->
    <property name="useHandshakeV10">1</property>
    <property name="useSqlStat">0</property>    <!-- 1為開啟實時統計、0為關閉 -->
    <property name="useGlobleTableCheck">0</property>    <!-- 1為開啟全加班一緻性檢測、0為關閉 -->
    <property name="sequnceHandlerType">2</property>
    <property name="subqueryRelationshipCheck">false</property>    <!-- 子查詢中存在關聯查詢的情況下,檢查關聯字段中是否有分片字段 .預設 false -->
    <!--預設為type 0: DirectByteBufferPool | type 1 ByteBufferArena | type 2 NettyBufferPool -->
    <property name="processorBufferPoolType">0</property>
    <!--分布式事務開關,0為不過濾分布式事務,1為過濾分布式事務(如果分布式事務内隻涉及全局表,則不過濾),2為不過濾分布式事務,但是記錄分布式事務日志-->
    <property name="handleDistributedTransactions">0</property>
    <!--off heap for merge/order/group/limit      1開啟   0關閉-->
    <property name="useOffHeapForMerge">1</property>
    <!--機關為m-->
    <property name="memoryPageSize">64k</property>
    <!--機關為k-->
    <property name="spillsFileBufferSize">1k</property>
    <property name="useStreamOutput">0</property>
    <!--機關為m-->
    <property name="systemReserveMemorySize">384m</property>
    <!--是否采用zookeeper協調切換  -->
    <property name="useZKSwitch">false</property>
  </system>
  <!-- 設定通路的使用者名密碼 -->
  <user name="root" defaultAccount="true">
    <property name="password">123456</property>
    <!-- 注意此處是之前設定的抽象資料庫名稱 -->
    <property name="schemas">TESTDB</property>
  </user>
</mycat:server>
           

啟動測試

輕按兩下bin/startup_nowrap.bat啟動MyCat,然後使用Navicat或其他工具連接配接MyCat虛拟的資料庫即可。

我們執行如下8條sql語句

insert into record (id,companyid,info)values(1,1,'test');
insert into record (id,companyid,info)values(4,2,'test');
insert into record (id,companyid,info)values(2,3,'test');
insert into record (id,companyid,info)values(3,4,'test');
insert into record (id,companyid,info)values(5,5,'test');
insert into record (id,companyid,info)values(7,6,'test');
insert into record (id,companyid,info)values(6,7,'test');
insert into record (id,companyid,info)values(8,8,'test');
           

執行完之後,我們看下真實實體資料庫中的資料:

record_0資料如下,說明是按companyid取模比對的,我們的政策生效了!

使用MyCat單庫分表實戰詳解場景實作配置真實伺服器資訊配置路由規則配置MyCat服務資訊啟動測試

其他三個庫也是按此規則運作的,即資料落入

record_[companyid%4]

表。