关于Redis(Redisson)超时问题的分析

概述

生产环境中流量高峰期会出现短时间的redis异常,主要报错如下:

  • Redis server response timeout
  • RedisTimeoutException: Command execution timeout for command: (PING)
  • Command still hasn’t been written into connection!

根据redisson官方所述,RedisTimeoutException可能是多种原因造成的:

  1. Redis服务器负载高,无法及时响应请求。
  2. 用于redis底层通信的Netty线程繁忙,也就是说Netty的线程池基本满载运行,没有多余的线程可用了。可以考虑增加netty线程池大小。
  3. Redis线程池用满了,没有空余的线程处理新的连接,导致新的redis操作一直在等待可用连接。可以考虑增加redis线程池大小。
  4. 服务器CPU限制。在某些托管环境中(如K8S)会限制服务器CPU使用,从而影响连接到Redis时的应用程序性能。
  5. 不稳定的网络和TCP数据丢失。
  6. Redis供应商限制并发连接数。

其中1,5,6点很容易确认,可以排除。接下来要考虑的就是2,3,4这几点。

Netty线程池优化

在redisson中,Netty 线程负责发送命令到 Redis 服务器并接收响应。

它们处理底层的网络 I/O 操作,包括建立连接、读取和写入数据等。Netty 线程使用非阻塞的 I/O 模型,可以高效地处理多个并发连接和请求。

Redisson 通过配置参数 nettyThreads 来控制 Netty 线程的数量。增加 nettyThreads 的值可以提供更多的线程来处理并发的网络请求,从而增加 Redisson 与 Redis 之间的通信能力。然而,过多的线程数量可能会增加系统资源的消耗,因此需要根据实际情况进行适当的调整。

尝试将以下值作为 nettyThreads 的设置:32、64、128、256。

查看redisson客户端集群配置参数发现,生产环境中nettyThreads配置为32,而线上流量确实比较高,因此考虑将其调整为64。
而redis连接池最大为64,正常是够的。

其他参数优化

根据github上redisson的#4381问题讨论,还进行了以下参数的优化:

1. 移除了fst解码器,因为此解码器是旧版本使用的,新版本使用默认的解码器就可以了
2. 设置keepAlive: true,该参数不指定的话默认为false
3. 调整了重试相关的参数,如超时时间和重试次数等

CPU限制优化

优化上线后,发现错误数量确实减少了,但还是存在少量报错。说明以上的优化是有一定效果的,但不是根本原因。最终经过多番排查发现,其实是第四点,也就是服务器CPU限制导致的。

生产环境是部署在k8s上,hpa扩容策略是根据cpu来扩容的。每次扩容后,新增的pod在刚开始启动的几分钟内,因为各种资源和配置项加载需要消耗较多的cpu,经过几分钟之后才会恢复到正常水平。在此期间,进入到该pod的请求就会由于cpu负载太高导致出现redis访问超时的问题。

出现错误日志的host和时间刚好与扩容的主机和扩容时间能对应上,这也证明了确实是此问题导致的。

CPU使用限制指标

想要判断pod的cpu是否达到了瓶颈,可以通过Prometheus的container_cpu_cfs_throttled_periods_totalcontainer_cpu_cfs_periods_total这两个指标来计算。

CFS是linux系统默认的CPU调度器,用于公平地分配CPU时间片给运行在容器中的进程。当容器的CPU使用超过其资源限制时,CPU CFS会对容器进行限制。

container_cpu_cfs_throttled_periods_total 指标表示容器在 CPU CFS 中发生 CPU 限制的总周期数。每个周期的持续时间取决于 CPU CFS 的配置和容器的限制情况。该指标可以用于监控容器是否经历了 CPU 限制,并可以帮助评估容器的 CPU 使用情况和性能。如果这个值较高或持续增长,说明容器的 CPU 使用可能接近或超出了其资源限制,可能需要调整容器的资源配置或进行性能优化。

