1.主从模式(Master-Slave)
1.1主从复制原理
主从复制是redis的一种基本的集群方式,它通过将一个Redis节点(主节点)的数据复制到一个或多个其他Redis节点来实现数据的冗余和备份
主节点负责处理客户端的写操作,同时从节点回自动同步主节点的数据。客户端可以从从节点读取数据,实现读取分离,提高系统效能。
1.2主从复制的优缺点
优点:
- 配置简单、易于实现
- 实现了数据冗余,提高数据可靠性
- 读写分离,提高系统能效性
缺点:
- 主节点单点故障时,需要手动切换到从节点,故障恢复时间长,并且整个redis集群的写操作将中断
- 写操作无法负载均衡,主节点承担所有的写操作,可能成为性能瓶颈
- 无法实现数据分片,受单节点内存限制
- 数据延迟,主从节点的操作是异步的,这种方式可能会使得从节点的数据落后于主节点,产生读写不一致的问题,在高并发或网络延迟的场景下,这种问题会更加显著
- 复制性能开销,每个从节点都需要从主节点读取数据,同步复制会增加主节点的开销
- 维护成本增加
- 网络分区问题,如果主从节点网络中断,那么从节点无法继续同步主节点的数据
1.3主从复制场景应用
适用于以下场景:
- 数据备份和容灾恢复
- 读写分离
- 在线升级和扩展
1.4实现
实现主从分离的集群模式,在主节点的conf文件不需要添加什么,在从节点中需要配置以下选项
port 6380
masterauth MelonTe #连接主节点的密码
repicaof 127.0.0.1 6379 #监听主节点
在docker使用以下命令,创建从节点
docker run -d --name myredisslave -p 6380:6380 -v C:/Users/minat/Desktop/Note/StudyNote/vocation/redis2.conf:/usr/local/etc/redis/redis.conf redis:7.0.12 redis-server /usr/local/etc/redis/redis.conf
使用docker进行主从分离时,监听的主节点IP需要通过该docker指令查看
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redis-master
成功启动主从分离后,在主节点使用以下命令查询是否开通成功:
INFO replication
成功
此时我们在主节点写一个key,通过以下命令连接从节点
redis-cli -h 127.0.0.1 -p 6380
此时进行Get,可以查看成功
2.哨兵模式(Sentinel)
2.1原理
哨兵模式是在主从复制基础上加入了哨兵节点,实现了自动故障转移。哨兵是一种特殊的Redis节点,它会监控主节点和从节点的运行状态,当主节点发生故障时,哨兵节点会自动从从节点中选出一个新的主节点,并通知其他从节点和客户端,实现故障转移。
2.2优缺点
优点:
- 自动故障转移,提高系统的高可用性
- 具有主从分离的所有优点
缺点:
- 配置和管理会更复杂
- 无法实现数据分片,受单节点内存限制
2.3哨兵模式场景应用
- 高可用性要求较高的场景:通过自动故障转移实现高可用性
- 数据备份和容灾恢复
2.4实现
配置redis-master.conf文件如下
bind 0.0.0.0
protected-mode no
port 6379
requirepass MelonTe
实现docker命令启动该redis,并且加入到redis-net同一个网络中
docker run -d --name redis-master --network redis-net -p 6379:6379 -v C:/Users/minat/Desktop/Note/StudyNote/vocation/redis-master.conf:/usr/local/etc/redis/redis.conf redis:7.0.12 redis-server /usr/local/etc/redis/redis.conf
配置redis-slave1.conf如下
bind 0.0.0.0
protected-mode no
port 6380
replicaof redis-master 6379
masterauth MelonTe
启动redis从节点:
docker run -d --name redis-slave1 --network redis-net -p 6380:6380 -v C:/Users/minat/Desktop/Note/StudyNote/vocation/redis-slave1.conf:/usr/local/etc/redis/redis.conf redis:7.0.12 redis-server /usr/local/etc/redis/redis.conf
同理配置一个slave2出来
接着,需要配置sentinel.conf
#Sentinel 通过这个端口来接收其他 Sentinel、客户端和 Redis 实例的通信。
port 26379
# sentinel monitor 被监控主节点名称 主节点IP 主节点端口 quorum表示至少有几个Sentinel认为主节点不可用时,进行故障转移
sentinel monitor redis-master (HOST) 6379 2
sentinel auth-pass mymaster MelonTe
#如果Sentine在5000ms内无法和主节点进行通信,则认为该节点失效
sentinel down-after-milliseconds redis-master 5000
#在故障转移(failover)期间,最多允许 1 个从节点同时与新的主节点进行同步。
sentinel parallel-syncs mymaster 1
#在这个时间范围内会尝试进行故障转移。如果在此时间内无法完成故障转移,则会认为故障转移失败。
sentinel failover-timeout redis-master 10000
启动3个sentinel容器,确保在出现故障时,Sentinel可以达到投票所需的法定人数。
docker run -d --name redis-sentinel1 --network redis-net -p 26379:26379 -v C:/Users/minat/Desktop/Note/StudyNote/vocation/sentinel.conf:/usr/local/etc/redis/sentinel.conf redis:7.0.12 redis-sentinel /usr/local/etc/redis/sentinel.confdocker run -d --name redis-sentinel2 --network redis-net -p 26380:26379 -v C:/Users/minat/Desktop/Note/StudyNote/vocation/sentinel.conf:/usr/local/etc/redis/sentinel.conf redis:7.0.12 redis-sentinel /usr/local/etc/redis/sentinel.confdocker run -d --name redis-sentinel3 --network redis-net -p 26381:26379 -v C:/Users/minat/Desktop/Note/StudyNote/vocation/sentinel.conf:/usr/local/etc/redis/sentinel.conf redis:7.0.12 redis-sentinel /usr/local/etc/redis/sentinel.conf
全部容器启动成功后,使用该指令进行检测
docker exec -it redis-sentinel1 redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
该命令用于通过Redis哨兵查询主节点的IP地址,mymaster是主节点的名称。返回以下信息
1) "172.18.0.2"
2) "6379"
接下来我们关闭主节点,检查是否完成了故障转移。
redis-salve1的log中显示如下信息:
2024-09-19 19:33:43 1:S 19 Sep 2024 11:33:43.379 * MASTER <-> REPLICA sync started
2024-09-19 19:33:43 1:S 19 Sep 2024 11:33:43.379 * Non blocking connect for SYNC fired the event.
2024-09-19 19:33:43 1:S 19 Sep 2024 11:33:43.379 * Master replied to PING, replication can continue...
2024-09-19 19:33:43 1:S 19 Sep 2024 11:33:43.380 # Unable to AUTH to MASTER: -ERR AUTH <password> called without any password configured for the default user. Are you sure your configuration is correct?
2024-09-19 19:33:44 1:S 19 Sep 2024 11:33:44.386 * Connecting to MASTER 172.18.0.4:6381
2024-09-19 19:33:44 1:S 19 Sep 2024 11:33:44.387 * MASTER <-> REPLICA sync started
2024-09-19 19:33:44 1:S 19 Sep 2024 11:33:44.387 * Non blocking connect for SYNC fired the event.
2024-09-19 19:33:44 1:S 19 Sep 2024 11:33:44.387 * Master replied to PING, replication can continue...
2024-09-19 19:33:44 1:S 19 Sep 2024 11:33:44.388 # Unable to AUTH to MASTER: -ERR AUTH <password> called without any password configured for the default user. Are you sure your configuration is correct?
2024-09-19 19:33:45 1:S 19 Sep 2024 11:33:45.391 * Connecting to MASTER 172.18.0.4:6381
可以看到是发生了故障转移尝试的,但是因为从节点的配置文件中,设置了masterauth 密码,但是从节点没有设置密码导致失败。因此在实际中,因此在实际中,应该使用相同的密码方便统一管理。
3.Cluster模式(集群)
3.1Cluster模式原理
Redis Cluster是一种分布式的Redis架构,用于在多个Redis实例之间自动分布数据和请求,以实现更高的扩展性和可用性。这种架构通过数据分片和分布式存储实现了负载均衡和高可用性,在Cluster模式下,Redis将所有的键值对数据分散在多个节点上,每个节点负责一部分数据,称之为槽位。通过数据分片,突破了单节点内存上限的限制,实现大规模的数据存储。
3.2核心架构
1.数据分片(Sharding)
- Redis Cluster将数据分片分布在多个节点上,而不是集中在单一节点。
- 它通过一致性哈希和哈希槽(Hash Slot)机制实现数据分片,整个数据空间被分为16384个slot,每个节点会被分配到一定数量的slot,当数据发送给cluster的时候,会通过哈希函数映射到对应的槽位,再把数据发到相对应的节点中。
2.去中心化架构
- Cluster模式是一个去中心化的架构,不需要像Sentinel模式那样需要独立的管理工具,每个节点都保存集群的部分数据,不需要了解其他节点的信息。
- 所有节点通过Gossip协议交换数据分布和节点状态信息
3.主从复制
可以结合主从复制结构,每一个主节点可以有多个从节点,实现数据复制和故障转移
3.3优缺点分析
优点:
- 数据分片,实现大规模数据存储
- 负载均衡,提高系统性能
- 自动故障转移,提高高可用性
缺点:
- 配置和管理复杂
- 多键操作可能受到限制
3.4使用场景
- 大规模数据存储
- 高性能要求
- 高可用性要求
3.5配置
首先先创建一个docker网络
docker network create redis-cluster-network
接着创建redis-cluster.conf模板
cluster-enabled yes
#表示cluster节点信息默认存储在nodes.conf上
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
启动redis容器,需要启动6个
docker run -d --name redis-node1 --net redis-cluster-network -v C:/Users/minat/Desktop/Note/StudyNote/vocation/cluster.conf:/usr/local/etc/redis/redis.conf redis:7.0.12 redis-server /usr/local/etc/redis/redis.conf --port 6379docker run -d --name redis-node2 --net redis-cluster-network -v C:/Users/minat/Desktop/Note/StudyNote/vocation/cluster.conf:/usr/local/etc/redis/redis.conf redis:7.0.12 redis-server /usr/local/etc/redis/redis.conf --port 6380docker run -d --name redis-node3 --net redis-cluster-network -v C:/Users/minat/Desktop/Note/StudyNote/vocation/cluster.conf:/usr/local/etc/redis/redis.conf redis:7.0.12 redis-server /usr/local/etc/redis/redis.conf --port 6381docker run -d --name redis-node4 --net redis-cluster-network -v C:/Users/minat/Desktop/Note/StudyNote/vocation/cluster.conf:/usr/local/etc/redis/redis.conf redis:7.0.12 redis-server /usr/local/etc/redis/redis.conf --port 6382docker run -d --name redis-node5 --net redis-cluster-network -v C:/Users/minat/Desktop/Note/StudyNote/vocation/cluster.conf:/usr/local/etc/redis/redis.conf redis:7.0.12 redis-server /usr/local/etc/redis/redis.conf --port 6383docker run -d --name redis-node6 --net redis-cluster-network -v C:/Users/minat/Desktop/Note/StudyNote/vocation/cluster.conf:/usr/local/etc/redis/redis.conf redis:7.0.12 redis-server /usr/local/etc/redis/redis.conf --port 6384
接着需要收集所有容器的IP地址
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redis-node1
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redis-node2
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redis-node3
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redis-node4
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redis-node5
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' redis-node6
创建redis cluster
docker exec -it redis-node1 redis-cli --cluster create 172.19.0.2:6379 172.19.0.3:6380 172.19.0.4:6381 172.19.0.5:6382 172.19.0.6:6383 172.19.0.7:6384 --cluster-replicas 1
--cluster-replicas 1 表示每一个主节点含有一个从节点
使用以下命令查询集群状态
docker exec -it redis-node1 redis-cli -p 6379 cluster info
docker exec -it redis-node1 redis-cli -p 6379 cluster nodes
成功。
参考博客:详解Redis三大集群模式,轻松实现高可用! - 一灯架构 - 博客园 (cnblogs.com)