数据库中间件分片算法之hash
前言
夜深人静的时候,打开云音乐
,点上一曲攀登
,带上真无线蓝牙耳机,瞬间燃到爆,键盘打字如飞倦意全无。
分片规则
这几天有人问我,dble和mycat到底有什么不同。其实dble作为mycat的同门,吸收了mycat的精华,同时也相应的做了一些减法。只支持mysql显得更加的纯粹。所以选择对比学习两者我觉得挺好。
前面我们学习了schema.xml文件的配置,我们能独立的把逻辑库
和逻辑表
搭建起来,让数据表跟随我们的定义规则(取模)进行分布。今天我们介绍具体的分片算法。dble
相对于mycat
来说,是做了一些减法的。比如一致hash算法就没有,而是使用了jumpstringhash
代替了一致性hash。具体原因可以参考文章dble 沿用 jumpstringhash,移除 mycat 一致性 hash 原因
hash分区算法
- stringhash分区算法
- enum分区算法
- numberrange分区算法
- patternrange分区算法
- date分区算法
- jumpstringhash算法
hash分区算法
hash分区算法是一种比较典型而且常用的算法。要使用hash分区算法需要在rule.xml中定义两个部分。
分区规则定义
如下所示,使用tablerule
标签定义,name对应的是规则的名字,而rule
标签中的columns
则对应的分片字段,这个字段必须和表中的字段一致。algorithm
则代表了执行分片函数的名字。
<tablerule name="auto-sharding-long"> <rule> <columns>id</columns> <algorithm>rang-long</algorithm> </rule> </tablerule>
分区算法定义
如下所示,使用
先根据分片键取出999,按照公式1的计算结果除取模,然后得到的值落到2计算出来的分片中。 根据公式1 也就是传进来的值需要对350取模。 根据公式2,物理分区为 999对350取模,正好是299。落在250-300这个区间里面。也就是第4个区间。 接下来我们实际来测试一下,我们在rule.xml中设置如下: 我们通过公式2算出有5个分片。所以在schema.xml中设置table属性如下: 我们先使用shell创建1000行数据,在创建表,通过load data语法将我们shell产生的文件进行导入。 请原谅我作为一个geek,把桌面和终端完美结合成二次元是标配。 这里可以看到我们查询999这个数据,会自动到dn4这个分片上进行查询。再比如我们查500,500对350取模是150,150是落在第二个分区里面的。 此时c _l=2_1000=2000,将对2000进行取模。 同时将划分如下的分区: 今天学习了分片算法hash。后续将继续分享其他的算法。谢谢支持!function
标签定义分区算法,name代表算法的名字,算法的名字要和上面的tablerule中的class
:指定分区算法实现类。property
指定了对应分区算法的参数。不同的算法参数不同。<function name="rang-long" class="com.actiontech.dble.route.function.autopartitionbylong">
<property name="mapfile">auto-sharding-long.txt</property>
...
</function>
partitioncount
:指定分区的区间数,具体为 c1 +c2 + ... + cnpartitionlength
:指定各区间长度,具体区间划分为 [0, l1), [l1, 2l1), ..., [(c1-1)l1, c1l1), [c1l1, c1l1+l2), [c1l1+l2, c1l1+2l2), ... 其中,每一个区间对应一个数据节点。测试hash分区算法
1.在启动的时候,两个数组点乘做运算,得到取模数。
2.两个数组进行叉乘,得出物理分区表。
3.根据where条件的值来落入实际分片
select * from shareding_key = 999;
4.举个简单的例子:
<property name="partitioncount">2,3</property>
<property name="partitionlength">100,50</property>
<tablerule name="rule_hash">
<rule>
<columns>id</columns>
<algorithm>func_hash_test</algorithm>
</rule>
</tablerule>
<function name="func_hash_test" class="hash">
<property name="partitioncount">2,3</property>
<property name="partitionlength">100,50</property>
</function>
<table name="hash_test" primarykey="id" rule="rule_hash" datanode="dn1,dn2,dn3,dn4,dn5"/>
5.创建表测试
for i in {1..1000}
do
echo $i'|name'$[i]'' >>a1.txt
done
6.另一个例子
<property name="partitioncount">2</property>
<property name="partitionlength">1000</property>
注意事项
partition size : 5 > table datanode size : 4 please make sure table datanode size = function partition size
后记
下一篇: Kotlin 使用高阶函数实现回调方式