32人参与 • 2025-11-26 • Redis
vm.swappinessvm.swappiness 降低,以减少对 swap 的依赖。默认值是较高(通常 60),可以调成 10 或 5,根据你的工作负载决定。较低值能使系统更倾向于使用内存,而不是 swap。vm.swappiness=10
永久设置可以写入 /etc/sysctl.d/99-sysctl.conf 或者 /etc/sysctl.conf。
vm.dirty_ratio 和 vm.dirty_background_ratiovm.dirty_background_ratio = 5 vm.dirty_ratio = 20
这两个值需要结合实际 i/o 压力测试。
关闭或限制 swap(视具体情况)
swapoff +从 fstab 移除 swap)。fs.file-maxfs.file-max = 2000000
这个值要根据并发连接数和负载调整。
/etc/security/limits.d/ 下的配置(例如 99-nofile.conf),对于服务账号 (如应用进程) 提高 nofile 限制。net.core.somaxconnnet.core.somaxconn = 1024
net.ipv4.tcp_fin_timeoutnet.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_tw_reusenet.ipv4.tcp_tw_reuse = 1
rmem 和 wmem:net.core.rmem_default = 262144 net.core.wmem_default = 262144 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_wmem = 4096 65536 16777216
performance(高性能) 或 schedutil / ondemand。如果负载是较为稳定且追求响应性,可以设置为 performance。# 安装 cpupower(如果还没装) dnf install kernel-tools # 设置 governor cpupower frequency-set --governor performance
noop 或 mq-deadline 等轻量调度器或者直接使用 none(如果硬件和内核版本支持)。其实在现代内核中,nvme 的默认调度器就非常高效。echo none > /sys/block/nvme0n1/queue/scheduler
(替换为实际使用的设备名)
dirty_* 参数(见上文)以控制内核何时将缓存写回磁盘。noatime, nodiratime)。systemd-analyze blame 查看启动和运行时开销,禁用不必要的服务。rsyslog 或 journal),考虑减少日志写频率或级别。长期高频日志会对 ssd 写入造成压力。一定要先备份自己系统当前的参数在修改,万一有问题方便回退。
# /etc/sysctl.d/99-performance.conf # === 内存管理 === vm.swappiness = 10 vm.dirty_ratio = 20 vm.dirty_background_ratio = 5 # 可能还加 dirty_expire / writeback,根据具体测试调优 # vm.dirty_expire_centisecs = 500 # vm.dirty_writeback_centisecs = 100 # 可选:如果你知道内存不是特别紧张,可设置 overcommit # vm.overcommit_memory = 1 # === 文件句柄限制 === fs.file-max = 2000000 # === 网络 / tcp 参数 === net.core.somaxconn = 8192 # 监听 backlog net.core.netdev_max_backlog = 50000 # 接收 / 发送缓冲 net.core.rmem_default = 262144 net.core.wmem_default = 262144 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_wmem = 4096 65536 16777216 # time_wait 和连接重用 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_tw_reuse = 1 # keepalive net.ipv4.tcp_keepalive_time = 600 net.ipv4.tcp_keepalive_intvl = 30 net.ipv4.tcp_keepalive_probes = 3 # 网络安全相关 kernel.sysrq = 0 net.ipv4.ip_forward = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.conf.all.accept_source_route =0 net.ipv4.conf.default.accept_source_route = 0 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.secure_redirects = 0 net.ipv4.conf.default.secure_redirects = 0 net.ipv4.icmp_echo_ignore_broadcasts = 1 net.ipv4.icmp_ignore_bogus_error_responses = 1 net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 net.ipv4.tcp_syncookies = 1 kernel.dmesg_restrict = 1 net.ipv6.conf.all.accept_redirects = 0 net.ipv6.conf.default.accept_redirects = 0 kernel.threads-max = 655350 # === 其他网络 /系统选项 === # 可以根据需要打开更多,但这里是基础
应用这个配置
sysctl --system
vm.swappiness=10 是为了让系统尽量少用 swap。maxmemory 设置 (12 gb) 是示例,根据 redis 实例所在机器上同时运行的其他进程 +操作系统需求来决定。如果 redis 是主要服务,可以设置得更高,但建议不要占用所有内存。allkeys-lru 淘汰策略是业界常用策略,适合缓存 +热点数据混合类型场景。lazyfree-lazy-eviction 等异步释放设置,可以减少 redis 主线程因内存回收 (删除大对象) 的阻塞。auto-aof-rewrite-percentage 和 min-size) 设置,能平衡磁盘写入和文件大小。hz 参数 (心跳 /后台任务频率) 控制周期性后台任务 (如过期检查) 的频率。调高可以更快响应但会增加 cpu 开销。swappiness 或非常高的 dirty_ratio),可能导致系统内存压力过大或频繁写盘。下面是建议写入 redis.conf
| 配置 | 建议值 / 设置 | 说明与理由 | |
|---|---|---|---|
maxmemory | 大约 48 gb(64 gb 节点的 ~75%) | 留出一部分给操作系统 + fork 过程中的开销。 | |
maxmemory-policy | allkeys-lru | 选择 lru 淘汰策略,以便在满内存时清除最少使用的 key。 | |
maxmemory-samples | 5 | 控制 lru 近似采样的样本数,默认是 5,通常够用。 | |
lazyfree-lazy-eviction | yes | 使用后台异步释放内存(异步删除),减少主线程停顿。 | |
lazyfree-lazy-expire | yes | 异步过期 key 的内存释放。 | |
appendonly | yes | 启用 aof。保证持久性。 | |
appendfsync | everysec | 每秒 fsync,一般来说在可靠性与性能之间是一个比较好的折中。 | |
auto-aof-rewrite-percentage | 100 | 当 aof 大小增长到 100%(翻倍)时触发重写。这个值可根据实际 aof 增长速度调整。 | |
auto-aof-rewrite-min-size | 64mb | 最小 aof 重写大小限制(避免过小文件频繁重写) | |
aof-load-truncated | yes | 启动时如果 aof 被截断,可以继续加载(更健壮)。 ([codingnote.cc][3]) | |
lua-time-limit | 5000(ms) | 限制 lua 脚本最大执行时间,防止长脚本阻塞。 | |
| 集群相关 | |||
cluster-enabled | yes | 开启集群。 | |
cluster-config-file | nodes.conf(具体路径根据部署) | 保存集群节点配置。 | |
cluster-node-timeout | 15000(ms) | 节点互连超时阈值,较常用值。 | |
cluster-replica-validity-factor | 10(默认或视情况设) | 决定从节点是否有资格做 failover(与 node-timeout 和 ping 周期有关)。 | |
cluster-migration-barrier | 1 | 控制当主节点只有一个从节点时,从节点是否可以迁移到其他主上。 | |
cluster-require-full-coverage | no | 即使某些 slot 没覆盖,也允许读写,提升容错性。 | |
| 网络 & 性能 | |||
timeout | 3000(秒或 ms,根据版本) | 客户端连接超时设置(视具体版本配置) | |
tcp-keepalive | 60 | 保持空闲连接,避免连接过早关闭。 | |
| 慢日志 | slowlog-log-slower-than | 比如 10000(微秒或微秒级,视版本) | 记录慢命令,有助于调优。 |
slowlog-max-len | 128 | 保存慢日志条数上限。 | |
| 数据结构内存优化 | |||
hash-max-ziplist-entries / hash-max-ziplist-value | 512 / 64(示例) | 对小 hash 使用 ziplist 编码节省内存。类似配置常见于实践。 ([cndba][4]) | |
list-max-ziplist-entries / list-max-ziplist-value | 512 / 64 | 同上,对 list 优化。 | |
| 客户端 & 连接 | |||
| 使用连接池 | 是 | 建议客户端使用连接池(如 jedispool、lettuce 等),避免频繁建立连接。 | |
| 使用 pipeline(批量命令) | 是 | 减少往返开销。 | |
| 命令建模 | |||
避免 keys * | 使用 scan | keys 是阻塞命令,在大数据量下严重影响性能。 | |
| 优化 lua 脚本 | 简短、快速 | 防止脚本阻塞主线程,特别是在集群中。 |
######################################## # redis 性能 +集群 配置示例 # 这个配置文件只做参考 不能直接拿来用 redis 是不允许再参数后买你添加注释的直接使用会报错 ######################################## # 内存管理 maxmemory 12gb # 假设节点内存 16g,为 redis 留约 12g maxmemory-policy allkeys-lru # 使用 lru 淘汰所有键(适合缓存 + 数据混合场景) maxmemory-samples 5 # 延迟释放 lazyfree-lazy-eviction yes lazyfree-lazy-expire yes lazyfree-lazy-server-del yes # 持久化 (rdb + aof) appendonly yes appendfilename "appendonly.aof" appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated yes # rdb 快照 (可根据需要) save 900 1 save 300 10 save 60 10000 # 集群配置 (如果是 redis cluster) cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 15000 cluster-replica-validity-factor 10 cluster-migration-barrier 1 cluster-require-full-coverage no # 性能 /调度相关 hz 10 dynamic-hz yes # lua 脚本执行限制 lua-time-limit 5000 # 毫秒 # 慢日志 (监控慢命令) slowlog-log-slower-than 10000 # 微秒 (10 ms) — 根据业务调整 slowlog-max-len 128 # 内存碎片 / 编码优化 hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-entries 512 list-max-ziplist-value 64 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 # 安全性 (可选,根据场景启用) # requirepass yourpassword # rename-command flushall "" # 其他 (可选,根据需求) notify-keyspace-events ""
used_memory_rss vs used_memory。noeviction),可能写入失败(oom),或策略太激进导致重要数据被淘汰。moved 重定向,影响性能。优先备份主节点
使用 rdb (快照) + aof 组合
定期触发 bgrewriteaof 与 bgsave
备份文件长期保留与版本管理
校验与恢复演练
redis-check-aof / redis-check-rdb 工具校验备份文件健康性获取所有主节点
/usr/local/redis/bin/redis-cli -h 192.168.1.11 -p 6379 -a ugwfssnuzgs4e62e cluster nodes|grep master | grep -v "fail" | awk '{print $2}' | cut -d@ -f1这条命令会列出所有 master 节点的
注意:此脚本需要现在测试环境中测试没问题 再拿到生产环境中使用。
#!/bin/bash
redis_ip="192.168.1.11" # 任意一个集群节点(用于获取节点列表)
redis_port="6379"
redis_pwd="ugwfssnuzgs4e62e"
backup_dir="/root/backup/"
timeout=300
mkdir -p "$backup_dir" || { echo "error: 无法创建备份目录 $backup_dir"; exit 1; }
# 获取所有 master 节点
nodes=$(redis-cli -c -h "$redis_ip" -p "$redis_port" -a "$redis_pwd" cluster nodes | \
grep master | grep -v fail | awk '{print $2}' | cut -d@ -f1)
for node in $nodes; do
ip=$(echo "$node" | cut -d: -f1)
port=$(echo "$node" | cut -d: -f2)
echo "=== 开始备份:redis 节点 $ip:$port ==="
# 触发 bgsave (rdb)
redis-cli -h "$ip" -p "$port" -a "$redis_pwd" bgsave
if [ $? -ne 0 ]; then
echo "warning: bgsave 在 $ip:$port 执行失败"
fi
# 等待 bgsave 完成
start_time=$(date +%s)
while true; do
inprog=$(redis-cli -h "$ip" -p "$port" -a "$redis_pwd" info persistence | \
grep rdb_bgsave_in_progress | cut -d: -f2 | tr -d '\r')
if [ "$inprog" = "0" ]; then
echo "bgsave 完成:$ip:$port"
break
fi
now=$(date +%s)
elapsed=$(( now - start_time ))
if [ $elapsed -gt $timeout ]; then
echo "error: bgsave 超时 ($elapsed 秒) 在 $ip:$port" >&2
break
fi
echo "等待 bgsave 完成 ($elapsed 秒) ..."
sleep 5
done
# 获取 rdb 文件路径
dir=$(redis-cli -h "$ip" -p "$port" -a "$redis_pwd" config get dir | awk 'nr==2')
dbfile=$(redis-cli -h "$ip" -p "$port" -a "$redis_pwd" config get dbfilename | awk 'nr==2')
src_rdb="${dir}/${dbfile}"
if [ ! -f "$src_rdb" ]; then
echo "error: 未找到 rdb 文件: $src_rdb" >&2
else
dst_rdb="${backup_dir}/${ip}_${port}_$(date +%y%m%d_%h%m%s).rdb"
cp "$src_rdb" "$dst_rdb" && echo "rdb 备份保存到 $dst_rdb"
fi
aof_enabled=$(redis-cli -h "$ip" -p "$port" -a "$redis_pwd" config get appendonly | awk 'nr==2')
if [ "$aof_enabled" = "yes" ]; then
aofdir=$(redis-cli -h "$ip" -p "$port" -a "$redis_pwd" config get appenddirname | awk 'nr==2')
aofname=$(redis-cli -h "$ip" -p "$port" -a "$redis_pwd" config get appendfilename | awk 'nr==2')
if [ -z "$aofdir" ]; then
src_aof="${dir}/${aofname}"
if [ -f "$src_aof" ]; then
dst_aof="${backup_dir}/${ip}_${port}_$(date +%y%m%d_%h%m%s).aof"
cp "$src_aof" "$dst_aof" && echo "aof 备份保存到 $dst_aof"
else
echo "error: aof 文件未找到: $src_aof" >&2
fi
else
# multi-part aof 模式 (redis 7+)
aof_dir_full="${dir}/${aofdir}"
if [ -d "$aof_dir_full" ]; then
dst_mp_dir="${backup_dir}/${ip}_${port}_aof_$(date +%y%m%d_%h%m%s)"
mkdir -p "$dst_mp_dir"
cp "${aof_dir_full}"/* "$dst_mp_dir"/ && echo "mp-aof 备份到 $dst_mp_dir"
else
echo "error: aof 目录不存在: $aof_dir_full" >&2
fi
fi
else
echo "aof 未启用在 $ip:$port,跳过 aof 备份"
fi
done
echo "=== 所有节点备份完成 ==="# 或者停止对应的 redis 服务 / systemd 单元 redis-cli -h <ip> -p <port> shutdown
cp /backup/redis/cluster/<ip>_<port>_yyyymmdd_hhmmss.rdb /var/lib/redis/$port/dump.rdb # 如果是 aof cp /backup/redis/cluster/<ip>_<port>_yyyymmdd_hhmmss.aof /var/lib/redis/$port/appendonly.aof
chown redis:redis /var/lib/redis/$port/dump.rdb chown redis:redis /var/lib/redis/$port/appendonly.aof
appendonly yes,那么 redis 启动时会优先用 aof 恢复具体命令 (如果是 systemd):
systemctl start redis
redis-cli -h <ip> -p <port> bgrewriteaof
恢复一个节点之后,如果这个节点之前属于集群 (有 slot),你需要让它重新加入 (如果它是孤立恢复):
cluster meetredis-cli -h <恢复节点 ip> -p <恢复节点 端口> cluster meet <任意健康节点 ip> <端口>
redis-cli -h <恢复节点 ip> -p <恢复端口> cluster nodes
看它是否成为了集群的一员 (节点状态应该是 slave 或 master 等)。
redis-cli --cluster reshard 进行 slot 重分布 (reshard):将部分 slot 从其他节点迁移给该节点。redis-cli --cluster reshard <一个集群节点 ip:端口> --from <其他节点列表,用逗号分隔> --to <恢复节点 id> --slots <slot 数量> --yes
appendfsync 策略)。到此这篇关于redis 集群模式优化和备份的文章就介绍到这了,更多相关redis 集群模式内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论