优化 Redis 集群缓存分配:解决节点间分配不均导致内存溢出问题
一、Redis 集群部署简介
在现代应用程序中,缓存被广泛应用以提高性能和减轻后端数据库的压力。本文将探讨面对 Redis 集群缓存分配不均问题时的解决方法。
我们的 Redis 集群部署包括 3 主 3 从,每个节点分配内存 4G(服务器总内存32G),内存淘汰策略相同:volatile-lru。
二、问题描述
在性能测试过程中,通过 pinpoint 监控发现报错:
Error in execution; nested exception is io.lettuce.core.RedisCommandExecutionException: OOM command not allowed when used memory> 'maxmemory'
三、排查、分析问题过程
1. 查看内存使用情况
清空缓存后,再次执行性能测试一段时间,使用 info memory 查看各节点内存使用情况,发现 2、6 节点内存快速上升,其它节点内存使用率很低。
例如,2 节点内存达到 3.81G,6 节点内存达到 3.8G,而其他 4 个节点内存仅为 80M 左右。
[root@iZ2ze3e0bvnd1hf5xbkxn3Z redis01]# ./redis-cli -h 192.168.0.213 -p 6692 -c -a Tiye@54L2!
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.0.213:6692> info memory
# Memory
used_memory:4095914816
used_memory_human:3.81G
used_memory_rss:4473937920
used_memory_rss_human:4.17G
used_memory_peak:4105896552
used_memory_peak_human:3.82G
used_memory_peak_perc:99.76%
used_memory_overhead:5159996
used_memory_startup:1483832
used_memory_dataset:4090754820
used_memory_dataset_perc:99.91%
allocator_allocated:4095978056
allocator_active:4728315904
allocator_resident:4765335552
total_system_memory:33019609088
total_system_memory_human:30.75G
used_memory_lua:30720
used_memory_lua_human:30.00K
used_memory_scripts:0
used_memory_scripts_human:0B
number_of_cached_scripts:0
maxmemory:4096000000
maxmemory_human:3.81G
maxmemory_policy:volatile-lru
allocator_frag_ratio:1.15
allocator_frag_bytes:632337848
allocator_rss_ratio:1.01
allocator_rss_bytes:37019648
rss_overhead_ratio:0.94
rss_overhead_bytes:-291397632
mem_fragmentation_ratio:1.09
mem_fragmentation_bytes:378064128
mem_not_counted_for_evict:0
mem_replication_backlog:1048576
mem_clients_slaves:20512
mem_clients_normal:2603516
mem_aof_buffer:0
mem_allocator:jemalloc-5.1.0
active_defrag_running:0
lazyfree_pending_objects:0
lazyfreed_objects:0
[root@iZ2ze3e0bvnd1hf5xbkxn3Z redis02]# ./redis-cli -h 192.168.0.213 -p 6691 -c -a Tiye@54L2!
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.0.213:6691> info memory
# Memory
used_memory:84125536
used_memory_human:80.23M
used_memory_rss:107753472
used_memory_rss_human:102.76M
used_memory_peak:109050608
used_memory_peak_human:104.00M
used_memory_peak_perc:77.14%
used_memory_overhead:9292232
used_memory_startup:1483832
used_memory_dataset:74833304
used_memory_dataset_perc:90.55%
allocator_allocated:84208120
allocator_active:102572032
allocator_resident:108343296
total_system_memory:33019609088
total_system_memory_human:30.75G
used_memory_lua:30720
used_memory_lua_human:30.00K
used_memory_scripts:0
used_memory_scripts_human:0B
number_of_cached_scripts:0
maxmemory:4096000000
maxmemory_human:3.81G
maxmemory_policy:volatile-lru
allocator_frag_ratio:1.22
allocator_frag_bytes:18363912
allocator_rss_ratio:1.06
allocator_rss_bytes:5771264
rss_overhead_ratio:0.99
rss_overhead_bytes:-589824
mem_fragmentation_ratio:1.28
mem_fragmentation_bytes:23669520
mem_not_counted_for_evict:0
mem_replication_backlog:1048576
mem_clients_slaves:20512
mem_clients_normal:2603360
mem_aof_buffer:0
mem_allocator:jemalloc-5.1.0
active_defrag_running:0
lazyfree_pending_objects:0
lazyfreed_objects:0
2. 分析主从关系
cluster nodes 命令获取 Redis 集群中所有节点的信息,并判断各节点主从关系。[root@iZ2ze3e0bvnd1hf5xbkxn3Z redis06]# ./redis-cli -h 192.168.0.213 -p 6696 -c -a Tiye@54L2!
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.0.213:6696> cluster nodes
e73a5ec3e26ed23e9b4bf56811527c8820a7bd79 192.168.0.213:6696@16696 myself,slave e2a678a004bc99e76180a16a6a41e2cad1c96052 0 1691992895000 2 connected
25317f0f8f7b2eebdbdc0914c659ab96ed3dab18 192.168.0.213:6693@16693 master - 0 1691992897074 3 connected 10923-16383
27aba75f54cccbb42125edb20f2f9d7c2f777d6c 192.168.0.213:6695@16695 slave 5e08015f75cdb05b1c7ed78dead1d85cdb0e838f 0 1691992895070 1 connected
5e08015f75cdb05b1c7ed78dead1d85cdb0e838f 192.168.0.213:6691@16691 master - 0 1691992894068 1 connected 0-5460
053916b96426f790244d984cad3f69f9151e4ece 192.168.0.213:6694@16694 slave 25317f0f8f7b2eebdbdc0914c659ab96ed3dab18 0 1691992896072 3 connected
e2a678a004bc99e76180a16a6a41e2cad1c96052 192.168.0.213:6692@16692 master - 0 1691992894000 2 connected 5461-10922
根据节点信息中的master字段判断该节点是主节点还是从节点。如果节点的master字段为空,则表示它是主节点;如果master字段不为空,则表示它是从节点,并且该字段的值是对应的主节点ID。
e2a678a004bc99e76180a16a6a41e2cad1c96052 节点是主节点,e73a5ec3e26ed23e9b4bf56811527c8820a7bd79 节点是从节点,并且它的主节点是 e2a678a004bc99e76180a16a6a41e2cad1c96052
综上判断:redis集群6个节点,其中2节点的从节点是6节点。
3. 分析哈希槽数量分配
在 Redis 集群中的任意一个节点上执行 cluster slots 命令,分析哈希槽数量分配是否均匀
192.168.0.213:6692> cluster slots
1) 1) (integer) 0
2) (integer) 5460
3) 1) "192.168.0.213"
2) (integer) 6691
3) "5e08015f75cdb05b1c7ed78dead1d85cdb0e838f"
4) 1) "192.168.0.213"
2) (integer) 6695
3) "27aba75f54cccbb42125edb20f2f9d7c2f777d6c"
2) 1) (integer) 5461
2) (integer) 10922
3) 1) "192.168.0.213"
2) (integer) 6692
3) "e2a678a004bc99e76180a16a6a41e2cad1c96052"
4) 1) "192.168.0.213"
2) (integer) 6696
3) "e73a5ec3e26ed23e9b4bf56811527c8820a7bd79"
3) 1) (integer) 10923
2) (integer) 16383
3) 1) "192.168.0.213"
2) (integer) 6693
3) "25317f0f8f7b2eebdbdc0914c659ab96ed3dab18"
4) 1) "192.168.0.213"
2) (integer) 6694
3) "053916b96426f790244d984cad3f69f9151e4ece"
根据提供的哈希槽信息,我们可以计算出以下三个哈希槽的数量:
- 第一个哈希槽范围:0到5460,共计5461个槽位。
- 第二个哈希槽范围:5461到10922,共计5462个槽位。
- 第三个哈希槽范围:10923到16383,共计5461个槽位。
综上判断:这三个哈希槽的数量分别是5461、5462和5461。即,哈希槽数量分配均匀。
四、尝试解决方案
方法一:使用 Predixy 代理
跟产品开发人员沟通,没有做predixy适配,但可以尝试配置。最后发现产品启动服务报错,放弃该方案。尝试过程记录如下:
1. 下载安装包
wget https://github.com/joyieldInc/predixy/releases/download/1.0.5/predixy-1.0.5-bin-amd64-linux.tar.gz
2. 解压&修改配置文件
tar zxvf predixy-1.0.5-bin-amd64-linux.tar.gz
cd predixy-1.0.5
① 编辑conf/predixy.conf文件
Include cluster.conf #Include cluster.conf解开注释
# Include sentinel.conf
# Include try.conf #注释掉Include try.conf
## Worker threads
WorkerThreads 3 #从1改为3,表示开启的进程数
② 编辑conf/cluster.conf文件
lusterServerPool {
MasterReadPriority 0 #设置为0代表开启读写分离
Password Tiye@54L2! #redis集群密码
StaticSlaveReadPriority 50
DynamicSlaveReadPriority 50
RefreshInterval 1
ServerTimeout 1
ServerFailureLimit 10
ServerRetryTimeout 1
KeepAlive 120
Servers {
+ 192.168.0.213:6691 #redis集群节点
+ 192.168.0.213:6692
+ 192.168.0.213:6693
+ 192.168.0.213:6694
+ 192.168.0.213:6695
+ 192.168.0.213:6696
}
}
配置文件解析文档:https://github.com/joyieldInc/predixy/blob/master/doc/config_CN.md
3. 创建脚本文件
① 创建启动和停止脚本,放到predixy-1.0.5目录下
mkdir -p /opt/predixy-1.0.5/logs/
cd /opt/predixy-1.0.5/bin
② 创建启动脚本up.sh
#!/bin/bash
path=`pwd`
nohup $path/bin/predixy conf/predixy.conf > $path/logs/predixy.log 2>&1 &
③ 查看日志
tail -f logs/predixy.log
④ 创建停止脚本down.sh
#!/bin/bash
path=`pwd`
pid=`ps -ef | grep $path/bin/predixy | grep -v grep | awk '{print $2}'`
kill -9 $pid
4. 测试predixy代理
./redis-cli -p 7617
127.0.0.1:7617> mset b1 b2
OK
127.0.0.1:7617> get b1
"b2"
5. 启动应用验证predixy代理
将应用配置文件中的集群地址修改为predixy地址,应用服务启动报错:
...Autowired annotation is not supported on static fields...
方法二:缩减为 4 个节点
尝试缩减为 4 个节点,但创建集群时提示至少需要 3 个主节点,因此该方案也不可行。
*** ERROR: Invalid configuration for cluster creation.
*** Redis Cluster requires at least 3 master nodes.
*** This is not possible with 4 nodes and 1 replicas per node.
*** At least 6 nodes are required
方法三:修改集群节点内存
最终解决方案是修改集群节点内存:1、3、4、5 节点分配内存 3G,2、6 节点分配内存 8G。
五、结论
面对 Redis 集群缓存分配不均的问题,我们可以通过逐步的优化方法来解决。首先,了解节点信息、主从关系和缓存占用情况,然后分析哈希槽分布情况,尝试不同的优化方案,最后通过调整内存分配来解决问题。
优化 Redis 集群缓存分配:解决节点间分配不均导致内存溢出问题的更多相关文章
- C#使用Redis集群缓存
C#使用Redis集群缓存 本文介绍系统缓存组件,采用NOSQL之Redis作为系统缓存层. 一.背景 系统考虑到高并发的使用场景.对于并发提交场景,通过上一章节介绍的RabbitMQ组件解决.对于系 ...
- Redis 集群缓存测试要点--关于 线上 token 失效 BUG 的总结
在测试账户系统过程中遇到了线上大面积用户登录态失效的严重问题,事后对于其原因及测试盲点做了一些总结记录以便以后查阅,总结分为以下7点,其中原理性的解释有些摘自网络. 1.账户系统token失效问题复盘 ...
- Net分布式系统之五:C#使用Redis集群缓存
本文介绍系统缓存组件,采用NOSQL之Redis作为系统缓存层. 一.背景 系统考虑到高并发的使用场景.对于并发提交场景,通过上一章节介绍的RabbitMQ组件解决.对于系统高并发查询,为了提供性能减 ...
- redis集群(单机6节点实现)
Redis集群搭建与简单使用 1.介绍安装环境与版本: 1)Redis使用的是Redis-3.2.8版本. 2)用一台虚拟机模拟6个节点,三个master节点,三个slave节点.虚拟机使用CentO ...
- POI读写大数据量excel,解决超过几万行而导致内存溢出的问题
1. Excel2003与Excel2007 两个版本的最大行数和列数不同,2003版最大行数是65536行,最大列数是256列,2007版及以后的版本最大行数是1048576行,最大列数是16384 ...
- tomcat+nginx+redis集群搭建并解决session共享问题。
1 集群搭建 https://www.cnblogs.com/yjq520/p/7685941.html 2 session共享 https://blog.csdn.net/tuesdayma/art ...
- 使用docker 创建6节点redis 集群 RedisCluster redis集群
1.RedisCluster 特点(3主节点redis 集群 及6节点集群) 1.无中心节点,客户端与redis 节点直连,不需要中间代理,(有选举机制 master个数需要奇数个) 2.数据可以被 ...
- Redis 集群实现
Nosql,作为程序员在当下不了解点儿,还真不行,出去聊起来别人就会说你土.那么就聊聊其中一个比较火的redis.redis单机版没得说,但是一直没有集群版,有也是山寨的.前段时间对redis的实现进 ...
- Redis集群进阶之路
Redis集群规范 本文档基于Redis 3.X或更高版本,讲解Redis集群算法以及设计原理.此官方文档长期更新且随着Redis新版本特性的变化变动,详细请留意官网. 官网地址:https://re ...
- Redis集群搭建采坑总结
背景 先澄清一下,整个过程问题都不是我解决的,我在里面就是起了个打酱油的角色.因为实际上我负责这个项目,整个过程也比较清楚.之前也跟具体负责的同事说过,等过段时间带他做做项目复盘.结果一直忙,之前做的 ...
随机推荐
- 2021-02-23:给定一个正数n,求n的裂开方法数。规定:后面的数不能比前面的数小 。比如4的裂开方法有: 1+1+1+1、1+1+2、1+3、2+2、4,5种,所以返回5。
2021-02-23:给定一个正数n,求n的裂开方法数.规定:后面的数不能比前面的数小 .比如4的裂开方法有: 1+1+1+1.1+1+2.1+3.2+2.4,5种,所以返回5. 福哥答案2021-0 ...
- Vue Element-ui 之 el-table自动滚动
首先是 div结构布局 <div id="scrollId">//对el-table盒子设置 id 属性 <div style="height: 100 ...
- AcWing 278. 数字组合
给定 N 个正整数 A1,A2,-,AN,从中选出若干个数,使它们的和为 M,求有多少种选择方案. 输入格式 第一行包含两个整数 N 和 M. 第二行包含 N 个整数,表示 A1,A2,-,AN. 输 ...
- 玩转服务器之数据传输篇:如何快速搭建FTP文件共享服务器
FTP 文件共享服务器介绍 FTP服务(File Transfer Protocol,FTP)是最早应用于主机之间数据传输的基本服务之一,是目前使用最广泛的文件传送协议.FTP文件共享服务器在日常办公 ...
- RStuido Server 选择不同的 R 版本(conda 中的不同 R 版本)
自从上一次服务器重装系统之后,总感觉缺少了一些东西,安装R包很多依赖库报错,也可以解决,但总是存在,烦. 一天,一个同事问我说ggpubr包安装不成功,我就自己试了一下,真的是--安装不成功. 当你到 ...
- Basic Pentesting
来自tryhackme的 Basic Pentesting 开靶场IP:10.10.227.255 # nmap 端口扫描 PORT STATE SERVICE VERSION 22/tcp open ...
- x86 机器指令编码规则
x86 机器指令编码依次由一下部分组成: 指令前缀(prefix,非必需) 操作码(opcode,必需) 寻址方式 R/M(ModR/M,非必需) 比例因子-变址-基址(SIB,非必需) 地址偏移量( ...
- 通过模仿学会Python爬虫(一):零基础上手
好家伙,爬虫来了 爬虫,这玩意,不会怎么办, 诶,先抄一份作业回来 1.别人的爬虫 Python爬虫史上超详细讲解(零基础入门,老年人都看的懂)_ChenBinBini的博客-CSDN博客 # -* ...
- easyexce报错BeanMap$Generator
class net.sf.cglib.core.DebuggingClassWriter overrides final method visit 这两个报错都可以在一起解决,因为这是由于Jar包冲突 ...
- 在Linux环境下通过命令行执行JMeter脚本后查看响应结果的配置
在Linux环境中进行性能测试时,我们可能会遇到一定程度的报错.如果无法打开JMeter的GUI界面,但又需要查看响应结果,可以按照以下步骤进行配置: 1. 打开JMeter的安装目录,在`bin/` ...