使用mycat分表(一致性hash)

業務介紹

我們有一個橫向分表的業務,本來是想自己搞的,但也想嘗試下一些中間件,找到了mycat先試下,
現在是2017/12 , 版本採用 mycat1.6.5

安裝及相關內容
https://github.com/MyCATApache/Mycat-Server

mysql準備

創建三個db :db1,db2,db3,都加入這張表:

CREATE TABLE `travelrecord` (
  `id` bigint(20) NOT NULL,
  `user_id` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
  `traveldate` date DEFAULT NULL,
  `fee` decimal(10,0) DEFAULT NULL,
  `days` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

相關配置

cd /alidata/server/mycat/mycat

基本上默認配置 加下小修改就行了,主要是server.xml 和 scheme.xml
server.xml:

    <property name="serverPort">4566</property>
    <property name="managerPort">4567</property>  



    <firewall>
       <whitehost>
          <host host="*" user="abcefg"/>
       </whitehost>
       <blacklist check="false">
       </blacklist>
    </firewall>


    <user name="abcefg">
            <property name="password">abcefg2017</property>
            <property name="schemas">TESTDB</property>
    </user>

scheme.xml
按照官網的默認配置修改了下,簡單配置:


<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">;
        <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
                <!-- auto sharding by id (long) -->
                <table name="travelrecord" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
        </schema>
        <dataNode name="dn1" dataHost="localhost1" database="db1" />
        <dataNode name="dn2" dataHost="localhost1" database="db2" />
        <dataNode name="dn3" dataHost="localhost1" database="db3" />

        <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="hostS1" url="127.0.0.1:3306" user="mycat"
                                   password="mycat123" />

        </dataHost>
      </mycat:schema>

如果你的內存不太夠,記得改一下 wrapper.conf 裏面的內存配置,

mycat的服務(用mysql客戶端訪問):xxxx 端口 4566 , 用戶xxx,密碼 xxx2017

實際數據庫表地址: xxx 端口 3306 用戶mycat 密碼 mycat123 (裏面的dn1,dn2,dn3)

啓動

/xxx/mycat/mycat/bin/mycat start
/xxx/mycat/mycat/bin/mycat stop

mycat 的一些策略

mycat的分片規則有很多,可能參考 其文檔http://www.mycat.io/document/Mycat_V1.6.0.pdf
這裏寫圖片描述

具體在規則配置上,則是rule.xml中
以下爲我取的一個 一致性hash的配置

<function name="murmur"
                class="io.mycat.route.function.PartitionByMurmurHash">
                <property name="seed">0</property><!-- 默認是0 -->
                <property name="count">4</property><!-- 要分片的數據庫節點數量,必須指定,否則沒法分片 -->
                <property name="virtualBucketTimes">160</property><!-- 一個實際的數據庫節點被映射爲這麼多虛擬節點,默認是160倍,也就是虛擬節點數是物理節點數的160倍 -->
                <!-- <property name="weightMapFile">weightMapFile</property> 節點的權重,沒有指定權重的節點默認是1。以properties文件的格式填寫,以從0開始到count-1的整數值也就是節點索引爲key,以節點權重值爲值。所有權重值必須是正整數,否則
以1代替 -->
        </function>

如果要使用,建立一個tableRule,algorithm 引用這個murmur

        <tableRule name="rule-guid">
                <rule>
                        <columns>device_guid</columns>
                        <algorithm>murmur</algorithm>
                </rule>
        </tableRule>

在表映射中的scheme.xml中,則這樣引用

<table name="tx_device_user_jiguang" primaryKey="device_guid" subTables="tx_device_user_jiguang0$0-3" dataNode="dn1" rule="rule-guid" />

一致性hash的分析

我們要使用其一致性hash,但不知道其具體的規則,於是找他們的源碼以確認,源碼可在其github中找
PartitionByMurmurHash.java
發現這個類的init的時候調用生成bucketMap,

private void generateBucketMap(){
    hash=Hashing.murmur3_32(seed);//計算一致性哈希的對象
    for(int i=0;i<count;i++){//構造一致性哈希環,用TreeMap表示
        StringBuilder hashName=new StringBuilder("SHARD-").append(i);
        for(int n=0,shard=virtualBucketTimes*getWeight(i);n<shard;n++){
            bucketMap.put(hash.hashUnencodedChars(hashName.append("-NODE-").append(n)).asInt(),i);
        }
    }
    weightMap=null;
}

在其使用的時候則用

public Integer calculate(String columnValue) {
    SortedMap<Integer, Integer> tail = bucketMap.tailMap(hash.hashUnencodedChars(columnValue).asInt());
    if (tail.isEmpty()) {
        return bucketMap.get(bucketMap.firstKey());
    }
    return tail.get(tail.firstKey());
}

結合 一致性hash的邏輯,可以確認,generateBucketMap是 生成一個主機數*160(160是默認值)的treeMap,其val爲主機序列,而calculate的方法,入參爲 字段值,出參則爲 主機序列.

提示,網上很多說的bucketMapPath 這個rule.xml 的配置在這裏沒作用, 看源代碼,貌似被註釋了。。。

發佈了62 篇原創文章 · 獲贊 17 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章