redis笔记(二)

redis集群

Redis集群是一个分布式、去中心化的Redis实现方案,它通过将数据自动分片(Sharding)存储在多个节点上,并提供内置的主从复制、故障检测和故障转移机制,来实现:

  1. 大规模数据存储: 突破单机内存限制,支持海量数据。
  2. 高性能: 通过分片将负载分散到多个节点,提高整体吞吐量。
  3. 高可用性: 当主节点故障时,其从节点能自动升级为主节点,继续提供服务,最大限度减少中断。
  4. 无缝扩展: 可以相对容易地通过添加新节点来增加集群的容量或性能。

核心机制:

  • 数据分片: 使用哈希槽(Hash Slot,共16384个)将数据划分。每个主节点负责一部分槽位。
  • 节点通信: 节点间通过Gossip协议交换信息(如节点状态、槽位映射)。
  • 故障转移: 基于Raft共识算法(选举新主节点),由主节点投票决定故障主节点的从节点升级。
  • 客户端交互: 客户端通常连接任意节点。如果请求的键不在该节点负责的槽位上,节点会返回重定向指令(MOVED/ASK),告知客户端应连接的正确节点。

简而言之:Redis集群是Redis官方提供的,用于构建大规模、高性能、高可用Redis服务的分布式解决方案。

创建Redis集群

集群规划

至少6台主机(3主3从),要求:

  • 所有节点禁用数据持久化(无save配置)
  • 无密码(省略requirepass
准备虚拟机

|---------|---------------|--------|-----------|
| 主机名 | IP 地址 | 端口 | 角色 |
| redis51 | 192.168.88.51 | 6379 | Redis 服务器 |
| redis52 | 192.168.88.52 | 6379 | Redis 服务器 |
| redis53 | 192.168.88.53 | 6379 | Redis 服务器 |
| redis54 | 192.168.88.54 | 6379 | Redis 服务器 |
| redis55 | 192.168.88.55 | 6379 | Redis 服务器 |
| redis56 | 192.168.88.56 | 6379 | Redis 服务器 |

配置所有节点
复制代码
# 每台主机执行相同操作
[root@redis51 ~]# yum -y install redis
[root@redis51 ~]# vim /etc/redis.conf
bind <本机IP>        # 如 192.168.88.51,或者0.0.0.0监听本地所有ip
port 6379
cluster-enabled yes                   # 启用集群
cluster-config-file nodes-6379.conf   # 集群配置文件
cluster-node-timeout 15000             # 节点超时时间(ms)
# 修改一个配置文件bind 0.0.0.0,其他远程拷贝过去
[root@redis51 ~]# for i in {52..56}; do scp /etc/redis.conf 192.168.88.$i:/etc/; done
[root@redis51 ~]# for i in {52..56}; do ssh root@192.168.88.$i "systemctl restart redis"; done
[root@redis51 ~]# systemctl start redis
[root@redis51 ~]# ss -antlpu | grep redis-server  # 应看到6379和16379端口
创建集群(任意节点执行)
复制代码
# CLUSTER RESET   # 重置集群状态(默认 HARD 模式)
[root@redis51 ~]# redis-cli --cluster create \
  192.168.88.51:6379 192.168.88.52:6379 \
  192.168.88.53:6379 192.168.88.54:6379 \
  192.168.88.55:6379 192.168.88.56:6379 \
  --cluster-replicas 1  # 1个从节点/主节点

  >>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.88.54:6379 to 192.168.88.51:6379
Adding replica 192.168.88.55:6379 to 192.168.88.52:6379
Adding replica 192.168.88.56:6379 to 192.168.88.53:6379
M: 0a9801b5e6c3041da90bb77d54b8b7ae0a39cda6 192.168.88.51:6379
   slots:[0-5460],[15629] (5461 slots) master
M: 64495886f286b7cd54f8206d0dbc2e89f7eaed81 192.168.88.52:6379
   slots:[5461-10922],[15629] (5462 slots) master
M: 08573c46bf41de51ca46cf765a61ab65f626300e 192.168.88.53:6379
   slots:[10923-16383] (5461 slots) master
S: bd72c965735b34aa51bc98fbaaac77e2789bec90 192.168.88.54:6379
   replicates 0a9801b5e6c3041da90bb77d54b8b7ae0a39cda6
S: 8728362b23b055efcf2ebe7a2b5764b304a21ef7 192.168.88.55:6379
   replicates 64495886f286b7cd54f8206d0dbc2e89f7eaed81
S: bf040fb40793c668cdf8495cee5a76200e6e3e0a 192.168.88.56:6379
   replicates 08573c46bf41de51ca46cf765a61ab65f626300e
Can I set the above configuration? (type 'yes' to accept): 

输出提示分配Slot和主从关系,输入 yes 确认。

查看集群信息
复制代码
[root@redis51 ~]# redis-cli --cluster info 192.168.88.51:6379
192.168.88.51:6379 (8cc0228e...) -> 0 keys | 5461 slots | 1 slaves.
192.168.88.53:6379 (08573c46...) -> 0 keys | 5461 slots | 1 slaves.
192.168.88.52:6379 (64495886...) -> 1 keys | 5462 slots | 1 slaves.
[OK] 1 keys in 3 masters.
0.00 keys per slot on average.
# 更详细的信息
[root@redis51 ~]# redis-cli --cluster check  192.168.88.51:6379
192.168.88.51:6379 (8cc0228e...) -> 0 keys | 5461 slots | 1 slaves.
192.168.88.53:6379 (08573c46...) -> 0 keys | 5461 slots | 1 slaves.
192.168.88.52:6379 (64495886...) -> 1 keys | 5462 slots | 1 slaves.
[OK] 1 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.88.51:6379)
M: 8cc0228e6f2a036840c951d853fb1ef0bbfa9bd7 192.168.88.51:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 08573c46bf41de51ca46cf765a61ab65f626300e 192.168.88.53:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: bd72c965735b34aa51bc98fbaaac77e2789bec90 192.168.88.54:6379
   slots: (0 slots) slave
   replicates 8cc0228e6f2a036840c951d853fb1ef0bbfa9bd7
