热点数据更新优化
- 热点数据更新带来的问题
- 问题的方向判断
- 用户线程被打挂
- 据库cpu被打挂(优先考虑,80%可能性)
- redis被打挂
- 临时解决方案
- 解决方案
- 流量控制
- 热点隔离
- 数据分批次提交
- 数据合并后更新
- 重写MySQL的执行层
热点数据更新带来的问题
问题的方向判断
用户线程被打挂
-
用活跃的线程数超过当前配置的最大值,新请求进来后,应用无法处理从而出现假死现象。
-
基于k8s部署的应用通过请求探活接口,发现没响应后会不断重启应用,导致c端时不时出现系统异常。
据库cpu被打挂(优先考虑,80%可能性)
-
数据库出现大量sql,而且业务请求量很大,导致大量线程阻塞,cpu很快升至100%。
-
并发请求太高,超过了数据库承受的最大线程数(业务请求TPS:2w/s,数据库单节点TPS:2k/s),cpu快速
升至100%。
redis被打挂
- redis cpu打爆,接近100%。一般可能的原因是:
redis 出现热key
。 - redis内存满了,接近100%。一般可能的原因是:redis key短时间内增长很快超过内存最大值(设计不合理或
者过期时间设置过长)。 - redis 网络IO太大,比如:1.8G/s。一般可能的原因是:
redis 出现大key
。
临时解决方案
- 重启出问题的MySQL或Redis
- 将流量切换到容灾。
解决方案
流量控制
- 在网关做好限流
- 或者使用基于redis的限流
热点隔离
- 热点业务独立部署
- 热点数据垂直拆分成独立数据库
数据分批次提交
- 自定义
mybatis拦截器
,拦截执行SQL,动态配置一个阈值,当insert或update的记录数超过阈值,改为分批次提交事务(可以参考:mybatis-plus批量提交的处理逻辑)
数据合并后更新
可以在内存中合并同一个记录的多条更新操作,之后只提交一次,减少数据库锁的冲突。
重写MySQL的执行层
通过重写mysql的执行层,提供自动探测热点行更新
开关,如果检测到单行有大量的热点更新,在执行层引入排队机制
,减少行锁冲突,提升并发性能。阿里与腾讯内部的mysql库都已经二次开发支持这个特性。