哨兵配置写失败时先确认磁盘是否真满:用df -h查挂载点空间、df -i查inode是否耗尽;哨兵日志需truncate清空而非rm删除,AOF/RDB文件须按需关闭或清理;inode占满时应kill -TERM释放句柄;CONFIG REWRITE前须备份并校验sentinel.conf完整性。

哨兵配置写失败时,先确认是不是磁盘真满了
Redis 哨兵(redis-sentinel)本身不存数据,但会持续写入日志、AOF(如果启用)、以及最重要的——sentinel.conf 的自动重写(比如故障转移后更新主节点地址)。一旦所在磁盘分区 Use% ≥ 95%,redis-sentinel 就可能因无法追加日志或重写配置而报错:Failed to rewrite config file: No space left on device。
别急着删文件,先验证:用 df -h 看哨兵进程所在挂载点(通常是 /var 或 /data),再用 df -i 确认是不是 inode 耗尽(常见于大量小日志文件)。
关键点:哨兵的配置重写失败 ≠ Redis 主从数据丢失,但会导致后续故障转移信息无法持久化,下次重启可能“失忆”。
清理空间必须绕开哨兵正在写的文件
哨兵默认把日志写进 /var/log/redis/sentinel.log(路径以你的 redis-sentinel 启动参数或 redis.conf 中 logfile 配置为准)。直接 rm -f sentinel.log 可能导致哨兵写入失败甚至崩溃——Linux 下已打开的文件被删,磁盘空间不会立即释放。
安全清理方式如下:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 清空日志内容但保留文件句柄:
truncate -s 0 /var/log/redis/sentinel.log - 删旧日志归档(如果有):
find /var/log/redis -name "sentinel.log.*" -mtime +7 -delete - 检查 AOF 文件(仅当哨兵启用了 AOF):
ls -lh /var/lib/redis/appendonly.aof*;若存在且巨大,可临时关闭 AOF:redis-cli -p 26379 CONFIG SET appendonly no(哨兵端口通常是 26379) - 清理 RDB 快照(哨兵不用 RDB,但共用同一磁盘时可能被 Redis 主从写满):
rm -f /var/lib/redis/*.rdb(确认不是主从实例在用)
重加载哨兵配置前,必须先释放 inodes
很多情况下,df -h 显示还有几 MB 空间,但 df -i 显示 IUse% 是 100%。这是因为哨兵每做一次故障转移,就可能生成一个临时配置片段并快速删除,留下大量未释放的 deleted inode(尤其在 ext4 文件系统上)。
此时即使 truncate 日志也无效。必须找出并终止占用这些 inode 的进程:
- 查被删除但仍被占用的日志文件:
lsof +L1 | grep redis - 看到类似
redis-sen 1234 redis 2w REG 8,2 1073741824 123456 /var/log/redis/sentinel.log (deleted),说明进程 1234 还锁着已删文件 - 安全做法是重启该哨兵进程:
kill -TERM 1234(优雅退出,它会释放句柄并重写配置) - 不要用
kill -9,否则配置重写中断,下次启动可能读到损坏的sentinel.conf
重加载配置不能只靠 CONFIG REWRITE
redis-cli -p 26379 CONFIG REWRITE 确实会重写 sentinel.conf,但它只写入运行时修改过的配置项(比如 sentinel monitor 地址变更),不会补全缺失的原始配置(如 bind、port、logfile)。如果原配置文件被意外截断或覆盖,直接 CONFIG REWRITE 会让哨兵启动失败。
稳妥流程是:
- 先备份当前配置:
cp /etc/redis/sentinel.conf /etc/redis/sentinel.conf.bak.$(date +%s) - 手动检查
/etc/redis/sentinel.conf是否完整(至少含port 26379、sentinel monitor mymaster行) - 执行
redis-cli -p 26379 CONFIG REWRITE,再立刻用diff /etc/redis/sentinel.conf /etc/redis/sentinel.conf.bak.xxx核对是否只改了预期字段 - 最后 reload:
kill -USR2 $(pgrep -f "redis-sentinel.*sentinel.conf")(向哨兵进程发 USR2 信号触发重载,比 restart 更轻量)
真正麻烦的不是磁盘满,而是清理后没检查 inode 和配置完整性——哨兵看似恢复,其实下次 failover 时会静默跳过重写,配置漂移无人察觉。

















