完整分库分表流程demo

完整分库分表流程demo

一、 技术

二、 模拟订单表分库分表迁移流程

1. 确认分库分表键

  • 可以统计查询订单表的where条件

    选用命中率高的, 减轻主要查询压力

  • 需要考虑分布式事务

    t_order表和t_order_item表, 保存一次订单,确保分库后order和order_item都放在同一个库中,
    这样就可以使用本地事务了。一般选用user_id, 选用order_id也可以, 本demo使用user_id

    注意事项,选用了user_id做分片键,则原先使用order_id查询的接口会遍历各个分库查询数据
       a. 如果数据量不是特别大,可以不处理
       b. 本demo将user_id和order_id映射关系保存到t_order_mapping表中,使用order_id查询时先查询一次user_id,然后带上user_id查询订单
       c. 基因id 处理,参考美团订单分库分表实现,定制order_id,中间嵌入user_id后几位数字,分片查询时根据user_id基因数字路由,这种改造工程比较大
       d. 多列分库分表,在将user_id做一次分库分表的同时,也将order_id做一次分库分表,存了两份数据,存储较大

2. 分片算法

  • range

    按时间或id范围划分,如[1-10000]放到1库,[10001-20000]放到2库
    优点:单表大小可控,天然水平扩展。
    缺点:无法解决集中写入瓶颈的问题。

  • hash

    hash取模 2^n
    分2(库) * 4 (表), 即分2个库,每个库4张表
    则 路由规则是 库号= user_id % 2, 表号= (user_id/2) % 4

    优点: 易扩展,解决集中写入瓶颈的问题
    缺点: 扩容麻烦,需要重新hash,(注意避免在同一张表的数据,重新hash到不同的表), 需要迁移数据

    (本demo采用该方法)

3. 确定容量,考虑扩容

  • 生产中一次性分够,够用好几年,不用考虑扩容

    分32(库) * 32 (表) , 分成32个库,每个库32张表, 共1024张表(也可以16*64)
    路由规则是 库号= user_id % 32, 表号= (user_id/32) % 32

  • 初始逻辑分库,实际上可以部署4台机器,每台机器8库, 每个库32表

    当表数据超过单机限制后,可以部署8台机器,每台机器4各库,每个库32表 最多可以部署1024台机器,每台机器1张表

    扩容时,仅仅是改一下配置,迁移数据就可以了, 原来在同一张表的数据,扩容之后,还在同一张表

    更具体的介绍看美团实现

4. 唯一id

  • uuid 字符串

    占用空间较多, 不能做到递增

  • 雪花算法

    可以做到递增,性能较好
    维护workId比较麻烦
    存在时钟回拨问题
    其他的实现一般都是基于雪花算法进行改造

  • 美团leaf唯一id实现

    比较复杂,暂不考虑

  • 百度uid-generator

    比较简单,解决workId维护问题,解决了时钟回拨问题,暂未提供workId重用实现

    本demo采用该实现,已实现复用workId

    ecp-uid整合了美团leaf、百度UidGenerator、原生snowflake 实现,可以参考,
    由于直接使用uid-generator足够简单,且有效使用,暂不采用ecp-uid

5. 单库表 迁移 到分库

参考美团双写实现

  • ① 原系统中将需要订单表的关联查询(join)去掉

    改成在应用中用代码处理join, 为后续分库分表做准备

  • ② 改造系统中订单id的实现,统一使用uid-generator生成的唯一id

  • ③ 数据库双写(先写单库,后写分库,事务以单库为主,读数据以单库为主 ),同步订单历史数据到分库,然后校验补偿分库数据

    a. 先写单库,后写分库,事务以单库为主,读数据以单库为主

    b. 同时,使用datax同步历史订单数据到分库

    c. 校验单库和分库数据,补偿数据到分库(插入或根据更新时间比较更新)

  • ④ 在③步骤数据补平后,数据仍双写(先写分库,后写单库,事务以分库为主,读数据以分库为主),同时校验补偿单库数据

    a. 先写分库,后写单库,事务以分库为主,读数据以分库为主
    (如果服务众多,可以切一小部分服务灰度尝试读写, 如果有问题,可以回退到③)

    b. 校验单库和分库数据,补偿数据到单库(插入或根据更新时间比较更新)

  • ⑤ 观察几天没问题后,下线单库订单表

6. 分库分表中间件

    • mycat

      基于数据库代理实现,存在单点问题

    • shardingsphere

      目前成为apache顶级项目, 从前景上说,采用该技术应是最好的

      • sharding-jdbc

        shardingsphere子项目, jdbc代理

        a. 不存在单点问题
        b. 可能会存在多份配置
        c. 升级比较麻烦,需要统一升级
        d. 只能应用于java语言

      • sharding-proxy

        shardingsphere子项目, 数据库代理

        a. 存在单点问题
        b. 兼容性问题
        c. 优点是没有语言限制

      目前demo采用sharding-jdbc实现为主,sharding-proxy运维为辅

  完整demo源码

后记

   分库分表是突破单机性能的重要手段,但分库分表实现比较复杂,不到万不得已不可轻易使用

   本demo尚未在真实项目中使用,仅供学习和参考

参考资料

      大众点评订单系统分库分表实践

      Java互联网架构-Mysql分库分表订单生成系统实战分析

     分库分表面试准备

    分库分表技术演进&最佳实践-修订篇

  

猜你喜欢

转载自www.cnblogs.com/timfruit/p/12770701.html
今日推荐