M: 64495886f286b7cd54f8206d0dbc2e89f7eaed81 192.168.88.52:6379
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: bf040fb40793c668cdf8495cee5a76200e6e3e0a 192.168.88.56:6379
   slots: (0 slots) slave
   replicates 08573c46bf41de51ca46cf765a61ab65f626300e
S: 8728362b23b055efcf2ebe7a2b5764b304a21ef7 192.168.88.55:6379
   slots: (0 slots) slave
   replicates 64495886f286b7cd54f8206d0dbc2e89f7eaed81
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

测试Redis集群

连接集群(自动重定向)

数据会根据算法存在某一个主节点上,数据在对应的从节点上有。

复制代码
[root@redis51 ~]# redis-cli -c -h 192.168.88.51 -p 6379  # -c 启用集群模式
192.168.88.51:6379> set school tarena
-> Redirected to 192.168.88.52:6379(Slot 8455) # 数据分片存储

# 根据crc算法分配数据存放节点
192.168.88.55:6379> set school tarena
-> Redirected to slot [8455] located at 192.168.88.52:6379
OK
192.168.88.52:6379> set teacher zhsan
-> Redirected to slot [12541] located at 192.168.88.53:6379
OK
192.168.88.53:6379> set class one
-> Redirected to slot [7755] located at 192.168.88.52:6379
OK

# 查看集群中所有数据
[root@host51 ~]# redis-cli --cluster call 192.168.88.56:6379 keys \*
>>> Calling keys *
192.168.88.56:6379: teacher
192.168.88.55:6379: school
class
192.168.88.54:6379: 
192.168.88.53:6379: teacher
192.168.88.52:6379: class
school
192.168.88.51:6379: 
[root@host51 ~]# 
验证主从复制
复制代码
# 在Slave节点查看数据(应自动同步)
redis-cli -c -h 192.168.88.55 -p 6379  # host55是host51的Slave
192.168.88.55:6379> keys *  # 应看到host51的数据
测试高可用
复制代码
# 停止Master(host53)
ssh host53 'systemctl stop redis'

# 查看集群状态(原Slave host54升主)
redis-cli --cluster info 192.168.88.51:6379
# 恢复host53,自动变为新Master的Slave

配置主从复制

什么是主从复制

主机数据更新后根据配置和策略, 自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主

Redis主从同步

多个Redis服务器数据实时同步的解决方案

工作原理

1、从服务器向主服务器发送sync命令

2、主服务器接收到sync命令后,开辟子进程,触发rdb持久化对已有数据做完整备份

3、主服务器同时开辟内存buffer空间,收集当前执行的所有的写操作的指令

4、完整备份完成后将rdb文件发送给从服务器

5、从服务器热加载rdb文件实现数据恢复

6、接收主服务器发送过来的buffer区域内记录的写操作的指令并进行复现

环境准备

准备三台linux虚拟机,具体配置如图,分别在三台虚拟机中安装redis并启动。

|---------------|---------|-----------|-----------------|
| IP 地址 | 主机名 | 角色 | 说明 |
| 192.168.88.61 | redis61 | Redis 服务器 | 关闭 selinux 和防火墙 |
| 192.168.88.62 | redis62 | Redis 服务器 | 关闭 selinux 和防火墙 |
| 192.168.88.63 | redis63 | Redis 服务器 | 关闭 selinux 和防火墙 |

复制代码
[root@redis61 ~]# yum -y install redis
[root@redis61 ~]# systemctl start redis
[root@redis61 ~]# ss -antlpu | grep redis # 查看redis端口信息

