美文网首页
初识分库分表

初识分库分表

作者: 味道_3a01 | 来源:发表于2019-03-26 20:03 被阅读0次

    1. 为什么要分库分表? 什么场景下需要分库分表?

    单表数据上亿,查询性能下降;

    解决大数据存储,提高访问性能;

    超大容量问题

    性能问题:单一数据库,服务器的CPU、磁盘、内存、IO都有极限

    如何去做

    垂直切分、水平切分

    垂直切分

    1. 垂直分库:按模块分库,每个功能模块按照业务领域区分,解决表过多的问题

    关联度低的不同表存储在不同的数据库

    2. 垂直分表:解决单表列过多的问题

    水平切分

    单表数据量过大,影响查询性能;解决办法:大数据表拆分成小表

    mysql单表性能在500W-1000W,超过1000W性能降低

    2. 分库分表原理

    拆分策略

    • 范围切分:按照日期、userId等,如userId 19999的记录分到第一个库,1000020000的分到第二个库,以此类推
    • 根据数值驱魔:一般采用hash取模mod的切分方式,后期分片集群扩容时,需要迁移旧的数据(使用一致性hash算法能较好的避免这个问题)

    垂直拆分(er分片)

    拆分带来的问题

    1. 跨库join问题:拆分时键的问题,对原业务的sql数据进行统计,合理选择;后续尽量避免join查询

      • 设计时考虑到应用层的join问题
      • 在服务层去做调用
      • 全局表:字典、省市区
        • 数据变更比较少的基于全局应用的表
      • 做字段冗余(空间换时间)
        • 订单表: 商家id,冗余商家名称,商家名称变更--定时任务、任务通知对订单表的商家名称进行更新
    2. 跨分片数据排序分页:在应用层做拼接(不推荐)

    3. 唯一主键问题:用自增id做主键

      解决方案

      • UUID 性能比较低;
      • 用算法生成主键:snowflake、MongoDB、zookeeper、数据库全局唯一表
    4. 分布式事务问题:多个数据库表之间保证原子性(2PC),只要达到最终一致性即可

    分库分表最难的在于业务的复杂度

    3. 应用

    如何权衡当前公司的存储需要优化

    1. 提前规划,提前防范(主键问题解决、join问题)
    2. 当前数据单表超过1000W,每天的增长量持续上升
    1551610230219.png

    最佳实践

    订单号索引表

    根据用户编号进行哈希分库分表,可以满足创建订单和通过用户编号维度进行查询操作的需求,但是根据统计,按订单号进行查询的占比达到80%以上,所以需要解决通过订单号进行订单的CURD等操作,所以需要建立订单号索引表。

    订单号索引表是用于用户编号与订单号的对应关系表,根据订单号进行哈希取模,放到分库里面。根据订单号进行查询时,先查出订单号对应的用户编号,再根据用户编号取模查询去对应的库查询订单数据。

    订单号与用户编号的关系在创建订单后是不会更改的,为了进一步提高性能,引入缓存,把订单号与用户编号的关系存放到缓存里面,减少查表操作,提升性能,索引不命中时再去查表,并把查询结果更新到缓存中。

    参考

    数据库分库分表思路

    相关文章

      网友评论

          本文标题:初识分库分表

          本文链接:https://www.haomeiwen.com/subject/jwnnvqtx.html