通过MyCat中间件去理解分库分表

数据库划分

OLTP:联机亊务处理。面向交易的处理系统,其基本特征是原始数据可立即传送到计算中心进行处理,并在很短时间内给出处理结果。
OLAP:联机分析处理。是指通过多维的方式对数据进行分析、查询和报表,可以同数据挖掘工具、统计分析工具配合使用,增强决策分析能力

通过MyCat中间件去理解分库分表

垂直切分和水平切分

数据切分的经验:

  • 第一原则:能不切分尽量不要切分。
  • 第二原则:如果要切分一定要选择合适的切分规则,提前规划好。
  • 第三原则:数据切分尽量通过数据冗余或表分组(Table Group)来降低跨库 Join 的可能。
  • 第四原则:由于数据库中间件对数据 Join 实现的优劣难以把握,而且实现高性能难度极大,业务读取尽量少使用多表 Join
  1. 垂直切分的最大特点就是规则简单,实施也更为方便,尤其适合各业务之间的耦合度非常低,相互影响很小,业务逻辑非常清晰的系统。

在这种系统中,可以很容易做到将不同业务模块所使用的表分拆到不同的数据库中。根据不同的表来进行拆分,对应用程序的影响也更小,拆分规则也会比较简单清晰

垂直切分优点:

  • 拆分后业务清晰,拆分规则明确
  • 系统之间整合或扩展容易
  • 数据维护简单

缺点:

  • 部分业务无法join,只能通过接口方式解决,提高了系统复杂度
  • 受每种业务不同的限制,存在单库性能瓶颈,不易数据扩展跟性能提高
  • 事务处理复杂
  1. 水平切分

切分第一原则是找到拆分维度

几种典型的分片规则包括:

  • 按照用户 ID求模,将数据分散到不同的数据库,具有相同数据用户的数据都被分散到一个库中;
  • 按照日期,将不同月甚至日的数据分散到不同的库中;
  • 按照某个特定的字段求摸,或者根据特定范围段分散到不同的库中。

优点:

  • 拆分规则抽象好,join 操作基本可以数据库做;
  • 不存在单库大数据,高并发的性能瓶颈;
  • 应用端改造较少;
  • 提高了系统的稳定性跟负载能力。
    缺点:
  • 拆分规则难以抽象;
  • 分片事务一致性难以解决;
  • 数据多次扩展难度跟维护量极大;
  • 跨库 join 性能较差。

垂直拆分和水平拆分共同缺点:

  • 引入分布式事务的问题;
  • 跨节点 Join 的问题;
  • 跨节点合并排序分页问题;
  • 多数据源管理问题。
数据拆分原则
    1. 达到一定数量级才拆分(800 万)
    1. 不到 800 万但跟大表(超 800 万的表)有关联查询的表也要拆分,在此称为大表关联表
    1. 大表关联表如何拆:小于 100 万的使用全局表;大于 100 万小于 800 万跟大表使用同样的拆分策略;无
      法跟大表使用相同规则的,可以考虑从 java 代码上分步骤查询,不用关联查询,或者破例使用全局表。
    1. 破例的全局表:如 item_sku 表 250 万,跟大表关联了,又无法跟大表使用相同拆分策略,也做成了全局 表。破例的全局表必须满足的条件:没有太激烈的并发 update,如多线程同时 update 同一条 id=1 的记录。虽有多线程update,但不是操作同一行记录的不在此列。多线程 update 全局表的同一行记录会死锁。批量 insert 没问题。
    1. 拆分字段是不可修改的
    1. 拆分字段只能是一个字段,如果想按照两个字段拆分,必须新建一个冗余字段,冗余字段的值使用两个字 段的值拼接而成(如大区+年月拼成 zone_yyyymm 字段)。
    1. 拆分算法的选择和合理性评判:按照选定的算法拆分后每个库中单表不得超过 800 万
    1. 能不拆的就尽量不拆。如果某个表不跟其他表关联查询,数据量又少,直接不拆分,使用单库即可。
分布式事务的解决方案

https://blog.csdn.net/broadview2006/article/details/54342788
MyCat采用弱XA事务

