在数据切分处理中,特别是水平切分中,中间件最终要的两个处理过程就是数据的切分、数据的聚合。选择合适的切分规则,至关重要,因为它决定了后续数据聚合的难易程度,甚至可以避免跨库的数据聚合处理。
避跨库 join 的很好的方式,但不是所有的业务场景都适合这样的规则,因此本文将讲述如何选择合适的切分规则。
如果业务中有些数据类似于数据字典,比如配置文件的配置,常用业务的配置或者数据量不大很少变动的表,这些表往往不是特别大,而且大部分的业务场景都会用到,那么这种表适合于 Mycat 全局表,无须对数据
进行切分,只要在所有的分片上保存一份数据即可, Mycat 在 Join *** 作中,业务表与全局表进行 Join 聚合会优先选择相同分片内的全局表 join,避免跨库 Join,在进行数据插入 *** 作时, mycat 将把数据分发到全局表对应的所有分片执行,在进行数据读取时候将会随机获取一个节点读取数据。
目前 Mycat 没有做全局表的数据一致性检查,后续版本 1.4 之后可能会提供全局表一致性检查,检查每个分片的数据一致性。
全局表的配置如下:
有一类业务,例如订单(order)跟订单明细(order_detail) ,明细表会依赖于订单,也就是说会存在表的主从关系,这类似业务的切分可以抽象出合适的切分规则,比如根据用户 ID 切分,其他相关的表都依赖于用户 ID,再或者根据订单 ID 切分,总之部分业务总会可以抽象出父子关系的表。这类表适用于 ER 分片表,子表的记录与所关联的父表记录存放在同一个数据分片上,避免数据 Join 跨库 *** 作。
以 order 与 order_detail 例子为例, schema.xml 中定义如下的分片配置,order,order_detail 根据 order_id进行数据切分,保证相同 order_id 的数据分到同一个分片上,在进行数据插入 *** 作时, Mycat 会获取 order 所在的分片,然后将 order_detail 也插入到 order 所在的分片。
有一类业务场景是 “主表 A+关系表+主表 B” ,举例来说就是商户会员+订单+商户,对应这类业务,如何切分?
从会员的角度,如果需要查询会员购买的订单,那按照会员进行切分即可,但是如果要查询商户当天售出的订单,那又需要按照商户做切分,可是如果既要按照会员又要按照商户切分,几乎是无法实现,这类业务如何选择切分规则非常难。目前还暂时无法很好支持这种模式下的 3 个表之间的关联。目前总的原则是需要从业务角度来看,关系表更偏向哪个表,即“A 的关系” 还是“B 的关系” ,来决定关系表跟从那个方向存储,未来 Mycat版本中将考虑将中间表进行双向复制,以实现从 A-关系表 以及 B-关系表的双向关联查询如下图所示:
当你没人任何字段可以作为分片字段的时候,主键分片就是唯一选择,其优点是按照主键的查询最快,当采用自动增长的序列号作为主键时,还能比较均匀的将数据分片在不同的节点上。
若有某个合适的业务字段比较合适作为分片字段,则建议采用此业务字段分片,选择分片字段的条件如下:
对于非主键分片的 table, 填写属性 primaryKey,此时 MyCAT 会将你根据主键查询的 SQL 语句的第一次执行结果进行分析,确定该 Table 的某个主键在什么分片上,并进行主键到分片 ID 的缓存。第二次或后续查询
mycat 会优先从缓存中查询是否有 id–>node 即主键到分片的映射,如果有直接查询,通过此种方法提高了非主键分片的查询性能。
通过在配置文件中配置可能的枚举 id,自己配置分片,本规则适用于特定的场景,比如有些业务需要按照省份或区县来做保存,而全国省份区县固定的,这类业务使用本条规则,配置如下:
上面 columns 标识将要分片的表字段, algorithm 分片函数,
其中分片函数配置中, mapFile 标识配置文件名称, type 默认值为 0, 0 表示 Integer,非零表示 String;
所有的节点配置都是从 0 开始, 0 代表节点 1:
本条规则类似于十进制的求模运算,区别在于是二进制的 *** 作,是取 id 的二进制低 10 位,即 id 二进制&1111111111 。
此算法的优点在于如果按照 10 进制取模运算,在连续插入 1 -10 时候 1 -10 会被分到 1 -10 个分片,增大了插入的事务控制难度,而此算法根据二进制则可能会分到连续的分片,减少插入事务事务控制难度。
配置说明:
上面 columns 标识将要分片的表字段, algorithm 分片函数,partitionCount 分片个数列表, partitionLength 分片范围列表
分区长度:默认为最大 2^n=1024 ,即最大支持 1024 分区
约 束 :
count,length 两个数组的长度必须是一致的。
1024 = sum((count[i] length[i])). count 和 length 两个向量的点积恒等于 1024
用法例子:
如果需要平均分配设置:平均分为 4 分片, partitionCount partitionLength=1024
此分片适用于,提前规划好分片字段某个范围属于哪个分片,
配置说明:
上面 columns 标识将要分片的表字段,algorithm 分片函数,rang-long 函数中 mapFile 代表配置文件路径,defaultNode 超过范围后的默认节点。
所有的节点配置都是从 0 开始,及 0 代表节点 1 ,此配置非常简单,即预先制定可能的 id 范围到某个分片:
此规则为对分片字段求摸运算。
配置说明:
上面 columns 标识将要分片的表字段, algorithm 分片函数,
此种配置非常明确即根据 id 进行十进制求模预算,相比固定分片 hash,此种在批量插入时可能存在批量插入单事务插入多数据分片,增大事务一致性难度。
此规则为按天分片:
配置说明:
columns :标识将要分片的表字段
algorithm :分片函数
dateFormat :日期格式
sBeginDate :开始日期
sEndDate:结束日期
sPartionDay :分区天数,即默认从开始日期算起,分隔 10 天一个分区
如果配置了 sEndDate 则代表数据达到了这个日期的分片后后循环从开始分片插入。
此种规则是取模运算与范围约束的结合,主要为了后续数据迁移做准备,即可以自主决定取模后数据的节点分布。
partition-pattern.txt内容如下:
配置说明:
上面 columns 标识将要分片的表字段, algorithm 分片函数,patternValue 即求模基数, defaoultNode默认节点,如果配置了默认,则不会按照求模运算;
mapFile 配置文件路径:
配置文件中, 1 -32 即代表 id%256 后分布的范围,如果在 1 -32 则在分区 1 ,其他类推,如果 id 非数据,则会分配在 defaoultNode 默认节点:
很抱歉给您带来不便,您可以尝试检查一下您的mycat配置是否正确,比如检查一下数据库连接是否正确,检查一下数据库表是否存在,检查一下数据库表是否有正确的字段,检查一下数据库表是否有正确的索引,检查一下数据库表是否有正确的权限,检查一下数据库表是否有正确的数据类型等等。如果您的mycat配置正确,您可以尝试检查一下您导入的数据格式是否正确,比如检查一下数据是否有正确的字段,检查一下数据是否有正确的数据类型,检查一下数据是否有正确的格式等等。如果您的数据格式正确,您可以尝试检查一下您的SQL语句是否正确,比如检查一下SQL语句是否有正确的字段,检查一下SQL语句是否有正确的连接,检查一下SQL语句是否有正确的查询条件等等。如果您的SQL语句正确,您可以尝试检查一下您的查询结果是否正确,比如检查一下查询结果是否有正确的字段,检查一下查询结果是否有正确的数据类型,检查一下查询结果是否有正确的格式等等。如果您的查询结果正确,您可以尝试检查一下您的mycat是否正确处理了您的查询结果,比如检查一下mycat是否有正确的缓存策略,检查一下mycat是否有正确的查询优化策略,检查一下mycat是否有正确的数据分片等等。希望以上建议能帮助您解决mycat导入大量数据报错的问题。欢迎分享,转载请注明来源:内存溢出
评论列表(0条)