跳到主要内容

安装手册

单机安装

使用Docker

  • 直接创建一个redis容器
docker run --name redis -p 6379:6379 -d redis
  • 挂载数据目录
docker run --name redis -v /your/path/data:/data -d redis redis-server --save 60 1 --loglevel warning
  • 挂载配置文件和数据目录
docker run --name redis /your/path/redis.conf:/usr/local/etc/redis/redis.conf -v /your/path/data:/data -p 6379:6379 -d redis

使用包管理器

APT

在Debian 13上,默认软件源已经包含了 redis,使用sudo apt install -y redis即可。如果需要安装最新版,可以参照以下步骤

sudo apt-get install lsb-release curl gpg
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
sudo chmod 644 /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list
sudo apt-get update
sudo apt-get install redis

sudo systemctl enable redis-server
sudo systemctl start redis-server

源码编译

nil

主从集群

Redis 主从复制(Replication)是一种将一个 Redis 服务器(主节点,Master)的数据自动复制到一个或多个 Redis 服务器(从节点,Slave)的机制。

一般来说从节点不要超过10个。因为主节点需要向从节点同步写操作(发送 RDB 快照 + 命令流)。从节点越多,主节点的网络和 CPU 负担越重。若需更多副本,可考虑级联复制(从节点再作为其他从节点的主)。

主节点

配置信息

# 绑定 IP(若需远程访问,不能只绑定 127.0.0.1)
bind 0.0.0.0

# 关闭保护模式(或设置密码)
protected-mode no

# 设置密码(可选,但建议设置)
requirepass your_master_password

从节点

# 指定主节点的 IP 和端口
replicaof 192.168.1.10 6379

# 如果主节点设置了密码,需配置以下项
masterauth your_master_password

# (可选)设置从节点只读(默认就是只读)
replica-read-only yes

# 绑定 IP(确保可被访问)
bind 0.0.0.0
protected-mode no

验证

  • 主节点查看从节点信息
redis-cli -h 192.168.1.10 info replication

输出应包含

role:master
connected_slaves:1
slave0:ip=192.168.1.11,port=6379,state=online,offset=...,lag=0
  • 从节点查看角色
redis-cli -h 192.168.1.11 info replication

输出应包含

role:slave
master_host:192.168.1.10
master_port:6379
master_link_status:up

哨兵

Redis Sentinel(哨兵)是 Redis 官方提供的高可用(HA)解决方案,用于监控 Redis 主从集群,并在主节点(Master)发生故障时自动进行故障转移(Failover),将一个从节点(Replica)提升为新的主节点,从而保证服务持续可用。

哨兵的核心功能:

  • 监控(Monitoring):持续检查主节点和从节点是否正常运行。
  • 通知(Notification):当被监控的 Redis 实例出现问题时,可通过 API 通知管理员。
  • 自动故障转移(Automatic Failover):主节点宕机时,自动选举一个从节点升级为主节点,并更新其他从节点的复制目标。
  • 配置提供者(Configuration Provider):客户端可通过哨兵获取当前的主节点地址(服务发现)。

哨兵节点数量建议奇数个,避免脑裂问题。常见部署方案为一主两从三哨兵, 哨兵可以和主从部署在一起,这样可以节省三台服务器; 也可以独立部署哨兵, 让生产环境更高可用。

配置主从复制

确保主从关系存在

创建哨兵

在每台哨兵服务器创建配置文件snetinel.conf

# 哨兵监听地址(允许远程连接)
bind 0.0.0.0
port 26379

# 后台运行
daemonize yes

# 日志文件
logfile "/var/log/redis/sentinel.log"

# 监控名为 mymaster 的主节点,IP 192.168.1.10,端口 6379
# 2 表示至少需要 2 个哨兵同意才认为主节点“客观下线”(quorum)
sentinel monitor mymaster 192.168.1.10 6379 2

# 主节点密码(如果设置了 requirepass)
sentinel auth-pass mymaster your_password

