干货地带 | Mycat水平拆分之十种分片规则
Posted 瑞友科技中国事业部
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了干货地带 | Mycat水平拆分之十种分片规则相关的知识,希望对你有一定的参考价值。
笔者:魏巍 所属部门: IT一部
大家好,相信大家现在会经常用到Mycat,所以我在这里就简单的介绍一下什么是Mycat、应用场景和水平拆分的十种规则。
什么是Mycat?它是一个开源的分布式数据库系统,是一个实现了mysql协议的Server,前端用户可以把它看作是一个数据库代理,而其后端可以用MySQL原生(Native)协议与多个MySQL服务器通信,也可以用JDBC协议与大多数主流数据库服务器通信,其核心功能是分表分库。
Mycat发展到现在,已经不是一个单纯的MySQL代理了,适用的场景已经很丰富,以下是几个典型的应用场景:
1.单纯的读写分离,支持读写分离,主从切换;
2.分表分库,对于超过1000万的表进行分片,最大支持1000亿的单表分片;
3.多租户应用,每个应用一个库,但应用程序只连接Mycat,从而不改造程序本身,实现多租户化;
4.报表系统,借助于Mycat的分表能力,处理大规模报表的统计;
对于Mycat的分表,有两种拆分方法:垂直拆分和水平拆分。
下面介绍一下水平拆分的10种常用的分片规则。
一、枚举法
<tableRulename="sharding-by-intfile">
<rule>
<columns>user_id</columns> 标识将要分片的表字段
<algorithm>hash-int</algorithm> 分片函数
</rule>
</tableRule>
<functionname="hash-int"class="io.mycat.route.function.PartitionByFileMap">
<property name="mapFile">partition-hash-int.txt</property>配置文件名称
<propertyname="type">0</property> 默认值为0,0表示Integer,非零表示String
<propertyname="defaultNode">0</property>
</function>
partition-hash-int.txt 配置: 10000=0 10010=1
defaultNode 默认节点:小于0表示不设置默认节点,大于等于0表示设置默认节点,结点为指定的值。
默认节点的作用:枚举分片时,如果碰到不识别的枚举值,就让它路由到默认节点,如果不配置默认节点(defaultNode值小于0表示不配置默认节点),碰到不识别的枚举值就会报错, like this:can't find datanode for shardingcolumn:column_name val:ffffffff
二、固定分片hash算法
<tableRulename="rule1">
<rule>
<columns>user_id</columns> 标识将要分片的表字段
<algorithm>func1</algorithm> 分片函数
</rule>
</tableRule>
<function name="func1"class="io.mycat.route.function.PartitionByLong">
<property name="partitionCount">2,1</property> 分片个数列表
<propertyname="partitionLength">256,512</property> 分片范围列表
</function>
分区长度:默认为最大2^n=1024 ,即最大支持1024分区
约束 :count,length两个数组的长度必须是一致的。
1024 = sum((count[i]*length[i])).count和length两个向量的点积恒等于1024
三、范围约定
<tableRulename="auto-sharding-long">
<rule>
<columns>user_id</columns> 标识将要分片的表字段
<algorithm>rang-long</algorithm> 分片函数
</rule>
</tableRule>
<functionname="rang-long"class="io.mycat.route.function.AutoPartitionByLong">
<propertyname="mapFile">autopartition-long.txt</property> 配置文件名称
</function>
autopartition-long.txt 配置:
# range start-end ,data node index
# K=1000,M=10000
0-500M=0 500M-1000M=1 1000M-1500M=2
或
0-10000000=0 10000001-20000000=1
所有的节点配置都是从0开始,及0代表节点1,此配置非常简单,即预先制定可能的id范围到某个分片。
四、求模法
<tableRulename="mod-long">
<rule>
<columns>user_id</columns> 标识将要分片的表字段
<algorithm>mod-long</algorithm> 分片函数
</rule>
</tableRule>
<function name="mod-long"class="io.mycat.route.function.PartitionByMod">
<!-- how many data nodes -->
<property name="count">3</property>
</function>
配置说明:
此种配置非常明确即根据id与count(你的结点数)进行求模预算,相比方式1,此种在批量插入时需要切换数据源,id不连续。
五、日期列分区法
<tableRulename="sharding-by-date">
<rule>
<columns>create_time</columns> 标识将要分片的表字段
<algorithm>sharding-by-date</algorithm> 分片函数
</rule>
</tableRule>
<function name="sharding-by-date"class="io.mycat.route.function..PartitionByDate">
<property name="dateFormat">yyyy-MM-dd</property>
<property name="sBeginDate">2014-01-01</property>
<property name="sPartionDay">10</property>
</function>
配置中配置了开始日期,分区天数,即默认从开始日期算起,分隔10天一个分区。
六、通配取模
<tableRulename="sharding-by-pattern">
<rule>
<columns>user_id</columns> 标识将要分片的表字段
<algorithm>sharding-by-pattern</algorithm> 分片函数
</rule>
</tableRule>
<functionname="sharding-by-pattern"class="io.mycat.route.function.PartitionByPattern">
<property name="patternValue">256</property> 即求模基数
<property name="defaultNode">2</property> 默认节点
<property name="mapFile">partition-pattern.txt</property> 配置文件名称
</function>
partition-pattern.txt 配置:
# id partition range start-end ,datanode index
###### first host configuration
1-32=0 33-64=1 65-96=2 97-128=3
######## second host configuration
129-160=4 161-192=5 193-224=6 225-256=7 0-0=7
配置文件中,1-32 即代表id%256后分布的范围,如果在1-32则在分区1,其他类推,如果id非数字数据,则会分配在defaoultNode 默认节点。
七、ASCII码求模通配
<tableRulename="sharding-by-prefixpattern">
<rule>
<columns>user_id</columns> 标识将要分片的表字段
<algorithm>sharding-by-prefixpattern</algorithm> 分片函数
</rule>
</tableRule>
<functionname="sharding-by-pattern"class="io.mycat.route.function.PartitionByPrefixPattern">
<property name="patternValue">256</property> 求模基数
<property name="prefixLength">5</property> ASCII 截取的位数
<propertyname="mapFile">partition-pattern.txt</property> 配置文件名称
</function>
partition-pattern.txt配置:
# range start-end ,data node index
# ASCII 48-57=0-9 64、65-90=@、A-Z 97-122=a-z
###### first host configuration
1-4=0 5-8=1 9-12=2 13-16=3
###### second host configuration
17-20=4 21-24=5 25-28=6 29-32=7 0-0=7
配置文件中,1-32 即代表id%256后分布的范围,如果在1-32则在分区1,其他类推。
八、编程指定
<tableRulename="sharding-by-substring">
<rule>
<columns>user_id</columns> 标识将要分片的表字段
<algorithm>sharding-by-substring</algorithm> 分片函数
</rule>
</tableRule>
<functionname="sharding-by-substring"class="io.mycat.route.function.PartitionDirectBySubString">
<property name="startIndex">0</property> <!--zero-based -->
<property name="size">2</property>
<property name="partitionCount">8</property>
<property name="defaultPartition">0</property>
</function>
此方法为直接根据字符子串(必须是数字)计算分区号(由应用传递参数,显式指定分区号)。
例如id=05-100000002
在此配置中代表根据id中从startIndex=0,开始,截取siz=2位数字即05,05就是获取的分区,如果没传默认分配到defaultPartition
九、字符串拆分hash解析
<tableRulename="sharding-by-stringhash">
<rule>
<columns>user_id</columns> 标识将要分片的表字段
<algorithm>sharding-by-stringhash</algorithm> 分片函数
</rule>
</tableRule>
<functionname="sharding-by-substring"class="io.mycat.route.function.PartitionByString">
<property name=length>512</property> 字符串hash求模基数
<property name="count">2</property> 分区数
<property name="hashSlice">0:2</property> hash预算位
</function>
十、一致性hash
<tableRulename="sharding-by-murmur">
<rule>
<columns>user_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">2</property> 要分片的数据库节点数量,必须指定,否则没法分片
<property name="virtualBucketTimes">160</property>一个实际的数据库节点被映射为这么多虚拟节点,默认是160倍,也就是虚拟节点数是物理节点数的160倍
<!--<propertyname="weightMapFile">weightMapFile</property>节点的权重,没有指定权重的节点默认是1。以properties文件的格式填写,以从0开始到count-1的整数值也就是节点索引为key,以节点权重值为值。所有权重值必须是正整数,否则以1代替 -->
<!--<propertyname="bucketMapPath">/etc/mycat/bucketMapPath</property>用于测试时观察各物理节点与虚拟节点的分布情况,如果指定了这个属性,会把虚拟节点的murmurhash值与物理节点的映射按行输出到这个文件,没有默认值,如果不指定,就不会输出任何东西 -->
</function>
一致性hash预算有效解决了分布式数据的扩容问题,前1-9中id规则都多少存在数据扩容难题,而10规则解决了数据扩容难点。
以上是关于干货地带 | Mycat水平拆分之十种分片规则的主要内容,如果未能解决你的问题,请参考以下文章