开发者学堂课程【全面讲解开源数据库中间件MyCat使用及原理(二):MyCat - 分片 - 分片规则 - 字符串 Hash 求模范围算法】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/756/detail/13271
MyCat - 分片 - 分片规则 - 字符串 Hash 求模范围算法
内容介绍:
一、字符串 hash 求模范围算法
二、测试
一、字符串 hash 求模范围算法
1.简介
刚才讲解了取模范围算法,取模范围算法实际上只能针对于数字类型进行取模运算。如果是字符串,则无法进行取模分片,这是他的弊端,接下来讲解的是字符串 hash 求模范围算法,这种算法与取模范围算法类似,但是该算法可以支持数值,符号,字母的取模算法,这种算法的原理是首先截取长度为 prefixlength 的子串,假如有一定长度的字符串,sjdkfjla238928029302 这样一串字符串,不会将全部的字符串进行取模运算,会截取一定长度,例如截取sjdk,在针对这个长度中的每一个字符 sjdk 这四个字母每一个字符都会获取到它的 ASCII 码值,在对子串中每一个字符的 ASCII 码求和,拿到 sjdk 的 ASCII 码值,然后对求和值进行取模运算,运算出来的结果模于基数,就可以计算出子串的分片数,再去根据范围求取分片,假如 sjdk 这四个字母获取出来的结果 ASCII 码值相加是 240,然后要去模于基数,基数是上节课内容讲解的 96,模于 96 获取一个结果,算出来的结果是 48,根据 48 找到对应的范围,然后求取对应的分片,这就是字符串 hash 求模算法特点。
2.优点
可以自主决定取模后数据的节点分布
3.缺点
datanode 划分节点事先建好的,需要扩展时比较麻烦,需要进行数据迁移
4.配置
<tab1eRule name =" sharding - by - prefixpattern ">
< rule >
< columrssid </ columns >
< algorithm > sharding - by - prefixpattern </ algorithm >
</ rule >
</ tableRule >
< function name =" sharding - by - prefixpattern ” class =" io . mycat . route . function . PartitionByPrefixPattern "
< property name =" mapFile "> partition - prefixpattern . txt </ property < property name =" prefixLength ">5</ pr operty
< property name =" patternvalue ">96</ property </ function >
首先需要配置一个分片规则 sharding - by - prefixpattern,然后指定分片字段是哪一个,还需要指定分片算法,通过分片算法来指定处理类,mapFile 指的是范围映射文件,prefix 指的是前缀 Length 长度,prefixLength 指的就是字符串前缀的长度,五就是代表要截取一个长度为五的字符串,patternvalue 指的是刚才模的基数,这是这块的配置,接下来看一下映射文件的配置。
5.partition - prefixpattern . txt 配置如下
# range start - end , data node index # ASCII
#48-57=0-9
#64、65-90=@、 A - Z
#97-122= a - Z
###### first host configur ation
0-32=0
33-64=1
65-96=2
映射文件中的配置与取模范围算法配置基本上是一致的,0-32 代表取模之后的结果如果在 0~32 之间将会落在第一个分片上,如果在 33~64 之间将会落在第二个分片上如果在 65~96 之间,将会落在第三个分片上,指的是这个含义。
二、测试
例如:假如截取出来的是这样一个字符串,gf89f9a,接下来要找到每一个字符所对应的 ASCII 码值
截取字符串的前 5 位进行 ASCII 的累加运算:
9-103
f -102
8-56
9-57
f -102
然后对 ASCII sum 求和:103+102++56+57+102=420求模:420%96=36
求模完以后再根据映射文件找到对应的分片,是这样的一个流程。
1.ASCII 码表
每一个字符对应的 ASCII 码是多少都有记录。
2.配置
< table name =' tb _ u " dataNode =' dnl ,dn2,dn3" rule =' sharding - by - prefixpattern "
首先需要配置一张逻辑表,在 schema.xml 中进行配置,tb _ u,然后指定分片规则,按照字符串 hash 取模,配置 ruler 规则以后需要在 ruler 中指定配置这个规则,要切换到 ruler.xml 中进行配置规则信息,
<tab1eRule name =" sharding - by - prefixpattern ">
< rule >
< columrssid </ columns >
< algorithm > sharding - by - prefixpattern </ algorithm >
</ rule >
</ tableRule >
在这里面还有一个分片的算法 prefixpattern,这里没有,需要进行手动配置,因为默认的配置文件中有很多的算法并没有进行配置,在这里进行配置,配置好以后还有 partition - pr efixpattern . txt 这个文件也需要指定,在 config 中创建个文件,文件名叫做 partition - pr efixpattern . txt,在这个文件中配置的信息是
0-32=0
33-64=1
65-96=2
首先配置一个逻辑表指定他的分片规则,在这个分片规则中指定分片算法,在分片算法中,指定分片的处理类,在指定映射文件以及截取的字符串长度是前五位,在指定基数为 96。
3.测试
接下来启动 my cat 进行测试,执行 mycat 的重启,重启后再次连接 mycat,重新连接好以后 show databases,然后 use PARTITION_DB,show tables
tb_u 这个表已经有了,接下来需要执行 SQL 语句创建这张表的表结构
CREATE TABLE “ tb _ u (
user name var char (200) NOT NULL cOMMENT ‘用户名’, age int (11)default0 cOMMENT ‘年龄',
PRIMARY KEY ( username )
) ENGINE = InnoDB DEFAULT CHARSET = ut f8mb4;
直接执行,报了一个错,是因为mql索引长度的限制,需要将长度手动改一下,假如改为 50。
CREATE TABLE “ tb _ u (
user name var char (200) NOT NULL cOMMENT ‘用户名’, age int (11)default0 cOMMENT ‘年龄',
PRIMARY KEY ( username )
) ENGINE = InnoDB DEFAULT CHARSET = ut f8mb4;
再来创建,这回表结构就创建好了,创建了表结构以后,select*from tb_u 是没有数据的,需要向里面插入数据,
insert into tb _ u ( username , age ) values ('Test100001',18);
insert into tb _ u ( username , age ) values ('Test200001',20);
insert into tb _ u ( username , age ) values ('Test300001',19);
insert into tb _ u ( username , age ) values ('Test400001',25);
insert into tb _ u ( username , age ) values ('Test500001',22);
向里面插入这五条数据,这张表里面两个字段一个是 user name,还有一个是age,而在刚才进行操作时设置的分配规则指定的是 age,这里应该是 user name,要根据 user name 进行分片操作,这块进行修改,再次进行重启,重启后再次进行重新连接 use PARTITION_DB,select*from tb_u,然后进行查询操作
五条数据已经插入进去,这五条数据到底插入到了哪一个节点中, 到第一个节点中进行查询 select*from tb_u 第一个节点没有,select*from tb_u 第二个节点也没有,select*from tb_u 第三个节点有,因为 test 100001,test 200001 这些数据在进行分配时会先截取字符串的前五位,截取出来前五位就是 test 12345,接下来又去计算它的 ASCII 码值,计算出 ASCII 码值之后再去模于 96,算出来的结果如果是在 0~32 之间是在第一个节点,33~64 的是在第二个节点,65~96 是在第三个节点,落在第三个分片则说明计算出来的结果是在 65~96 之间。