随着业务的快速发展,数据库已经有了上亿条记录,数据存储达到了上百G,原有的单库单表设计已经无法支持系统的稳定性以及接口的响应速度了,数据库存在大量慢查询,且需要提供对C端这种大访问量场景提供支持。数据库随时面临着宕机的风险,基于此,决定对大表进行治理,下面是对大表改造的一些通用方案实践总结
上面第一张表是存储主用户数据的主表,日增量70万左右,第二张表是第一张表的关联表,为1:N的关系,目前已经有213.12GB的容量了,持续增长下去会严重影响系统的稳定性
综合市面上现有的成熟大表治理技术,最终采用了Apache ShardingSphere来治理大表,对大表进行水平分片
目标表现存数据量:3.8亿 日新增数据:70W(随着业务增加,数据可能增加) 年新增数据:70W * 30 * 12 = 2.5亿 5年后数据总量:16.3亿 大表拆分为几个库,每个库拆分成多少表应根据以上关键指标进行合理评估,拆分的库表太小了,则拆分后每个库表也容易变为大表,拆分的太大了,服务器,数据库成本又太高。 所以综合以上数据采用32个库x8张表进行分库分表,5年后每张表平均数据量为:636W 单表数据量不超过千万,查询性能在当前机器配置下可以接受,如果未来数据过多,可以根据数据创建时间根据年限进行归档处理,保留最近5年用户最新数据,做冷热分离改造
1.上线双写以及数据迁移,数据对比程序,此时业务还是读取旧库 2.双写读旧:切换apollo之类的开关(apollo对应配置)以及记录双写开始时原数据库的最大主键ID及上线双写时间,方便后续数据迁移 3.数据迁移:开启定时任务,在夜间访问低峰期分页迁移历史数据(ID小于双写时记录的最大主键ID的数据) 4.数据对比:等所有历史数据迁移完成,校验历史数据是否全部迁移完成。可以采用分页对比,抽样对比,中断对比后重新对比(模拟发布重启时的异常情况) 5.双写读新:修改读写策略为双写读新库 观察切换读取新库一段时间(具体时长待定),若没有问题则修改读写策略为读写新库策略,若观察到日志异常或用户反馈则切回旧库,问题解决后再观察一段时间 6.写新读新:日志观察没问题,也没有异常反馈时,切换数据库的访问读写均为新库,完成大表改造 7.数据清理:针对老表的历史数据进行归档清理
上面是只有C端用户访问的一些通用大表治理方法,但实际上除了C端用户(点查)还有有B端运营的数据统计分析,方便售后,促销等(范围查询),但分片键是以用户维度确定的,B端用户无法进行分片查询,这时需要引入ES将原数据中的索引信息实时同步到ES中。对于B端的访问,先查询ES中的索引信息,再根据ES中的信息点查数据库中的信息做聚合。
数据分片:https://shardingsphere.apache.org/document/current/cn/features/sharding/
分布式事务:https://shardingsphere.apache.org/document/current/cn/features/transaction/
数据迁移:
https://shardingsphere.apache.org/document/current/cn/features/migration/