mycat位于应用与数据库的中间层,可以灵活解耦应用与数据库,后端数据库可以位于不同的主机上。在mycat中将表分为两大类;对于数据量小且不需要做数据切片的表,称之为分片表;对于数据量大到单库性能,容量不足以支撑,数据通常需要通过水平切分均匀分布到不同的数据库中的表,称之为分片表。而中间件最终需要处理的数据是对数据切分,聚合。

上一片博文中,详细说明了mycat的server.xml, schema.xml, rule.xml配置文件,下面通过具体的实例,来说明分片的用法及类型。

在说明mycat分片类型之前,需要首先正确配置mycat配置文件。

配置server.xml配置文件: 这个文件如果不修改system标签中的属性,那么久可以默;这里通过实例来说明一下user标签!

        <user name="user">
<property name="password">user</property>
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property>
</user> #标签中的shcemas属性与schemal.xml配置文件中指定的schema标签的name属性值相等。在连接mycat客户端时,使用show databases命令就会看到这个值

server.xml文件中user标签

配置schema.xml配置文件: 这个文件配置相对比较多,可以有多个schema标签:

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100"> #上面提到过的schema标签
<!-- auto sharding by id (long) -->
<table name="employee" dataNode="dn1,dn2" rule="mod-long" /> #要分片的表,dataNode和下面的dataNode标签中name属性对应,rule指定分片规则,分片规则定义在rule.xml文件中 </schema>
<!-- <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743"
/> -->
<dataNode name="dn1" dataHost="backup-one" database="mytest" /> #分片服务器,一个服务器上可以放多个分片;这里是一个服务器防止一个分片,dataHost属性指向真正的后端服务器,database指定表在后端服务器上的schema
<dataNode name="dn2" dataHost="backup-two" database="mytest" /> <dataHost name="backup-one" maxCon="1000" minCon="10" balance="0" #dataHost标签:指定后端真实服务器,由name属性的值可以被dataNode引用
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat> #这个语句用于初始化每个服务器的连接,在主从配置的时候语句会不一样。
<writeHost host="hostS1" url="10.0.102.222:3306" user="root"
password="123456" />
</dataHost> <dataHost name="backup-two" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostS1" url="10.0.102.221:3306" user="root"
password="123456" />
</dataHost>
<!--
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" #dataHost里面是一个类似于主从的架构,但是可以像上面那样只配置一个服务器
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="hostM1" url="localhost:3306" user="root"
password="123456">
<readHost host="hostS2" url="192.168.1.200:3306" user="root" password="xxx" />
</writeHost>
<writeHost host="hostS1" url="localhost:3316" user="root"
password="123456" />
</dataHost> --> </mycat:schema>

rule.xml: 主要是分片规则和分片键的定义,会在具体分片类型的时候说明。

首先我们要在真实的服务器上,对应的schema中创建测试库:

