抚顺物流,腾讯qq公仔,天王巨星系统
前段时间我离职了,因为个人原因,在休整一段时间后,重新入职了一家新公司。
图片来自 Pexels
入职的第一天我就经历了一次生产事故,运维同学告警说线上 MySQL 负载压力大,直接就把主库 MySQL 压崩了(第一天这可不是好兆头)。
运维同学紧急进行了主从切换,在事后寻找导致生产事故的原因时,排查到是慢查询导致 MySQL 雪崩的主要原因。
在导出慢查询的 SQL 后,项目经理直接说吧这个 MySQL 优化的功能交给新来的吧!
我赶紧打开跳板机进行查看,不看不知道一看吓一跳:
单表的数据量已经达到了 5 亿级别!这尼玛肯定是历史问题一直堆积到现在才导致的啊,项目经理直接就把这个坑甩给了我,我心中想,我难道试岗期都过不了么??
好在我身经百战,赶快与项目经理与老同事进行沟通,了解业务场景,才发现导致现在的情况是这样的。
我所在的公司是主要做 IM 社交系统的,这个 5 亿级别的数据表是关注表,也是俗称的粉丝表,在类似于某些大 V、或者是网红,粉丝过百万是非常常见的。
在 A 关注 B 后会产生一条记录,B 关注 A 时也会产生一条记录,时间积累久了才达到今天这样的数据规模,项目经理慢悠悠的对我说,这个优化不用着急,先出方案吧!
我心中一万个草泥马经过,这上来就给了一块不好啃的骨头,看来是要试试我能力的深浅啊。
按照我之前经验,单表在达到 500W 左右的数据就应该考虑分表了,常见分表方案无非就是 hash 取模,或者 range 分区这两种方法。
但是这次的数据分表与迁移过程难度在于两方面:
数据平滑过渡,在不停机的情况把单表数据逐步迁移。(老板说:敢宕机分分钟损失几千块,KPI 直接给你扣成负的)
数据分区,采用 hash 还是 range?(暂时不能使用一些分库分表中间件,无奈)
首先说说 hash:
常规我们都是拿用户 id 进行取模,模到多少直接把数据塞进去就行了,简单粗暴。
但是假如说 user_id=128 与 user_id=257 再模 128 后都是对应 user_attention_1 这个表,他俩也恰好是网红,旗下粉丝过百万,那轻轻松松两个人就能把数据表撑满。
其他用户再进来数据的时候无疑 user_attention_1 这个表还会成为一张大表,这就是典型的数据热点问题,这个方案可以 PASS。
有的同学说可以 user_id 和 fans_id 组合进行取模进行分配,我也考虑过这个问题。
虽然这样子数据分配均匀了,但是会有一个致命的问题就是查询问题(因为目前没有做类似 MongoDB 与 DB2 这种高性能查询 DB,也没做数据同步,考虑到工作量还是查询现有的分表内的数据)。
例如业务场景经常用到的查询就是我关注了那些人,那些人关注了我,所以我们的查询代码可能会是这样写的:
在我们进行 user_id 与 fans_id 组合后 hash 后,如果我想查询我关注的人与谁关注我的时候,那我将检索 128 张表才能得到结果。
这个也太恶心了,肯定不可取,并且考虑到以后扩容至少也要影响一半数据,实在不好用,这个方案 PASS。
接下来说说 range:
本文地址:http://www.reviewcode.cn/youxikaifa/211358.html 转载请注明出处!