此文已由做者张镐薪受权网易云社区发布。
html
欢迎访问网易云社区,了解更多网易技术产品运营经验。java
表被水平切分后,每一个分片表所在的数据库就是一个分片节点。一个分片节点对应一个数据库(mysql数据库)。一个分片节点只能保存每一个分片表的一个分片,由于db中不容许出现同名的表。 例如:node
<dataNode name="test1" dataHost="test" database="db1" />
这就表示,名字为test1这个分片节点,对应test节点主机(MySQL实例)主机上的db1数据库mysql
分片节点究竟被放在那个主机上。对应mysql里的mysql实例:一台主机能够部署多个mysql实例,一个mysql实例能够有多个数据库。为了规避单节点主机并发数限制,尽可能将读写压力高的分片节点(dataNode)均衡的放在不一样的节点主机(dataHost). 例如:算法
<dataHost name="test" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100"> <heartbeat>select 1 from dual</heartbeat> <writeHost host="master" url="10.202.4.181:3306" user="root" password="sf123456"> <readHost host="slave" url="10.202.4.181:3307" user="root" password="sf123456"/> </writeHost></dataHost>
这个会在以后的配置文件说明中细讲。sql
就决定分片表的记录如何分布在不一样的分片节点上。分片规则有不少种,咱们根据业务须要,并考虑到开发,维护以及扩容的难度,来决定用哪一种分片方案。 分片规则通常还涉及到全局id生成,这个以后会讲。 MyCat支持咱们本身开发本身的分片规则,如何开发,咱们后面会讲到(如下规则最好不要照搬,参考以后并按照本身的须要开发本身的分片方案):数据库
这是最多见的一种分片方案,根据分片字段(通常是主键,由于按主键查找的场景偏多)的哈希值,对分片个数取模运算,根据结果决定记录到哪一个分片上。 通常分片个数最好为2的n次方,这样计算起来能够用取与运算(x%(2^n)=x&(2^n - 1)). 好处:记录平均分布(除非id生成器故意生成取模正好只为同一个数的id),压力平均分布,数据没有倾斜 坏处:扩容(增长分片)是个大问题,分片个数改变,基本很难迁移数据 配置举例: rule.xml:安全
<tableRule name="mod-long-rule1"> <rule> <columns>user_id</columns> <algorithm>mod-long</algorithm> </rule></tableRule><function name="mod-long" class="org.opencloudb.route.function.PartitionByMod"> <!-- how many data nodes --> <property name="count">3</property></function>
能够看出,用java反射机制加载org.opencloudb.route.function.PartitionByMod这个类,在这个org.opencloudb.route.function的全部类都为分片算法,如何实现,将会在以后的rule.xml配置说明中提到。这个算法接收一个参数,其实就是分片个数。以后在tableRule标签中,规定是哪一列(字段)为分片字段,对应哪一算法。 在这里,就是用user_id对3取模以后的值做为该记录分布在哪个分片节点上。并发
rule.xml:url
<tableRule name="file-map-rule1"> <rule> <columns>address</columns> <algorithm>file-map</algorithm> </rule></tableRule><function name="file-map" class="org.opencloudb.route.function.PartitionByFileMap"> <property name="mapFile">partition-file-map.txt</property> <property name="type">1</property> <property name="defaultNode">0</property></function>
type为零则字段类型为整型,为1则为字符串类型。维护一个对应表配置文件partition-file-map.txt,以下所示: partition-file-map.txt:
北京=0 上海=1 深圳=2 广州=2 default=3
意思就是分片字段为北京的到分片0上,上海的到分片1上,深圳和广州的到分片2上,其余的到分片3上。 若是某天发现北京的分片须要扩容,能够将北京的数据总体迁移到一个更大的分片上,以后重载配置。MyCat支持在线重载配置 好处:扩容比较灵活 坏处:数据容易有倾斜,扩容不是很灵活,并且,分片字段很难是经常使用查询字段(若是查询字段不是分片字段,就是全分片检索)
也是维护一个文件,以下所示:
<tableRule name="auto-sharding-long"> <rule> <columns>user_id</columns> <algorithm>rang-long</algorithm> </rule></tableRule><function name="rang-long" class="org.opencloudb.route.function.AutoPartitionByLong"> <property name="mapFile">autopartition-long.txt</property> <property name="defaultNode">0</property></function>
autopartition-long.txt
0~1000k=01000k~2000k=1default=2
就是指分片字段在0~1000k范围内的到分片0上。。。。。。 好处:保证每一个分片数据稳定,扩容也比较方便 坏处:须要配合id生成器,不然按顺序自增会有压力集中在一个分片的问题。同时,扩容时同时要改变MyCat配置以及id生成器配置。及时作数据清理,id最好能复用,这个规则才能很好的应用。
将哈希取模与范围路由结合。
<tableRule name="sharding-by-pattern"> <rule> <columns>user_id</columns> <algorithm>sharding-by-pattern</algorithm> </rule></tableRule><function name="sharding-by-pattern"class="org.opencloudb.route.function.PartitionByPattern"> <property name="patternValue">64</property> <property name="defaultNode">2</property> <property name="mapFile">partition-pattern.txt</property></function>
0~15=0 16~31=1 32~47=2 48~63=3
哈希取模后范围在0~15的流向分片1.。。。 这样能够某种程度上减轻扩容的压力。
有时候,咱们并不想一个字段的全部内容都做为分片咱们能够取某个字段的一部分做为分片依据。配合id生成器使用。
其实,咱们能够结合id生成器,作一种既好扩容,又维护不复杂,又能平均分摊压力的方法。 参考百X的某些项目,他们是项目开始就建64个库,每一个库64张表。假设每张表1000w数据,那么一共能承受409.6亿的数据。。。从如今来看估计这个项目作到死也许都用不完。 不过这给咱们一个思路,咱们根据项目须要估计将来n年的量,在项目一开始就分配这么多库。这些库可能在项目初期位于同一个实例上。在不够用时,咱们把其中某几个库迁移到其余实例上。 咱们可让id生成器去作平均分布的事情。 好比下面这个id: 01-01-XXXASD1239091234 咱们用第一个-以前的数字直接做为分片id,咱们为了考虑到之后的业务增加,一开始就分配了64个库。id生成器先开始只会随机平均生成00~03开头的,以后业务增加到某个程度时,再按照需求多少在某个范围生成。
是从分片字段中抽取一段作分片路由,再取另外一段作自动哈希分片。同时再规定某个范围内是某个分片规则,另外一范围是另外一个分片规则。 id示例: 北京-A0000001 配置文件:
北京(A0000000~A9999999)=0,1,2,3,4 北京(B0000000)=5,6,7,8,9 上海(00000000~10000000)=10,11 上海=10,11,12,13,14,15
意思就是,开头为北京的范围在A0000000~A9999999的根据后面的哈希值对5取模平均分布在0,1,2,3,4分片节点上。开头为北京的范围在B0000000以上的根据后面的哈希值对5取模平均分布在5,6,7,8,9分片节点上。开头为上海的范围在00000000~10000000的根据后面的哈希值对2取模平均分布在10,11分片节点上,剩下的开头为上海的,对6取模平均分布在10,11,12,13,14,15上。 这样,在发现某个开头的分片不够用时,能够随时改变分片规则,同时不影响之前数据的访问。
更多网易技术、产品、运营经验分享请点击。
相关文章:
【推荐】 Spring Boot + Mybatis 多数据源配置实现读写分离
【推荐】 一个小需求引起的思考