配置一主一从

主服务器配置(host61):

复制代码
# 修改redis配置文件,更改监听ip及地址
[root@redis61 ~]# vim /etc/redis.conf
bind 192.168.88.61
port 6379
# 重启redis
[root@redis61 ~]# systemctl restart redis
# 连接redis命令控制台
[root@redis61 ~]# redis-cli -h 192.168.88.61 -p 6379
# 验证角色为master
192.168.88.61:6379> info replication

# 也可以直接在linux终端以非交互式执行redis命令
[root@redis61 ~]# redis-cli  info replication

从服务器配置(host62):

复制代码
[root@redis62 ~]# vim /etc/redis.conf
bind 192.168.88.62
port 6379
[root@redis62 ~]# systemctl restart redis
[root@redis62 ~]# redis-cli -h 192.168.88.62 -p 6379

# 将当前Redis节点设置为192.168.88.61:6379的从节点(副本节点)
# 配置后当前节点会从主节点复制数据,实现主从复制架构
192.168.88.62:6379> replicaof 192.168.88.61 6379

# 将当前的Redis配置(包括刚才设置的主从关系)写入到配置文件中
# 确保Redis重启后配置依然生效,避免重启后丢失主从配置
192.168.88.62:6379> config rewrite

192.168.88.62:6379> info replication  # 验证角色为slave

验证可以再主服务器写入数据,在从服务器上确认数据是否同步。

配置一主多从

将host63加入为host61的从服务器

复制代码
[root@redis63 ~]# vim /etc/redis.conf
bind 192.168.88.63
port 6379
[root@redis63 ~]# systemctl restart redis
[root@redis63 ~]# redis-cli -h 192.168.88.62 -p 6379

# 将当前Redis节点设置为192.168.88.61:6379的从节点(副本节点)
# 配置后当前节点会从主节点复制数据,实现主从复制架构
192.168.88.63:6379> replicaof 192.168.88.61 6379

# 将当前的Redis配置(包括刚才设置的主从关系)写入到配置文件中
# 确保Redis重启后配置依然生效,避免重启后丢失主从配置
192.168.88.63:6379> config rewrite

192.168.88.63:6379> info replication  # 验证角色为slave

配置主从从(级联)结构

将host63改为host62的从服务器

从服务器默认是只读的

复制代码
[root@redis63 ~]# redis-cli -h 192.168.88.63 -p 6379
192.168.88.63:6379> replicaof no one  # 重置为独立服务器

# 可以修改配置文件,
[root@redis63 ~]# vim /etc/redis.conf
# replicaof <masterip> <masterport>
286 replicaof 192.168.88.62 6379
[root@redis63 ~]# systemctl restart redis

# 也可以命令行配置master
192.168.88.63:6379> replicaof 192.168.88.62 6379
# 此命令会在/etc/redis.conf配置文件中追加一行 replicaof 192.168.88.61 6379
192.168.88.63:6379> config rewrite

配置带验证的主从复制

主机host61设置Redis密码为123456

从机host62配置连接主机的密码

主服务器设置密码:/etc/redis.conf 507行

复制代码
[root@redis61 ~]# redis-cli -h 192.168.88.61 -p 6379
192.168.88.61:6379> config set requirepass 123456
# 此命令会在/etc/redis.conf配置文件中追加一行requirepass "123456"
192.168.88.61:6379> config rewrite

从服务器配置密码:

复制代码
[root@redis62 ~]# redis-cli -h 192.168.88.62 -p 6379
192.168.88.62:6379> config set masterauth 123456
# 此命令会在/etc/redis.conf配置文件中追加一行masterauth "123456"
192.168.88.62:6379> config rewrite
192.168.88.62:6379> info replication  # 验证状态为up

配置哨兵服务

准备新虚拟机redis69配置ip为192.168.88.69,安装redis,运行哨兵服务。测试故障切换

沿用之前redis61,redis62的主从配置。

哨兵配置(redis69):

复制代码
[root@redis69 ~]# vim /etc/redis-sentinel.conf
# 绑定的IP地址,指定Sentinel实例监听的网络接口
bind 192.168.88.69

# 端口号,Sentinel实例运行的端口(默认26379)
port 26379

# 是否以守护进程模式运行(后台运行),yes表示启用守护进程模式
daemonize yes

# 监控主服务器配置:
# 格式:sentinel monitor <主服务器名称> <主服务器IP> <主服务器端口> <quorum数量>
# mymaster:自定义的主服务器名称
# 192.168.88.61 6379:被监控的主服务器IP和端口
# 1:表示至少需要1个Sentinel同意,才能判定主服务器主观下线并进行故障转移
sentinel monitor mymaster 192.168.88.61 6379 1

# 指定主服务器及其从服务器的密码:sentinel auth-pass <master-name> <password>
sentinel auth-pass mymaster YourSuperStrongPassword123!

