一次redis内存泄露故障分析
文章目录
- 一、内存使用情况分析
- 1.1 使用redis-cli --bigkeys命令分析大键
- 1.2 扫描结果分析
- 键空间统计
- 各类型键分布
- 1.3 关键发现
- 二、Stream键详细分析
- 2.1 精确计算Stream键内存占用
- 2.2 内存占用计算说明
- 三、解决方案与配置优化
- 3.1 临时解决方案
- 检查Stream键内容
- 清理过期数据
- 3.2 长期解决方案:配置内存限制和淘汰策略
本文档记录了Redis内存使用异常问题的完整排查过程和解决方案。通过实际案例展示了如何识别内存占用过高的原因,并提供了相应的配置优化方法。
Redis实例出现内存使用异常,总内存达到14.63G,需要排查具体的内存占用来源并制定优化策略。
一、内存使用情况分析
1.1 使用redis-cli --bigkeys命令分析大键
首先使用redis-cli --bigkeys命令扫描Redis中的所有键,找出占用空间最大的键:
redis-cli --bigkeys
命令输出分析:
# Scanning the entire keyspace to find biggest keys as well as
# average sizes per key type. You can use -i 0.1 to sleep 0.1 sec
# per 100 SCAN commands (not usually needed).[00.00%] Biggest string found so far '"security:session:437a3e858bbc4c7c9c901758935ef285"' with 1222 bytes
[00.00%] Biggest string found so far '"security:session:86f51e274dbb449197dc6e822a18ada4"' with 2926 bytes
[00.20%] Biggest string found so far '"security:session:e410459a661047bebaafe4e505df5da6"' with 2946 bytes
[00.38%] Biggest string found so far '"security:session:ba199388578e4381aab5ab641086975a"' with 2977 bytes
[00.74%] Biggest string found so far '"security:session:38ca729df2fc4c0d92a392adfa9cc45e"' with 3055 bytes
[01.77%] Biggest string found so far '"security:kick-out:1967618337785159681:common"' with 3081 bytes
[02.41%] Biggest string found so far '"security:kick-out:1966114719120936962:common"' with 9451 bytes
[08.43%] Biggest string found so far '"security:session:d400f11c3ddd43c4bbc5a09261e12f2b"' with 19331 bytes
[47.28%] Biggest string found so far '"security:session:eeb1b0fba2e64fa99818e648b1e785c1"' with 35489 bytes
[48.54%] Biggest stream found so far '"myLogStream"' with 5721626 entries
[50.91%] Biggest string found so far '"security:kick-out:1967592428340420610:common"' with 37101 bytes
[75.47%] Biggest hash found so far '"application"' with 6 fields-------- summary -------Sampled 34701 keys in the keyspace!
Total key length in bytes is 1688599 (avg len 48.66)Biggest hash found '"application"' has 6 fields
Biggest string found '"security:kick-out:1967592428340420610:common"' has 37101 bytes
Biggest stream found '"myLogStream"' has 5721626 entries0 lists with 0 items (00.00% of keys, avg size 0.00)
1 hashs with 6 fields (00.00% of keys, avg size 6.00)
34699 strings with 45262599 bytes (99.99% of keys, avg size 1304.44)
1 streams with 5721626 entries (00.00% of keys, avg size 5721626.00)
0 sets with 0 members (00.00% of keys, avg size 0.00)
0 zsets with 0 members (00.00% of keys, avg size 0.00)
1.2 扫描结果分析
键空间统计
- 总键数: 34,701个键
- 键名总长度: 1,688,599字节(约1.61MB)
- 平均键名长度: 48.66字符
各类型键分布
- 字符串键: 34,699个(99.99%),总大小45.26MB
- 哈希键: 1个(0.00%),6个字段
- Stream键: 1个(0.00%),5,721,626个条目
- 列表、集合、有序集合: 0个
1.3 关键发现
通过分析发现:
- 虽然字符串键数量占绝对优势(99.99%),但总内存占用仅为45MB
- Stream键
myLogStream虽然只有1个,但包含572万条数据,是内存占用的主要来源 - 结合总内存14.63G的情况,可以推断
myLogStream占用了绝大部分内存
二、Stream键详细分析
2.1 精确计算Stream键内存占用
由于--bigkeys命令只显示条目数量而不显示具体内存占用,需要使用MEMORY USAGE命令精确计算:
# 连接Redis
redis-cli# 查看myLogStream键的实际内存占用
MEMORY USAGE "myLogStream"
2.2 内存占用计算说明
--bigkeys通过统计条目数快速判断键的大小,不计算具体内存MEMORY USAGE会深入计算键的总内存开销,包括条目内容、内部数据结构、元信息等- 对于包含572万条数据的Stream键,实际内存占用很可能接近14G
三、解决方案与配置优化
3.1 临时解决方案
检查Stream键内容
# 查看Stream键的基本信息
XLEN "myLogStream"# 查看部分条目内容
XRANGE "myLogStream" - + COUNT 10
清理过期数据
# 如果数据可以清理,使用XTRIM命令
# 保留最近1000条数据
XTRIM "myLogStream" MAXLEN 1000
3.2 长期解决方案:配置内存限制和淘汰策略
通过配置文件(推荐,永久生效)
- 编辑Redis配置文件:
vim /etc/redis/redis.conf
- 设置最大内存限制:
maxmemory 15G
- 设置淘汰策略:
maxmemory-policy allkeys-lru
- 重启Redis服务:
systemctl restart redis
