Redis介绍
Redis(Remote Dictionary Server)是一款由意大利开发者 antirez(Salvatore Sanfilippo)使用 C 语言编写的高性能内存键值数据库。作为 NoSQL 数据库的代表,它采用 key-value 数据模型,支持多种数据结构,包括 String(字符串)、List(双向链表)、Hash(哈希)、Set(集合)和 Sorted Set(有序集合)。Redis 支持数据持久化,可将内存中的数据保存到磁盘,确保数据安全,同时提供主从复制、哨兵、集群等高可用方案。
1. 业务使用场合
Redis 凭借其丰富的数据结构和优异的性能,在多种业务场景中广泛应用:
- 排行榜应用(Sorted Set):如微博热门话题、游戏积分榜等需要取 Top N 操作的场景。
- 最新数据获取(List):获取最新 N 条数据或某个分类的最新数据,如新闻列表、消息流。
- 计数器应用(String):如网站访问量、点赞数、库存扣减等需要原子性增减的场景。
- 社交网络(Set):如获取共同好友、共同关注等集合运算。
- 防攻击系统(Set):基于 IP 的黑白名单过滤,快速判断 IP 是否在名单内。
2. 对比 Memcached
| 特性 | Redis | Memcached |
|---|---|---|
| 数据结构 | 支持 String、List、Hash、Set、Sorted Set 等多种数据结构 | 仅支持简单的 key-value |
| 主从复制 | 支持 master-slave 模式,数据可复制到从节点 | 不支持 |
| 数据持久化 | 支持 RDB 和 AOF 两种持久化方式,重启可恢复数据 | 数据仅存于内存,重启即丢失 |
| 单 value 大小限制 | 最大 512 MB | 最大 1 MB |
| 多核性能 | 单核,小数据性能更高 | 多核,大数据(>100K)性能更优 |
| 内存使用率 | 对于简单 key-value,Memcached 更高;使用 hash 等结构时 Redis 更高 | 简单 key-value 场景内存使用率更高 |
结论:Redis 功能更丰富,适合需要复杂数据结构、持久化、高可用的场景;Memcached 更适合纯粹的、大 value 的缓存场景。在实际应用中,两者的每秒请求处理能力通常都不会成为瓶颈,选择时更应关注内存使用率和业务需求。
一、环境准备
| 角色 | IP 地址 | 说明 |
|---|---|---|
| Master | 192.168.2.123 | 主节点,可读写 |
| Slave1 | 192.168.2.124 | 从节点,只读 |
| Slave2 | 192.168.2.125 | 从节点,只读 |
确保三台机器之间网络互通,可使用 ping 验证:
bash
# 在 2.123 上测试
ping 192.168.2.124
ping 192.168.2.125

关闭防火墙和Selinux
bash
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
配置yum源
bash
# aliyun
curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
# Epel
curl -o /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
# 可选
yum install -y http://rpms.remirepo.net/enterprise/remi-release-7.rpm
准备依赖包
https://download.csdn.net/download/qq_44769717/93022090
前置
1.安装前置依赖
bash
yum install -y gcc gcc-c++ make wget vim

2.创建运行用户与目录规范
bash
useradd -s /sbin/nologin -M redis
mkdir -pv /etc/redis /var/lib/redis/6379 /var/lib/redis/sentinel /var/log/redis /var/run
chown -R redis:redis /etc/redis /var/lib/redis /var/log/redis /var/run

3.配置主机名
cat >>/etc/hosts<<'EOF'
192.168.2.123 node1
192.168.2.124 node2
192.168.2.125 node3
EOF
cat /etc/hosts
ping 192.168.2.123 -c2 &> /dev/null ; echo $?
ping node1 -c2 &> /dev/null ; echo $?
ping 192.168.2.124 -c2 &> /dev/null ; echo $?
ping node2 -c2 &> /dev/null ; echo $?
ping 192.168.2.125 -c2 &> /dev/null ; echo $?
ping node3 -c2 &> /dev/null ; echo $?

