1.一致性Hash分片的概念

所谓的一致性哈希,指的是相同的哈希因子计算值总是会被划分到相同的分片节点上,也就是作为分表依据的字段说通过Hash计算的哈希因子计算值,具有相同计算值的数据会被划分到相同的分片节点中,是按照哈希因子的计算值进行水平分表的。

通过一致性哈希分片不会因为将来分片节点数的增加,而改变数据原来的存放位置,有效解决了分布式数据的问题。

Hash分片依据的字段值要求是UUID类型。

2.使用一致性Hash分片对某张表进行水平拆分

2.1.在所有的分片节点中创建表结构

分片依旧是2个,还是之前垂直分库分表时使用的两套双主双从集群。

#在分片1节点中创建表结构
[root@mysql-1 ~]# mysql -uroot -p123456 -P3306 -h 192.168.20.11
mysql> use db_2;
mysql> create table tb_order( id varchar(100) not null primary key, money int null, content varchar(200) null );


#在分片2节点中创建表结构
[root@mysql-1 ~]# mysql -uroot -p123456 -P3307 -h 192.168.20.11
mysql> use db_2;
mysql> create table tb_order( id varchar(100) not null primary key, money int null, content varchar(200) null );

2.2.配置Mycat实现一致性Hash分片的水平分表

2.2.1.配置Schema配置文件
[root@mysql-1 ~]# vim /data/mycat/conf/schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">  
<mycat:schema xmlns:mycat="http://io.mycat/">
         <!--定义逻辑库 库名叫做db_shopping 该逻辑库关联dn1这个数据节点-->
        <schema name="db_2" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
            <!--一致性Hash分片-->
            <table name="tb_order" dataNode="dn1,dn2" rule="sharding-by-murmur"/>
        </schema>  

        <!--定义数据节点 也就是分片 一个分片会关联一个数据主机组 然后对应真实的数据库名称-->
        <dataNode name="dn1" dataHost="mysqlcluster-1" database= "db_2" />          
        <dataNode name="dn2" dataHost="mysqlcluster-2" database= "db_2" />          

        <!--定义数据主机 在这个标签下定义具体的读写操作路由的数据库实例地址 schema、table划分如何指定的是该数据主机关联的数据节点 那么对应的库、表都会被存储在数据主机定义的数据库实例中-->
        <dataHost name="mysqlcluster-1" maxCon="1000" minCon="10" balance="1"  writeType="0" dbType="mysql"  dbDriver="native" switchType="1">    
                <heartbeat>select user()</heartbeat>  
                <!--定义写操作路由的数据库实例-->
                <writeHost host="c1-1-master3306" url="192.168.20.11:3306" user="root" password="123456">
                        <!--定义读操作路由的数据库实例-->
                        <readHost host="c1-1-slave3308" url="192.168.20.11:3308" user="root" password="123456" />
                </writeHost> 
                <!--备用的主库 也是提供写操作的数据库,当主库c1-1-master3306故障后 备用库开始提供写操作-->
                <writeHost host="c1-2-master3306" url="192.168.20.12:3306" user="root" password="123456">
                        <!--备用主库的从库 从始至终 只要备用主库不故障 会一直提供读服务-->
                        <readHost host="c1-2-slave3308" url="192.168.20.12:3308" user="root" password="123456" />
                </writeHost> 
        </dataHost>  

        <dataHost name="mysqlcluster-2" maxCon="1000" minCon="10" balance="1"  writeType="0" dbType="mysql"  dbDriver="native" switchType="1">    
                <heartbeat>select user()</heartbeat>  
                <writeHost host="c2-1-master3307" url="192.168.20.11:3307" user="root" password="123456">
                        <readHost host="c2-1-slave3309" url="192.168.20.11:3309" user="root" password="123456" />
                </writeHost> 
                <!--备用主库db3 主库db1故障后 开始提供写操作-->
                <writeHost host="c2-2-master3307" url="192.168.20.12:3307" user="root" password="123456">
                        <!--备用主库的从库 从始至终 只要备用主库不故障 会一直提供读服务-->
                        <readHost host="c2-2-slave3309" url="192.168.20.12:3309" user="root" password="123456" />
                </writeHost> 
        </dataHost>  

</mycat:schema>
2.2.2.配置Rule分片规则配置文件

如果我们以id列作为一致性哈希分片的依据列,那么就不需要调整分片规则了,只需要调整分片规则函数中的节点数量即可。

