mysql分库分表

分库分表:分库分表是解决数据过大问题的良方,目的是为了缓解数据库的压力,最大限度减轻数据库压力,提高数据处理的效率。建议建数据库就分表,不然后期损耗大有连锁问题。分多少个库需要用并发量来预估分多少表需要用数据量来预估。分表是因为数据量比较大,导致事务执行缓慢;分库是因为单库的性能无法满足要求。
  • 水平分表:本质是将一张大表拆成多个结构相同的子表。

    • 采用关键字哈希进行分表,让相同关键字的数据落在同一张表里。如user_id%10。但分表数据不均匀
    • 直接根据数据范围进行分表,比如每200w记录,就自动生成一张新表。适用于数据和关键字无关的场景,数据分布均匀但有比较多的场景限制
    • 根据时间来进行分表,比如按天、按月、按年。如账单流水表就可以按月分表。思路简单,且很容易清理掉旧数据,整个表能自动变冷。但后期随着业务量突飞猛进,一个月都有千万条甚至上亿条数据,此时又得进行拆分
    • 结合数据范围和关键字哈希
  • 水平分库: 可以把一个表的数据(按数据行)分到多个不同的库,每个库只有这个表的部分数据,这些库可以分布在不同服务器

  • 垂直分表:将一张表的数据,根据场景切分成多张表

  • 垂直分库:可以把多个表按业务耦合松紧归类,分别存放在不同的库

  • 分表实现方式:

    • 公共包实现:本地依赖包,即将分表逻辑写在公共的代码库里,每个需要调用服务的客户方都集成该公共包,就接入了自动分表的能力。不引入组件但不符合开闭原则,服务小可用。
    • 中间件实现:最优解,耦合性低、架构清晰。但增加了运维成本。如mycat
  • 拆分老项目:分表过程中,是否可以停服?如果不停服,怎么保证数据一致性?

    1. 双写读老阶段:通过中间件,对write sql同时进行两次转发,也就是双写,保持新数据一致,同时开始历史数据拷贝。本阶段建议施行一周;
    2. 双写双读阶段:采用灰度策略,一部分流量读老表,一部分流量读新表,读新表的部分在一开始,还可以同时多读一次老表数据,本阶段建议施行至少两周;
    3. 双写读新阶段:此时基本已经稳定,可以只读新表,为了安全保证,建议还是多双写一段时间,本阶段建议周期一个月;
    4. 写新读新阶段:已经完成了分表的迁移,老表数据可以做个冷备。

分库分表后引入的问题:

  1. 多库唯一主键:UUID 是无序且很长且不具有业务能力,基于 Snowflake 算法但存在时钟回拨。基于数据库维护自增ID区间,引入Redis使用原子操作生成 ID,利用 Zookeeper 的 znode 数据版本来生成序列号但要分布式锁。

    • ID严格自增容易被猜测不安全,基于MAC的uuid也不安全

    • 时钟回拨解决方案:回拨时间短5ms可以等待,否则

      • 匀出少量位作为回拨位,一旦时间回拨,将回拨位加 1,可得到不一样的 ID。
      • 启动前检查时间戳合法性
      • 在出现任何刻度的时钟回拨时都会直接抛异常给到业务层
      • 预生成ID保存+获取时间脱离服务器依赖
      • 回拨时多条时间线切换
  2. 分布式事务问题:同一个操作会分散到多个数据库中,涉及跨库执行 SQL 语句,也就出现了分布式事务问题。

  3. 跨库关联查询问题:针对这种需要跨库访问的业务场景,一般会使用额外的存储,比如维护一份文件索引。另一个方案是通过合理的数据库字段冗余,避免出现跨库查询。

  4. 跨库跨表的合并和排序问题:数据分散存储到不同的数据库和表中,如果查询指定数据列表,或者需要对数据列表进行排序时,就变得异常复杂,可以依赖开源的分库分表中间件来处理。如Apache ShardingSphere,淘宝的 TDDL

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值