二、源码编译安装 Redis(三台服务器均执行)
步骤 1:上传并解压软件
bash
# 上传 redis-7.0.15.tar.gz 到 /opt 目录后执行
cd /opt
tar -xvzf redis-7.0.15.tar.gz
cd redis-7.0.15

步骤 2:编译安装
bash
# 编译安装
make -j$(nproc); echo $?
# 安装到系统路径,全局可用
make install PREFIX=/usr/local/redis;echo $?
# 查看
ln -sv /usr/local/redis/bin/* /usr/local/bin/
# 验证安装:执行 redis-server -v,输出版本号即安装成功。
redis-server -v
redis-cli -v
# 看到以下内容则成功
#Redis server v=7.0.15 sha=00000000:0 malloc=jemalloc-5.2.1 bits=64 build=ca1b32a8ae9fab97
#redis-cli 7.0.15

安装完成后,可执行文件位于 /usr/local/redis/bin:
/usr/local/redis/bin/redis-server 启动服务端
/usr/local/redis/bin/redis-cli 命令行客户端
三、命令行客户端基础操作
bash
cd /usr/local/redis/bin
./redis-cli

进入交互界面后,简单测试:
bash
127.0.0.1:6379> set name test
OK
127.0.0.1:6379> get name
"test"
127.0.0.1:6379> info # 查看系统状态
127.0.0.1:6379> help set # 查看命令帮助

常用 key 相关操作速查:
| 命令 | 作用 |
|---|---|
exists key |
判断 key 是否存在 |
type key |
查看数据类型 |
keys * |
查询所有 key |
expire key seconds |
设置过期时间 |
ttl key |
查看剩余过期时间 |
del key |
删除 key |
select 0-15 |
切换数据库(默认16个) |
dbsize |
查看当前库 key 数量 |
flushdb |
清空当前库 |
案例:
1.创建一个name的key
bash
set name lengmoxi

2.exists name --- 判断 key 是否存在
bash
exists name
exists name2
#返回 1 表示存在,0 表示不存在。

3.type name --- 查看数据类型
bash
type name

4.keys * --- 查询所有 key
bash
keys *
#可模糊匹配
keys na*

5.expire name seconds --- 设置过期时间
bash
expire name 60

6.ttl name --- 查看剩余过期时间
bash
ttl name

7.del name --- 删除 key
bash
del name
get name

8.select 0-15 --- 切换数据库
bash
set name lmx
select 3
get name
# 切到 3 号库后 [3] 提示符变了,0 号库的 name 在这里拿不到
set name lmx2
get name
select 0
get name
# 两个库互不干扰,各存各的 name。


9.dbsize --- 查看当前库 key 数量
bash
dbsize
select 3
dbsize

10.flushdb --- 清空当前库
bash
flushdb
keys *
dbsize

四、五种数据类型操作速览
1. String(字符串)
bash
set key value # 设置
get key # 获取
mset k1 v1 k2 v2 # 批量设置
mget k1 k2 # 批量获取
incr key / decr key # 自增/自减 1
incrby key num # 增加指定值
append key str # 追加内容
strlen key # 获取长度
2. List(双向链表)
bash
lpush key value # 左进
rpush key value # 右进
lpop key # 左出
rpop key # 右出
llen key # 查看长度
lrange key 0 -1 # 查看全部
栈(先进后出):
lpush+lpop;队列(先进先出):lpush+rpop
3. Set(无序集合,不重复)
bash
sadd key v1 v2 # 添加元素
smembers key # 查看所有元素
sinter k1 k2 # 交集
sunion k1 k2 # 并集
sdiff k1 k2 # 差集
srem key v1 # 移除元素
sismember key v # 判断是否存在
smove k1 k2 v # 移动元素到另一个集合
scard key # 统计元素数量
4. ZSet(有序集合,按权重排序)
bash
zadd key score1 v1 score2 v2 # 添加(带权重)
zrange key 0 -1 # 从小到大排序
zrevrange key 0 -1 # 从大到小排序
zscore key v # 查看某个元素的权重
zincrby key num v # 增加/减少权重
5. Hash(哈希)
bash
hmset key f1 v1 f2 v2 # 批量插入
hget key field # 获取单个字段
hmget key f1 f2 # 获取多个字段
hgetall key # 获取所有字段和值
hdel key field # 删除字段
五、Redis主从配置(一主两从)
1.核心配置说明
所有Redis节点统一设置访问密码,保证安全
所有节点同时配置masterauth:故障转移后原主节点会自动变为从节点,无需手动修改配置
开启RDB+AOF双持久化,保证数据安全
2.主节点(node1)配置
bash
# 在node1创建Redis配置文件:
cat > /etc/redis/redis_6379.conf << 'EOF'
# 监听地址,允许内网访问,生产建议替换为具体内网IP
bind 0.0.0.0
port 6379
# 后台守护进程运行
daemonize yes
pidfile /var/run/redis_6379.pid
logfile /var/log/redis/redis_6379.log
# 数据持久化目录
dir /var/lib/redis/6379
# 访问密码,生产环境请修改为复杂密码
requirepass lengmoxi
# 主从同步认证密码,与上面密码完全一致
masterauth lengmoxi
# RDB持久化策略
save 900 1
save 300 10
save 60 10000
rdbcompression yes
# AOF持久化
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
# 从节点默认只读
replica-read-only yes
EOF

3.从节点(node2/node3)配置
node2和node3配置与主节点几乎完全一致,仅新增一行指定主节点地址。以node2为例,node3操作完全相同:
bash
cat > /etc/redis/redis_6379.conf << 'EOF'
bind 0.0.0.0
port 6379
daemonize yes
pidfile /var/run/redis_6379.pid
logfile /var/log/redis/redis_6379.log
dir /var/lib/redis/6379
requirepass lengmoxi
masterauth lengmoxi
save 900 1
save 300 10
save 60 10000
rdbcompression yes
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
replica-read-only yes
# 唯一新增:指定初始主节点的IP和端口
replicaof 192.168.2.123 6379
EOF
注意:将replicaof后的IP替换为你node1的实际IP。

4.配置Systemd服务(所有节点)
配置系统服务,实现开机自启、后台稳定运行:
bash
cat > /usr/lib/systemd/system/redis_6379.service << 'EOF'
[Unit]
Description=Redis 6379 Service
After=network.target
[Service]
Type=forking
User=redis
Group=redis
ExecStart=/usr/local/bin/redis-server /etc/redis/redis_6379.conf
ExecStop=/usr/local/bin/redis-cli -a lengmoxi -p 6379 shutdown
Restart=always
RestartSec=5
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF

5.启动Redis并验证主从同步
所有节点启动Redis服务
bash
systemctl daemon-reload
systemctl start redis_6379
systemctl enable redis_6379
systemctl restart redis_6379
验证主节点状态(node1执行)
bash
redis-cli -a lengmoxi info replication
主Msater

从slave


出现master_link_status:up说明主从同步成功,若为down请检查网络、防火墙、密码是否一致。
bash
redis-cli -a lengmoxi info replication | grep 'master_link_status'

六、配置哨兵(一主两从三哨兵)
1.所有节点Sentinel配置
三台机器执行完全相同的配置,仅需修改主节点IP为你的node1地址:
bash
cat > /etc/redis/sentinel_26379.conf << 'EOF'
# Sentinel端口
port 26379
bind 0.0.0.0
daemonize yes
pidfile /var/run/redis-sentinel_26379.pid
logfile /var/log/redis/sentinel_26379.log
# 工作目录,存放运行时自动更新的配置
dir /var/lib/redis/sentinel
# 监控主节点:名称mymaster + 初始主节点IP端口 + quorum=2
sentinel monitor mymaster 192.168.2.123 6379 2
# 主节点认证密码
sentinel auth-pass mymaster lengmoxi
# 主观下线超时:30秒无响应判定主观下线
sentinel down-after-milliseconds mymaster 30000
# 故障转移后并行同步从节点数
sentinel parallel-syncs mymaster 1
# 故障转移超时时间:3分钟
sentinel failover-timeout mymaster 180000
# 关闭保护模式,允许跨节点通信
protected-mode no
EOF
修改了配置文件,要重启生效(后面设置了systemctl)
bash
systemctl restart redis-sentinel_26379
mymaster`不是 node1 的主机名,也不是服务器的主机名/IP,它是 Sentinel 集群给「这一整套被监控的主从集群」起的自定义逻辑名称(集群标识名),和服务器 hostname 没有任何对应关系。

2.配置Sentinel系统服务(所有节点)
bash
cat > /usr/lib/systemd/system/redis-sentinel_26379.service << 'EOF'
[Unit]
Description=Redis Sentinel 26379 Service
After=network.target redis_6379.service
[Service]
Type=forking
User=redis
Group=redis
ExecStart=/usr/local/bin/redis-sentinel /etc/redis/sentinel_26379.conf
ExecStop=/usr/local/bin/redis-cli -p 26379 shutdown
Restart=always
RestartSec=5
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF

3.修复权限
bash
# 1. 修正属主
chown redis:redis /etc/redis/sentinel_26379.conf
# 2. 确保目录也对 redis 可写(避免后面 pid/log )
chown -R redis:redis /var/log/redis
chown -R redis:redis /var/lib/redis/sentinel
# 顺手把 pid 目录也保证存在
mkdir -p /var/lib/redis/sentinel
chown redis:redis /var/lib/redis/sentinel
# 3. 重载并启动(如果之前反复 failed,最好清一次 systemd 状态)
systemctl reset-failed redis-sentinel_26379.service
systemctl daemon-reload
systemctl start redis-sentinel_26379
systemctl restart redis-sentinel_26379
systemctl status redis-sentinel_26379 -l

4.启动Sentinel集群并验证
(1)所有节点启动哨兵服务
bash
systemctl daemon-reload
systemctl start redis-sentinel_26379
systemctl enable redis-sentinel_26379
systemctl restart redis-sentinel_26379
systemctl status redis-sentinel_26379 -l
主Master

从salve1

从salve2

(2)验证哨兵集群状态(任意节点执行)
bash
redis-cli -p 26379 info sentinel
预期输出核心信息:
master0:name=mymaster,status=ok,address=192.168.2.123:6379,slaves=2,sentinels=3
关键验证点:sentinels=3说明三个哨兵已互相发现并组成集群,slaves=2说明已识别所有从节点。
主Msater:

从salve1

从salve2

查询当前主节点地址
bash
redis-cli -p 26379 sentinel get-master-addr-by-name mymaster
正常返回初始主节点的IP和端口6379
正常返回初始主节点的IP和端口6379

七、故障转移
当前环境的路径和密码:
| 项目 | 值 |
|---|---|
| Master 初始 | 192.168.2.123 |
| Slave | 192.168.2.124、192.168.2.125 |
| 密码 | lengmoxi |
| Sentinel 端口 | 26379 |
| 配置目录 | /etc/redis/ |
| systemd 服务 | redis_6379、redis-sentinel_26379 |
前置准备:在 2.125 上开启实时日志监控
bash
# 清空旧日志
> /var/log/redis/sentinel_26379.log
# 开启实时监控
tail -f /var/log/redis/sentinel_26379.log
保持这个终端窗口不要关,稍后故障转移的所有日志都会实时滚动出来。

1.确认初始状态(Master = 2.123)
在任意节点执行:
bash
redis-cli -p 26379 sentinel get-master-addr-by-name mymaster
预期返回:
192.168.2.123
6379

再确认整体集群状态:
bash
redis-cli -p 26379 info sentinel | grep master0
预期输出:
master0:name=mymaster,status=ok,address=192.168.2.123:6379,slaves=2,sentinels=3
三项关键指标:status=ok、slaves=2、sentinels=3,确认无误后开始测试。

2.模拟 Master 宕机
在 Master 机器(192.168.2.123)上或用 SSH 远程执行:
bash
# 方式一:通过 systemd 停服务(推荐,你在用 systemd)
systemctl stop redis_6379
# 方式二:通过 redis-cli 远程关闭
redis-cli -h 192.168.2.123 -a lengmoxi shutdown

验证已停:
bash
redis-cli -h 192.168.2.123 -a lengmoxi ping
# 返回 Could not connect 即为已停止

3.观察日志(在 2.125 的 tail 窗口)
10 秒左右,日志中会依次出现以下关键行:
+sdown master mymaster 192.168.2.123 6379 ← 主观下线
+odown master mymaster 192.168.2.123 6379 #quorum 3/2 ← 客观下线(≥2票)
+vote-for-leader xxxxx 1 ← 开始投票
+elected-leader master mymaster 192.168.2.123 6379 ← Leader 选出
+failover-state-select-slave master mymaster ... ← 选择新 Master
+selected-slave slave 192.168.2.124:6379 ... ← 选定 124 为新 Master
+switch-master mymaster 192.168.2.123 6379 192.168.2.124 6379 ← 切换完成

4.验证 Sentinel 已切换
bash
redis-cli -p 26379 info sentinel | grep master0
现在 address 应该已变为:
master0:name=mymaster,status=ok,address=192.168.2.124:6379,slaves=2,sentinels=3
address从 2.123 变成了 2.124,说明故障转移成功。

命令行快速确认三件套:
bash
# 当前 Master 是谁
redis-cli -p 26379 sentinel get-master-addr-by-name mymaster
# 所有 Slave 列表
redis-cli -p 26379 sentinel slaves mymaster
# Master 详细状态(含切换次数)
redis-cli -p 26379 sentinel master mymaster
5.在新 Master(2.124)上验证主从状态
bash
redis-cli -h 192.168.2.124 -a lengmoxi info replication
预期看到:
role:master
connected_slaves:1
slave0:ip=192.168.2.125,port=6379,state=online,...
role:master✅ 124 已提升为 Masterconnected_slaves:1--- 125 已跟随新 Master(123 还没启动,所以是 1)

6.启动原来的 Master(2.123)
bash
# 在 192.168.2.123 上
systemctl start redis_6379
验证已启动:
bash
redis-cli -h 192.168.2.123 -a lengmoxi ping
# 返回 PONG

7.验证原 Master 已变为 Slave
bash
redis-cli -h 192.168.2.123 -a lengmoxi info replication
预期看到:
role:slave
master_host:192.168.2.124
master_port:6379
master_link_status:up
这说明 2.123 重新上线后,自动变成了新 Master(2.124)的 Slave。

8.最终全局验证
在新 Master 上确认两从已齐:
bash
redis-cli -h 192.168.2.124 -a lengmoxi info replication
预期:
role:master
connected_slaves:2
slave0:ip=192.168.2.125,port=6379,state=online,...
slave1:ip=192.168.2.123,port=6379,state=online,...

Sentinel 全局确认:
bash
redis-cli -p 26379 info sentinel | grep master0
预期:
master0:name=mymaster,status=ok,address=192.168.2.124:6379,slaves=2,sentinels=3

故障转移全流程总结
| 阶段 | 事件 | Master 角色 |
|---|---|---|
| 初始 | 正常运作 | 2.123 |
| 宕机 | systemctl stop redis_6379 |
--- |
| 10s 内 | +sdown → +odown → 选举 → 切换 | 2.124 |
| 启动旧 Master | systemctl start redis_6379 |
2.124(2.123 变 Slave) |
| 恢复后 | 一主两从正常运行 | 2.124 |
注意事项
- 恢复环境 :如果想重新做一次测试,需要先把 2.123 恢复为 Master。最简单的方式是用
sentinel failover mymaster手动触发一次转移,让 2.123 重新成为 Master,然后再做上述测试 - 日志解读 :关键看日志中的
+sdown→+odown→+switch-master这五条线,任何一步缺失都说明哨兵集群有问题 - 密码:所有 Redis 节点和 Sentinel 节点密码必须一致,否则故障转移时会因认证失败而中断