container_cpu_cfs_periods_total指标表示容器在 CPU CFS 中获得的总周期数。

注意,这两个指标均是针对单个容器的

通过统计一段时间内CPU受限周期数占总调度周期数的比例,可以判断出在这段时间内容器的cpu使用是否正常。

这也是上文中判断新启的pod在刚开始的几分钟内CPU被打满的依据。

优化方式

分析了原因之后,那就可以想办法来优化了。

思路有两种,一是增加pod申请的CPU资源,保证新增的pod在系统初始化时有足够CPU使用。二是调整startUp探针的初始化时间,保证在刚开始的几分钟内请求不会进入到pod中(startUp探针的机制参见k8s工作负载(1))。

但这两种方案也会带来负面影响,增加CPU资源虽然会满足应用初始化时的CPU消耗,但系统平稳后太大的CPU就比较浪费了,而且会对根据CPU利用率来进行扩缩容的HPA策略有影响。增大startUp探针的初始化时间虽然可以让流量晚一点进入,但是也会降低扩容的速率。举例来说,在某个时间点需要扩容3个pod,原来经过2分钟时间就扩好了,但现在可能需要5分钟才能扩好。

总之,具体的优化措施需要结合实际的应用场景来考虑。

参考资料

[1].https://blog.csdn.net/xiaoyi52/article/details/133277904
[2].https://github.com/redisson/redisson/issues/4381

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/113516.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计模式之建造者模式

什么是建造者模式 建造者模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。这种模式将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。 举一个简单的例子:假设我们要创建一个复杂的对象,例如一…

【Edabit 算法 ★☆☆☆☆☆】Maximum Edge of a Triangle

【Edabit 算法 ★☆☆☆☆☆】Maximum Edge of a Triangle algorithms math numbers Instructions Create a function that finds the maximum range of a triangle’s third edge, where the side lengths are all integers. Examples nextEdge(8, 10) // 17 nextEdge(5, 7…

matlab bin格式转txt输出

matlab bin格式转txt输出 clc,clear; fid fopen(\text.bin,rb); data fread(fid,Inf,int16); fclose(fid);fidfopen(\text.txt,w); fprintf(fid,%d\n,data); fclose(fid);

vscode摸鱼插件开发

不知道大家在写代码的时候,摸不摸鱼,是不是时不时得打开一下微博,看看今天发生了什么大事,又有谁塌房,而你没有及时赶上。 为此,我决定开发一个vscode插件,来查看微博热搜 插件名称&#xff1…

influxDB学习记录

一、官网 influxdb官方英文文档:https://docs.influxdata.com/influxdb/v1.8/query_language/spec/influxdb中文文档:https://jasper-zhang1.gitbooks.io/influxdb/content/ 二、centos安装与基本配置 influxdb安装与基本配置(centos) 三…

论文阅读[51]通过深度学习快速识别荧光组分

【论文基本信息】 标题:Fast identification of fluorescent components in three-dimensional excitation-emission matrix fluorescence spectra via deep learning 标题译名:通过深度学习快速识别 三维激发-发射矩阵荧光光谱中的荧光组分 期刊与年份&…

【量化交易笔记】10.建立最简单的交易策略

概述 量化说得简单一些用策略进行股票交易,在实施交易之前,需要制定策略,并回测试共效果 为了把交易说明清楚,将这个过程,能简单,就简单,总之,简单,简单再简单。 以下主…

unity NPR 卡通渲染

文章目录 一、 介绍二、 素材准备三、 步骤四、 shader代码五、工程链接 一、 介绍 NPR是计算机图形学中的一类,即非真实感绘制(Non-photorealistic rendering),主要用于模拟艺术式的绘制风格,也用于发展新绘制风格,形式一般是卡…

owasp top 10