# 主节点宕机后,多久(毫秒)认为“主观下线”(默认 30 秒)
sentinel down-after-milliseconds mymaster 30000

# 故障转移时,最多允许几个从节点同时同步新主(避免网络拥塞)
sentinel parallel-syncs mymaster 1

# 故障转移超时时间(毫秒)
sentinel failover-timeout mymaster 180000

启动哨兵

redis-sentinel /etc/redis/sentinel.conf
# 或
redis-server /etc/redis/sentinel.conf --sentinel

验证哨兵状态

redis-cli -p 26379

# 查看主节点信息
127.0.0.1:26379> SENTINEL MASTER mymaster

# 查看所有从节点
127.0.0.1:26379> SENTINEL REPLICAS mymaster

# 查看所有哨兵
127.0.0.1:26379> SENTINEL SENTINELS mymaster

# 查看当前主节点地址(客户端用这个获取真实主节点)
127.0.0.1:26379> SENTINEL GET-MASTER-ADDR-BY-NAME mymaster

客户端连接

客户端通过哨兵动态获取主节点,python示例

from redis.sentinel import Sentinel

sentinel = Sentinel([('192.168.1.10', 26379),
('192.168.1.11', 26379),
('192.168.1.12', 26379)],
socket_timeout=0.1)

# 获取主节点连接
master = sentinel.master_for('mymaster', socket_timeout=0.1, password='your_password')

# 获取从节点连接(只读)
slave = sentinel.slave_for('mymaster', socket_timeout=0.1, password='your_password')

# 使用
master.set('key', 'value')
print(slave.get('key'))

Redis Cluster

Redis Cluster 是 Redis 官方提供的分布式解决方案,用于实现数据分片(Sharding) + 高可用(High Availability),适用于大规模数据存储和高并发访问场景。

为什么需要Redis Cluster

  • 单机 Redis 容量有限(内存、CPU、网络带宽)。
  • 主从复制 + 哨兵只能解决高可用和读扩展,不能解决写扩展和数据容量瓶颈
  • Redis Cluster 通过分片(Sharding) 将数据分布到多个节点,突破单机限制。

基本架构

  1. 哈希槽(Hash Slot)
  • Redis Cluster 将整个 key 空间划分为 16384 个哈希槽
  • 每个 key 通过 CRC16(key) % 16384 计算出所属槽。
  • 每个主节点负责一部分槽(例如 3 主节点,各负责约 5461 个槽)。
  1. 节点角色
  • 主节点(Master):负责一部分哈希槽,处理读写请求。
  • 从节点(Replica):复制主节点数据,主节点故障时参与选举。
  1. 最小集群规模
  • 至少 3 个主节点(保证故障时能达成多数派)。
  • 建议每个主节点配 1 个从节点总共至少 6 个节点(3 主 3 从)。

工作原理

  1. 数据写入流程
  • 客户端向任意节点发送写请求。
  • 如果 key 所属槽不在该节点,返回 MOVED <slot> <ip:port>
  • 客户端重定向到正确节点(智能客户端会缓存槽映射)。
  1. 故障转移
  • 主节点宕机 → 从节点通过 Raft-like 投票选举新主。
  • 集群自动更新槽分配信息,客户端重定向到新主。
  1. 节点通信
  • 使用 Gossip 协议(meet/ping/pong 消息)维护集群状态。
  • 每个节点保存整个集群的元数据(节点、槽、状态)。

使用docker-compose搭建单机cluster

  • ip:192.168.0.10
  • redis信息:
    • 客户端连接端口:7001 -7006
    • 集群间通信端口:17001 - 17006
    • 密码:123456
  • 版本:
    • docker:18.06
    • docker-compose:1.24
    • redis:6.2.4
    • centos: 7.4

准备

  1. 下载redis镜像
docker pull redis:6.2.4
  1. 准备redis的配置文件:redis.conf。主要修改端口和ip
