本文是对58同城沈剑的文章二次整理,并结合自己的实践再加工得来。所以非常感谢沈剑。
先总结下:
因为业务发展从生产环境迁移了三亿数据:
0、先迁移总量数据,再分阶段迁移增量数据。
增量不断追加无限逼近总量后,打开开关对外公告服务暂时不可用,迁移并对比增量数据(十多秒),然后重新恢复服务。
1、新表不建立索引,迁移完成再建立索引。有实践为证,亿级表无索引迁移需要约10分钟,有索引迁移约需要50个小时;
2、hint语句:加上append、nologging、parallel等能极大优化效率;
3、如果是分区表,可单张分区表独立迁移。
详细:
小表有索引插入250万数据为15分钟;
大表有索引插入250万数据为150分钟;
大表有索引插入250万数据到分区表为40分钟,
大表无索引插入250万数据为15秒;
重建大表索引约为30S。
一、引子
- 故事:业务遇到了瓶颈,多张表每个月新增亿级数据,如何仍然保证高可用。
- 开始:所有不与业务结合的架构都是耍流氓,针对具体场景进行分析得出具体方案。
- 收集:所以先需要对所有数据库架构有所了解,才能比较。以下内容分为三个话题:
- 数据库架构
- 数据水平切分实践
- 迁移或者扩容方案
二、数据库架构
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等能极大优化效率;
如果是分区表,可单张分区表独立迁移。