[root@redis69 ~]# systemctl start redis-sentinel

测试故障切换:

  • 停止redis61的Redis服务
  • 检查redis62是否升级为master
  • 重启redis61,验证其自动变为slave

redis数据持久化

Redis 数据持久化:

概念:Redis 数据备份的方式,不是把 Redis 的数据存放到硬盘!!!

分类:

rdb (拍照片):定期将内存中的 Redis 数据快照到硬盘

特性:速度快,文件体积小,适合大规模数据备份恢复,但丢失数据量大

触发方式:

1、手工执行 bgsave 命令

2、Redis 服务正常退出

3、触发配置文件中的 save 规则

aof (写日记):记录 Redis 执行过的所有的写操作指令

特性:速度慢,文件体积大,数据备份恢复速度慢,但数据丢失量小

RDB

RDB 文件是 Redis 在某个时间点生成的数据集的二进制快照。

备份 RDB 文件本质上就是复制这个 .rdb文件(默认名为 dump.rdb)到一个安全的位置(例如:不同的磁盘、网络存储、云存储等)。

恢复则是用这个备份的 .rdb文件替换当前 Redis 实例使用的 .rdb文件,并在 Redis 重启时加载它。

修改存盘频率:

复制代码
[root@redis61 ~]# vim /etc/redis.conf
save 120 10  # 设置存盘间隔为120秒且10个key改变时自动存盘
[root@redis61 ~]# rm -rf /var/lib/redis/*
[root@redis61 ~]# systemctl start redis

触发存盘

复制代码
192.168.88.61:6379> mset a 1 b 2 c 3 d 4 x 1 y 2 z 3 k 6 i 7 z 9 f 22 zz 99 cc 66

使用RDB文件数据备份与恢复:

复制代码
[root@redis61 ~]# cp /var/lib/redis/dump.rdb /opt/
[root@redis61 ~]# redis-cli flushall  # 清空数据

# 先停再拷贝
[root@redis61 ~]# systemctl stop redis
[root@redis61 ~]# cp /opt/dump.rdb /var/lib/redis/
[root@redis61 ~]# chown -R redis:redis /var/lib/redis/
[root@redis61 ~]# systemctl start redis

AOF

AOF(Append Only File)备份的本质与 RDB 完全不同。它不是保存数据的快照,而是记录对数据库状态进行修改的所有写命令,并以日志的形式追加存储到文件中。

启用AOF:

复制代码
# 热部署,无需重启服务,自动配置文件里添加aof-use-rdb-preamble yes
127.0.0.1:6379> CONFIG set appendonly yes
OK
127.0.0.1:6379> config rewrite
OK
127.0.0.1:6379> mset a 1 b 2 c 3

使用AOF文件备份与恢复:

复制代码
[root@redis70 ~]# cp /var/lib/redis/appendonly.aof /opt/
[root@redis70 ~]# redis-cli flushall
OK
[root@redis70 ~]# cat /var/lib/redis/appendonly.aof | wc -l
30
[root@redis70 ~]# systemctl stop redis
[root@redis70 ~]# cp /opt/appendonly.aof /var/lib/redis/
cp: overwrite '/var/lib/redis/appendonly.aof'? y
[root@redis70 ~]# cat /var/lib/redis/appendonly.aof | wc -l
27
[root@redis70 ~]# chown -R redis:redis /var/lib/redis/appendonly.aof 
[root@redis70 ~]# systemctl start redis

如果启用了 AOF (appendonly yes),Redis 重启时默认优先加载 AOF 文件,因为 AOF 通常能保证更高的数据持久性(记录所有写操作)。这就是为什么在恢复 RDB 时建议临时禁用或移除 AOF 文件,否则你恢复的 RDB 数据会被 AOF 文件中的数据覆盖掉!

相关推荐
Java小Y4 分钟前
redis(2)-java客户端使用(IDEA基于springboot)
java·redis·intellij-idea
liulanba19 分钟前
Redis 缓存问题详解及解决方案
redis·缓存·oracle
Zfox_5 小时前
Redis应⽤-缓存与分布式锁
服务器·数据库·redis·分布式·缓存
文丑颜不良啊20 小时前
Redis 主从复制
redis·redis 主从复制
我们从未走散1 天前
Redis学习笔记-----Redis内存回收
java·redis·笔记·学习
小小工匠1 天前
Redis - 使用 Redis HyperLogLog 进行高效基数统计
redis·hyperloglog
@Jackasher1 天前
Redis如何实现一个分布式锁?
redis·分布式·wpf
Volunteer Technology1 天前
openresty-lua-redis案例
redis·lua·openresty
小李同学_LHY1 天前
Redis一站式指南二:主从模式高效解决分布式系统“单点问题”
java·数据库·redis·缓存