Redis部署详细步骤

发布于:2025-03-27 ⋅ 阅读:(26) ⋅ 点赞:(0)

1. 单机模式部署

单机模式指在一台服务器上运行一个 Redis 实例,常用于开发测试或小规模部署。

1.1、安装 Redis (YUM 安装与源码安装)

1.1.1、YUM 安装: CentOS 默认仓库或 EPEL 源提供了 Redis 包。可以通过 yum 快速安装 Redis:

sudo yum install epel-release -y   # 安装 EPEL 源
sudo yum install redis -y         # 安装 Redis

安装完成后,Redis 的可执行文件和默认配置会就绪。使用 systemctl 启动 Redis 服务

sudo systemctl start redis.service    # 启动 Redis
sudo systemctl enable redis          # 设置开机自启
sudo systemctl status redis.service  # 查看运行状态

以上命令启动 Redis 并将其设为开机自启 。安装完成后可通过 redis-cli ping 测试,正常应返回 PONG 。

1.1.2、源码安装: 如果需要特定版本或自定义安装路径,可从源码编译。步骤简要如下:

  1. 获取源码:从官方网站下载稳定版源码包,或使用 wget 获取,例如:

    wget http://download.redis.io/releases/redis-6.2.6.tar.gz
    tar xzf redis-6.2.6.tar.gz && cd redis-6.2.6
    
  2. 编译安装:确保已安装开发工具,如 GCC:

    yum install -y gcc tcl   # 安装编译所需环境
    make 
    make test
    make install PREFIX=/usr/local/redis
    
    ##如果make编译报错,使用如下命令来编译
    make MALLOC=libc
    

    编译完成后,可使用 make install 将可执行文件安装到指定前缀路径(如 /usr/local/redis/bin)。

  3. 配置文件:将源码目录下的 redis.conf 拷贝到合适位置(如 /etc/redis.conf 或安装目录下),备用。

  4. 启动服务:使用自带脚本或手动启动:

    /usr/local/redis/bin/redis-server /etc/redis.conf
    

    (可以通过将上述命令加入 systemd 服务或编写 init 脚本来实现系统管理和开机自启)。

1.2、基本配置(绑定地址、端口、日志、密码等)

Redis 安装后,其配置文件(默认 /etc/redis.conf)包含丰富的注释。常见基本配置如下:

  • 绑定 IP: 为了安全,Redis 默认仅监听本地回环接口。配置文件中的 bind 指令控制允许访问的网卡地址。通常建议绑定 127.0.0.1 本地地址,防止外部直接访问 。如果需要远程访问,可改为绑定服务器的内网IP,并避免绑定 0.0.0.0 公网地址。例如:

    bind 127.0.0.1        # 仅允许本机访问
    # bind 192.168.0.10   # 或允许特定内网IP访问
    

    注意: 若启用了保护模式(protected-mode yes,默认开启),且Redis未设置密码,绑定非本地地址时将拒绝外部连接。生产环境应结合密码或防火墙来确保安全。

  • 监听端口: 默认端口为 6379,可通过配置 port 6379 修改。如需同时运行多个 Redis 实例,应为每个实例指定不同端口。

  • 日志输出: Redis 默认以守护进程方式运行(daemonize yes)并将日志写入文件。配置项 logfile 指定日志文件路径。CentOS 安装包通常默认日志文件为 /var/log/redis/redis.log(或 redis-server.log)。确保该路径存在且 Redis 用户有写权限。例如:

    logfile /var/log/redis/redis.log
    loglevel notice        # 日志级别:debug、verbose、notice、warning
    

    如果希望使用系统日志(syslog),可将 syslog-enabled 设置为 yes,并配置 syslog-ident 等参数。

  • 数据库数量: databases 16 默认有16个逻辑数据库,可根据需要调整。

  • 最大内存(maxmemory):未设置则不限制(受物理内存限制),可配置如 maxmemory 2gb 并设置淘汰策略(maxmemory-policy)防止内存耗尽。

  • 访问密码: Redis 默认无密码。可通过在配置文件中加入 requirepass <your_password> 来启用密码认证。一旦设置,客户端连接后必须执行 AUTH <密码> 验证,否则操作会被拒绝。设置密码示例:

    requirepass MyStrongPassword123
    

    设置后重启 Redis 服务,并使用 redis-cli 验证:未 AUTH 前执行命令会得到 (error) NOAUTH Authentication required 错误,AUTH 后应返回 OK。

  • 危险命令处理: 为防止误操作,Redis 提供命令重命名或禁用功能。可在配置文件 SECURITY 部分使用 rename-command <原命令> <新名称> 实现 。将命令重命名为空字符串可禁用之。生产环境常禁用/重命名高危命令,例如:

    rename-command FLUSHALL ""         # 禁用清空数据库命令
    rename-command SHUTDOWN SHUTDOWN_MENOT   # 重命名 SHUTDOWN 命令
    rename-command CONFIG ASC12_CONFIG      # 重命名 CONFIG 命令
    

    如上,将 FLUSHALL 禁用,将 SHUTDOWN 重命名为 SHUTDOWN_MENOT(防止意外关闭),将 CONFIG 重命名为不易猜测的名字。修改后重启 Redis 使其生效。验证时,原命令应提示未知命令,新命令可正常执行。

1.3、持久化配置(RDB 与 AOF)

