成熟的业务系统都会配套一个重要的旁路系统--操作日志,它用于监控和记录核心业务系统的操作,以确保系统的稳定性和安全性。
操作日志系统会通过MQ去解耦核心业务,通过采集各个微服务的操作数据,最终将数据持久化在DB等廉价媒介。
而随着业务的快速发展,数据量急剧增长,为了提高数据存储和查询效率,则需要根据业务场景选择不同的拆表方案。
我们的业务系统也配套了操作日志系统,用来记录用户的日常代码评审事件。从2014年服务上线至今,随着业务的不断扩展,产生了许多大表,其中之一就是事件表events。
在运维工具看到事件表events已经比较臃肿,有几个亿的数据,表体积达几百GB;面临的问题有:
(1)业务慢sql问题:虽然在DB高可用设计上,对Mysql集群采用了读写分离,但事件表依旧存在“读慢写慢”的问题
>读数据(个别读sql执行时间>40s)
>写数据(写sql执行时间>1s)
(2)业务表拓展问题:单一大表支撑不了日益膨胀的数据增量,当下事件表日增量20w,半年增量1500w,问题迫切
(3)DB 运维:
如上文所说,旁路系统一般不直接和业务系统耦合,而是通过mq来进行解耦合。
你需要做到:
按照表拆分原则可以分为3种方法:
如下所示:
原理 | 好处 | 不足 | |
---|---|---|---|
水平分表 | 将一个大表按照某种规则(如行键范围)拆分成多个结构相同的小表 | 1.将数据分散到这些拆分出来的表中,解决了单一表数据量过大而产生的性能问题 2.避免IO争抢并减少锁表的几率 | 1.路由规则复杂 2.多次拆分和分表扩容难度大 3.跨库join的问题 4.分表存储不均匀(导致子表数据量过大) |
垂直分表 | 将一个表按照字段分成多个表,每个表存储其中一部分字段 | 1.业务表功能划分明确 2.避免IO竞争减少锁表的概率,更好地提升热门数据的查询效率 | 事务处理较复杂 |
冷热分表 | 将一个表数据分为冷热两部分,分别采用不同的存储和访问策略 | 1.提高性能:通过将热数据存储在高性能的存储中,可以大大提高数据的访问速度,从而提高数据库的性能。 2.降低存储成本:将冷数据存储在低成本的存储中,可以降低存储成本,同时也可以释放出更多的高性能存储资源,用于存储热数据。 3.提高数据管理效率:通过将冷热数据分开管理,可以更好地控制数据的生命周期,如定期清理冷数据等,从而提高数据的管理效率。 | 1.保证数据的完整性和一致性的方案复杂 2.实现数据的迁移和管理要额外进行 3.仍然无法解决单表数据量过大的问题 |
选取技术方案,要结合产品需求去落地,否则南辕北辙。
汇总一下产品需求:
最终,研发抽象出以下需求:
综上所述,考虑了当前产品需求、开发成本和可扩展性,决定采用冷热分表存储的方案。
确定冷热分表方案后,需要进行实施落地。这包括数据迁移、表结构调整、索引优化、应用程序代码修改等一系列工作。同时,需要考虑如何保证数据的一致性和完整性,以及如何进行故障恢复等问题。
冷热分界线是一个在业务层面定义区分数据冷热的分界线,一般按数据量和查询时间覆盖范围,确定多长时间之前的数据需要转移到冷存储。另外,也要结合业务产品的需求,例如,对冷项目也有保留定量数据的兜底需求。
最终的冷热数据分界线规则如下:
冷表模型和热表模型是可以存在差异的。
调研了当下有以下几种较合适的冷数据存储方案
结合当下迫切需求和开发工作量,同时也使得开发成本好评估,我们觉得可以继续把冷数据存Mysql,切换冷数据源的任务还可以再讨论。
方案步骤:
方案步骤:
原理 | 好处 | 不足 | |
---|---|---|---|
只迁热数据 | events当作冷表,hot_events作为热表 | 迁移热数据量小 | 原有的复杂业务调用都要改,且迁移步骤复杂业务兼容工作量较大 |
只迁冷数据 | events当作热表,cold_events作为冷表 | 迁移步骤简单原有的复杂业务调用不用任何调整,业务兼容工作量较小 | 迁移数据量大 |
最后我们选择方案二,即只迁移冷数据;虽然迁移冷数据量会大一点,但迁移任务本身不要求过高性能。
具体实现细节大同小异,无非是查出冷数据,数据写入新表,删除旧表数据,但还是有以下的几个点需要注意下:
因为迁移任务执行过程中,往往可能有突发状况,比如,升级hotfix,下游业务发布影响等;这会导致任务中断,此时需要迁移任务天然支持重放。
为确保数据一致性,写入删除数据最好封装成一个事务,并且控制写入删除的粒度尽量小,最好写一条删一条。
迁移任务一般是异步执行,并且依赖线程池和事务框架来满足需求;
业务一般喜欢用大的try..catch..捕获迁移异常,而因为事务框架往往是通过捕获异常去实现回滚的(例如Spring-tx框架),这个冲突要注意下。
查冷数据本质就是读大表的sql,我们可以参考各部门的sql开发规范:
真实迁移过程中,会产生慢SQL,比如,单个项目的索引命中的数据量>2000w,这时候的分页+排序的方式读数据将不可取,可以考虑下,遗留数据有序性是否有必要。
按使用场景划分,业务调用分为数据检索类和数据统计类,下面分别给出一点建议:
为了防止线上意外情况,我们需要额外冗余一批接口来解决意外情况,比如:
经过一段时间的迁移,我们完成了既定目标:将冷数据迁移到了冷表,效果如下:
从观测效果来看,因为大表导致超时的接口(nginx监控>45s),在做了冷数据迁移后,响应时间降低到了1.76s,因此大表冷热数据分级的效果还是很明显的。
冷热数据分级是一种有效的解决单表大数据存储和查询问题的方案,可以优化存储资源分配和提高查询效率,在实施过程中需要考虑以下几点:
在可预测的未来,我们还有几个地方可以做的更好:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有