首页 » Web前端 » hgetallphp技巧_Redis 的 KEYS HGETALL 敕令引起 RDS 数据库雪崩宕机 2 次

hgetallphp技巧_Redis 的 KEYS HGETALL 敕令引起 RDS 数据库雪崩宕机 2 次

访客 2024-11-21 0

扫一扫用手机浏览

文章目录 [+]

在这里讲述一下最近发生在我公司的事件,以及如何避免,并且如何处理优化。
该宕机的直接缘故原由是利用 Redis 的 keys 命令引起的,php运用 利用hgetall函数一共造成了某个做事化项目的两次宕机。

间接缘故原由还有很多,技能跟不上业务的发展,由逐日百万量到千万级是一个大的跨进,公司对付系统优化的处理优先级不高,技能开拓人手的短缺。

hgetallphp技巧_Redis 的 KEYS HGETALL 敕令引起 RDS 数据库雪崩宕机 2 次

第一次宕机

hgetallphp技巧_Redis 的 KEYS HGETALL 敕令引起 RDS 数据库雪崩宕机 2 次
(图片来自网络侵删)

2018年9月13日的某个点,公司某做事化项目的 RDS 实例连接飙升,CPU 升到 100%,谢绝了其他运用的所有要求做事。

全体过程如下:

监控报警,显示RDS的CPU利用率达到80%以上,DBA参与,准备KILL慢SQL

1分钟内,没有创造明显壅塞的SQL,CPU持续上升到99%

5分钟内,大量运用报警,并且谢绝做事,RDS的监控显示涌现大量慢SQL,联系做事器数据库供应商进行帮忙

8分钟内,进行数据库主备切换(业务会受损,但是也没办法,没有定位到问题)

9分钟内,部分业务规复,但是一些业务订单的回调堆积超过20w,备库的CPU利用率也持续上升

15分钟内,备库CPU利用率超过97%,业务再次中断,进行切回主库,并进行限流

20分钟内,关闭一些次要运用的流量入口

25分钟内,主库CPU利用率规复正常

30分钟内,逐步开启关闭的限流运用

35分钟内,所有运用规复正常

接下来便是与做事器数据库供应商成立应急小组紧急优化可能涌现的慢SQL,虽然说可能办理了一些慢SQL,但这次并没有定位到详细的问题,也就为几天后再次发生宕机事宜埋下了伏笔

事件影响

某做事化项目做事不可用几十分钟,造成订单数减少几十万笔,丢失百万资金。

缘故原由剖析

当时是没有定位到详细的缘故原由的,但是下面的缘故原由也是一部分可能引起宕机的情形。

某做事化项目的业务增速非常快,在高峰期,数据库QPS打破35000,系统处于高负荷状态。

在高峰期如果同时实行几个全表扫描的SQL,会造成数据库压力急剧上升,运用超时增多,前端运用超时,用户重试,流量飙升,形成了雪崩效应。

紧张缘故原由在与一些老项目的SQL查询性能较差,并且利用的主库,对数据库影响较大。
数据库QPS太高,但是缓存方案由于人手缘故原由一贯没有落地,慢SQL的问题处理优先级该当提升。

改进方案

针对每个运用建一个数据库账号,严格按照规范利用

缓存优化方案即时落地,慢SQL问题优先处理,集中处理目前已经创造的慢SQL(查询韶光超过1S)

升级数据库配置

迁移非核心业务到新的RDS实例中去

第二次宕机

由于上一次的宕机缘故原由未找到,以是这次的宕机是可以预见的。

20180919,还是一样的”配方”,还是原来的”味道”。
同一个RDS,CPU飙升至100%,接下来便是谢绝做事,宕机。
当然,有了第一次的履历,直接主从切换,在几十秒旁边就规复了所有业务,但还是严重影响了公司的业务和形象

缘故原由剖析

规复业务后,公司紧急召开了紧急事件研究会议,当然,我的级别是参与不了的。
公司的高管,高层技能架构、DBA、各个项目的主卖力人一起进行了会议。