mysql> CREATE table employee(id int, name varchar(30));
Query OK, 0 rows affected (0.05 sec) #连接mycat客户端
[root@test1 conf]# mysql -uroot -P8066 -h127.0.0.1
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.6.29-mycat-1.6-RELEASE-20161028204710 MyCat Server (OpenCloundDB) Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases;
+----------+
| DATABASE |
+----------+
| TESTDB |
+----------+
1 row in set (0.01 sec) mysql> use TESTDB;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A Database changed
mysql> show tables;
+------------------+
| Tables in TESTDB |
+------------------+
| employee |
+------------------+
1 row in set (0.00 sec) mysql>
  • 求模分片: 对分片的字段进行取模处理,配置如下:

            <tableRule name="mod-long">                              #分片规则名称
    <rule>
    <columns>id</columns> #进行分片的字段值
    <algorithm>mod-long</algorithm> #分片算法,由后面的function标签指定。
    </rule>
    </tableRule> <function name="mod-long" class="io.mycat.route.function.PartitionByMod">
    <!-- how many data nodes -->
    <property name="count">2</property> # 数据要分成几分片,这个值不能大于datanode指定的数值,不然会报错
    </function> 配置说明:
    上面说明columns标识将要分片的表字段,algorithm标识分片函数。
    此种配置非常明确即根据id进行十进制求模预算,相比固定分片的hash,此种在批量插入时可能存在批量插入单事务插入多数据分
    片,增大事务一致性难度。

    测试:

    #通过mycat客户端插入数据,
    mysql> insert into employee(id, name) values(1,"a");
    Query OK, 1 row affected (0.02 sec) mysql> insert into employee(id, name) values(2,"b");
    Query OK, 1 row affected (0.01 sec) mysql> insert into employee(id, name) values(3,"c");
    Query OK, 1 row affected (0.03 sec) mysql> insert into employee(id, name) values(4,"d");
    Query OK, 1 row affected (0.01 sec) mysql> insert into employee(id, name) values(5,"e");
    Query OK, 1 row affected (0.01 sec) mysql> insert into employee(id, name) values(6,"f");
    Query OK, 1 row affected (0.01 sec) #上面的6条数据会分以字段id的值为分片键,因为分片基数为2,所以数据分奇数,偶数分别存储到对应的服务器上。【id的值除以2取模,模的数值对应着对应的服务器】
    mysql> show @@datasource;
    +----------+--------+-------+--------------+------+------+--------+------+------+---------+-----------+------------+
    | DATANODE | NAME | TYPE | HOST | PORT | W/R | ACTIVE | IDLE | SIZE | EXECUTE | READ_LOAD | WRITE_LOAD |
    +----------+--------+-------+--------------+------+------+--------+------+------+---------+-----------+------------+
    | dn2 | hostS1 | mysql | 10.0.102.221 | 3306 | W | 0 | 10 | 1000 | 438 | 3 | 3 |
    | dn1 | hostS1 | mysql | 10.0.102.222 | 3306 | W | 0 | 10 | 1000 | 444 | 8 | 3 |
    +----------+--------+-------+--------------+------+------+--------+------+------+---------+-----------+------------+
    2 rows in set (0.01 sec)
  • 枚举分片: 通过配置文件中配置可能的枚举id,自己配置分片,本规则适用于特定的场景,比如有些业务需要按照省份或区县来保存,而全国省份是固定的,这类业务可以使用本条规则。配置如下:
            <tableRule name="sharding-by-intfile">
    <rule>
    <columns>name</columns> #枚举分片字段
    <algorithm>hash-int</algorithm>
    </rule>
    </tableRule> <function name="hash-int"
    class="io.mycat.route.function.PartitionByFileMap">
    <property name="mapFile">partition-hash-int.txt</property> #枚举需要一个文件来填写枚举数值与,服务器之间的映射。
    <property name="type">1</property> #值为0表示的是整型,非0表示string
    </function> #查看partition-hash-int.txt文件,文件就在当前配置文件目录下面
    [root@test1 conf]# cat partition-hash-int.txt
    zhao=0 #如果name的值为“zhao”则分片到第一个服务器
    qian=1 #插入数据测试
    mysql> insert into employee(id, name) values(1,"zhao");
    Query OK, 1 row affected (0.06 sec) mysql> insert into employee(id, name) values(2,"qian");
    Query OK, 1 row affected (0.01 sec) mysql> insert into employee(id, name) values(3,"wang"); #如果插入的值在映射文件中没有对应的映射则会报错,因此需要一个参数来配置默认的存储位置。
    ERROR 1064 (HY000): can't find any valid datanode :EMPLOYEE -> NAME -> wang <property name="defaultNode">1</property> #表示默认的配置文件,当插入的值在映射中找不到时就会插入到这个服务上。对应的映射配置文件如下
    [root@test1 conf]# cat partition-hash-int.txt 
    zhao=0
    qian=1
    DEFAULT_NODE=1
  • 范围分片,适用于想明确知道某个范围属于哪个分片。
    #第一修改schema.xml中的分片规则
    <table name="employee" dataNode="dn1,dn2" rule="auto-sharding-long" />
    #范围分片的rule文件不用修改,如下
    <tableRule name="auto-sharding-long">
    <rule>
    <columns>id</columns>
    <algorithm>rang-long</algorithm>
    </rule>
    </tableRule> <function name="rang-long"
    class="io.mycat.route.function.AutoPartitionByLong">
    <property name="mapFile">autopartition-long.txt</property> #指定映射文件的路径
    <property name="defaultNode">0</property> #默认分片
    </function> #查看autopartition-long.txt文件
    [root@test1 conf]# cat autopartition-long.txt
    # range start-end ,data node index
    # K=1000,M=10000. #在这个文件中,K表示1000, M表示10000.
    0-500=0 #0~500,分入第一个分片
    500-1000=1 #500~1000, 分入第二个分片

    测试数据:

    #连接mycat客户端,插入测试数据
    mysql> insert into employee(id, name) values(1,"a"),(501,"b");
    Query OK, 2 rows affected (0.01 sec) mysql> insert into employee(id, name) values(2,"a"),(502,"b");
    Query OK, 2 rows affected (0.01 sec)
    #连接到对应的mysql服务器查看,数据
    [root@test1 conf]# mysql -uroot -p123456 -h10.0.102.222 -e "select * from mytest.employee"
    mysql: [Warning] Using a password on the command line interface can be insecure.
    +------+------+
    | id | name |
    +------+------+
    | 1 | a |
    | 2 | a |
    +------+------+
    [root@test1 conf]# mysql -uroot -p123456 -h10.0.102.221 -e "select * from mytest.employee"
    mysql: [Warning] Using a password on the command line interface can be insecure.
    +------+------+
    | id | name |
    +------+------+
    | 501 | b |
    | 502 | b |
    +------+------+
    [root@test1 conf]#
  • 范围求模算法: 该算法为先进行范围分片,计算出分片组,组内再求模,综合了范围分片和求模分片的优点。分片组内使用求模可以保证组内的数据分布比较均匀,分片组之间采用范围分片可以兼顾范围分片的特点。事先规定好分片的数量,数据扩容时按分片组扩容,则原有分片组的数据不需要迁移。由于分片组内的数据分布比较均匀,所以分片组内可以避免热点数据问题。
    #注意修改schema.xml中分片算法名字       
    <tableRule name="auto-sharding-long">
    <rule>
    <columns>id</columns>
    <algorithm>rang-long</algorithm>
    </rule>
    </tableRule> <function name="rang-mod" class="io.mycat.route.function.PartitionByRangeMod">
    <property name="mapFile">partition-range-mod.txt</property>
    <property name="defaultNode">2</property>
    </function> #查看映射文件的数值
    [root@test1 conf]# cat partition-range-mod.txt
    # range start-end ,data node group size
    0-200M=5 #id取值在这个范围的有5个分片节点
    200M1-400M=1
    400M1-600M=4
    600M1-800M=4
    800M1-1000M=6 #这个分片算法需要的分片节点相对比较多,因此没有测试!首先根据id进行分组,然后再组内根据id的值进行取模求值,确定该记录究竟存在组内的哪一个节点上。
    #后续补上测试数据。
  • 固定分片哈希算法:本条规则类似于十进制的求模运算,区别在于是二进制的操作,是取id的二进制低10位,即id二进制&1111111111.此算法的优点在于如果按照10进制取模运算,在连续插入1-10时候1-10会被分到1-10个分片,增大了插入的事务控制难度,而此算法根据二进制则可能会分到连续的分片上,减少插入的事务控制难度。为了测试这个分片算法,我们在schema.xml中又添加了一个服务器,限制schema.xml配置文件如下:
            <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">
    <!-- auto sharding by id (long) -->
    <table name="employee" dataNode="dn1,dn2,dn3" rule="rule1" />
    </schema>
    <!-- <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743"
    /> -->
    <dataNode name="dn1" dataHost="backup-one" database="mytest" />
    <dataNode name="dn2" dataHost="backup-two" database="mytest" />
    <dataNode name="dn3" dataHost="backup-three" database="mytest" />
    <!--<dataNode name="dn4" dataHost="sequoiadb1" database="SAMPLE" />
    <dataNode name="jdbc_dn3" dataHost="jdbchost" database="db3" /> -->
    <dataHost name="backup-one" maxCon="1000" minCon="10" balance="0"
    writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
    <heartbeat>select user()</heartbeat>
    <writeHost host="hostS1" url="10.0.102.222:3306" user="root"
    password="123456" />
    </dataHost> <dataHost name="backup-two" maxCon="1000" minCon="10" balance="0"
    writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
    <heartbeat>select user()</heartbeat>
    <writeHost host="hostS2" url="10.0.102.221:3306" user="root"
    password="123456" />
    </dataHost> <dataHost name="backup-three" maxCon="1000" minCon="10" balance="0"
    writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
    <heartbeat>select user()</heartbeat>
    <writeHost host="hostS3" url="10.0.102.204:3306" user="root"
    password="123456" />
    </dataHost>

    schema.xml配置文件

    rule配置文件如下:

            <tableRule name="rule1">
    <rule>
    <columns>id</columns>
    <algorithm>func1</algorithm>
    </rule>
    </tableRule> <function name="func1" class="io.mycat.route.function.PartitionByLong">
    <property name="partitionCount">2,1</property>
    <property name="partitionLength">256,512</property>
    </function>   partitionCount属性表示分片的个数。
    partitionLength属性表示分片范围列表。
    分区长度默认为1024=2^10,最大长度也就为1024.
    约束条件:
    count,和length两个数组长度必须是一致的。
    count和length两个向量的点积恒等于1024.上面的256*2 + 512*1=1024.

    上面的分片把数据水平分为三分,那么究竟怎么分片呢?上面提到了分片键数值的二进制与1111111111(10个1)取与值,结果也就是分片键的二进制低10位的数值,因为2**10=1024,所以最大支持1024个分区。数据水平分为3分,前面分别为256:256:512。partitionCount取值中所有的分片个数为2+1=3;前2个分区中每个分区的范围是256,后面一个是512;恰好为1024.测试如下:

    #插入数据,分析数据插入哪个分片时,要使用分片键id值的低10位二进制数字。
    mysql> insert into employee(id, name) values(129,"a"),(145,"b");
    Query OK, 2 rows affected (0.01 sec)
    Records: 2 Duplicates: 0 Warnings: 0 mysql> insert into employee(id, name) values(257,"a"),(300,"b");
    Query OK, 2 rows affected (0.01 sec)
    Records: 2 Duplicates: 0 Warnings: 0 mysql> insert into employee(id, name) values(500,"a"),(600,"b");
    Query OK, 2 rows affected (0.01 sec) mysql> insert into employee(id, name) values(198,"a"),(734,"b");
    Query OK, 2 rows affected (0.03 sec) mysql> insert into employee(id, name) values(1444,"a"),(2345,"b");
    #十进制数1444,二进制表示为100 1010 0100,低10位的二进制数为:00 1010 0100,化为十进制数为420,因此在256~512这个区间。更快的方法是id值除以1024取模,哪个余数多少,就落在对应的空间。
    #1444*1024=1余420
    Query OK, 2 rows affected (0.00 sec)
    Records: 2 Duplicates: 0 Warnings: 0

    #查看数据分布
    [root@test1 conf]# mysql -uroot -p123456 -h10.0.102.222 -e "select * from mytest.employee"
    mysql: [Warning] Using a password on the command line interface can be insecure.
    +------+------+
    | id | name |
    +------+------+
    | 129 | a |
    | 145 | b |
    | 198 | a |
    +------+------+
    [root@test1 conf]# mysql -uroot -p123456 -h10.0.102.221 -e "select * from mytest.employee"
    mysql: [Warning] Using a password on the command line interface can be insecure.
    +------+------+
    | id | name |
    +------+------+
    | 257 | a |
    | 300 | b |
    | 500 | a |
    | 1444 | a |
    | 2345 | b |
    +------+------+
    [root@test1 conf]# mysql -uroot -p123456 -h10.0.102.204 -e "select * from mytest.employee"
    mysql: [Warning] Using a password on the command line interface can be insecure.
    +------+------+
    | id | name |
    +------+------+
    | 600 | b |
    | 734 | b |
    +------+------+
  • 取模范围算法: 此种规则是取模运算与范围约束结合,主要为了后续数据迁移做准备,即可以自主决定取模后数据的节点分别。
    #schema.xml中选择算法
    <table name="employee" dataNode="dn1,dn2,dn3" rule="sharding-by-pattern" /> #这个算法在rule默认文件中并没有,因此需要自己编写对应的参数,调用接口即可!
    <tableRule name="sharding-by-pattern">
    <rule>
    <columns>id</columns>
    <algorithm>sharding-by-pattern</algorithm>
    </rule>
    </tableRule> <function name="sharding-by-pattern"
    class="io.mycat.route.function.PartitionByPattern">
    <property name="mapFile">partition-pattern.txt</property>
    <property name="patternValue">8</property>
    <property name="defaultNode">2</property>
    </function> patternValue: 即求模基数 #这里需要注意tableRule标签和function标签不要写一块,不然会报错,【感觉很奇怪,就像这样写一块会报如下错误,但是若是分开写就可以】
    The content of element type "mycat:rule" must match "(tableRule*,function*)". #然后编写映射文件
    [root@test1 conf]# cat partition-pattern.txt
    0-3=0
    4-6=1
    7-8=2 id除以求模基数,得到的余数在0-3之间的分配到第一个节点。依次类推。如果id为非数值类型,则会分配到默认节点。
  • 字符串hash求模范围算法: 与取模范围算法类似,该算法支持数值,符合,字母取模。
    <table name="employee" dataNode="dn1,dn2,dn3" rule="sharding-by-prefixpattern" />
    
    #rule.xml配置文件如下
    <tableRule name="sharding-by-prefixpattern">
    <rule>
    <columns>name</columns>
    <algorithm>sharding-by-prefixpattern</algorithm>
    </rule>
    </tableRule> <function name="sharding-by-prefixpattern"
    class="io.mycat.route.function.PartitionByPrefixPattern">
    <property name="mapFile">partition-pattern.txt</property>
    <property name="patternValue">8</property>
    <property name="prefixLength">1</property>
    </function>
    #patternValue为求模基数
    #prefixLength:为截取的位数
    #mapFile为配置文件
    [root@test1 conf]# cat partition-pattern.txt
    0-3=0
    4-6=1
    7-8=2 #说明,该算法与取模范围算法类似,截取长度为prefixLength的子串,再对子串的每个字符的ASCII码求sum,然后再对sum的值以patternValue为基数求模。
    #这里为了测试方便prefixLength长度设置为了1.

    测试数据如下:

    先插入数据
    mysql> insert into employee(id, name) values(11,"ano");
    Query OK, 1 row affected (0.01 sec) mysql> insert into employee(id, name) values(12,"eno");
    Query OK, 1 row affected (0.01 sec) mysql> insert into employee(id, name) values(13,"gno");
    Query OK, 1 row affected (0.03 sec) #查看插入数据的数据分布
    [root@test1 conf]# mysql -uroot -p123456 -h10.0.102.204 -e "select * from mytest.employee"
    mysql: [Warning] Using a password on the command line interface can be insecure.
    +------+------+
    | id | name |
    +------+------+
    | 13 | gno |
    +------+------+
    [root@test1 conf]# mysql -uroot -p123456 -h10.0.102.221 -e "select * from mytest.employee"
    mysql: [Warning] Using a password on the command line interface can be insecure.
    +------+------+
    | id | name |
    +------+------+
    | 12 | eno |
    +------+------+
    [root@test1 conf]# mysql -uroot -p123456 -h10.0.102.222 -e "select * from mytest.employee"
    mysql: [Warning] Using a password on the command line interface can be insecure.
    +------+------+
    | id | name |
    +------+------+
    | 11 | ano |
  • 应用指定算法: 此规则是在运行阶段由自主决定路由到那个分片。
     <table name="employee" dataNode="dn1,dn2,dn3" rule="sharding-by-substring" />
    
    #rule.xml配置如下:
    <tableRule name="sharding-by-substring">
    <rule>
    <columns>id</columns>
    <algorithm>sharding-by-substring</algorithm>
    </rule>
    </tableRule> <function name="sharding-by-substring"
    class="io.mycat.route.function.PartitionDirectBySubString">
    <property name="startIndex">0</property>
    <property name="size">2</property>
    <property name="partitionCount">3</property>
    <property name="defautlPartition">0</property>
    </function>
    #直接根据子字串(必须是数字)计算分区号(由应用传递函数,显式指定分区号)。例如id=05-10043,其中分区号是从startindex=0的位置开始截取,然后截取2个字节的数字,
    #即05, 表示第5个分区。

    测试数据:

    #mysql直接插入以0开始的数字,存储时会自动把0去掉,可以在对应字段上添加zerofill属性,但是这样只是在显示的时候,不够指定的位数时补上0而已。
    #因此这里把id的属性由int类型修改为varchar类型,这样就可以作为字符串存储了。若是不想修改字符串类型,毕竟如果表特别大,这是一个代价很大的操作。
    #可以修改rule的配置文件,把startIndex修改为不是0开始的,这样也是可以的。
    mysql> alter table employee modify id varchar(10);
    Query OK, 3 rows affected (0.16 sec)
    Records: 0 Duplicates: 0 Warnings: 0 mysql> insert into employee(id, name) values("014354","first");
    Query OK, 1 row affected (0.01 sec) mysql> insert into employee(id, name) values("025463","second");
    Query OK, 1 row affected (0.03 sec) mysql> insert into employee(id, name) values("039864","third");
    Query OK, 1 row affected (0.04 sec) mysql> insert into employee(id, name) values("099864","third");
    Query OK, 1 row affected (0.01 sec) [root@test1 conf]# mysql -uroot -p123456 -h10.0.102.222 -e "select * from mytest.employee"
    mysql: [Warning] Using a password on the command line interface can be insecure.
    +--------+-------+
    | id | name |
    +--------+-------+
    | 039864 | third |
    +--------+-------+
    [root@test1 conf]# mysql -uroot -p123456 -h10.0.102.221 -e "select * from mytest.employee"
    mysql: [Warning] Using a password on the command line interface can be insecure.
    +--------+-------+
    | id | name |
    +--------+-------+
    | 014354 | first |
    +--------+-------+
    [root@test1 conf]# mysql -uroot -p123456 -h10.0.102.204 -e "select * from mytest.employee"
    mysql: [Warning] Using a password on the command line interface can be insecure.
    +--------+--------+
    | id | name |
    +--------+--------+
    | 025463 | second |
    +--------+--------+
  • 一致性哈希算法:一致性哈希算法有效的解决了数据的扩容问题。
  • 按时间分片:这个按时间分片范围有点大,mycat支持可以使用按天,按小时,按自然月的分片算法。这里仅通过一个按自然月分片的算法实例,说明其用法。按月分片时:单月内按小时拆分,最小粒度是小时,一天最多可以有24个分片,最少1个分片,下个月从头开始,每个月末需要手工清理数据。自然月分片使用场景为按月份分区,每个自然月一个分区,查询条例时使用between and。

    <table name="employee" dataNode="dn1,dn2,dn3" rule="sharding-by-month" />
    
    #rule.xml配置文件
    
            <tableRule name="sharding-by-month">
    <rule>
    <columns>id</columns>
    <algorithm>partbymonth</algorithm>
    </rule>
    </tableRule> <function name="partbymonth"
    class="io.mycat.route.function.PartitionByMonth">
    <property name="dateFormat">yyyy-MM-dd</property>
    <property name="sBeginDate">2018-11-01</property>
    </function> #dataFormat: 为日期格式
    #sBeginDate: 为开始日期

    测试:

    因为测试只有3个分片,因此上面的哪个开始日期选择的是距现在3个月的时间。
    在测试之前需要修改表字段类型为date:
    mysql> alter table employee modify id date;
    Query OK, 0 rows affected (0.08 sec)
    Records: 0 Duplicates: 0 Warnings: 0 #插入数据
    mysql> insert into employee(id, name) values("2018-11-23", "fuck");
    Query OK, 1 row affected (0.00 sec) mysql> insert into employee(id, name) values("2018-12-15", "what a fuck");
    Query OK, 1 row affected (0.01 sec) mysql> insert into employee(id, name) values("2019-1-16", "yesterday");
    Query OK, 1 row affected (0.03 sec)
    #查看数据
    [root@test1 conf]# mysql -uroot -p123456 -h10.0.102.221 -e "select * from mytest.employee"
    mysql: [Warning] Using a password on the command line interface can be insecure.
    +------------+-------------+
    | id | name |
    +------------+-------------+
    | 2018-12-15 | what a fuck |
    +------------+-------------+
    [root@test1 conf]# mysql -uroot -p123456 -h10.0.102.222 -e "select * from mytest.employee"
    mysql: [Warning] Using a password on the command line interface can be insecure.
    +------------+------+
    | id | name |
    +------------+------+
    | 2018-11-23 | fuck |
    +------------+------+
    [root@test1 conf]# mysql -uroot -p123456 -h10.0.102.204 -e "select * from mytest.employee"
    mysql: [Warning] Using a password on the command line interface can be insecure.
    +------------+-----------+
    | id | name |
    +------------+-----------+
    | 2019-01-16 | yesterday |
    +------------+-----------+ #插入一个在分片时间区间之外的时间,会报错
    mysql> insert into employee(id, name) values("2018-1-16", "yesterday");
    ERROR 1064 (HY000): Can't find a valid data node for specified node index :EMPLOYEE -> ID -> 2018-1-16 -> Index : -10
    mysql>
  • 一致性哈希算法:一致性hash算法有效解决了分布式数据的扩容问题,
    <table name="employee" dataNode="dn1,dn2,dn3" rule="sharding-by-murmur" />
    
    #rule配置文件如下
    <tableRule name="sharding-by-murmur">
    <rule>
    <columns>id</columns>
    <algorithm>murmur</algorithm>
    </rule>
    </tableRule> <function name="murmur"
    class="io.mycat.route.function.PartitionByMurmurHash">
    <property name="seed">0</property><!-- 默认是0 -->
    <property name="count">3</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>

    测试:

    mysql> insert into employee(id, name) values(12,"a");
    Query OK, 1 row affected (0.02 sec) mysql> insert into employee(id, name) values(34,"b");
    Query OK, 1 row affected (0.01 sec) mysql> insert into employee(id, name) values(56,"7");
    Query OK, 1 row affected (0.02 sec) #查看数据
    [root@test1 conf]# mysql -uroot -p123456 -h10.0.102.204 -e "select * from mytest.employee"
    mysql: [Warning] Using a password on the command line interface can be insecure.
    +------+------+
    | id | name |
    +------+------+
    | 12 | a |
    +------+------+
    [root@test1 conf]# mysql -uroot -p123456 -h10.0.102.222 -e "select * from mytest.employee"
    mysql: [Warning] Using a password on the command line interface can be insecure.
    +------+------+
    | id | name |
    +------+------+
    | 34 | b |
    +------+------+
    [root@test1 conf]# mysql -uroot -p123456 -h10.0.102.221 -e "select * from mytest.employee"
    mysql: [Warning] Using a password on the command line interface can be insecure.
    +------+------+
    | id | name |
    +------+------+
    | 56 | 7 |
    +------+------+

    网上看到一片博文,说明了一致性hash算法:https://blog.csdn.net/ydyang1126/article/details/70313981

  • 字符串hash解析算法【暂时没有找到资料,网上资料净抄袭】

