开发者学堂课程【全面讲解开源数据库中间件MyCat使用及原理(二):MyCat - 分片 - 分片规则 - 固定分片 hash 算法】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/756/detail/13269
MyCat - 分片 - 分片规则 - 固定分片 hash 算法
内容介绍:
一、固定分片 hash 算法
二、测试
一、固定分片 hash 算法
1.算法
现在讲解固定分片 hash 算法,这种算法类似于十进制的求模运算,但是却不是十进制的操作而是二进制的操作,举个例子:如果根据 ID 字段进行分片,采用这种方法进行分片,这时会取 ID 的二进制低 10 位,也就是将 ID 转化为二进制然后取后面的十位并且与十个一进行位与运算,最终 ID 低的二进制的十位与十个一进行位与运算的结果实际上是这样的。
最小值不外乎是 ID 的二进制低十位全部是零,这时位与上 111111111 结果就是全部都是零,转化为十进制就是零,最大值是 ID 的低十位制全部都是 1,全部都是一之后再与上 1111111111,计算出来的结果就是十个一,十个一实际上就是2的10 次方减一,最终算出来的结果是 1023,一共有 1024 个值,他的值介于 0~1023 之间,也就是说无论是哪个 ID,算出来的 hash 值与上 1111111111 最终的值都是介于 0~1023 之间
2.优点
这种策略比较灵活,可以均匀分配,也可以非均匀分配,各节点的分配比例和容量大小由 partitioncount 和 partitionlength 两个参数定,一个是分配比例的参数,一个是容量的参数
3.缺点
和取模分片类似
4.配置
在 ruler.node 可以去配置一个这样的分片规则,然后指定要按照哪个字段进行分片,按照 br and _ id,算法名称是 func1,分片的处理类是 PartitionByLong,这里有两个属性,一个是 partitionCount,一个是 partitionL ength,partitionCount 代表的是分片个数的列表,一个是两个分片,一个是一个分片,partitionL ength 指的是分片范围的列表,在刚才算出的 1024,不管是哪一个 ID和十个一进行位与运算算出来的值永远在 0~1023 之间 2,1 代表分片列表的数量,也就是说这 1024 个数会分为两块区域,第一块儿区域里面有两个分片,每一个分片占 256 个长度,1024 从中间一分,左边为二,右边为二,左边 512 在中间又分,也就是第一个部分的区域是 0~256 个区间,第二个部分的直径与 256 和512 之间,后面的部分介于 512~1023 之间,会泽这片区域整个长度分为三份,如果算出来的值介于 0~256 之间会存储到第一个节点,算出来的值在 256~512 之间会存储在第二个节点,算出来的值如果在 512~1023 之间会存储在第三个节点,所以在上面的分片示例中将数据分为三份,前两份各占 25%,第三份占 50%
< tableRule name =" sharding - by - long - hash ”
< rule >
< columns > br and _ id </ columns >< algorithm >func1</ algorithm ></ rule >
</ tableRule >
< function name ="func1" class =" org . opencloudb . route . function . PartitionByLong ">
< property name =" partitionCount ">2,1</ proper ty >
< property name =" partitionL ength ">256,512</ property </ function >
5.约束
(1)分片长度也就是 partitionL ength,默认最大为 1024
(2)Count 和 length 的数据组长度必须是一致的,也就是 partitionCount ">2,1partitionL ength ">256,512,必须是一致的,二代表是有两个分片,它的长度都是 256,有一个分片的长度是 512
二、测试
下面进行一个简单的测试,对固定分片 hash 算法有一个深刻的了解。
1.配置
< table name =" tb _brand ” dataNode =' dnl ,dn2,dn3" rule =" sharding - by - long - hash "/>
首先在 schema.xml 增加一个逻辑表,逻辑表叫做 tb_ brand,指定一个分片规则sharding - by - long - hash 保存
接下来在 ruler.xml 中指定这个分片规则,这个分片规则在原来 ruler.xml 中是并没有定义的,这个分片规则需要自己定义,将 < talbleRule name=ruler> 换为< talbleRule name=sharding - by - long - hash>,fun1 向下走,func 对应的就是 PartitionByLong,里面两个参数一个是 partitionCount 一个是partitionLength
< function name =" funcl "clas8=" io . mycat . route . function . PartitionByLong ">
< property name =" partitionCount ">2,1</ property property
Bame =' partitionLength ">256,512</property2
</ funetion >
2.测试
配置好以后进行测试,首先需要先重启一下 my cat,cd/usr/local/mycat/ 重新启动 mycat,执行 bin 目录下的 bin/mycat restart,mycat 重启之后重新连接mycat,连接好以后 show databases
可以看到逻辑库已经有了,接下来执行一个操作 use PARTITION_DB 切换一下数据库,数据库切换过来以后,通过 show tables 查看一下里面的逻辑表
逻辑表已经有了,接下来先创建表
CREATE TABLE “ tb _ br and (
id int (11) NOTNULL cOMMENT ' ID ',
name var char (200) DEFAULT NULL cOMMENT ‘名称’, firstChar char (1) coMMENT '首字母’,
PRIMARY KEY ( id )
) ENGINE = InnoDB DEFAULT CHARSET =utf8mb4;
执行表结构已经有了,还需要向这个表中插入数据,这个表结构中现在是没有数据的
insert into tb brand ( id , name , firstChar ) values (1,'七匹狼’,' Q );
insert into tb _ br and ( id , name , firstChar ) values (529,八匹狼',' B ');
insert into tb _ brand ( id , name , firstChar ) values (1203,'九匹狼",'3);
insert into tb _ brand ( id , name , frstChar ) values (1205,'十匹狼’,' S ');
insert into tb _ br and ( id , name , firstChar ) values (1719,'六匹狼",' L ');
将这些数据直接插入进去,接下来大家可以思考一下这些数据在哪个节点中存储,这里的数据 1,529,1203,1205,1719 是乱的,是随便插入的 ID,接下来执行select*from tb_brand
数据确实是插入进来了,到底插入到了哪个节点中,
select*from tb_brand
看到第一个节点存储了三条,再 select*from tb_brand
第二个节点没有,再select*from tb_brand
第三个节点中有两条,实际上分配规则是根据拿到 ID 值的后十位,进行位与运算,与上十个 1,与上十个 1 以后就可以拿到结果,通过结果判定到底要分配到哪个节点当中,最终在大数据的情况量之下分配的结果就是前面两个节点分担的存储容量基本上是相当的占 25% 左右,最后一个节点占的存储容量在 50% 左右,这是由 partitionCount 以及 partitionLength 这两个变量来决定的。