redis Jedis SDK使用故障复盘,redis不可用

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 线上故障,连接池不可用,内存占用高,带宽打满,redis不可用,pipeline太大,jedis,redis 客户的读value 缓存队列

##线上一次故障导致客户方的应用无法使用

现象描述

业务切换到云redis后,出现业务不可用情况。通过监控看到 千兆带宽流量打满 ,内存占用情况:

查看 info memory 信息,

used_memory_human:198.23M,

used_memory_overhead:10443988934 ,也就说overhead占用超过10g左右,监控信息均正常,开始怀疑 lua,但是

used_memory_lua_human:37.00K


那么分析源码getMemoryOverheadData函数

微信截图_20211225124033.png

看到 overhead内存占用主要是

初始化之后的内存(这部分很少都是一些redis出事数据结构占用)+backlog(历史增量日志一般也就几Mb)+主从复制连接读写缓存+client 读写缓存+AOF 写缓冲和 rewrite写缓存+ 数据部分的 (hash entry,object )占用。


那么查看 client list 可以看到如图,omem,占用大量内存但是不释放。参数调整到了 256mb 30秒,所以outputbuffer没有及时超过阈值释放。

client-output-buffer-limit normal 513741824 256870912 30

所以这个时候大概定位内存占用高的直接指标信息了。

20211224-161057.png

#分析客户方无法使用的原因

我们在分析 client的连接,看到客户方已经迁走业务,到自建redis,但是 redis的tcp队列依然有发送队列挤压数据问题,并且看到 这些client的 omem几乎没有变化,

image.png


这是为什么?恶意使用?经过和客户方的沟通查看到 客户方的 采用jedis代码调用,但是排查代码发现 采用 java的 timeout 1秒钟作为基础,那么就释放掉jedis的连接。排查jedis代码发现,从jedis连接池中拿出来的 连接 close调用 会直接归还连接池中。



publicvoidclose() {
//如果使用了连接池,检查客户端状态,归还到池中if (dataSource!=null) {
if (client.isBroken()) {
this.dataSource.returnBrokenResource(this);
      } else {
this.dataSource.returnResource(this);
      }
    } else {
//未使用连接池,直接关闭client.close();
    }
  } 


完整还原:

经过分析大概是这样,客户端通过jedis发送大量的请求导致带宽打满,由于带宽打满导致 redis连接的缓冲区无法及时发送到 jedis客户端,导致业务代码超时,从而释放jedis连接,从而导致归还连接池后,再次从连接池中拿数据会导致连接中结果读取错误无法解析,从而导致业务逻辑全部都除了问题。


优化方案:jedis 超时判断这需要把jedis 直接client.close(),就不能调用连接池的close方法。还有一个就是 将大批量的带宽占用调整成集群,分摊带宽压力从而减少这类异常的发生。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
4月前
|
NoSQL Java API
Redis官方推荐的Java连接开发工具Jedis
Redis官方推荐的Java连接开发工具Jedis
|
4月前
|
NoSQL Java Redis
redis-学习笔记(Jedis 通用命令)
redis-学习笔记(Jedis 通用命令)
45 1
|
4月前
|
存储 监控 负载均衡
保证Redis的高可用性是一个涉及多个层面的任务,主要包括数据持久化、复制与故障转移、集群化部署等方面
【5月更文挑战第15天】保证Redis高可用性涉及数据持久化、复制与故障转移、集群化及优化策略。RDB和AOF是数据持久化方法,哨兵模式确保故障自动恢复。Redis Cluster实现分布式部署,提高负载均衡和容错性。其他措施包括身份认证、多线程、数据压缩和监控报警,以增强安全性和稳定性。通过综合配置与监控,可确保Redis服务的高效、可靠运行。
222 2
|
1月前
|
NoSQL Java Linux
Jedis测试redis。(redis在linux虚拟机中)
该博客文章提供了使用Jedis客户端连接Linux虚拟机中的Redis服务器的步骤,包括Maven依赖配置、测试用例编写以及测试结果的截图。
|
27天前
|
缓存 NoSQL Java
【Azure Redis 缓存】定位Java Spring Boot 使用 Jedis 或 Lettuce 无法连接到 Redis的网络连通性步骤
【Azure Redis 缓存】定位Java Spring Boot 使用 Jedis 或 Lettuce 无法连接到 Redis的网络连通性步骤
|
29天前
|
缓存 NoSQL Java
【Azure Redis 缓存 Azure Cache For Redis】当使用Jedis客户端连接Redis时候,遇见JedisConnectionException: Could not get a resource from the pool / Redis connection los
【Azure Redis 缓存 Azure Cache For Redis】当使用Jedis客户端连接Redis时候,遇见JedisConnectionException: Could not get a resource from the pool / Redis connection los
|
2月前
|
监控 NoSQL 算法
Redis问题之哨兵模式中的配置文件会在故障转移后发生什么变化如何解决
Redis问题之哨兵模式中的配置文件会在故障转移后发生什么变化如何解决
|
2月前
|
Java Redis 数据安全/隐私保护
Redis14----Redis的java客户端-jedis的连接池,jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗,最好用jedis连接池代替jedis,配置端口,密码
Redis14----Redis的java客户端-jedis的连接池,jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗,最好用jedis连接池代替jedis,配置端口,密码
|
2月前
|
Java Redis 数据安全/隐私保护
Redis13的Java客户端-Jedis快速入门,建立连接的写法,ip地址,设置密码密码,选择库的写法
Redis13的Java客户端-Jedis快速入门,建立连接的写法,ip地址,设置密码密码,选择库的写法
|
2月前
|
安全 NoSQL Java
网络安全-----Redis12的Java客户端----客户端对比12,Jedis介绍,使用简单安全性不足,lettuce(官方默认)是基于Netty,支持同步,异步和响应式,并且线程是安全的,支持R
网络安全-----Redis12的Java客户端----客户端对比12,Jedis介绍,使用简单安全性不足,lettuce(官方默认)是基于Netty,支持同步,异步和响应式,并且线程是安全的,支持R