mycat分片操作的更多相关文章

  1. Mysql系列八:Mycat和Sharding-jdbc的区别、Mycat分片join、Mycat分页中的坑、Mycat注解、Catlet使用

    一.Mycat和Sharding-jdbc的区别 1)mycat是一个中间件的第三方应用,sharding-jdbc是一个jar包 2)使用mycat时不需要改代码,而使用sharding-jdbc时 ...

  2. Mysql系列六:(Mycat分片路由原理、Mycat常用分片规则及对应源码介绍)

    一.Mycat分片路由原理 我们先来看下面的一个SQL在Mycat里面是如何执行的: , ); 有3个分片dn1,dn2,dn3, id=5000001这条数据在dn2上,id=10000001这条数 ...

  3. mycat分片及主从(二)

    一.mycat分片规则 经过上一篇幅讲解,应该很清楚分片规则配置文件rule.xml位于$MYCAT_HOME/conf目录,它定义了所有拆分表的规则.在使用过程中可以灵活使用不同的分片算法,或者对同 ...

  4. [置顶] MongoDB 分布式操作——分片操作

    MongoDB 分布式操作——分片操作 描述: 像其它分布式数据库一样,MongoDB同样支持分布式操作,且MongoDB将分布式已经集成到数据库中,其分布式体系如下图所示: 所谓的片,其实就是一个单 ...

  5. Mongodb 分片操作 介绍

    为什么需要分片操作?由于数据量太大,使得CPU,内存,磁盘I/O等压力过大.当MongoDB存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的读写吞吐量.这时,我们就可以通过在多台 ...

  6. mycat分片规则之分片枚举(sharding-by-intinfile)

    mycat分片规则之分片枚举(sharding-by-intinfile) http://blog.51cto.com/goome/2058959 mycat安装及分片初体验 https://blog ...

  7. Solr分片机制以及Solrcloud搭建及分片操作

    Solr分片描述 分片是集合的逻辑分区,包含集合中文档的子集,这样集合中的每个文档都正好包含在一个分片中.集合中包含每个文档的分片取决于集合的整体"分片"策略. 当您的集合对于一个 ...

  8. Mycat 分片规则详解--数据迁移及节点扩容

    使用的是 Mycat 提供的 dataMigrate 脚本进行对数据进行迁移和节点扩容,目前支持的 Mycat 是1.6 版本,由于 Mycat 是由 Java 编写的因此在做数据迁移及节点扩容时需要 ...

  9. Mycat 分片规则详解--固定 hash 分片

    实现方式:该算法类似于十进制的求模运算,但是为二进制的操作,例如,取 id 的二进制低 10 位 与 1111111111 进行 & 运算 优点:这种策略比较灵活,可以均匀分配也可以非均匀分配 ...