1、访问控制的崩溃: 通过身份验证的用户可以访问其他用户的信息,越权 达成方式:通过修改url、内部应用程序状态或html页面绕过 防范:除了公有资源外,默认情况下拒绝访问,严格判断权限,记录失败的…

冰蝎默认加密的流量解密

破解冰蝎的默认加密 流量包分析 上传的冰蝎流量包 POST /web-zh/DVWA/vulnerabilities/upload/ HTTP/1.1 Host: 192.168.197.111 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/118.0 Accept: text/html,application/xhtmlxml,a…

Ansible定义各类变量,引用变量方式介绍及注册变量和vars_prompt的用法示例

目录 一.Ansible定义变量 1.用途 2.定义规则 3.变量优先级 二.命令行定义变量 三.定义主机和主机组变量 1.主机变量 (1)内置主机变量 (2)简单示例 2.主机组变量 四.定义playbook变量 1.通过vars表示定义变量&#xff…

HTML 实现 点击按钮切换 整张界面 点击按钮切换局部界面

点击按钮实现页面切换 点击按钮切换全局界面方法一: 使用a标签进行跳转连接 href方法二:在button标签中加上onclick属性,赋值为Javascript方法三:触发一个函数跳转方法四:表单的action定向提交跳转 点击按钮切换局部界…

shell条件测试与条件测试操作符

shell条件测试与条件测试操作符 条件测试变量#?test与条件测试语句方括号测试表达式字符串测试操作符逻辑测试操作符整数测试操作符双小括号的整数测试操作符与含义文件测试操作符条件测试举例 条件测试 条件测试是可以根据某个特定条件是否满足,来选择…

vscode调试container(进行rocksdb调试)+vscode比较git项目不同分支和fork的哪个分支

vscode调试container(进行rocksdb调试) 参考链接: https://blog.csdn.net/qq_29809823/article/details/128445308#t5 https://blog.csdn.net/qq_29809823/article/details/121978762#t7 使用vscode中的插件dev containners->点击左侧的…

zmq封装

ZmqBindlib zmq常用封装 使用方法 基本使用 1.简单请求回复 ZmqRequest request new ZmqRequest();request.RemoteAddress localaddes;request.PubClient "A";int num 0;while (true){// Thread.Sleep(1000);//string msg request.Request("hi"…

【微信小程序开发】小程序微信用户授权登录(用户信息手机号)

🥳🥳Welcome Huihuis Code World ! !🥳🥳 接下来看看由辉辉所写的关于小程序的相关操作吧 目录 🥳🥳Welcome Huihuis Code World ! !🥳🥳 授权流程讲解 一.用户信息授权登录 1.w…

MD-MTSP:粒子群优化算法PSO求解多仓库多旅行商问题MATLAB(可更改数据集,旅行商的数量和起点)

一、多仓库多旅行商问题MD-MTSP 多旅行商问题(Multiple Traveling Salesman Problem, MTSP)是著名的旅行商问题(Traveling Salesman Problem, TSP)的延伸,多旅行商问题定义为:给定一个𝑛座城市…

LabVIEW中管理大型数据

LabVIEW中管理大数据 LabVIEW的最大优势之一是自动内存管理。这种内存管理允许用户轻松创建字符串、数组和集群,而无需C/C用户经常担心。但是,这种内存管理设计为绝对安全,因此数据被非常频繁地复制。这通常不会造成任何问题,但是…

vue3 列表页开发【选择展示列】功能

目录 背景描述: 开发流程: 详细开发流程: 总结: 背景描述: 这个功能是基于之前写的 封装列表页 的功能继续写的,加了一个选择展示列的功能,可以随时控制表格里展示那些列的数据&#xf…

【算法教程】排列与组合的实现

数据准备 在讲排列与组合之前,我们先定义数据元素类型Fruit class Fruit{constructor(name,price){this.name namethis.price price} }排列 对N个不同元素进行排序,总共有多少不同的排列方式? Step1: 从N个元素中取1个,共N种…