Redis 数据类型、消息队列、客户端与高可用集群完整详解
基于学习文档整理,适合技术博客发布,内容包含:5 大基础数据类型、消息队列实现、多语言客户端使用、主从复制、哨兵模式、Redis Cluster 集群、Docker 容器化部署,原理 + 命令 + 实战案例 + 优缺点分析。
目录
- Redis 五大基础数据类型
- Redis 实现消息队列(生产者消费者 / 发布订阅)
- Redis 多种客户端使用
- Redis 高可用体系:主从复制
- Redis Sentinel 哨兵模式
- Redis Cluster 集群(3 主 3 从)
- Docker 部署 Redis(单机 + Compose 集群)
1、Redis 五大基础数据类型
Redis 是 Key‑Value 的 NoSQL 内存数据库,所有的 key 统一都是字符串类型,value 支持 5 种不同的数据结构,每种结构适配不同业务场景。
1.1 String 字符串
字符串是 Redis 最基础的数据单元,二进制安全,可以存储普通字符串、数字、图片序列化数据,单个 value 最大支持 512MB。
常用核心命令
表格
| 命令 | 作用 | |
|---|---|---|
| `set key value EX seconds[NX | XX]` | 设置 key‑value;EX 设置过期时间;NX 不存在才设置;XX 存在才覆盖 |
get key |
获取 key 对应值 | |
mset k1 v1 k2 v2 |
批量设置多个键值 | |
mget k1 k2 |
批量获取多个 key | |
incr / decr key |
数字自增、自减,原子操作 | |
ttl key |
查看剩余过期时间,‑1永不过期,‑2key 不存在 |
|
expire key seconds |
设置 key 生存时间 |
业务场景:缓存、计数器、分布式锁、session 存储。
小提示:
SET key value NX PX 30000是分布式锁加锁标准写法。
1.2 List 列表
Redis 的 List 是双向链表结构,元素有序、允许重复,可以从头部 (left)、尾部 (right) 插入和弹出数据。
常用核心命令
表格
| 命令 | 作用 |
|---|---|
lpush key v1 v2 |
从链表头部(左边)插入数据 |
rpush key v1 v2 |
从链表尾部(右边)插入数据 |
lpop / rpop key |
头部 / 尾部弹出元素 |
brpop key timeout |
阻塞式弹出,没有数据就阻塞等待,timeout 为 0 代表永久阻塞 |
lrange key start stop |
获取区间元素,0 -1获取列表全部元素 |
llen key |
获取列表长度 |
业务场景:简单消息队列、日志存储、最新消息列表。
注意:
BRPOP阻塞命令可以避免 while (true) 轮询带来的 CPU 空耗。
1.3 Set 集合
集合中元素无序、不能重复,原生支持多个集合的交、并、差集合运算。
常用核心命令
表格
| 命令 | 作用 |
|---|---|
sadd key m1 m2 |
向集合添加成员,重复元素自动忽略 |
smembers key |
查看集合全部元素 |
sismember key member |
判断元素是否存在集合中 |
sinter k1 k2 |
交集:同时存在于 k1、k2 的元素 |
sunion k1 k2 |
并集:k1 或者 k2 中存在的全部元素 |
sdiff k1 k2 |
差集:存在 k1 但是不在 k2 的元素 |
srem key m1 |
删除集合成员 |
业务场景:用户签到、好友共同好友、去重统计。
1.4 ZSet 有序集合(sorted set)
有序集合,成员 value 不可重复,score 分数可以重复,依靠 score 实现自动排序。
常用核心命令
表格
| 命令 | 作用 |
|---|---|
zadd key score member |
添加元素,设置分数 score |
zrange key 0 -1 [WITHSCORES] |
分数从小到大升序展示;WITHSCORES 同时输出分数 |
zrevrange key 0 -1 [WITHSCORES] |
分数从大到小降序 |
zrank key member |
获取成员升序排名 |
zscore key member |
获取成员对应的分数 |
zrem key member |
删除成员 |
业务场景:排行榜、积分排名、热度榜单。
1.5 Hash 哈希
Hash 结构:hashkey → field‑value,非常适合存储对象,不用把对象序列化为字符串。
常用核心命令
表格
| 命令 | 作用 |
|---|---|
hset hashkey f1 v1 f2 v2 |
设置 hash 的字段与值 |
hget hashkey f1 |
获取单个字段值 |
hgetall hashkey |
获取 hash 下全部 field 和 value |
hmget hashkey f1 f2 |
批量获取多个字段 |
hdel hashkey f1 |
删除指定字段 |
hexists hashkey f1 |
判断字段是否存在 |
业务场景:存储用户信息、商品简要信息,部分字段更新不需要修改整个对象。
对比 String 序列化对象:Hash 可以只更新对象的某一个字段,不用全部重写。
2、Redis 实现消息队列
Redis 可以实现两类消息模型:生产者‑消费者模型 、发布‑订阅 (Pub/Sub) 模型。注意:Redis 实现的队列不是专业 MQ(RabbitMQ/Kafka),有局限性。
2.1 生产者消费者模型(List 实现)
原理:使用 List 作为队列,生产者往队列写数据,消费者读取数据。
- 生产者:
LPUSH queue msg1 msg2消息入队 - 消费者:
BRPOP queue 0阻塞读取消息,有消息立刻返回,没有消息阻塞等待。
流程图:生产者写入 List 队列,多个消费者抢消息,一条消息只会被一个消费者消费。
✅ 优点:阻塞读取,无空轮询,实现简单。 ❌ 缺点:
- 没有消息 ACK 确认机制;消费者拿到消息还没处理完宕机,消息直接丢失。
- 消息堆积会占用大量内存。
- 没有死信队列、重试等高级特性。
2.2 发布订阅 Pub / Sub
- 发布者:
PUBLISH channel msg,向指定频道发布消息 - 订阅者:
SUBSCRIBE channel,监听频道消息;PSUBSCRIBE pattern通配符订阅多个频道。
特点:同一条消息,所有订阅该频道的客户端全部收到,一对多广播。
✅ 适用场景:配置变更通知、集群消息通知、群消息推送。 ❌ 致命缺点:
- 消息不持久化,订阅客户端离线期间的消息直接丢失。
- 没有消息回溯,只能接收订阅之后产生的消息。
💡生产建议:对消息可靠性要求高,不要用 List 和 PubSub 做业务队列,优先使用专业 MQ;仅做简单通知、异步任务可以临时使用。
3、Redis 客户端访问方式
Redis 提供多种访问方式:shell 命令行、shell 脚本、GUI 图形客户端、编程语言客户端 (Python 示例)。
3.1 redis‑cli 命令行客户端
bash
#基础连接
redis-cli
#远程带密码连接
redis-cli -h 192.168.108.172 -p 6379 -a 123456 --no-auth-warning
#集群模式连接,开启自动重定向
redis-cli -c
3.2 Shell 脚本操作 Redis
可以直接在 shell 调用redis‑cli实现批量写入数据。 示例脚本 write_redis.sh
bash
#!/bin/bash
REDIS_HOST="127.0.0.1"
REDIS_PORT=6379
REDIS_DB=0
#循环写入100条key
for i in {0..99}; do
KEY="key:$i"
VALUE="$i"
redis-cli -h "$REDIS_HOST" -p "$REDIS_PORT" -n "$REDIS_DB" SET "$KEY" "$VALUE"
done
echo "写入完成"
赋予执行权限运行
bash
chmod +x write_redis.sh
./write_redis.sh
大批量导入数据优先使用
redis‑cli --pipe管道模式,性能更高。
3.3 GUI 图形客户端 Another‑Redis‑Desktop‑Manager
开源可视化 Redis 管理工具,支持 Windows/Mac/Linux。 使用前提:
- 修改 redis 配置
bind 0.0.0.0允许外部访问 - 设置密码
requirepass xxx - 关闭防火墙或者开放 6379 端口 可以可视化查看 key、编辑数据、查看内存、查看 info 运行状态。
3.4 Python 客户端 redis‑py
- 安装依赖
bash
pip install redis
- 基础连接示例
bash
import redis
#创建连接对象
r = redis.Redis(host='192.168.108.172',port=6379,password="123456",db=0)
#string操作
r.set("color1","red")
val = r.get("color1")
print(val)
#list操作
r.lpush("mylist","nihao")
print(r.lrange("mylist",0,-1))
#hash操作
r.hset("student","name","lisi")
print(r.hgetall("student"))
⚠️注意:redis‑py 默认返回 bytes 字节类型,需要 decode 转字符串。
4、Redis 高可用:主从复制 Master‑Replica (Slave)
4.1 作用
- 数据冗余备份:主节点数据复制到从节点,防止单节点数据丢失
- 读写分离:主节点处理写请求,从节点承担读请求,分担压力。
4.2 核心特性
- 一个 Master 可以拥有多个 Replica 从节点;一个从节点只能归属一个主节点
- 数据单向同步:只能主→从,从节点不会写回主节点
- Master 可读可写;Replica 默认只读,拒绝写操作。
4.3 复制工作原理
- Slave 向 Master 发送
SYNC同步请求 - Master fork 子进程执行 BGSAVE,生成 RDB 快照文件
- Master 把完整 RDB 快照发送给从节点;从节点清空本地数据,加载 RDB,完成全量同步
- 全量同步完成后,Master 持续把后续所有写命令发送给从节点,执行增量同步,保持数据一致。
4.4 配置方式
修改从节点 redis.conf 配置文件
bash
replicaof 192.168.108.10 6379
或者 redis‑cli 运行时动态配置(重启失效)
bash
REPLICAOF 192.168.108.10 6379
#取消主从,把从节点独立成主节点
REPLICAOF NO ONE
4.5 查看主从状态
bash
info replication
4.6 主从复制的痛点
❗没有自动故障转移 。当 Master 宕机,从节点不会自动升级为主节点,需要人工操作
REPLICAOF NO ONE手动切换,业务会中断。 为了解决这个痛点,引入哨兵 Sentinel。
5、Redis Sentinel 哨兵模式
哨兵是独立运行的进程 ,基于主从复制实现自动故障转移高可用 ,不需要人工介入切换主节点。生产环境哨兵部署奇数个(3 个最佳),用来防止脑裂问题。
5.1 Sentinel 四大核心功能
- 监控 Monitoring:持续探测 Master、Slave 节点运行状态。
- 通知 Notification:实例故障后可以通知运维。
- 自动故障转移 Automatic Failover:主节点宕机,自动选举最优从节点升级为新 Master,其他从节点自动指向新主。
- 配置提供者:客户端连接哨兵获取当前真实 master 地址,实现服务动态发现。
注意:哨兵进程不存储业务数据,仅仅做监控和调度。
5.2 故障转移完整流程
- 主观下线 SDOWN:某一个哨兵探测到主节点超时无响应,单方面标记为主观下线。
- 客观下线 ODOWN:超过配置 quorum 数量的哨兵都判定主节点故障,达成共识,标记客观下线,确认主节点真的挂掉。
- 哨兵集群内部通过 Raft 算法,选举一个 Leader 哨兵,由 Leader 执行故障转移。
- Leader 挑选最优从节点(优先级高、复制偏移量大)执行
REPLICAOF NO ONE提升为新 Master。 - 剩余所有从节点重新配置,复制指向新的 master。
- 通过发布订阅通知全部客户端主节点地址变更。
5.3 sentinel.conf 关键配置
bash
#监控主节点,mymaster自定义名称,2代表至少2个哨兵判定故障才触发客观下线
sentinel monitor mymaster 192.168.108.10 6379 2
#判定主观下线超时时间,单位毫秒
sentinel down-after-milliseconds mymaster 30000
启动哨兵
bash
redis-sentinel sentinel.conf &
5.4 哨兵模式局限
✅解决主节点故障自动切换,实现高可用。 ❌不支持数据分片,全部数据还是存储在一套主从,无法突破单机内存上限;适合中小规模业务;海量大数据场景选择 Redis‑Cluster 集群。
6、Redis‑Cluster 集群(3 主 3 从)
Redis3.0 之后官方提供分布式集群方案,去中心化架构,不需要哨兵,同时实现:数据分片(水平扩容)+ 主从副本 + 内置自动故障转移。
标准生产部署:3 主 3 从架构,每个主节点配套一个从节点。
6.1 核心概念:哈希槽 hash slot
Redis 集群一共固定 16384 个哈希槽,编号 0‑16383,是数据分片最小单元。
key 映射槽计算公式: HASH_SLOT = CRC16(key) mod 16384
- 每个主节点分配一部分连续哈希槽;
- 同一个 key,计算出来的槽永远固定,key 只会保存在负责该槽的主节点;
- 客户端访问 key,会计算 key 所属槽,访问对应主节点;不在当前节点返回 MOVED 重定向。
6.2 集群通信 Gossip 协议
集群节点之间通过独立集群总线端口(服务端口 + 10000,例如 6379 集群总线端口 16379)互相通信。 消息类型:PING/PONG 心跳检测、FAIL 节点失效广播、更新槽位拓扑信息。
6.3 故障转移机制
- 集群其他主节点 Gossip 探测某 master 超时无响应,多数主节点投票标记节点 FAIL 客观下线。
- 该故障 master 对应的从节点发起选举,获取集群主节点多数投票。
- 从节点晋升为新 Master,接管原主节点全部哈希槽。
- Gossip 协议广播新集群拓扑,整个集群更新节点状态。
⚠️极端风险:如果一个 Master 和它所有从节点同时宕机,该 master 负责的哈希槽无人接管,整个集群状态变为
cluster_state:fail,整个集群读写全部报错不可用。 生产实践:主节点和它的从节点必须部署到不同服务器,避免机器断电全部挂掉。
6.4 创建 3 主 3 从集群实战
准备 6 台 Redis 实例,开启集群配置redis.conf
bash
bind 0.0.0.0
cluster-enabled yes #开启集群模式
执行创建集群命令,--cluster‑replicas 1代表每个主分配 1 个从节点。
bash
redis-cli --cluster create 192.168.108.21:6379 192.168.108.22:6379 192.168.108.23:6379 192.168.108.24:6379 192.168.108.25:6379 192.168.108.26:6379 --cluster-replicas 1
交互输入yes确认分配槽位。
集群常用查看命令
bash
#查看集群节点详细信息
cluster nodes
#查看集群整体状态
cluster info
客户端连接集群务必加
-c参数,开启自动重定向,否则访问不属于本节点槽的 key 会返回 MOVED 报错。
6.5 Redis Cluster 优缺点
✅优点
- 数据分片,多主并行读写,突破单机内存上限,支持水平扩容;
- 自带主从副本,故障自动转移,不需要哨兵;
- 去中心化,没有单点。
❌缺点
- 多键跨不同哈希槽命令受限,不支持多 key 跨槽事务;
- 主从复制是异步复制,故障转移瞬间可能存在少量数据丢失风险;
- 运维复杂度高于哨兵模式。
适用场景:海量热数据存储,高并发访问,单机内存不够用的业务。
7、Docker 部署 Redis(单机 + compose 集群)
7.1 Docker 单机部署 Redis
bash
# 启动redis容器,端口映射,挂载数据目录持久化RDB
docker run --name redis -p 6379:6379 -d -v /data/redis:/data redis
#进入容器客户端操作
docker exec -it redis redis-cli
7.2 docker‑compose 部署 3 主 3 从 Redis‑Cluster
编写docker‑compose.yml,定义 6 个容器,3 主 3 从。
重点配置:
cluster‑announce‑ip,向外部宣告容器宿主机 IP,否则外部客户端无法访问集群。
bash
version: '2.27'
networks:
redis-cluster-net:
driver: bridge
ipam:
config:
- subnet: 192.168.109.0/24
services:
redis-21:
image: redis:latest
container_name: redis-21
restart: always
ports:
- "6379:6379"
- "16379:16379"
networks:
redis-cluster-net:
ipv4_address: 192.168.109.21
volumes:
- ./node21/data:/data
command: >
redis-server
--bind 0.0.0.0
--port 6379
--cluster-enabled yes
--cluster-config-file nodes.conf
--cluster-node-timeout 5000
--cluster-announce-ip 192.168.109.21
--cluster-announce-port 6379
--cluster-announce-bus-port 16379
--appendonly yes
--protected-mode no
redis-22:
image: redis:latest
container_name: redis-22
restart: always
ports:
- "6380:6379"
- "16380:16379"
networks:
redis-cluster-net:
ipv4_address: 192.168.109.22
volumes:
- ./node22/data:/data
command: >
redis-server
--bind 0.0.0.0
--port 6379
--cluster-enabled yes
--cluster-config-file nodes.conf
--cluster-node-timeout 5000
--cluster-announce-ip 192.168.109.22
--cluster-announce-port 6379
--cluster-announce-bus-port 16379
--appendonly yes
--protected-mode no
redis-23:
image: redis:latest
container_name: redis-23
restart: always
ports:
- "6381:6379"
- "16381:16379"
networks:
redis-cluster-net:
ipv4_address: 192.168.109.23
volumes:
- ./node23/data:/data
command: >
redis-server
--bind 0.0.0.0
--port 6379
--cluster-enabled yes
--cluster-config-file nodes.conf
--cluster-node-timeout 5000
--cluster-announce-ip 192.168.109.23
--cluster-announce-port 6379
--cluster-announce-bus-port 16379
--appendonly yes
--protected-mode no
redis-25:
image: redis:latest
container_name: redis-25
restart: always
ports:
- "6382:6379"
- "16382:16379"
networks:
redis-cluster-net:
ipv4_address: 192.168.109.25
volumes:
- ./node25/data:/data
command: >
redis-server
--bind 0.0.0.0
--port 6379
--cluster-enabled yes
--cluster-config-file nodes.conf
--cluster-node-timeout 5000
--cluster-announce-ip 192.168.109.25
--cluster-announce-port 6379
--cluster-announce-bus-port 16379
--appendonly yes
--protected-mode no
redis-26:
image: redis:latest
container_name: redis-26
restart: always
ports:
- "6383:6379"
- "16383:16379"
networks:
redis-cluster-net:
ipv4_address: 192.168.109.26
volumes:
- ./node26/data:/data
command: >
redis-server
--bind 0.0.0.0
--port 6379
--cluster-enabled yes
--cluster-config-file nodes.conf
--cluster-node-timeout 5000
--cluster-announce-ip 192.168.109.26
--cluster-announce-port 6379
--cluster-announce-bus-port 16379
--appendonly yes
--protected-mode no
redis-24:
image: redis:latest
container_name: redis-24
restart: always
ports:
- "6384:6379"
- "16384:16379"
networks:
redis-cluster-net:
ipv4_address: 192.168.109.24
volumes:
- ./node24/data:/data
command: >
redis-server
--bind 0.0.0.0
--port 6379
--cluster-enabled yes
--cluster-config-file nodes.conf
--cluster-node-timeout 5000
--cluster-announce-ip 192.168.109.24
--cluster-announce-port 6379
--cluster-announce-bus-port 16379
--appendonly yes
--protected-mode no
启动容器
bash
docker compose up -d
进入其中一个容器,执行集群创建命令
bash
docker exec -it redis-21 redis-cli --cluster create \
192.168.109.21:6379 \
192.168.109.22:6379 \
192.168.109.23:6379 \
192.168.109.24:6379 \
192.168.109.25:6379 \
192.168.109.26:6379 \
--cluster-replicas 1
输入yes确认分配槽,集群构建完成。
小结
- Redis 五大数据类型对应不同业务场景,理解结构才能选对类型。
- Redis 队列能力有限,仅适合简单通知;可靠性业务选择专业 MQ。
- 高可用演进路线:单机 → 主从复制(备份读写分离,无自动故障切换) → Sentinel 哨兵(自动故障转移,不分片) → Redis‑Cluster 集群(分片 + 高可用,海量数据)。
- Docker 可以快速部署单机和集群,集群模式重点注意
cluster‑announce‑ip配置,否则外部客户端无法访问。