在这次会议中,经由查看各个项目的日志,后台的监控数据,创造在那台RDS数据库CPU飙升时,有一台Redis数据库内存将近100%,然后急剧低落。
联系第一次的宕机情形,也是类似的。

接下来便是联系做事器数据库供应商,将那台Redis最近一周的命令全部调用出来,末了创造,在那个韶光点运行了一条keys ...命令。
公司的一个工程师实行keys模糊的匹配命令是为了清理没用的键,但是没有考虑到keys 进行模糊匹配引发Redis锁,造成Redis锁住,CPU飙升,引起了所有调用链路的超时并且卡住,等Redis锁的那几秒结束,所有的要求流量全部要求到RDS数据库中,使数据库产生了雪崩,使数据库宕机。

改进方案

所有线上操作,全部要经由运维通过后方可实行,运维部门逐步快速收回各项权限

新增Redis实例,进行分离

如果有利用类似keys正则命令需求,利用scan命令代替

总结

该事宜中涌现的两次事件,完备是由于人为操作引起的,如果那位工程师,看过Redis的开拓规范,会创造是建议禁用keys命令的。
其余,有线上的命令操作,一定要经由运维评估后方可进行操作,估计那个工程师是老员工吧,有权限,然后直接就进行操作了。

其余,公司的业务发展确实很快,技能跟不上,这是非常非常危险的,极大的增加了宕机的概率。

在业务量不大的情形下,那位工程师的操作是完备没什么问题的,毕竟并发也不大,但是现在,随着公司的发展,业务量的成倍成倍增加,技能的扩展却没有随着增长那么快。

公司的技能人手不敷也是一方面,绝大多数人都是边掩护老项目边做新功能,但是对付项目的重构优化,人手却少了很多,项目优化的优先级不高,这也是很大的一个缘故原由,极有可能涌现类似的情形,新做事化构建迫不及待。

末了的末了,线上操作的任何一条命令,再小心也不为过。

由于由于你的一个符号而引起的事件可能是你所承担不起的

Redis开拓建议

末了附上Redis的一些开拓规范和建议:

1.冷热数据分离,不要将所有数据全部都放到Redis中

虽然Redis支持持久化,但是Redis的数据存储全部都是在内存中的,本钱昂贵。
建议根据业务只将高频热数据存储到Redis中【QPS大于5000】,对付低频冷数据可以利用MySQL/ElasticSearch/MongoDB等基于磁盘的存储办法,不仅节省内存本钱,而且数据量小在操作时速率更快、效率更高!

2.不同的业务数据要分开存储

不要将不干系的业务数据都放到一个Redis实例中,建议新业务申请新的单独实例。
由于Redis为单线程处理,独立存储会减少不同业务相互操作的影响,提高要求相应速率;同时也避免单个实例内存数据量膨胀过大,在涌现非常情形时可以更快规复做事!
在实际的利用过程中,redis最大的瓶颈一样平常是CPU,由于它是单线程作业以是很随意马虎跑满一个逻辑CPU,可以利用redis代理或者是分布式方案来提升redis的CPU利用率。

3.存储的Key一定要设置超时时间

如果运用将Redis定位为缓存Cache利用,对付存放的Key一定要设置超时时间!
由于若不设置,这些Key会一贯占用内存不开释,造成极大的摧残浪费蹂躏,而且随着韶光的推移会导致内存占用越来越大,直到达到做事器内存上限!
其余Key的超时是非要根据业务综合评估,而不是越长越好!

4.对付必须要存储的大文本数据一定要压缩后存储

对付大文本【+超过500字节】写入到Redis时,一定要压缩后存储!
大文本数据存入Redis,除了带来极大的内存占用外,在访问量高时,很随意马虎就会将网卡流量占满,进而造玉成部做事器上的所有做事不可用,并引发雪崩效应,造成各个别系瘫痪!

5.线上Redis禁止利用Keys正则匹配操作

