前言
当谈到数据库管理系统时,Redis就像是那个充满魔法的巫师,能够让你的应用程序变得更快、更可靠,就像是施了魔法一样。而今天,我们将进入Redis的神奇世界,探索一种有趣而强大的架构——一主三从三哨兵(One Master, Three Slaves, Three Sentinels)。
在这个故事中,主节点是我们的英雄,它是数据的守护者,负责处理所有的写入操作。三个从节点则是主节点的忠实追随者,他们时刻准备好学习主节点的一切,并在需要时出手相助。而哨兵们则像是这个神奇世界的守护者,他们负责监控、保护主节点,以确保它永远不会倒下。
这个故事将引领我们深入Redis的奥秘,揭示一主三从三哨兵架构的神奇之处。我们将一起探索如何配置、管理和维护这个强大的架构,使你的应用程序在任何情况下都能够如临大敌,稳步前行。
所以,准备好进入Redis的神奇世界吧,让我们一起开始这段有趣而令人兴奋的冒险之旅!
【说明】使用的是docker-compose搭建的
docker相关的
1️⃣:关于虚拟网络docker0,对于mac来说它依靠的是docker desktop,然而它并没有这个docker0了。所以我们的主机并不能直接去访问docker中的容器ip。
https://docs.docker.com/desktop/networking/#i-cannot-ping-my-containers
2️⃣:关于network的区别
- Bridge 模式:
- 默认网络模式。
- 创建一个本地的虚拟网络,使容器可以相互通信,同时又与主机隔离。
- 容器可以通过容器名或 IP 地址进行通信。
- 容器可以使用映射端口与外部通信。
- Host 模式:
- 容器共享主机的网络命名空间。
- 容器与主机共享 IP 地址和端口,可以直接使用主机的网络资源。
- 容器与主机之间网络隔离较小,但也可能导致网络冲突或不稳定性。
- None 模式:
- 容器不加入任何网络,完全与外部网络隔离。
- 适用于一些特殊用例,如需要在容器内执行某些隔离的网络任务。
- Overlay 模式:
- 用于在多个 Docker 宿主机上创建跨主机的虚拟网络,例如在集群环境中。
- 可以在不同主机上的容器之间建立通信,即使这些容器位于不同的宿主机上。
- Macvlan 模式:
- 允许为容器分配与主机网络接口相对应的 MAC 地址。
- 容器可以拥有自己的 MAC 地址,就像实际物理机器一样。
- Bridge-Network 模式:
- 在用户定义的 Docker 网络上创建连接的容器。
- 用户可以通过设置网络选项来控制容器之间的通信和隔离。
【警告】 这里即使我们创建的是桥接的网络,也实现不了容器和主机互通的,但是在centos下可以,使用host模式这里我也尝试了,还是不行,我最后发现host模式下它询到的主机是docker desktop中的ip,也就是127.0.0.1是相对于docker desktop而不是你的主机
docker-compose.yml
version: '3' services: # Redis 主节点配置 redis-master: image: myredis:latest container_name: redis-master ports: - "6399:6379" # 将主节点的6379端口映射到宿主机的6379端口 command: redis-server --appendonly yes --save 900 1 --save 300 10 --save 60 10000 volumes: - ./data/master:/data # 将主节点的数据持久化到宿主机的./data/master目录 networks: - redis-network # Redis 从节点1配置 redis-slave-1: image: myredis:latest container_name: redis-slave-1 ports: - "6398:6379" command: redis-server --slaveof redis-master 6379 # 设置从节点1为主节点的从节点 volumes: - ./data/slave-1:/data # 将从节点1的数据持久化到宿主机的./data/slave-1目录 networks: - redis-network extra_hosts: - "host.docker.internal:192.168.1.75" # 设置自定义网络别名 # Redis 从节点2配置 redis-slave-2: image: myredis:latest container_name: redis-slave-2 ports: - "6397:6379" command: redis-server --slaveof redis-master 6379 # 设置从节点2为主节点的从节点 volumes: - ./data/slave-2:/data # 将从节点2的数据持久化到宿主机的./data/slave-2目录 networks: - redis-network extra_hosts: - "host.docker.internal:192.168.1.75" # 设置自定义网络别名 # Redis 从节点3配置 redis-slave-3: image: myredis:latest container_name: redis-slave-3 ports: - "6396:6379" command: redis-server --slaveof redis-master 6379 # 设置从节点3为主节点的从节点 volumes: - ./data/slave-3:/data # 将从节点3的数据持久化到宿主机的./data/slave-3目录 networks: - redis-network extra_hosts: - "host.docker.internal:192.168.1.75" # 设置自定义网络别名 # Redis 哨兵配置 sentinel-1: image: myredis:latest container_name: redis-sentinel-1 ports: - "26379:26379" command: redis-sentinel /sentinel.conf # 启动哨兵服务并加载sentinel.conf配置 volumes: - ./sentinel.conf:/sentinel.conf # 将哨兵的配置文件挂载到容器中 - ./redis.conf:/redis.conf # 添加 Redis 配置文件挂载 - ./sentinel-logs-1:/var/log # 挂载哨兵的日志目录 depends_on: - redis-master - redis-slave-1 - redis-slave-2 - redis-slave-3 networks: - redis-network # Redis 哨兵配置 sentinel-2: image: myredis:latest container_name: redis-sentinel-2 ports: - "26378:26379" command: redis-sentinel /sentinel.conf # 启动哨兵服务并加载sentinel.conf配置 volumes: - ./sentinel.conf:/sentinel.conf # 将哨兵的配置文件挂载到容器中 - ./redis.conf:/redis.conf # 添加 Redis 配置文件挂载 - ./sentinel-logs-2:/var/log # 挂载哨兵的日志目录 depends_on: - redis-master - redis-slave-1 - redis-slave-2 - redis-slave-3 networks: - redis-network # Redis 哨兵配置 sentinel-3: image: myredis:latest container_name: redis-sentinel-3 command: redis-sentinel /sentinel.conf # 启动哨兵服务并加载sentinel.conf配置 volumes: - ./sentinel.conf:/sentinel.conf # 将哨兵的配置文件挂载到容器中 - ./redis.conf:/redis.conf # 添加 Redis 配置文件挂载 - ./sentinel-logs-3:/var/log # 挂载哨兵的日志目录 depends_on: - redis-master - redis-slave-1 - redis-slave-2 - redis-slave-3 networks: - redis-network networks: redis-network: driver: bridge
【说明】如果想用host模式,可以直接将networks删除掉,然后在各个配置中的command中加入port 指定的端口,如下图
sentinel.conf
# 哨兵监控的主节点名称,后面的参数2代表的是quorum,表示需要两个哨兵的时候才可以进行故障转移 sentinel monitor mymaster 127.0.0.1 6399 2 # 哨兵配置文件的名称 sentinel config-epoch mymaster 0 # 哨兵当前的配置版本号 sentinel leader-epoch mymaster 0 # 选举超时时间 sentinel down-after-milliseconds mymaster 5000 # 故障判定下线阈值和判定上线阈值 sentinel failover-timeout mymaster 10000 sentinel parallel-syncs mymaster 1
重点解释一下上面的语句
redis-server --appendonly yes --save 900 1 --save 300 10 --save 60 10000
--appendonly yes:
这个参数用于启用 Redis 的持久化方式中的"Append Only File"(AOF)机制。
当 AOF 启用时,Redis 会将每个写操作追加到一个文件中,以便在服务器重新启动时重放这些操作,从而达到数据持久化的目的。
--save 900 1 --save 300 10 --save 60 10000:
这个参数用于配置 Redis 数据快照的条件。
每个 --save 参数指定一个时间(以秒为单位)和一个更改的键数阈值。
在指定的时间内,如果更改的键数达到指定的阈值,Redis 就会触发一个数据快照,将当前内存中的数据保存到磁盘中。
在这个例子中,有三个 --save 参数:
如果在 900 秒内有至少 1 个键被更改,就触发一次数据快照。
如果在 300 秒内有至少 10 个键被更改,就触发一次数据快照。
如果在 60 秒内有至少 10000 个键被更改,就触发一次数据快照。
【说明】这里为什么要使用AOF和RDB呢,其实也是可以只使用默认的RDB模式的,但是如果想实现更加好的持久化,可以使用AOF+RDB,也就是在两个RDB直接加入AOF
sentinel monitor mymaster 127.0.0.1 6399 2
sentinel
:表示这是 Redis Sentinel 的配置。monitor mymaster
:这是一个指令,用于告诉 Sentinel 要监控一个名为 “mymaster” 的主节点。127.0.0.1
:这是主节点的 IP 地址或主机名。在这里,它设置为 127.0.0.1,意味着主节点是在本地(同一台机器)上运行。6399
:这是主节点的端口号。在这个例子中,主节点的 Redis 服务监听在端口 6399。2
:这是一个故障判断的配置参数,表示 Sentinel 在判断主节点是否宕机时需要多少个 Sentinel 同意。如果 Sentinel 发现主节点失效,至少有2
个 Sentinel 同意认为主节点宕机,才会执行故障转移操作。
【注意】这里的2是最少2个Sentinel同意才行,一般的哨兵是3,5,7,