port 7001
cluster-enabled yes
cluster-config-file nodes-7001.conf
cluster-node-timeout 5000
appendonly yes
protected-mode no
requirepass 123456
masterauth 123456
cluster-announce-ip 192.168.0.10
cluster-announce-port 7001
cluster-announce-bus-port 17001
  1. 准备持久化目录
mkdir -p /home/web/redis
cd /home/web/redis
for i in $(seq 7001 7006); do mkdir -p /home/web/redis/node_${i}/{conf,data};done
# 或者: for i in $(seq 7001 7006); do mkdir -p ./node_${i}/{conf,data};done

# 假设redis.conf在 /home/web/redis,且当前目录为/home/web/redis
for i in $(seq 7001 7006); do sed "s/7001/${i}/g" /home/web/redis/redis.conf > /home/web/redis/node_${i}/conf/redis.conf;done
# 或者: for i in $(seq 7001 7006); do sed "s/7001/${i}/g" ./redis.conf > ./node_${i}/conf/redis.conf;done

配置docker-compose.yaml

  1. 编写docker-compose.yaml(注意路径、密码、IP和端口号)
version: "3"

# 定义服务,可以多个
services:
redis-7001: # 服务名称
image: redis:6.2.4 # 创建容器时所需的镜像
container_name: redis-7001 # 容器名称
restart: always # 容器总是重新启动
volumes: # 数据卷,目录挂载
- /home/web/redis/node_7001/conf/redis.conf:/usr/local/etc/redis/redis.conf
- /home/web/redis/node_7001/data:/data
ports:
- 7001:7001
- 17001:17001
command:
redis-server /usr/local/etc/redis/redis.conf

redis-7002: # 服务名称
image: redis:6.2.4 # 创建容器时所需的镜像
container_name: redis-7002 # 容器名称
restart: always # 容器总是重新启动
volumes: # 数据卷,目录挂载
- /home/web/redis/node_7002/conf/redis.conf:/usr/local/etc/redis/redis.conf
- /home/web/redis/node_7002/data:/data
ports:
- 7002:7002
- 17002:17002
command:
redis-server /usr/local/etc/redis/redis.conf

redis-7003: # 服务名称
image: redis:6.2.4 # 创建容器时所需的镜像
container_name: redis-7003 # 容器名称
restart: always # 容器总是重新启动
volumes: # 数据卷,目录挂载
- /home/web/redis/node_7003/conf/redis.conf:/usr/local/etc/redis/redis.conf
- /home/web/redis/node_7003/data:/data
ports:
- 7003:7003
- 17003:17003
command:
redis-server /usr/local/etc/redis/redis.conf

redis-7004: # 服务名称
image: redis:6.2.4 # 创建容器时所需的镜像
container_name: redis-7004 # 容器名称
restart: always # 容器总是重新启动
volumes: # 数据卷,目录挂载
- /home/web/redis/node_7004/conf/redis.conf:/usr/local/etc/redis/redis.conf
- /home/web/redis/node_7004/data:/data
ports:
- 7004:7004
- 17004:17004
command:
redis-server /usr/local/etc/redis/redis.conf

redis-7005: # 服务名称
image: redis:6.2.4 # 创建容器时所需的镜像
container_name: redis-7005 # 容器名称
restart: always # 容器总是重新启动
volumes: # 数据卷,目录挂载
- /home/web/redis/node_7005/conf/redis.conf:/usr/local/etc/redis/redis.conf
- /home/web/redis/node_7005/data:/data
ports:
- 7005:7005
- 17005:17005
command:
redis-server /usr/local/etc/redis/redis.conf

redis-7006: # 服务名称
image: redis:6.2.4 # 创建容器时所需的镜像
container_name: redis-7006 # 容器名称
restart: always # 容器总是重新启动
volumes: # 数据卷,目录挂载
- /home/web/redis/node_7006/conf/redis.conf:/usr/local/etc/redis/redis.conf
- /home/web/redis/node_7006/data:/data
ports:
- 7006:7006
- 17006:17006
command:
redis-server /usr/local/etc/redis/redis.conf
  1. 启动