Redis是单线程处理,在线上KEY数量较多时,操作效率极低【韶光繁芜度为O(N)】,该命令一旦实行会严重壅塞线上其它命令的正常要求,而且在高QPS情形下会直接造成Redis做事崩溃!
如果有类似需求,请利用scan命令代替!

6.可靠的行列步队做事

Redis List常常被用于行列步队做事。
假设消费者程序在从行列步队中取出后急速崩溃,但由于该已经被取出且没有被正常处理,那么可以认为该已经丢失,由此可能会导致业务数据丢失,或业务状态不一致等征象发生。

为了避免这种情形,Redis供应了RPOPLPUSH命令,消费者程序会原子性的从主行列步队中取出并将其插入到备份行列步队中,直到消费者程序完成正常的处理逻辑后再将该从备份行列步队中删除。
同时还可以供应一个守护进程,当创造备份行列步队中的过期时,可以重新将其再放回到主行列步队中,以便其它的消费者程序连续处理。

7.谨慎全量操作Hash、Set等凑集构造

在利用HASH构造存储工具属性时,开始只有有限的十几个field,每每利用HGETALL获取所有成员,效率也很高,但是随着业务发展,会将field扩展到上百个乃至几百个,此时还利用HGETALL会涌现效率急剧低落、网卡频繁打满等问题【韶光繁芜度O(N)】,此时建议根据业务拆分为多个Hash构造;或者如果大部分都是获取所有属性的操作,可以将所有属性序列化为一个STRING类型存储!
同样在利用SMEMBERS操作SET构造类型时也是相同的情形!

8.根据业务场景合理利用不同的数据构造类型

目前Redis支持的数据库构造类型较多:字符串(String),哈希(Hash),列表(List),凑集(Set),有序凑集(Sorted Set), Bitmap, HyperLogLog和地理空间索引(geospatial)等,须要根据业务场景选择得当的类型。

常见的如:String可以用作普通的K-V、计数类;Hash可以用为难刁难象如商品、经纪人等,包含较多属性的信息;List可以用作行列步队、粉丝/关注列表等;Set可以用于推举;Sorted Set可以用于排行榜等!

9.命名规范

虽然说Redis支持多个数据库(默认32个,可以配置更多),但是除了默认的0号库以外,其它的都须要通过一个额外要求才能利用。
以是用前缀作为命名空间可能会更明智一点。

其余,在利用前缀作为命名空间区隔不同key的时候,最好在程序中利用全局配置来实现,直接在代码里写前缀的做法要严格避免,这样可掩护性实在太差了。

如:系统名:业务名:业务数据:其他

但是把稳,key的名称不要过长,只管即便清晰明了,随意马虎理解,须要自己衡量

10.线上禁止利用monitor命令

禁止生产环境利用monitor命令,monitor命令在高并发条件下,会存在内存暴增和影响Redis性能的隐患

11.禁止大string

核心集群禁用1mb的string大key(虽然redis支持512MB大小的string),如果1mb的key每秒重复写入10次,就会导致写入网络IO达10MB;

12.redis容量

单实例的内存大小不建议过大,建议在10~20GB以内。

redis实例包含的键个数建议掌握在1kw内,单实例键个数过大,可能导致过期键的回收不及时。

13 可靠性

须要定时监控redis的康健情形:利用各种redis康健监控工具,实在弗成可以定时返回redis 的 info信息。

客户端连接只管即便利用连接池(长链接和自动重连)

标签:

相关文章

大数据助力老年生活,科技赋能,幸福晚年

随着我国人口老龄化程度的不断加深,老年人口数量逐年上升,老年人的生活质量和健康问题成为社会关注的焦点。大数据作为一种新兴的技术手段...

Web前端 2024-12-17 阅读0 评论0

大数据助力防霾,科技赋能,共建清新蓝天

随着全球气候变化和大气污染问题的日益严重,雾霾已成为我国许多城市面临的共同挑战。近年来,大数据技术在环境保护领域的应用越来越广泛,...

Web前端 2024-12-17 阅读0 评论0