分布式事务处理( Distributed Transaction Processing , DTP ): 指一个程序或程序段,在一个或多个资源 如数据库或文件上为完成某些功能的执行过程的集合,分布式事务处理的关键是必须有一种方法可以知道事务在 任何地方所做的所有动作,提交或回滚事务的决定必须产生统一的结果(全部提交或全部回滚)

XA事务成功:
通过MyCat中间件去理解分库分表

XA事务失败:
通过MyCat中间件去理解分库分表

XA 事务的问题:

  • timeout 问题,比如当一个 RM 出问题了,那么整个事务只能处于等待状态。这样可 以会连锁反应,导致整个系统都很慢,最终不可用,
  • 另外 2 阶段提交也大大增加了 XA 事务的时间,使得 XA 事务 无法支持高并发请求
  • 同步阻塞问题。执行过程中,所有参与节点都是事务阻塞型的。
  • 单点故障。由于协调者的重要性,一旦协调者发生故障。参与者会一直阻塞下去。
  • 数据不一致(脑裂问题。在二阶段提交的阶段二中,当协调者向参与者发送 commit 请求之后,发生了局部网络异 常或者在发送 commit请求过程中协调者发生了故障,导致只有一部分参与者接受到了 commit请求。于是整个分布式系统便出现了数据部一致性的现象(脑裂现象)。
  • 二阶段无法解决的问题(数据状态不确定)。协调者再发出 commit 消息之后宕机,而唯一接收到这条消息的参与者同时也宕机了。那么即使协调者通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没人知道事务是否被已经提交。
跨节点Join的解决方案
  1. ER表。表分组(Table Group)是解决跨分片数据 join 的一种很好的思路,也是数据切分规划的重要一条规则

关系型数据库是基于实体关系模型(Entity-Relationship Model)之上,通过其描述了真实世界中事物与关系,Mycat 中的 ER表即是来源于此。根据这一思路,提出了基于 E-R 关系的数据分片策略,子表的记录与所关联的父表记录存放在同一个数据分片上,即子表依赖于父表,通过表分组(Table Group)保证数据 Join 不会跨库操
作。

  1. 全局表。数据冗余是解决跨分片数据 join 的一种很好的思路

对于变动不频繁、数据量总体变化不大、数据规模不大,很少有超过数十万条记录这类的表,Mycat中通过数据冗余来解决这类表的 join,即所有的分片都有一份数据的拷贝,所有将字典表或者符合字典表特性的一些表定义为全局表

  1. ShareJoin。ShareJoin 是一个简单的跨分片 Join,基于 HBT 的方式实现
  • 支持 2 个表的 join,原理就是解析 SQL 语句,拆分成单表的 SQL 语句执行,然后把各个节点的数据汇集
  1. catlet(人工智能)

提供一个 SQL执行框架,完全是异步的模式执行,并且以后会提供更多高质量的API,简化分布式数据处理,比如内存结合文件的数据 JOIN 算法,分组算法,排序算法等等

跨节点合并排序分页解决

https://blog.csdn.net/u013898617/article/details/80402956

  1. 执行分页操作时必须显示加上排序条件
  2. 改写SQL。下发有 limit m,n的SQL语句时会对其进行改写,改写成 limit 0, m+n 来保证查询结果的逻辑正确性
全局序列号问题解决

https://zhuanlan.zhihu.com/p/92958382

  1. 本地文件方式.

此方式 MyCAT 将 sequence 配置到文件中,当使用到 sequence 中的配置后,MyCAT 会更下 classpath 中的 sequence_conf.properties 文件中 sequence 当前的值。

使用示例:
insert into table1(id,name) values(next value for MYCATSEQ_GLOBAL,‘test’);

  • 缺点:当 MyCAT 重新发布后,配置文件中的 sequence 会恢复到初始值。
  • 优点:本地加载,读取速度较快
  1. 数据库方式。在数据库中建立一张表,存放 sequence 名称(name),sequence当前值(current_value),步长(incrementint 类型每次读取多少个sequence,假设为 K)等信息

使用示例:
insert into table1(id,name) values(next value for MYCATSEQ_GLOBAL,‘test’);

  1. 雪花算法,本地时间戳方式。ID= 64 位二进制 (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加)
    通过MyCat中间件去理解分库分表

  2. 分布式 ZK ID 生成器
    基于 ZK 与本地配置的分布式 ID 生成器(可以通过 ZK 获取集群(机房)唯一 InstanceID,也可以通过配置文
    件配置 InstanceID)

配置文件:sequence_distributed_conf.properties,只要配置里面:INSTANCEID=ZK 就是从 ZK 上获取 InstanceID

  1. Zk 递增方式

  2. UUID
    UUID缺点:

  • 占内存
  • 有序的ID可以提升数据写入的性能,UUID不能
  • UUID不具备业务相关性
分片规则
  1. 分片枚举

比如有些业务需要按照省份或区县来做保存,而全国省份区县固定的,这类业务使用本条规则

  1. 固定分片 hash 算法

本条规则类似于十进制的求模运算,区别在于是二进制的操作,是取 id 的二进制低 10 位,即 id 二进制&1111111111。此算法根据二进制则可能会分到连续的分片,减少插入事务事务控制难度。

  1. 范围约定

此分片适用于,提前规划好分片字段某个范围属于哪个分片

  1. 取模

此规则为对分片字段求摸运算

  1. 按日期(天)分片
  2. 取模范围约束

此种规则是取模运算与范围约束的结合,主要为了后续数据迁移做准备,即可以自主决定取模后数据的节点 分布。

  1. 截取数字 hash 解析

此种规则类似于取模范围约束,此规则支持数据符号字母取模。

  1. 应用指定

此规则是在运行阶段有应用自主决定路由到那个分片。

  1. 截取数字 hash 解析

此规则是截取字符串中的 int 数值 hash 分片。

  1. 一致性 hash
  2. 按单月小时拆分
  3. 范围求模分片

先进行范围分片计算出分片组,组内再求模

  • 优点可以避免扩容时的数据迁移,又可以一定程度上避免范围分片的热点问题
  • 综合了范围分片和求模分片的优点,分片组内使用求模可以保证组内数据比较均匀,分片组之间是范围分片可以 兼顾范围查询。
  • 最好事先规划好分片的数量,数据扩容时按分片组扩容,则原有分片组的数据不需要迁移。由于分片组内数据比 较均匀,所以分片组内可以避免热点数据问题。
  1. 日期范围 hash 分片

思想与范围求模一致,当由于日期在取模会有数据集中问题,所以改成 hash 方法。 先根据日期分组,再根据时间 hash 使得短期内数据分布的更均匀

  • 优点可以避免扩容时的数据迁移,又可以一定程度上避免范围分片的热点问题
  • 要求日期格式尽量精确些,不然达不到局部均匀的目的
  1. 冷热数据分片

根据日期查询日志数据 冷热数据分布 ,最近 n个月的到实时交易库查询,超过 n 个月的按照 m 天分片。

  1. 自然月分片
  2. 有状态分片算法

有状态分片算法与之前的分片算法不同,它是为数据自动迁移而设计的.

  1. crc32slot 分片算法
多租户问题
  1. 独立数据库

优点:

  • 为不同的租户提供独立的数据库,有助于简化数据模型的扩展设计,满足不同租户的独特需求;
  • 如果出现故障,恢复数据比较简单。
    缺点:
  • 增大了数据库的安装数量,随之带来维护成本和购置成本的增加。
  1. 共享数据库,隔离数据架构

优点:

  • 为安全性要求较高的租户提供了一定程度的逻辑数据隔离,并不是完全隔离;每个数据库可以支持更多的租户数量。
    缺点:
  • 如果出现故障,数据恢复比较困难,因为恢复数据库将牵扯到其他租户的数据;
  • 如果需要跨租户统计数据,存在一定困难
  1. 共享数据库,共享数据架构

优点:

  • 三种方案比较,第三种方案的维护和购置成本最低,允许每个数据库支持的租户数量最多。
    缺点:
  • 隔离级别最低,安全性最低,需要在设计开发时加大对安全的开发量;
  • 数据备份和恢复最困难,需要逐表逐条备份和还原;
  • 如果希望以最少的服务器为最多的租户提供服务,并且租户接受以牺牲隔离级别换取降低成本,这种方案最适合。

参考:
《MyCat权威指南》
https://blog.csdn.net/u013898617/article/details/80402956

上一篇:mycat配置文件schema.xml配置说明


下一篇:Mycat分布式架构-多实例准备