zoukankan      html  css  js  c++  java
  • 无限容量数据库架构总结

    本文是对58同城沈剑的文章二次整理,并结合自己的实践再加工得来。所以非常感谢沈剑。

    先总结下:

    因为业务发展从生产环境迁移了三亿数据:

    0、先迁移总量数据,再分阶段迁移增量数据。

    增量不断追加无限逼近总量后,打开开关对外公告服务暂时不可用,迁移并对比增量数据(十多秒),然后重新恢复服务。

    1、新表不建立索引,迁移完成再建立索引。有实践为证,亿级表无索引迁移需要约10分钟,有索引迁移约需要50个小时;

    2、hint语句:加上append、nologging、parallel等能极大优化效率;

    3、如果是分区表,可单张分区表独立迁移。

    详细:

    小表有索引插入250万数据为15分钟;
    大表有索引插入250万数据为150分钟;
    大表有索引插入250万数据到分区表为40分钟,
    大表无索引插入250万数据为15秒;
    重建大表索引约为30S。

    一、引子

    • 故事:业务遇到了瓶颈,多张表每个月新增亿级数据,如何仍然保证高可用。
    • 开始:所有不与业务结合的架构都是耍流氓,针对具体场景进行分析得出具体方案。
    • 收集:所以先需要对所有数据库架构有所了解,才能比较。以下内容分为三个话题:
      1.  数据库架构
      2.  数据水平切分实践
      3.  迁移或者扩容方案

    二、数据库架构

      1、单库方案

       2、分组架构:

        常见为一主多从、主从同步、读写分离架构;

        技术实现方式常见有数据库在线或者归档日志(oracle goldengate、mysql binlog)、ETL技术。

        适用于读多写少场景,用于解决读瓶颈;

      3、分片架构:分表、分区、分库。

        相同点:减少索引的B-树深度,所以提高了插入或者查询数据的效率;

        不同点:分表在同一个表空间,仍有IO竞争、分区支持不同表空间可改善IO竞争、分库可实现彻底物理隔离;

        分片常见算法有hash算法、范围算法、和复合算法(此外,还有列表分片)

        适用于数据库量过大的场景,一般建议数据量多大则分库,原因见上。

      4、分组+分片复合架构

        适用于读写量都巨大的场景。

      5、垂直切分

          包含垂直分表和垂直分表分库;

        需要考虑长度和访问频度,长度短、访问频度高的放在一起。例如用户表与用户扩展信息表。

        适用于业务字段较多、访问频度且不一致的场景,这样可以使得访问频度高的数据加载到内存,减少IO,加快访问速度。如果分库,还也可以降低单库容量。

    三、数据库水平切分实践

      1、单key业务

        A、使用分片架构,详见2.3章节;

        B、单key衍生场景——

          A、用户多弱key业务,例如,:户登录,UID为key,后续业务都用UID处理。同时需要支持手机、身份证号等登录。

            (1)部分时候可参照多key场景

            (2)基本方案为:索引外置(索引表法、映射缓存法)和基因法(弱key内置key中,弱key的分片算法结果内置key中)

          B、运营侧业务,常见问题场景是批量分页或者统计查询

              (1)解耦:中间件、数据库、数据库表层解耦。

            (2)可以是插入时冗余一套数据,也可以使用ods库、或者索引外置的方案

      2、一对多业务

        A、切分方案,分库场景如下——

          外键分库,导致外联表分到不同库中,需要遍历库;主键分库,导致根据外键查询详细信息时,需要先反向查找主键定位库,可结合索引外置方案;基因法分库,目前最好的实践。

        B、衍生场景,分库后的弱key查询——

          元数据与索引数据分离:元数据用于满足key查询;索引数据用于根据弱key查找key,然后就能根据key找到对应库,并且根据key查询元数据。

      3、多对多业务

        A、基本思路:数据冗余方式分库

        B、实践方式:例如,A关注B,则为在关注表中,A关注了B,在被关注表中,B是A的粉丝。这样单个查询命中单库就能满足要求。

        C、关键点:数据存储多份要保证(最终)一致性。

      4、多key业务

        A、基本思路:通过冗余的方式来降维,通过降维来用低维度的手段解决问题;

        B、实践方式:例如订单关系中的客户与商家,则为客户存储订单信息,变为一对多;也为商家存储订单信息,变为一对多;实践中有时是变为多对多。

        C、关键点:数据存储多份要保证(最终)一致性。

    四、迁移或者扩容方案

      迁移和扩容是两个不同的事件,有时扩容伴随着迁移。

    •   迁移方案:
      • 全量迁移+停机增量迁移:停机是为了保证不会在迁移期间产生新的增量数据;
      • 双写法(非停机迁移:旧库修改变为新旧库同时修改,在此期间迁移数据到新库,最终对比数据,然后切换过去。
    •   扩容方案:
      • 全量迁移+停机增量迁移
      • 双主同步方案(完美方案)——

          (1)假设,现在有A/B两台,%2=0路由到A,%2=1路由到B

          (2)现在为AB建立双主同步库,A对应C、B对应D

          (3)修改配置项建立新的链接,%4=0对应A、%4=1对应B、%4=2对应C、%4=3对应D

          (4)撤销双主,A与C、B与D不再建立关系

          (5)数据缩容:例如将A中%4=2的全部干掉,C中%4=0的全部干掉。完美结束。

    • 数据迁移的效率:

        大表迁移数据的几种有效方式——

        新表不建立索引,迁移完成再建立索引。有实践为证,亿级表无索引迁移需要约10分钟,有索引迁移约需要50个小时;

        hint语句:加上append、nologging、parallel等能极大优化效率;

        如果是分区表,可单张分区表独立迁移。

      

        

        

            

      

        

        

      

  • 相关阅读:
    Java常考面试题整理(一)
    TLPI读书笔记第29章:线程介绍
    TLPI读书笔记第57章-SOCKET:UNIX DOMAIN
    TLPI读书笔记第23章:定时器与休眠1
    java中线程安全的集合
    在springboot中使用jdbcTemplate
    springboot设置定时任务(转)
    springboot中使用swagger
    springboot中的@RequestMapping和@GetMapping(转)
    springboot在controller中传递参数
  • 原文地址:https://www.cnblogs.com/baimingqian/p/7599850.html
Copyright © 2011-2022 走看看