随机推荐

  1. Exception in thread “main” java.sql.SQLException: No suitable driver

    问题背景:通过Spark SQL的jdbc去读取Oracle数据做测试,在本地的idea中没有报任务错误.但是打包到集群的时候报: Exception in thread “main” java.sq ...

  2. [py]super调用父类的方法---面向对象

    super()用于调用父类方法 http://www.runoob.com/python/python-func-super.html super() 函数是用于调用父类(超类)的一个方法. clas ...

  3. [LeetCode] 124. Binary Tree Maximum Path Sum_ Hard tag: DFS recursive, Divide and conquer

    Given a non-empty binary tree, find the maximum path sum. For this problem, a path is defined as any ...

  4. Generator yield语法和 co模块

    Generator  yield 语法使用,也叫生成器,实际上就是多个异步按顺序执行 1.下面是一个读取两个文件的例子 const fs = require('fs'); const readFile ...

  5. Go win32 - 1

    上次说到,我们的GO可以执行系统调用,嘿嘿 不假,但如果你认为你已经掌握了,哈哈,那么不然 网上的例子,总是不深入,不彻底,除非是官网上的demo,也就是说只有设计者才知道告诉你什么才是它设计的正真意 ...

  6. 第一章入门篇CSS样式的分类、盒模型

    1.CSS样式的分类 CSS样式分为一项4种: 1.内联样式表,直接写在元素style属性里面的样式,如 <p style="color:red;">内联样式</ ...

  7. Xcode 常用命令

    一些自己在开发过程中总结的命令,并不是完整的,会不断的更新. 1.图片转png格式 sips -s format png start.jpg --out StartBg.png 转换时,先cd 当前图 ...

  8. sqli-labs(八)——修改密码处sql注入+http头sql注入

    第17关: 这是一个重置密码的功能存在sqk注入,尝试账号密码都输入'",发现只会显示登陆失败,没有报错信息. 这个时候先推测一下后台的sql形式大概应该是: update users se ...

  9. C#中换行的代码

    1.Windows 中的换行符"\r\n"2.Unix/Linux 平台换行符是 "\n".3.MessageBox.Show() 的换行符为 "\n ...

  10. 深入解析Java反射(1) - 基础

    深入解析Java反射(1) - 基础 最近正筹备Samsara框架的开发,而其中的IOC部分非常依靠反射,因此趁这个机会来总结一下关于Java反射的一些知识.本篇为基本篇,基于JDK 1.8. 一.回 ...