Redis 是内存数据库,但通过持久化机制可以将数据保存到磁盘。主要有 RDB 快照和 AOF 日志两种方式:

  • RDB(Redis DataBase)快照: 将某一时刻的全量数据快照保存成 dump 文件(默认 dump.rdb)。Redis 可根据配置周期性地触发 RDB 快照,例如默认配置中:

    save 900 1       # 900秒(15分钟)内有>=1次写操作就触发快照
    save 300 10      # 300秒内有>=10次写操作触发
    save 60 10000    # 60秒内有>=10000次写操作触发
    dir /var/lib/redis  # RDB 文件保存目录
    

    当满足条件时 Redis 会 fork 子进程异步将内存数据写入 RDB 文件。RDB 持久化的优点是文件紧凑,适合备份,恢复大数据集时比AOF更快;对性能影响小,主进程几乎不执行磁盘 IO 。缺点是无法实时持久化,可能丢失最后几分钟的数据(具体取决于 save 间隔);另外在数据量很大时 fork 操作可能造成短暂阻塞 。

  • AOF(Append Only File)日志: 以日志形式记录每次写命令来实现持久化。开启方式是在配置中设置:

    appendonly yes
    appendfilename "appendonly.aof"
    appendfsync everysec   # 默认策略:每秒同步一次
    

    AOF模式下,Redis将每个写命令追加到AOF文件。其优点是持久化频率高,默认每秒fsync一次最多丢失1秒数据 ;采用只追加写,不会破坏已有内容,崩溃后可通过 redis-check-aof 修复日志尾部不完整的指令;还能自动在后台重写压缩AOF文件体积,以只保留当前数据集所需命令 ;AOF日志是易读的文本格式,便于分析和恢复单条命令。缺点是AOF文件通常比RDB大,恢复速度略慢于RDB;根据fsync策略不同,写入性能可能略低于RDB。不过在默认每秒同步的情况下性能影响很小。 (Redis persistence | Docs

如何选择: 可以同时开启 RDB 和 AOF 以兼顾定期备份和实时性。一般生产环境下,如果对数据容忍几分钟丢失,可仅启用 RDB(Redis 默认配置即如此);如果要求几乎不丢数据,可同时启用 AOF(及 RDB 作为额外备份),不建议只开启 AOF 而不做快照 。当两者同时开启时,Redis 重启将优先加载 AOF 以保证数据最新。

配置完成后,启动 Redis 时会根据配置自动进行持久化。也可在运行时用命令 SAVE(阻塞式) 或 BGSAVE(后台异步) 手动触发 RDB 快照,BGREWRITEAOF 手动重写 AOF 文件。

1.4、启动与开机自启配置

手动启动: 可以通过命令行直接运行 redis-server /path/to/redis.conf 来启动实例。如果 daemonize yes,Redis 将以守护进程方式在后台运行。前台启动用于调试则需设 daemonize no

systemd 管理: 使用 yum 安装的 Redis 已含有 systemd 服务文件(通常位于 /usr/lib/systemd/system/redis.service)。可用以下方式管理:

  • systemctl start redis / stop redis:启动或停止服务。

  • systemctl enable redis / disable redis:设置开机自动启动或禁用。

  • systemctl restart redis:重启服务。

启用开机自启后,系统引导时会自动启动 Redis。如是源码安装,建议手动编写 systemd 服务文件。例如 /etc/systemd/system/redis.service 内容(需根据安装路径调整):

[Unit]
Description=Redis In-Memory Data Store
After=network.target

[Service]
ExecStart=/usr/local/redis/bin/redis-server /etc/redis.conf --supervised systemd
ExecStop=/usr/local/redis/bin/redis-cli shutdown
User=redis
Group=redis

[Install]
WantedBy=multi-user.target

写好后执行 systemctl daemon-reloadsystemctl enable redis。这样既可通过 systemctl 管理进程,也方便日志集成和资源限制。

数据目录及权限: 默认情况下,Redis 会将 RDB/AOF 文件保存在配置的 dir 目录下(如 /var/lib/redis)。确保该目录权限属主为 redis 用户,避免因为权限问题导致持久化失败。可以通过 chown redis:redis /var/lib/redis 调整。Redis 配置文件也应设置属主属组为 redis:redis 并权限600,保证只有redis用户可读写。

防火墙开放端口设置

在 CentOS 上,如果启用了防火墙(firewalld),需要开放 Redis 端口以便远程访问:

  • 单机模式端口: 默认6379/TCP。若 Redis 仅本地使用且已绑定127.0.0.1,则无需在防火墙开放端口。若需允许远程访问,在防火墙增加例外。使用 firewalld 可执行:

    sudo firewall-cmd --permanent --zone=public --add-port=6379/tcp
    sudo firewall-cmd --reload
    

    上述命令在 public 区域开放6379端口(所有来源)。更安全的做法是创建专用区域并限定来源IP:

    sudo firewall-cmd --permanent --new-zone=redis              # 新建 redis 区域
    sudo firewall-cmd --permanent --zone=redis --add-port=6379/tcp
    sudo firewall-cmd --permanent --zone=redis --add-source=192.168.0.0/24
    sudo firewall-cmd --reload
    

    以上配置仅允许来源于指定内网网段的地址访问6379端口,其余流量仍受缺省区域规则限制 。如果使用 iptables,同样需要添加允许规则,例如允许来自特定IP的6379端口流量 。

  • 注意:如果设置了 Redis 只绑定本地且不对外,则无需开放防火墙端口。同时,无论如何不要直接暴露 Redis 在公网,即使设置了密码,也应通过内网访问或搭配 VPN/SSH 隧道等方式。

安全优化建议

除了上述绑定本地和密码、禁用命令等措施,单机部署还应注意以下安全事项:

  • 最小权限运行: 确保 Redis 以低权限用户运行(安装包默认创建 redis 用户)。不要以 root 启动 Redis 服务。

  • 文件权限: 限制配置文件只对属主可读写,持久化文件及日志目录只允许运行用户写入,防止敏感信息泄露和不必要的访问。 

  • 关闭危险功能: 如果不需要,可在配置中关闭 CONFIG 等命令的远程执行能力(通过 rename-command 为空禁用)。同时可以考虑关闭 FLUSHALL/FLUSHDB 等容易被误用的数据清空命令。

  • Protected mode: 保持 protected-mode yes(默认)以增加在未设置密码且绑定非本地时的保护。一旦开启保护模式且检测到安全风险,Redis 会拒绝外部请求并给出警告信息。

  • 监控和审计: 打开日志并定期检查异常登录或命令(例如突然的 FLUSHALL 日志)。可以使用CONFIG GET dir等命令查看当前数据目录,CONFIG GET requirepass验证密码是否生效等。

  • 更新和补丁: 及时升级 Redis 版本以获取安全补丁。关闭不必要的功能模块,关注官方安全公告。

通过以上配置和措施,可以在 CentOS 上安全地运行单机版 Redis,并为后续扩展到高可用架构(哨兵或集群)打好基础。

2. 哨兵(Sentinel)模式部署

哨兵模式是 Redis 提供的高可用解决方案。当主节点发生故障时,哨兵可以自动完成主从切换,保证服务持续可用。哨兵本身是独立的进程,通常需要部署多个来协同工作。下面介绍 Sentinel 架构及在 CentOS 上的部署配置。

2.1、部署架构说明

Redis Sentinel (哨兵) 实质是运行在哨兵模式下的特殊 Redis 实例,用于监控数据库实例的状态并在故障时协调故障转移。一个典型的高可用架构包括:一个主节点,若干从节点,以及至少 3 个哨兵节点 。哨兵进程彼此通信,形成一个分布式监控系统。架构示意如下: Redis Sentinel 高可用架构示意:包含1个主服务器 (master)、1个从服务器 (replica)、以及3个哨兵(其中两个与Redis同机部署,另一个独立部署在应用服务器)。哨兵进程监控主从状态,在检测到主库故障且多数哨兵达成共识时执行自动切换。

如上图,哨兵通常和 Redis 实例 co-locate 部署,即和 master、replica 节点位于相同或近端的服务器,同时增加一个独立哨兵节点,形成奇数个哨兵。至少需要3个哨兵以形成仲裁机制,防止单点故障。哨兵通过Redis协议定期向主和从发送 PING,判断其是否在线,并与其他哨兵交换状态信息。当多数哨兵判断主节点下线时(达到配置的 quorum 法定数量),将发起领导者选举并由当选哨兵执行故障转移。

简而言之,Sentinel 的作用包括:

  • 监控 (Monitoring): 不断检查主节点和从节点是否正常运作。

  • 通知 (Notification): 在检测到故障时,按照配置触发警报通知管理员或其他系统。

  • 自动故障转移 (Failover): 当确认主节点失效时,选举出新的主节点(从现有从节点中提升) ;并让其他从节点改为跟随新主节点 。

  • 配置提供 (Configuration provider): 哨兵可以告知客户端当前的主节点地址,客户端应用可通过哨兵获取主服务的地址,实现连接无缝切换。

2.2、哨兵配置文件讲解

Redis 安装包通常包含 sentinel.conf 样例文件。哨兵配置与 Redis 本身配置格式类似,但指令不同。以下是关键配置项说明:

  • 端口: 默认哨兵监听 26379 端口 。可以在配置中通过 port 26379 修改。需要注意的是,哨兵必须监听在各节点上,使它们能够互相通信;其 bind 通常留空或设为0.0.0.0,以便监听所有网络接口(哨兵不对客户端提供数据服务,安全性依赖网络隔离和防火墙)。

  • 监控主节点: 使用 sentinel monitor <名称> <主IP> <主端口> <quorum> 定义哨兵要监控的主节点。各哨兵对于同一主节点配置必须使用相同的名称和 quorum 数。quorum 是最小同意数,例如配置为2表示至少2个哨兵判定主机下线才触发故障转移 。示例:

    sentinel monitor mymaster 192.168.1.10 6379 2
    

    此行表示监控名为 “mymaster” 的主节点,其地址为192.168.1.10:6379,判定故障需要至少2个哨兵同意。

  • 主节点认证: 如果 Redis 主节点启用了 requirepass,哨兵需要配置认证密码才能连接监控。使用:

    sentinel auth-pass mymaster <主节点密码>
    

    将 “mymaster” 主节点的密码告知哨兵 。必须在 monitor 配置之后、其他之前,避免找不到主节点名错误。

  • 故障判定时长: sentinel down-after-milliseconds <name> <毫秒> 定义判定实例断线的毫秒数 。哨兵在该时间内未能从实例收到有效回复,则标记其为主观下线 (SDOWN)。例如:

    sentinel down-after-milliseconds mymaster 5000
    

    表示5秒内无响应则认为故障。

  • 故障转移超时: sentinel failover-timeout <name> <毫秒> 设置一次故障转移从开始到完成的超时时间 。默认约 180000ms(3分钟)。在该时间内如果切换未成功,可能放弃或重试。

  • 平行同步数: sentinel parallel-syncs <name> <N> 限制故障转移后有多少个从节点可以同时与新主节点进行同步 。例如配置为1表示一个从节点完成同步后才让下一个开始,可避免新主过载。

  • 通知脚本和重配置脚本: (可选)哨兵可以在故障转移事件发生时调用外部脚本发送通知(如邮件报警),通过 sentinel notification-script 指定脚本路径;以及在新主产生后调用客户端更新脚本(如更新应用配置)的 client-reconfig-script。这部分按需配置,不是必须。

配置完成后,将该 sentinel.conf 部署到每个哨兵节点上。哨兵实例启动命令与 Redis 类似,例如:

redis-sentinel /etc/redis-sentinel.conf

(或者 redis-server /etc/redis-sentinel.conf --sentinel。建议使用系统服务管理哨兵:CentOS 安装 Redis 后通常自带 redis-sentinel 服务,可通过 systemctl enable redis-sentinel 设置自启。

2.3、多个节点配置样例

假设有三台服务器:redis-1(主),redis-2(从),redis-3(从)。我们在每台上都运行一个哨兵,总计三个哨兵协同监控。基本配置思路:

  • redis-1(主):
    Redis 主节点 (port 6379requirepass 如设置则从节点和哨兵需使用)。
    Sentinel 配置(摘录):

    port 26379
    bind 0.0.0.0
    sentinel monitor mymaster 127.0.0.1 6379 2    # 对本机主服务器,用本地回环监控
    sentinel auth-pass mymaster <主节点密码>
    sentinel down-after-milliseconds mymaster 5000
    sentinel failover-timeout mymaster 180000
    sentinel parallel-syncs mymaster 1
    
  • redis-2(从)redis-3(从):
    Redis 从节点通过 replicaof 指向主节点 (replicaof redis-1-ip 6379) 或启动后执行 SLAVEOF 命令。
    Sentinel 配置:

    port 26379
    bind 0.0.0.0
    sentinel monitor mymaster <主节点IP> 6379 2   # 都指向 redis-1 主的IP
    sentinel auth-pass mymaster <主节点密码>
    sentinel down-after-milliseconds mymaster 5000
    sentinel failover-timeout mymaster 180000
    sentinel parallel-syncs mymaster 1
    

    所有哨兵使用相同的 mymaster 名称和参数。注意:在主节点本机哨兵可以用127.0.0.1监视本机Redis,而在其他从机上则需填主节点IP。

将上述配置文件分发并在三台机器分别启动 redis-sentinel。启动后,可通过 redis-cli 连到哨兵端口验证配置。例如执行 SENTINEL masters 查看哨兵监控的主节点信息,SENTINEL slaves mymaster 列出已发现的从节点。哨兵启动后会将自身发现的集群拓扑写回配置文件(增加例如 sentinel known-slave 等行,自动维护,无需手工编辑)。

2.4、主从自动切换演示

当哨兵集群运行稳定后,我们可以模拟主节点故障,验证自动故障转移过程:

  1. 初始状态检查: 主节点 redis-1 正常提供读写,从节点 redis-2、redis-3 正常复制。哨兵通过命令可以报告主节点处于 ok 状态,SENTINEL get-master-addr-by-name mymaster 返回当前主节点地址。

  2. 模拟故障: 停止 redis-1 主服务器(例如 systemctl stop redis 或 kill 进程)。此时哨兵将很快检测到无法连接主节点。在 down-after-milliseconds 5000 配置下,大约5秒后哨兵标记主节点主观下线 (SDOWN)。

  3. 达成一致 (ODOWN): 三个哨兵相互通信,若至少2个哨兵同意主节点下线(quorum=2),则进入客观下线状态 ODOWN 。随后触发领袖哨兵选举。哨兵使用基于 Raft 算法的投票过程选出一个领袖来执行故障转移。

  4. 执行故障转移: 领袖哨兵从剩余的从节点中挑选新的主节点。选择依据包括:复制偏移量(数据最完整者优先)、设置的优先级、与哨兵连接正常性等 。假设 redis-2 被选为新的主库。哨兵向其发送 SLAVEOF NO ONE 提升为主,并通知集群中的其它从节点改为从属 redis-2。Redis-3 将执行 SLAVEOF <redis-2 IP> 6379 开始同步新的主库数据。整个切换通常在几秒到数十秒内完成(取决于数据同步量和 failover-timeout 设置)。

  5. 恢复服务: 切换完成后,哨兵更新内部配置,新主节点 (redis-2) 状态改为 OK。客户端若使用哨兵机制,可通过哨兵获取新的主节点地址并重新建立连接,读写请求将自动在新主上继续。整个过程中缓存层对外服务中断时间很短,实现高可用。

  6. 旧主重启: 此时 redis-1 原主重启后,会以从节点身份加入(哨兵会将其设为新主的从节点)。数据会通过增量同步赶上当前主节点,然后正常提供只读服务。至此完成一次故障切换周期。

通过上述过程,可以看到哨兵有效保障了 Redis 的高可用。当主库故障恢复后也无需人工干预,哨兵体系会自动将拓扑调整到健康状态。

注意事项: 哨兵架构虽能自动故障转移,但由于 Redis 复制是异步的,可能存在极短时间窗口的数据丢失(刚写入主但尚未传到从就主机宕机的场景)。这与Redis集群模式类似,属于设计权衡 。另外,确保哨兵进程本身高可用,推荐部署奇数个哨兵且分布在不同主机/可用区,防止网络隔离或单点失败影响仲裁。

2.5、安全与防火墙设置

Sentinel 本身也需要一些安全考虑:

  • 端口访问控制: 默认哨兵监听 26379,建议通过防火墙限制只有受信任的地址可以连接哨兵端口。哨兵端口不需要对外开放给应用客户端,只需哨兵之间和与Redis实例互通。所以可以像 Redis 主端口一样,在 firewalld 上仅开放给内网机器:

    sudo firewall-cmd --permanent --add-port=26379/tcp
    sudo firewall-cmd --permanent --add-source=<trusted_IP_range> --zone=public
    sudo firewall-cmd --reload
    

    这样仅允许特定来源访问哨兵端口。确保哨兵节点彼此网络互通,以及能访问各Redis实例的端口。

  • 哨兵认证: 哨兵对客户端的连接默认没有密码认证机制(Redis 6之前如此)。因此,不要将哨兵端口暴露给不可信网络。另外,在 Redis 6+ 中可以通过 ACL 为哨兵指定专门用户密码用于哨兵间通信,但典型环境下哨兵通信应在内网环境中进行,外部不直接访问。

  • 最小权限和隔离: 哨兵运行也可使用 redis 用户,无需root权限。哨兵不会访问Redis数据文件,但会自身写配置文档(如 sentinel.conf 会动态更新),确保配置文件可写且仅对运行用户可写。

  • 客户端安全: 如果应用需要通过哨兵获取主节点信息(如使用 SENTINEL get-master-addr-by-name),应用侧应也做好认证或限制,只让应用服务器访问哨兵接口。

  • 关闭不需要命令: 哨兵模式下,redis-sentinel进程仍提供部分 Redis 命令(如 INFO, PING 等)。可以考虑和普通 Redis 一样禁用敏感命令,但通常哨兵开放命令较有限,不像数据实例有那么多高危操作。

总之,哨兵模式主要风险在于端口暴露和通信安全,通过网络分隔和访问控制可以较好地保障其安全。

3. Redis Cluster 集群部署

Redis Cluster 模式通过分片(sharding)将数据分布在多个节点上,同时提供内置的高可用(主从复制和自动故障转移)。它适合数据量和并发更大的场景。Redis 官方推荐至少使用 6 个节点(3主3从)来部署生产集群。下面介绍 Redis 集群的部署步骤和原理。

3.1、最少6节点集群架构与安装配置

节点规划: Redis 集群要求至少3个主节点,才能覆盖全部16384个哈希槽(slot)。为保证高可用,每个主节点应至少有一个从节点。所以最小拓扑是3个主节点+3个从节点,共6个实例 。这样即使宕掉一个主节点,其对应从节点还能升级为主,集群仍有多数主节点存活。

例如,我们准备节点编号1~6:其中1、2、3作为初始主节点,4、5、6作为对应从节点(分别复制1、2、3)。每个节点可以在不同机器上,或在测试环境中单机用不同端口模拟。**注意:**生产环境应将集群节点分布在不同物理机/容器上,避免单点故障。

安装 Redis: 与单机部署类似,在每台机器上安装 Redis 服务(版本需一致)。可以用 yum 或源码安装,多实例通常使用同一可执行文件,不同配置文件来启动多个实例。假设使用端口7001-7006来分别启动6个实例。

配置节点: 为每个实例准备一个配置文件,例如:7001.conf, 7002.conf, ... 7006.conf。每个文件至少要区别以下参数:

  • port <端口>:如7001, 7002, ..., 7006。

  • cluster-enabled yes:启用集群模式。

  • cluster-config-file nodes-<端口>.conf:集群节点状态配置文件名,每个实例必须不同,例如 nodes-7001.conf 等。Redis启动集群模式时会自动生成/更新这个文件,保存集群的拓扑信息。

  • cluster-node-timeout 5000:节点通信超时阈值,毫秒。节点超过此时长未响应将被视为下线,默认15000,可按需求调整(这里示例用5秒)。

  • appendonly yesno:持久化策略。集群模式可选RDB或AOF或两者,都由各节点独立持久化。一般也建议开启持久化以防止全集群重启时数据丢失。

  • requirepass <密码>(如果需要):集群模式下每个节点都需要配置相同的密码,否则客户端重定向时会遇到认证问题。需要注意的是,Redis Cluster对内部节点通信并不使用密码认证,所以开启密码主要保护客户端访问。若开启,后续创建集群和管理命令也要附加 -a <密码>

  • bind <IP>:节点绑定地址。通常集群各节点需要彼此通讯,若部署在多台机器上应绑定各自内网IP或0.0.0.0。确保不同机器的节点可以互通端口。

  • protected-mode no:当需要节点对外提供服务(非仅127.0.0.1)时关闭保护模式,否则在未设置密码情况下会拒绝外部连接。

  • daemonize yes:守护进程方式运行,根据需要设置。

  • dir, logfile 等:指定各节点的数据目录和日志文件,避免冲突。例如数据目录可设 /var/lib/redis/7001 等不同路径,日志文件 /var/log/redis_7001.log 等,以区分节点。

配置完成后,在每台机器启动各自的 Redis 实例。例如一台机器上可能跑两个节点7001和7004(一个主一个从属于不同主),另一台7002和7005,第三台7003和7006,这样保证每台各承担一个主一个从,增强容灾(当一台宕机,只丢失一个主和一个非其自身的从)。

启动命令比如:

redis-server /etc/redis/7001.conf
redis-server /etc/redis/7004.conf
# ...其他节点类似

启动后,用 redis-cli -p 7001 等可以连接到各节点,但此时它们还只是独立的 Redis 实例,还未组成集群。

3.2、使用 redis-cli 创建集群

Redis 提供 redis-cli --cluster 子命令来简化集群搭建(3.0以前使用 redis-trib.rb 脚本,现已废弃)。我们可以在任意一台安装了 redis-cli 的机器上执行集群创建命令。

假设6个节点分布在三台服务器上,IP分别为10.0.0.1~10.0.0.3,每台两个节点端口(7001/7004, 7002/7005, 7003/7006)。在10.0.0.1上执行:

redis-cli --cluster create \
  10.0.0.1:7001 10.0.0.2:7002 10.0.0.3:7003 \   # 三个主节点
  10.0.0.1:7004 10.0.0.2:7005 10.0.0.3:7006 \   # 三个从节点
  --cluster-replicas 1

--cluster-replicas 1 表示为每个主节点自动分配1个从节点。上述命令会列出各节点信息并询问确认(输入 yes 执行)。redis-cli 会连接这些实例,分配哈希槽并设置主从关系,然后引导它们组成一个集群。

执行成功后,可在任意节点用 redis-cli -c -p 7001 进入集群模式下的交互(-c 启用集群支持,会跟随重定向)。运行 CLUSTER NODES 命令,可以看到6个节点各自的ID、角色(master/slave)、正在负责的槽区间等信息,验证集群状态正常。

在上例中,三个节点将被选作主节点,各自分配大约 16384/3 ≈ 5461 个槽位,另外三个节点自动成为对应主节点的从节点。集群创建完成后,客户端可以对集群任一节点发送命令,Redis会根据键的哈希槽自动路由请求到正确的主节点执行。如果请求打到非负责该键的节点,会返回 MOVED 重定向到正确节点的地址(redis-cli -c 会自动跟随)。

3.3、分片与复制原理说明

数据分片 (Sharding): Redis Cluster将整个键空间预划分为 16384 个哈希槽。每个键通过 CRC16 校验计算槽编号(取模16384)。集群中的主节点各自负责一部分槽位范围,从而共同覆盖全部槽位。例如3个主节点可能负责槽0-5500、5501-11000、11001-16383。这样,当增加或移除节点时,只需迁移部分槽位的数据即可重平衡。

由于采用固定槽数量,增减节点实质是重新映射槽到节点:添加节点时,从现有节点挪一些槽给新节点;删除节点时,将其槽转移给其他节点,再移除之。Redis Cluster支持在不停机情况下进行这些操作,槽的迁移在后台完成,期间集群仍可用。

复制与故障转移: 集群模式中,每个主节点可以有 N 个从节点(官方建议至少1个作为副本) 。这些从节点不参与正常请求分片,但在对应主失败时顶上。集群要求过半数的主节点存活才能正常运行;如果多数主节点不可达,整个集群将不可用(这是为了保证数据分区的协调和一致性)。在我们的6节点(3主3从)方案下,允许宕掉最多1个主节点(其从节点接管)且集群仍健全。但如果同时两个主节点失效,剩下1个主不足以形成多数(3个主中仅1个存活 < 50%),则集群将进入失败状态,停止对外服务,等待管理员干预。

当某个主节点下线时(例如崩溃或网络隔离超过 cluster-node-timeout 时间),集群中负责监控的其他主节点通过彼此通信感知此事。如果故障主有从节点,剩余主节点将协商选举其中一个从节点提升为新的主节点。这个过程类似于Sentinel但由集群内部完成。新主接管原有槽位,未完全同步的数据可能丢失(异步复制的局限,和 Sentinel 情况相同。故障转移通常需要多数存活主节点投票同意方可执行,确保不会出现脑裂。

通过这种主从模式,一个主节点和它的从节点们构成分片(shard)。集群中的每个分片负责部分槽位,且有高可用冗余。一旦原主恢复,它会自动变成某个主的从节点加入集群(类似Sentinel场景)。

3.4、集群配置文件示例与说明

下面给出一个节点配置片段示例(如7001.conf),涵盖集群相关的重要参数:

port 7001
bind 0.0.0.0
daemonize yes
pidfile /var/run/redis_7001.pid

cluster-enabled yes                   # 开启集群模式
cluster-config-file nodes-7001.conf   # 集群节点状态文件
cluster-node-timeout 5000             # 节点通信超时阈值(ms)
cluster-announce-ip 10.0.0.1          # 如有必要,向集群通告的IP
cluster-announce-port 7001            # 通告的客户端连接端口
# cluster-announce-bus-port 17001     # 通告的集群总线端口(默认+10000,可省略)

appendonly yes
appendfilename "appendonly-7001.aof"
dbfilename "dump-7001.rdb"
dir /data/redis/7001                   # 持久化文件目录
logfile "/var/log/redis_7001.log"

说明:

  • cluster-announce-ip/port:在NAT或Docker等网络环境下用来告知集群其它节点和客户端自己的可访问地址。如果节点实际 IP 与它绑定IP不一致(例如0.0.0.0或内网/外网转换),需要手动指定,否则可能出现节点通讯问题。

  • cluster-announce-bus-port:集群总线端口(用于内部二进制协议通讯,默认是主端口+10000,即例如7001的总线端口为17001)。通常无须配置,除非端口被占用或固定要求。务必在防火墙中开放总线端口供节点间通信。

  • cluster-node-timeout:该值除了用于判断节点失联时间,也影响故障转移的触发时机。一般保持默认15秒或缩短到5秒左右,太短可能误判,太长则故障切换慢。

  • 节点状态文件nodes-*.conf文件由 Redis 自动维护,包含节点ID、彼此连接信息、槽位分配等。不需要也不应手工编辑。该文件默认在 dir 目录下,如未指定文件名默认叫 nodes.conf。管理集群时可能会用到它(如重置集群要删除此文件)。

  • slots 配置:在配置文件中不需要手动指定槽分配。集群创建时 redis-cli 会通过 CLUSTER ADDSLOTS 等指令写入槽映射到各节点,节点状态文件会持久保存这个映射。

注意: 在集群模式下,有些配置自动生效:如 protected-mode 会自动关闭(因为绑定非本地),且一些命令受限(集群模式下不允许执行非本分片的数据相关命令,如FLUSHALL需要加特殊标志等)。另外,一旦节点加入集群,后续很多配置需通过命令变更(比如添加从节点、迁移槽)而非修改配置文件。

3.5、启动、关闭、重启与扩缩容操作

启动集群各节点: 按前述配置启动所有 Redis 实例后,通过 redis-cli --cluster create 一次性配置集群。如果节点启动时未指定 cluster-enabled yes 会拒绝加入集群,请确保配置正确。集群创建成功后,可以通过 CLUSTER INFO 检查状态(比如 cluster_state:ok 表示正常)。

正常运行管理: 集群模式下每个实例依然用 redis-cli -p <port> 管理常规Redis命令。常用集群管理命令包括:

  • CLUSTER INFO:查看集群总体信息(状态、槽分配是否完整、节点数等)。

  • CLUSTER NODES:列出节点清单和角色。

  • CLUSTER SLOTS:列出槽分配详情。

  • CLUSTER FAILOVER:在某从节点上执行,手动将该从提升为主(用于模拟故障转移或主从切换维护)。

  • CLUSTER KEYSLOT <key>:计算一个键所属的槽位编号,方便调试。

  • CLUSTER MEET <ip> <port>:引入新节点加入集群(用于扩容)。

  • CLUSTER FORGET <node-id>:从集群元数据中移除节点(用于缩容或清理故障节点)。

  • CLUSTER REPLICATE <node-id>:将本节点设置为指定节点的从节点。

关闭节点: 平滑关闭某个节点前,最好确保:如果是主节点,已有其从节点在集群;或者在维护前将槽迁移或执行故障转移让其从节点接管,以避免服务中断。直接关闭一个有从节点的主节点时,集群会感知并自动提升其从节点。但要注意一次不要下线多个主节点,否则会触发多数失联导致集群不可用。

使用 redis-cli -p <port> shutdown 可以安全地关闭单个节点。集群其他节点会将其标记为下线。如果是计划内下线一个主节点,建议先将其槽位迁移到其他节点:可以使用 redis-cli --cluster reshard 命令交互式完成槽迁移,然后再下线该节点并执行 CLUSTER FORGET 通知集群移除它。

添加新节点(扩容): 可以启动新 Redis 实例(集群配置开启,但暂未加入集群)。然后在现有集群上执行:

redis-cli --cluster add-node <new_host>:<new_port> <existing_host>:<existing_port>

这会将新节点加入集群,默认为主节点但尚未承担槽。然后需要将部分槽分配给它,可用:

redis-cli --cluster reshard <any_host>:<any_port>

按照提示分配一定数量槽给新节点(Redis会建议分配平均的槽)。reshard 过程会自动迁移数据。在完成后,新节点开始分担流量。若要将新节点作为某主的从节点(不是增加分片而是增加冗余),可以在 add-node 时加 --cluster-slave 以及 --cluster-master-id <ID> 来指定其主节点。

删除节点(缩容): 需要先迁移该节点上所有槽位到其他节点:

redis-cli --cluster reshard <host>:<port> --cluster-from <node-id> --cluster-to <recipient-id> --cluster-slots <N>

将待移除节点上的槽逐步迁空。槽都迁走后,该节点变为不负责任何数据。这时在集群任一节点执行:

redis-cli --cluster del-node <host>:<port> <node-id>

将其移出集群。之后可以关闭该 Redis 实例。

故障节点替换: 如果某主节点故障且无法恢复,需要用它的从节点或新节点替换。通常步骤是:确保故障节点下线(集群应已自动提升其从节点);然后执行 CLUSTER FORGET <dead-node-id> 在所有存活节点上清除对故障节点的记录。最后可以部署一个新从节点挂载到现存主节点,或者等待之后扩容操作。

重启集群: 有时需要整体重启所有节点(例如升级版本)。因为集群信息持久化在 nodes.conf 文件中,只要逐一重启节点,集群即可自行恢复连接。切勿同时关闭多数节点,否则可能丢失集群配置信息。正确的做法是:一次重启一个节点,等待其重新加入集群(cluster meet 通信是自动的,因为 nodes.conf 记忆了拓扑)。如果必须全停再启,务必保留每个节点原有的 nodes.conf 和持久化数据文件,这样重启后每个节点会加载之前的集群配置,自动互相发现并恢复集群状态。

3.6、安全与网络设置

Redis 集群环境的安全主要涉及网络访问控制和各节点认证:

  • 防火墙配置: 集群每个节点需要两个TCP端口开放:一个是数据端口(如6379/7000系列),另一个是集群总线端口(数据端口+10000)。例如节点端口7001,则总线端口默认17001。总线端口用于节点间交互,客户端不使用它,但必须确保集群内所有节点彼此可达该端口,否则集群通信会失败。在 firewalld 中需要开放这些端口并允许节点IP之间互通。例如:

    firewall-cmd --permanent --add-port=7001/tcp
    firewall-cmd --permanent --add-port=17001/tcp
    firewall-cmd --permanent --add-source=<IP_of_other_node>
    firewall-cmd --reload
    

    如果使用了非默认 cluster-bus 端口或自定义 cluster-announce 配置,也相应调整。建议将所有节点置于受限的内网环境,通过防火墙仅允许内部互访和受信任的应用服务器访问客户端端口。

  • 客户端认证: 如前述,可选配置 requirepass 实施密码。如果设置了,所有节点必须使用相同密码,否则集群创建和槽迁移可能无法进行(因为内部重定向到另一个节点时需要认证)。客户端在连接集群时,也需要先 AUTH;很多 Redis 客户端库在 cluster 模式下提供统一的密码配置,会对每次重定向自动认证。需要注意的是,集群总线通信不支持密码,因此 requirepass 不能保护节点间的 Gossip 通信,这部分应该由防火墙和内网隔离来保障。

  • 命令权限与ACL: Redis 6 引入 ACL,可以为集群设置专门的用户用于节点内部通信和客户端访问分别使用。但一般情况下,集群模式下仍以整体一个密码控制即可。如果对安全要求极高,可考虑启用 TLS 加密通信(Redis 6+支持集群总线走 TLS,但配置较复杂,这里不展开)。

  • 敏感命令: 在集群模式下,像 FLUSHALL 这类命令默认会广播到所有节点执行,具有更大风险。可以酌情通过配置 rename-command 禁用,如单机模式部分所述,以防止一条命令清空整个集群的数据。

  • 监控与审计: 对集群各节点应做好日志集中收集,以及 Redis 内置统计监控(例如 INFO 输出)观察。特别关注 cluster_state 是否为 ok、各节点的连接数、内存使用等,以提前预警问题。

3.7、常见故障排查建议

在实际部署 Redis 集群过程中,可能遇到一些常见问题:

  • 节点无法加入集群: 执行 --cluster create 时如果一直卡在等待,可能是节点之间通信不通。请检查所有节点的端口是否开放(包括集群总线端口)、cluster-enabled yes 是否配置、以及节点 bind 地址是否能让其他机器访问。如果节点开启了 protected-mode 又未设置密码且绑定了0.0.0.0,也可能拒绝外部命令,造成创建集群失败。在这种情况下,设置 protected-mode no 或正确配置密码。

  • 集群状态不稳定: 执行 CLUSTER INFO 出现 cluster_state:fail,说明有槽位未分配或多数主节点失效。可以用 CLUSTER SLOTS 查看是否有槽位显示为未知节点。如果某节点掉线导致槽位无人负责且无从节点接管,会出现集群失败状态。这时需要手动介入:如果故障节点可恢复,尽快启动重新加入;如果不可恢复,考虑使用 CLUSTER FAILOVER 提升对应从节点为主。确保集群再次拥有所有槽位的主节点后,状态会变为 OK。

  • 重新组建集群: 在测试环境,经常需要销毁重建集群。务必在所有节点上删除之前生成的 nodes.conf 文件和持久化数据(dump.rdb/AOF),否则旧配置会干扰新集群组建。常见症状是新建集群时节点仍记着旧集群的槽信息,导致 create 失败。这时停掉实例,清理旧文件,然后重启再建。

  • 槽位迁移问题: 扩容或缩容时使用 redis-cli --cluster reshard 有时会遇到迁移卡住或失败,可能因为网络不通或目标节点内存不足等。可以通过 CLUSTER INFO 查看 migrating 和 importing 槽情况,必要时尝试使用手动命令 CLUSTER SETSLOT 等调整(较高级,不熟悉建议多尝试自动reshard或使用官方 redis-trib/redis-cli 工具)。

  • 性能和延迟抖动: 如果发现集群操作延迟增大,检查是否出现集群重配置频繁的情况(比如某节点不稳定导致槽频繁转移)。另外 AOF 重写和 RDB 快照在集群模式下也可能造成个别节点短暂卡顿,可通过调整 cluster-node-timeout 和合理配置持久化来缓解。例如避免所有主节点同时在整点做RDB快照,可以错开定时。

  • 集群不可用场景:了解一些限制,如当超过半数主节点下线时集群会停止写入。此时即使从节点还在也无法自动恢复,因为缺少仲裁。需要尽快恢复至少半数以上主节点并确保其中包含原有槽位覆盖。例如3主集群挂掉2台,就只能恢复服务后手动重建或引入新主节点了。另一个常见问题是脑裂:网络分区导致一部分节点无法与另一部分通信,这可能使双方各自选主。Redis Cluster通过要求多数投票避免双主,但脑裂期间可能短暂停止服务或丢写,需通过架构设计(如部署奇数节点、跨AZ分布)减少几率。