基于redis的抢资源应用负载高问题调查

自述:这是一个存在10多年的老应用,其本身有很多待解决更新的技术债务。抢资源类似抢红包系统,没有使用缓存也没有限流,即使是使用redis也很糟糕的使用多个慢操作。本文的目的不是想表达解决了什么难度的问题,是想说明面对线上问题,缺乏经验时会对数据不敏感,面对一堆现象无法挑出最核心的线索。我完整记录了我思考错误和之后纠正的过程,给大家引发一些面对问题的思考方式。

问题现象

一个历史系统于每天晚上 20:00 开始,放出一批资源,供公司销售同事抢占作为私有资源,高峰期持续2分钟到20:02。

从调用接口来看,抢资源分为 listAccount、detailAccount、 robAccount。listAccount是列表页查询,简单理解由3个SRANDMEMBER和1个HMGET共4个redis操作组成。查到列表之后,点击进行detailAccount详情查询,并点击进行robAccount抢占。

从销售人员的用户行为来看,他们会一直按F5刷新查询列表页,所以详情查询和抢占请求会是很少数。

从nginx日志分析,20:00开始整体响应变慢甚至超过1秒,5分钟内慢记录占全天一半左右,而其中90%以上均为列表页查询,也印证了用户行为的分布状况。nginx日志中列表页80%以上都返回499。而499是Nginx自定义的一个状态码,表示客户端主动关闭连接,无法返回结果。其实用户浏览器对F5无限刷新会进行请求筛选,不会每次刷新都发出新的请求,每个浏览器的策略有轻微差别。但从大量的499来看还是重复发出了不少请求,F5产生的爆炸力还是挺惊人的。

从应用日志来看,20:00:37秒开始出现大量的JedisConnectionException: Could not get a resource from the pool,配置的timeout是2秒,还有少量的readTimeout异常。从pingpoint监控来看20:00:37开始只看到readTimeout异常没有get resource from pool异常,因此对pingpoint的采集精准度表示质疑。

从redis实例来看,info命令打印出来的clint连接数一直处于46左右的很低数量,从slow-log得知20:00:37开始有7个1ms的慢操作,均是列表页的SRANDMEMBER和HMGET,到20:02分抢客户高峰期过了之后就不再有slow-log出现。从zabbix来看redis所在虚拟机的cpu只有60%左右,进出IO低,负载系数也不高。

初步分析

所以从应用客户端取不到连接且reids只有46连接数和不高的负载来简单判断,可能是客户端连接来不及创建。这里出现了两个错误判断:
一是从20:00:37到20:02分请求高峰期间,已经出现7个1ms slow-log,1ms看似很快没在意,忽略了redis是单线程架构TPS能达到单机读写2万,明知SRANDMEMBER和HMGET都是需要警惕的慢操作,忘记换算1ms对应的TPS已经降到1000,这已经是很明显的性能警告,前面nginx统计高峰期间应用各实例合计每秒有1300个listAccount即5200次redis读写,远远超过1000TPS所以才出现1ms的slow-log。
二是没有通过top命令直接查看机器负载而是依赖zabbix,忽略了zabbix采样间隔过大导致可能错过请求高峰期间的精准信息,不是cpu负载不高,只是zabbix跳过去了没采集到。

问题解决

基于客户端连接来不及创建的初步结论,我们修改cache-client默认配置,设置idle-connect数量从0改为30-50。再次观察redis实例,info命令显示client连接数维持在280左右的较低数量,说明每个应用都准备好了空闲连接。但现象没有任何区别,20:00:37到20:02分期间,slow-log依然出现,应用日志依然抛出readTimeout异常,pingpoint大量请求响应时间陡增,nginx日志大量慢查询和499。之后才意识到slow-log里1ms表达出来的严重性能问题,直接top命令观察到redis机器已经cpu 97%,说明页面F5发出的大量重复的listAccount请求转化为SRANDMEMBER和HMGET,对redis造成了严重的负担。

回顾redis的架构,不管是连接事件还是读写事件,都是排队被单线程执行。如果有慢操作阻塞,其余读写事件很可能会readTimeout,连接事件很容易超过2秒抛出Connection异常。就算提前准备好空闲连接,只要阻塞的慢操作还在,整体效果不会有改观。

最后使用guava cache建立应用本地缓存,相邻1s的listAccount结果会被缓存并直接返回,就这一步就省了大量的SRANDMEMBER和HMGET慢操作,redis的负担瞬间就没了。使用guava cache优化后改善效果明显,从nginx日志来看,虽然列表页还有499记录(由于运维日志没有时间记录,无法知道是否超时),但499本就由用户主动触发可视为没有影响,对于有时间记录的列表页查询慢记录,3秒以上的由6000次降为0,1-3秒的由1800此降为180。

思考:

考虑采用限流或缓存方式改造系统。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,692评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,482评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,995评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,223评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,245评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,208评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,091评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,929评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,346评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,570评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,739评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,437评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,037评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,677评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,833评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,760评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,647评论 2 354

推荐阅读更多精彩内容

  • NOSQL类型简介键值对:会使用到一个哈希表,表中有一个特定的键和一个指针指向特定的数据,如redis,volde...
    MicoCube阅读 3,981评论 2 27
  • 对于高并发架构,毫无疑问缓存是最重要的一环,对于大量的高并发,可以采用三层缓存架构来实现nginx+redis+e...
    java高并发阅读 3,092评论 1 95
  • Redis是一个基于内存的键值对存储系统,常用作数据库、缓存和消息代理。它支持字符串、字典、列表、集合、有序集合、...
    Four__years阅读 601评论 0 0
  • 使用缓存是系统性能优化的第一黄金法则。 缓存的设计和使用对一个系统的性能至关重要,平时接触到项目无论多少也都会在某...
    刀刃丿阅读 1,342评论 0 6
  • 第一话:大概是从远方而来的生物,低等而又奇异;是与常见的动植物完全不同的可怕之物,从古时开始,人们就怀着畏惧,将这...
    赤爷阅读 448评论 0 1