[root@mysql-1 ~]# vim /data/mycat/conf/rule.xml
	<tableRule name="sharding-by-murmur">
        <rule>
            <columns>id</columns>
            <algorithm>murmur</algorithm>
        </rule>
    </tableRule>

    <function name="murmur"
        class="io.mycat.route.function.PartitionByMurmurHash">
        <!-- 默认是0 -->
        <property name="seed">0</property>
        <!-- 要分片的数据库节点数量,必须指定,否则没法分片 -->
        <property name="count">2</property>
        <!-- 一个实际的数据库节点被映射为这么多虚拟节点,默认是160倍,也就是虚拟节点数是物理节点数的160
倍 -->
        <property name="virtualBucketTimes">160</property>
    </function>
2.2.3.配置Server配置文件
[root@mysql-1 ~]# vim /data/mycat/conf/server.xml
    <user name="root" defaultAccount="true">
        <!--登录用户的密码-->
        <property name="password">123456</property>
        <!--该用户登录后可以显示那些Schema-->
        <property name="schemas">db_2</property>
    </user>
2.2.4.重启Mycat
[root@mysql-1 ~]# mycat restart
Stopping Mycat-server...
Stopped Mycat-server.
Starting Mycat-server...

2.3.写入数据观察分片效果

[root@mysql-1 ~]# mysql -uroot -p123456 -P8066 -h 192.168.20.11
mysql> use db_2;
mysql> insert into tb_order (id,money,content) values ('b92fdaaf-6fc4-11ec-b831-482ae33c4a2d',10,'b92fdaf8-6fc4-11ec-b831-482ae33c4a2d');
mysql> insert into tb_order (id,money,content) values ('b93482b6-6fc4-11ec-b831-482ae33c4a2d',20,'b93482d5-6fc4-11ec-b831-482ae33c4a2d');
mysql> insert into tb_order (id,money,content) values ('b937e246-6fc4-11ec-b831-482ae33c4a2d',50,'b937e25d-6fc4-11ec-b831-482ae33c4a2d');
mysql> insert into tb_order (id,money,content) values ('b93be2dd-6fc4-11ec-b831-482ae33c4a2d',100,'b93be2f9-6fc4-11ec-b831-482ae33c4a2d');
mysql> insert into tb_order (id,money,content) values ('b93f2d68-6fc4-11ec-b831-482ae33c4a2d',130,'b93f2d7d-6fc4-11ec-b831-482ae33c4a2d');
mysql> insert into tb_order (id,money,content) values ('b9451b98-6fc4-11ec-b831-482ae33c4a2d',30,'b9451bcc-6fc4-11ec-b831-482ae33c4a2d');
mysql> insert into tb_order (id,money,content) values ('b9488ec1-6fc4-11ec-b831-482ae33c4a2d',560,'b9488edb-6fc4-11ec-b831-482ae33c4a2d');
mysql> insert into tb_order (id,money,content) values ('b94be6e6-6fc4-11ec-b831-482ae33c4a2d',10,'b94be6ff-6fc4-11ec-b831-482ae33c4a2d');
mysql> insert into tb_order (id,money,content) values ('b94ee10d-6fc4-11ec-b831-482ae33c4a2d',123,'b94ee12c-6fc4-11ec-b831-482ae33c4a2d');
mysql> insert into tb_order (id,money,content) values ('b952492a-6fc4-11ec-b831-482ae33c4a2d',145,'b9524945-6fc4-11ec-b831-482ae33c4a2d');
mysql> insert into tb_order (id,money,content) values ('b95553ac-6fc4-11ec-b831-482ae33c4a2d',543,'b95553c8-6fc4-11ec-b831-482ae33c4a2d');
mysql> insert into tb_order (id,money,content) values ('b9581cdd-6fc4-11ec-b831-482ae33c4a2d',17,'b9581cfa-6fc4-11ec-b831-482ae33c4a2d');
mysql> insert into tb_order (id,money,content) values ('b95afc0f-6fc4-11ec-b831-482ae33c4a2d',18,'b95afc2a-6fc4-11ec-b831-482ae33c4a2d');
mysql> insert into tb_order (id,money,content) values ('b95daa99-6fc4-11ec-b831-482ae33c4a2d',134,'b95daab2-6fc4-11ec-b831-482ae33c4a2d');

根据HASH算法,一部分数据写入到分片1节点中。

第109讲:Mycat实践指南:一致性Hash分片下的水平分表详解-LMLPHP

另一部分数据写入到了分片2节点中。

第109讲:Mycat实践指南:一致性Hash分片下的水平分表详解-LMLPHP

数据写入后在Mycat中可以看到完整表的数据。

第109讲:Mycat实践指南:一致性Hash分片下的水平分表详解-LMLPHP

03-16 18:21