docker-compose -f ./docker-compose.yaml up -d
# 如果docker-compose.yaml文件在当前路径:
# docker-compose up -d

搭建集群

  1. 进入任意一个redis容器
docker exec -it redis-7001 bash
  1. 创建集群
# 注意IP、端口号和密码
echo -e 'yes' | redis-cli -a 123456 --cluster create 192.168.0.10:7001 192.168.0.10:7002 192.168.0.10:7003 192.168.0.10:7004 192.168.0.10:7005 192.168.0.10:7006 --cluster-replicas 1
  1. 检查集群状态
# 查看集群状态
redis-cli -a 123456 -h 192.168.0.10 -p 7001 cluster info
# 查看集群节点
redis-cli -a 123456 -h 192.168.0.10 -p 7001 cluster nodes

运维命令

# 查看集群状态
redis-cli -c -p 7000 cluster info

# 查看节点信息
redis-cli -c -p 7000 cluster nodes

# 手动故障转移(在从节点执行)
redis-cli -c -p 7003 cluster failover

# 添加新主节点
redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000

# 重新分片(迁移槽)
redis-cli --cluster reshard 127.0.0.1:7000

动态扩缩容

增加节点

  1. 启动节点服务
  2. 将新节点加入集群
# 将 7006 加入集群(连接任意现有节点, 如 127.0.0.1:7000)
redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000

刚加入cluster的节点是一个空的节点,不负责任何哈希槽。

  1. 迁移哈希槽到新节点
redis-cli --cluster reshard 127.0.0.1:7000

按提示操作:

3.1. How many slots do you want to move? → 输入要迁移的槽数(如 4096)。 3.2. What is the receiving node ID? → 输入 7006 的 node ID(通过 cluster nodes 查看)。 3.3 Please enter all the source node IDs. → 输入 all(从所有主节点均匀迁移)或指定节点 ID。 3.4 输入 yes 确认。

减少节点

例:移除7001主节点。主节点不能被直接删除,必须先将其负责的槽迁移到其他主节点。

# 查看 7001 负责哪些槽
redis-cli -p 7001 cluster nodes | grep <7001_node_id>

# 将 7001 的所有槽迁移到其他节点(如 7000)
redis-cli --cluster reshard 127.0.0.1:7000

交互式操作:

  1. 输入要迁移的槽数(如 5461)。
  2. 接收节点 ID:选择目标主节点(如 7000)。
  3. 源节点 ID:输入 7001 的 node ID。
  4. 确认迁移。

移除主节点,如果有对应的从节点,从节点也要移除

# 从集群中删除节点(在任意节点执行)
redis-cli --cluster del-node 127.0.0.1:7000 <7001_node_id>

# 假设 7004 是从节点,先迁移从节点的槽(其实从节点无槽,直接删除)
redis-cli --cluster del-node 127.0.0.1:7000 <7004_node_id>

只增减从节点

# 增加从节点
# 启动新实例 7008
redis-server /redis-cluster/7008/redis.conf

# 将其设为某主节点(如 7000)的从节点
redis-cli --cluster add-node 127.0.0.1:7008 127.0.0.1:7000 \
--cluster-slave \
--cluster-master-id <7000_node_id>

# 删除从节点
# 直接删除(从节点无槽)
redis-cli --cluster del-node 127.0.0.1:7000 <7008_node_id>

客户端连接

客户端会自动处理 MOVED 重定向和槽缓存。python示例

from redis.cluster import RedisCluster

startup_nodes = [
{"host": "127.0.0.1", "port": 7000},
{"host": "127.0.0.1", "port": 7001},
# ... 其他节点
]

rc = RedisCluster(startup_nodes=startup_nodes, decode_responses=True)
rc.set("foo", "bar")
print(rc.get("foo"))