Skip to content

Redis 日志分析

日志配置

日志级别

Redis 支持不同的日志级别来控制日志消息的详细程度:

  • debug: 详细的调试信息
  • verbose: 比 notice 更详细的信息
  • notice: 正常操作消息(默认)
  • warning: 有关潜在问题的警告消息
  • critical: 需要立即关注的严重错误

配置参数

txt
# 设置日志级别
loglevel notice

# 日志文件路径(使用 "stdout" 表示标准输出)
logfile "/var/log/redis/redis-server.log"

# 启用 syslog 日志
syslog-enabled no

# Syslog 设备(如果启用)
syslog-facility local0

# 日志时间戳格式
log-timestamp yes

动态日志配置

bash
# 在运行时更改日志级别
redis-cli config set loglevel warning

# 查看当前日志配置
redis-cli config get loglevel
redis-cli config get logfile

日志格式

基本日志格式

[时间戳] [日志级别] [进程ID] [消息]

日志条目示例

# 服务器启动
23 Mar 10:15:00.123 # Server started, Redis version 7.0.0
23 Mar 10:15:00.124 * Ready to accept connections

# 客户端连接
23 Mar 10:16:30.456 * Accepted 127.0.0.1:54321

# 键空间通知
23 Mar 10:17:45.789 * DB 0: 1000 keys (500 volatile) in 2000 slots HT.

# AOF重写
23 Mar 10:18:15.234 * Starting automatic rewriting of AOF on 100% growth
23 Mar 10:18:16.567 * AOF rewrite done: 1000 bytes in 1.333 seconds

# 错误消息
23 Mar 10:19:20.890 # ERROR: Out of memory reading dataset

常见日志模式

启动和关闭

  • 成功启动: "Server started, Redis version X.Y.Z"
  • 准备接受连接: "Ready to accept connections"
  • 优雅关闭: "Received SIGTERM, scheduling shutdown"
  • 强制关闭: "Received SIGKILL, hard stopping now"

客户端连接

  • 新连接: "Accepted IP:PORT"
  • 连接关闭: "Connection closed by client"
  • 达到最大客户端数: "Error accepting client connection: max number of clients reached"

复制

  • 从节点连接: "Slave IP:PORT asks for synchronization"
  • 开始全量同步: "Full resync from master: REPL_ID"
  • 增量同步: "Partial resync accepted: REPL_OFFSET"
  • 复制延迟: "Slave IP:PORT lagging behind master"

持久化

  • RDB快照开始: "Background saving started by pid X"
  • RDB快照完成: "Background saving terminated with success"
  • RDB快照失败: "Background saving terminated with error"
  • AOF重写开始: "Starting automatic rewriting of AOF"
  • AOF重写完成: "AOF rewrite done: X bytes in Y seconds"
  • AOF错误: "Error writing to AOF file: No space left on device"

内存和性能

  • 内存不足: "ERROR: Out of memory reading dataset"
  • 开始驱逐: "Evicting key KEY_NAME due to memory pressure"
  • 高内存使用: "WARNING: Memory usage is approaching the maxmemory limit"

日志分析技术

手动分析

  1. 按日志级别过滤:

    bash
    grep "#" /var/log/redis/redis-server.log | grep -i error
    grep "*" /var/log/redis/redis-server.log | grep -i warning
  2. 按时间范围过滤:

    bash
    sed -n '/23 Mar 10:15/,/23 Mar 10:20/p' /var/log/redis/redis-server.log
  3. 搜索特定事件:

    bash
    grep -i "replication" /var/log/redis/redis-server.log
    grep -i "persistence" /var/log/redis/redis-server.log

自动化分析

使用日志管理工具

  • ELK Stack: 收集、索引和可视化 Redis 日志
  • Prometheus + Grafana: 监控 Redis 指标和日志
  • Splunk: 企业级日志分析
  • Datadog: 基于云的监控和日志管理

自定义脚本

bash
#!/bin/bash

LOG_FILE="/var/log/redis/redis-server.log"

# 统计错误消息
ERROR_COUNT=$(grep -c "# ERROR" $LOG_FILE)

# 统计警告消息
WARNING_COUNT=$(grep -c "WARNING" $LOG_FILE)

# 统计连接事件
CONNECTION_COUNT=$(grep -c "Accepted" $LOG_FILE)

