记一次redis异常停止排查及参数优化

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介:

背景
跑一个程序,程序采取redis存储任务状态及任务值,程序通过redis获取任务后进行任务下发

image

现象
正在运行的任务进度突然停止,查看执行应用日志,发现报错
日志报错信息
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool

处理过程
根据报错猜测的可能原因有:

  • 1 Jedis 对象用完以后,没有释放掉,被一直占用,所以会出现无法获取新的资源
  • 2 redis服务找不到了
    考虑到只有一个程序在连接redis,应该不会出现连接不够用的情况

所以先从redis的状态开始排查

1 查看redis状态

 ps  -ef | grep  redis

发现redis进程没了,查看历史登陆和历史命令,没有人工停止的迹象

因为没发现什么问题,就手动重启了redis

/redis-server ../redis.conf &

重启后观察应用日志,发现开始又报新的错误:
redis.clients.jedis.exceptions.JedisDataException: MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk. Commands that may modify the data set are disabled, because this instance is configured to report errors during writes if RDB snapshotting fails (stop-writes-on-bgsave-error option). Please check the Redis logs for details about the RDB error.
redis.clients.jedis.exceptions.JedisDataException: MISCONF Redis is configured to save RDB snapshots, but it is currently not able to persist on disk.

通过日志可以看到,报空间不足,所以进行查看服务器状态
查看磁盘空间显示是充足的
查看内存状态

 free -m

发现内存剩余不足

image

登陆redis客户端查看内存使用情况

 redis-cli -h ip -p port
 info memory

image

参数详解:

used_memory : 由 Redis 分配器分配的内存总量,以字节(byte)为单位
used_memory_human : 以人类可读的格式返回 Redis 分配的内存总量
used_memory_rss : 从操作系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致
used_memory_peak : Redis 的内存消耗峰值(以字节为单位)
used_memory_peak_human : 以人类可读的格式返回 Redis 的内存消耗峰值
used_memory_lua : Lua 引擎所使用的内存大小(以字节为单位)
mem_fragmentation_ratio : used_memory_rss 和 used_memory 之间的比率
mem_allocator : 在编译时指定的, Redis 所使用的内存分配器。可以是 libc 、 jemalloc 或者 tcmalloc

对比几个值
1)当 rss > used ,且两者的值相差较大时,表示存在(内部或外部的)内存碎片。
内存碎片的比率可以通过 mem_fragmentation_ratio 的值看出。
2)当 used > rss 时,表示 Redis 的部分内存被操作系统换出到交换空间了,在这种情况下,操作可能会产生明显的延迟
参数参考:
https://jingyan.baidu.com/article/2c8c281dbd079f0008252a0f.html

发现redis使用内存已经4G了,比最开始启动时的内存多出来很多,查看相关资料了解:
Redis的内存如果不在启动前限制,默认是无限制的,32位的redis会限制在3G,目前使用的是64位,所以在使用过程中因为key的增加内存不断的增加

调节配置参数

总结实际修改过的的步骤:

  • 1 将stop-writes-on-bgsave-error设置为no
stop-writes-on-bgsave-error no
  • 2 配置maxmemory(部分起到作用)
maxmemory 内存大小(字节)
  • 3 系统层面添加overcommit_memory
vim /etc/sysctl.conf
vm.overcommit_memory=1 
使文件生效
sysctl -p /etc/sysctl.conf
  • 4 修改redis
    清理不使用的key(实际解决问题的办法)

实际试错的排查过程
1 查询资料说可能是bgsave失败,临时的解决办法是
stop-writes-on-bgsave-error yes修改为 stop-writes-on-bgsave-error no
bgsave方法的介绍:
image
image

结果:
修改了,重启,没效果
2 又看到需要修改系统层面参数
vim /etc/sysctl.conf

vm.overcommit_memory=1

使文件生效

sysctl -p /etc/sysctl.conf

结果:

内存仍然没有下去,不可用

3 修改redis key过期算法
maxmemory-policy volatile-lru

LRU是Least Recently Used 近期最少使用算法。

  1. volatile-lru -> 根据LRU算法生成的过期时间来删除。
  2. allkeys-lru -> 根据LRU算法删除任何key。
  3. volatile-random -> 根据过期设置来随机删除key。
  4. allkeys->random -> 无差别随机删。
  5. volatile-ttl -> 根据最近过期时间来删除(辅以TTL)
  6. noeviction -> 谁也不删,直接在写操作时返回错误。
    image

结果:
内存占用还是4G,没有消减

image

4 修改maxmemory
查看redis相关资料,发现:
如果不设置maxmemory或者设置为0,64位系统不限制内存,32位系统最多使用3GB内存。

所以通过修改redis.conf配置,指定可使用的最大内存

修改maxmemory 3221225472(3G)

image

重启
结果:
启动后直接报错
redis.clients.jedis.exceptions.JedisDataException: OOM command not allowed when used memory > 'maxmemory'.

使用config get * 命令得到redis 的maxmemory

>config get *

image

查看修改的配置是生效的

查看实际使用的内存:

>info memory

image

实际使用还是4G

看来还是key太大了,自动清理机制还是不能解决问题

解决
为了任务能继续跑下去,把key消费完,手动的调低同服务器其他机器的jvm启动参数,程序继续跑了下去

5 手动清理key
在任务跑的差不多时候,手动清理不需要的key值

总结
这次问题最原始的原因是没有做内存限制,导致随着key的不断增加,内存逐渐变多
以后在安装配置64位的redis时,最开始就要设置最大使用内存和清理key的算法,这样不会影响其他服务

相关实践学习
基于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
相关文章
|
21天前
|
存储 消息中间件 NoSQL
Redis数据类型详解:选择合适的数据结构优化你的应用
Redis数据类型详解:选择合适的数据结构优化你的应用
|
26天前
|
缓存 监控 NoSQL
【Redis性能瓶颈揭秘】「调优系列」深入分析热Key的排查策略和解决方案
【Redis性能瓶颈揭秘】「调优系列」深入分析热Key的排查策略和解决方案
66454 1
|
2月前
|
存储 NoSQL 5G
redis优化编码之字符串
Redis数据结构之字符串
40 2
redis优化编码之字符串
|
26天前
|
缓存 运维 NoSQL
【Redis故障排查】「连接失败问题排查和解决」带你总体分析和整理Redis的问题故障实战开发指南及方案
【Redis故障排查】「连接失败问题排查和解决」带你总体分析和整理Redis的问题故障实战开发指南及方案
222 0
|
1月前
|
存储 缓存 NoSQL
探索Redis的多样应用场景:加速和优化现代应用
探索Redis的多样应用场景:加速和优化现代应用
33 2
|
1月前
|
NoSQL 算法 数据管理
【Redis】Redis配置参数详解:优化过期删除机制
【Redis】Redis配置参数详解:优化过期删除机制
77 0
|
1月前
|
存储 NoSQL 前端开发
【SpringBoot】Redis集中管理Session和自定义用户参数解决登录状态及校验问题
【SpringBoot】Redis集中管理Session和自定义用户参数解决登录状态及校验问题
|
2月前
|
存储 监控 NoSQL
Redis 大键问题解析:如何管理和优化巨型数据【redis拓展】
Redis 大键问题解析:如何管理和优化巨型数据【redis拓展】
72 0
|
2月前
|
缓存 NoSQL Java
一次访问Redis延时高问题排查与总结
作者抽丝剥茧的记录了一次访问Redis延时高问题的排查和总结。
414 1
|
3月前
|
缓存 监控 NoSQL
Redis 突然变慢了如何排查并解决?
Redis 突然变慢了如何排查并解决?
62 2