冷热分离场景分析&实际业务落地
[原创]个人理解,请批判接受,有误请指正。转载请注明出处: https://heyfl.gitee.io/design/cold-hot-separation.html
前言
在数据库的读写研发中,我们遇到最多的可能就是数据量过多
导致的『读/写慢』
了。针对这些问题,我们一般主要会采取的措施有:
- 优化SQL
- 优化索引
- 优化硬件
- 分库分表
- 业务拆分
冷热分离
- 读写分离
这次我们主要讲讲冷热分离的实际使用场景,以及如何以前刚出来时候的项目实际落地方案。
冷热分离
使用冷热分离条件:
数据总量足够大
,导致影响读写冷数据不更新,只读。或者,冷数据更新频率极低,可以忽略不计
冷数据占比较大,热数据占比较小
以之前在联通做的一次工单业务为业务场景
每天新增工单10w左右,数据存放6个月,过期数据定期删除,项目上线6个月,数据库该表数据量预计大约有近2000w,上线到第四个月用户反馈工单查询/操作很慢。
问题分析排查
- 表数据95%以上都是已归档状态的工单
- 大部分用户、大部分场景下只关心未归档工单
- 上线后根据业务反馈,以及表数据排查,一般客服、业务人员对归档工单基本不会再去做查询
- 业务上不允许对已经归档的更新操作
以上场景满足冷热的使用条件,很适合做冷热分离,以下来看看我们具体怎么做的
解决方案
- 将归档工单单独拆分出来,单独存放一张表(归档工单表,即冷表),不参与查询
- 将工单表的查询功能进行拆分,拆分为『工单查询』、『归档工单查询』2个功能,其中『工单查询』查询工单表,『归档工单查询』查询工单归档表
落实的细节
工单归档时候,如何把数据move到冷表中(其实不在同个数据库)
- (
✓
)修改数据时,触发业务代码将数据同步到冷库的冷表中(我们采用的是这种
,保证了实时性,而且是用了另一个库,采用XA的分布式事务)
具体是: 修改工单为归档时,先写冷表,再写热表,如果热表写失败,冷表回滚
- 优点:实时性高,数据准确性高
- 缺点: 业务代码需要改动,需要引入分布式事务(当然,其实也可以不引入分布式事务,这样做主要是快准狠)
- 消费binlog,(异步)将数据同步到冷库的冷表中
- 优点:这种方式业务代码不需要改动
- 缺点:实时性不高、需要canal这些数据库binlog同步工具
- 定时任务,将数据同步到冷库的冷表中
- 优点:这种方式业务代码不需要改动
- 缺点:需要定时任务、实时性不高
优化效果
优化后原表数据从近2000w减少到热表的不到100w的数据量,用户对其更新、查询响应效果明显大幅提升
问题
- 由于归档工单表数据量还是很大,对其查询效率也不高
- 当时只有mysql数据库,要做优化可以通过分区存储、或者分库分表存储
- 现在有了es、hbase这种大数据存储,现在看来,解决起来还是比较简单,无非是es存索引+hbase的rowkey,hbase存储实际数据
笔记
冷数据如何分离
- 业务修改时,同步到冷库
- (异步)消费binlog
- (异步)定时任务扫表同步
前提:冷热分离硬性要求
:冷数据不更新,只读。或者,冷数据更新频率极低,可以忽略不计
Other more
其实除了这些归档数据,一些大部分业务的历史数据也是可以做冷热分离的。
在顺丰这些公司也有不少类似功能,查询历史订单、运单、图片等数据,但因为数据量问题,冷库一般使用es、hbase这些大数据组件实现。
这次先写到这,后面再写『通过实际业务分析读写分离的使用场景
』
冷热分离场景分析&实际业务落地