echo "Redis 日志分析报告"
echo "========================="
echo "错误消息: $ERROR_COUNT"
echo "警告消息: $WARNING_COUNT"
echo "客户端连接: $CONNECTION_COUNT"

使用日志进行故障排除

连接问题

症状: 客户端无法连接到 Redis

日志分析:

  • 检查是否有 "Max clients reached" 错误
  • 查找 "Connection refused" 消息
  • 验证是否存在 "Ready to accept connections" 消息

解决方案:

  • 增加 maxclients 配置
  • 检查网络连接和防火墙规则
  • 确保 Redis 在正确的端口上运行

持久化失败

症状: RDB 或 AOF 持久化失败

日志分析:

  • 查找 "Background saving terminated with error" 消息
  • 检查是否有 "Error writing to AOF file" 消息
  • 在日志中验证磁盘空间可用性

解决方案:

  • 检查磁盘空间和权限
  • 验证持久化配置
  • 如有必要,修复损坏的 AOF 文件

复制问题

症状: 复制不能正常工作

日志分析:

  • 检查是否有 "Slave asks for synchronization" 消息
  • 查找 "Partial resync accepted" 或 "Full resync from master" 消息
  • 监控复制延迟消息

解决方案:

  • 验证主从节点之间的网络连接
  • 如果使用密码认证,检查 masterauth 配置
  • 确保主从节点版本兼容

日志轮转

配置日志轮转

使用 logrotate

txt
# /etc/logrotate.d/redis
/var/log/redis/redis-server.log {
    daily
    missingok
    rotate 7
    compress
    delaycompress
    notifempty
    create 644 redis redis
    postrotate
        /bin/kill -USR1 $(cat /var/run/redis/redis-server.pid 2>/dev/null) 2>/dev/null || true
    endscript
}

使用 Redis 日志轮转

bash
# 在运行时轮转日志文件
redis-cli config set logfile "/var/log/redis/redis-server.new.log"
kill -USR1 $(cat /var/run/redis/redis-server.pid)

最佳实践

日志级别配置

  • 生产环境使用 "notice" 级别
  • 仅在故障排除时使用 "verbose" 或 "debug" 级别
  • 避免在生产环境使用 "debug" 级别,因为会影响性能

日志存储

  • 将日志存储在与数据文件不同的分区上
  • 实施日志轮转以防止磁盘空间问题
  • 考虑将日志发送到集中式日志管理系统

监控和告警

  • 为关键日志消息设置告警
  • 监控日志文件大小和增长率
  • 定期查看日志以寻找模式和趋势

安全性

  • 限制日志文件权限(推荐 644)
  • 避免记录敏感信息
  • 如果日志包含敏感数据,考虑加密日志

常见问题(FAQ)

Q1: 如何在不重启Redis的情况下更改日志级别?

A1: 您可以使用CONFIG SET命令在运行时更改日志级别:

bash
redis-cli config set loglevel warning

此更改将立即生效,无需重启。

Q2: Redis日志默认存储在哪里?

A2: 默认情况下,如果未指定logfile,Redis会将日志输出到标准输出(stdout)。在大多数Linux发行版中,Redis被配置为将日志记录到/var/log/redis/redis-server.log。

Q3: 如何启用syslog日志?

A3: 要启用syslog日志,请在redis.conf中设置以下参数:

txt
syslog-enabled yes
syslog-facility local0

然后重启Redis或使用CONFIG SET在运行时应用更改。

Q4: 如何有效地分析Redis日志?

A4: 有效的日志分析包括:

  • 使用适当的日志级别
  • 实施日志轮转
  • 集中化日志以便于分析
  • 使用日志管理工具进行可视化和告警
  • 定期查看日志以寻找模式和异常

Q5: 最需要监控的日志消息是什么?

A5: 需要监控的关键日志消息包括:

  • 严重错误(内存不足,持久化失败)
  • 警告消息(高内存使用,复制延迟)
  • 连接问题(达到最大客户端数,连接被拒绝)
  • 持久化事件(RDB/AOF失败,成功重写)
  • 复制事件(从节点连接,重新同步操作)

Q6: 如何在不丢失数据的情况下轮转Redis日志?

A6: 要在不丢失数据的情况下轮转Redis日志:

  1. 使用CONFIG SET命令更改logfile路径
  2. 向Redis进程发送USR1信号以重新打开日志文件
  3. 按照最佳实践部分所示实现带有postrotate脚本的logrotate