一、基本概念
**Redis:**即 "Remote DIctionary Server" ,翻译为"远程字典服务器"。从字面意义上讲,它指的是一个远程的字典服务,意味着它是一个可以远程访问的服务,主要用于存储键值对(key-value pairs)。Redis 是一个开源的、支持网络、基于内存亦即易失性的键值对存储数据库,用作数据库、缓存和消息中间件。它支持多种类型的值(value),如字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)等。此外,Redis 还提供了数据持久化选项,可以在内存中的数据丢失时恢复数据;还支持事务、发布/订阅模式、Lua脚本执行等功能。
基础知识
NoSQL 数据库: NoSQL 指的是"Not Only SQL",即不仅限于 SQL 查询语言的非关系型数据库。MongoDB 是文档型数据库,Cassandra 是列族存储数据库。
(包括Redis ,这些 NoSQL 数据库都是为了处理大规模数据并提供高可用性和扩展性设计的。然而,Redis 专注于内存中数据的高效读写,同时也提供了持久化能力;而 MongoDB 和 Cassandra 则各有侧重,比如 MongoDB 强调灵活的文档模型,Cassandra 注重分区容忍性和线性扩展。)
关系型数据库(RDBMS): 关系型数据库管理系统,指的是一种基于表格结构存储数据的数据库系统。每个表都包含行和列,行代表记录,列定义了字段的数据类型。
(关系型数据库如 MySQL、PostgreSQL 等通常用于持久化存储结构化的数据,并支持复杂的查询操作。而 Redis 主要作为内存中的键值存储,提供快速读写性能,常被用作缓存层来减轻关系型数据库的压力。)
Memcached: 一个简单的分布式内存对象缓存系统,主要用于加速动态Web应用程序。
(与Redis的联系,两者都是内存缓存解决方案,但 Redis 提供更多的功能,例如对多种数据结构的支持、持久化选项以及更丰富的命令集。Memcached 更加轻量级,适合需要简单键值对缓存的应用场景。)
本地缓存 vs 分布式缓存: 本地缓存是指在同一进程或机器上的缓存机制,例如 Java 中的 HashMap;分布式缓存则是跨越多个节点的缓存系统。
(Redis 作为一个分布式缓存方案,允许不同服务器之间的数据共享,并且能够保证数据的一致性和可靠性。相比之下,本地缓存只能服务于单个应用实例,一旦该实例重启,所有缓存数据都会丢失。)
ACID事务 vs BASE理论 vs CAP理论: ACID 理论Atomicity(原子性)、Consistency(一致性)、Isolation(隔离性)、Durability(持久性),是传统关系型数据库遵循的原则;分布式系统BASE理论则是 Basically Available(基本可用)、Soft state(软状态)、Eventually consistent(最终一致性),反映了某些分布式系统的设计理念;分布式系统CAP理论C代表一致性,通过数据副本阶段同步或锁机制各节点数据读写一致,A代表可用性,读写请求都可立即相应且无错,通常与C相矛盾,副本写操作要同步数据就不一致,多节点同时写就影响可用性,P代表分区容忍性,比如网络延迟拥堵、硬件故障等,在实际情况是必然存在的。在分布式系统理论中,BASE 理论侧重于描述一种宽松的一致性和高可用性的系统行为模式,而 CAP 理论则是一个理论上的限制,指出了分布式系统中三个关键属性之间的权衡关系。
(Redis 支持一种简化版的事务,它能确保一系列命令按顺序执行,但是不提供回滚机制。在 CAP 理论下,Redis 更倾向于 AP,采用最终一致性模型以换取更高的可用性和性能。)
OSS Cluster: 即"Open Source Software Cluster",是 Redis 集群的一种部署模式,表明该集群是以 Redis 的开源版本为基础构建的,使用了 Redis 内置的集群功能
("OSS Cluster" 作为 Redis 集群的一种类型,意味着它是基于官方提供的、未经修改的 Redis 开源代码实现的集群解决方案。与之相对的是企业级或商业版的 Redis 集群,例如由 Redis Labs 提供的 Redis Enterprise)
redis核心概念
键: 键是字符串类型的数据,用于唯一标识一个值(在 Redis 中,键用于唯一标识一个值。所有的数据操作都是通过键来进行的,用户可以通过键来存取、更新或删除数据。)
值:由键关联的数据内容(值是 Redis 数据库中实际存储的内容,可以是字符串、列表、集合等多种类型的数据结构)
**持久化:**redis存储的数据保持不变的状态或性质(持久化机制确保即使在服务器重启后,数据仍然能够被保存下来。Redis 提供了 RDB 和 AOF 两种持久化方式。RDB 是 "Redis 数据库备份" 的缩写,它指的是创建 Redis 数据库的一个快照;AOF 表示 "仅追加文件",意味着所有对数据库的写操作命令都会被追加到该文件中)
**发布/订阅(Pub/Sub):**一种消息通信模式,发送者不知道接收者是谁,只需要发送者(发布者)将消息发送到频道,接收者订阅频道即可接收其他客户端发布的消息(Redis 实现了 Pub/Sub 模式,允许客户端订阅频道并接收其他客户端发布的消息)
**事务:**一系列作为单一工作单元执行的操作(Redis 事务保证一组命令要么全部被执行,要么都不执行,提供了基本的原子性。它通过MULTI, EXEC, WATCH等命令实现,允许多个命令排队并一次性执行。)
**管道:**一种优化技术,允许多个任务连续进行而不需要等待每个任务完成。(Redis 管道减少了客户端和服务器之间的往返次数,从而提高了效率。)
**复制:**创建数据副本或拷贝(Redis 的主从复制机制使得数据可以从一个主节点复制到多个从节点,增强了系统的可用性和读扩展能力。)
**集群:**一种分布式部署方式,它将数据分布在多个节点上以提高性能和可靠性(Redis集群提供了一种水平扩展的方式,通过分片来分配数据,同时保证高可用性。)
**哨兵(Sentinel):**警戒或监视的角色,提供监控、自动故障转移和其他管理任务(Redis Sentinel,它是为了提高 Redis 部署的可靠性和可用性而设计的一个组件,是 Redis 官方提供的一个高可用性解决方案,监控 Redis 实例(包括主节点和从节点)的健康状况,并在主节点出现故障时自动执行故障转移操作)
**模块:**可插入系统中的独立组件(自Redis 4.0起,允许开发者添加自定义的数据类型和命令,通过模块扩展Redis的功能)
Lua脚本: 使用 Lua 编程语言编写的代码片段(Redis 支持执行 Lua 脚本,这使得可以在服务器端运行复杂的逻辑,减少客户端和服务器之间的交互次数。)
redis集群核心概念
节点: 节点是集群中的一个单独的Redis实例,可以是主节点(Master Node)或从节点(Replica Node)。每个节点都运行Redis服务,并存储一部分数据。
(Redis集群由多个节点组成。主节点负责存储数据和处理请求,而从节点用于数据的备份。当主节点故障时,从节点可以接管其角色,确保集群的高可用性。)
分片: 将数据拆分并分布到多个存储位置的技术。每个分片只存储数据集的一部分。
(Redis集群通过分片将数据分散到多个主节点上。每个主节点负责一部分数据,提升了存储能力和查询性能。分片使得Redis能够处理比单个实例更大的数据量。)
哈希槽: 哈希槽是一个数据结构,用于将数据(键)映射到集群中的特定位置。Redis集群将数据映射到16384个哈希槽上。
(哈希槽是Redis集群分片的基础。每个键通过哈希算法映射到一个哈希槽,哈希槽决定了数据在哪个主节点上存储。哈希槽是集群内数据分配的核心机制。而哈希槽的分配是Redis集群通过一致性哈希来进行的,这种分布式哈希技术使得节点的加入或移除不会导致大量数据重新分配,从而减少了对集群性能的影响)
迁移: 指的是重新分配哈希槽或数据从一个节点到另一个节点的过程。
(迁移发生在扩展集群、增加节点或节点故障恢复时。Redis集群通过迁移哈希槽来确保数据均匀分布,避免某些节点过载)
键的分配: 指将数据(键)按照一定规则分布到不同的节点或分片上。
(在Redis集群中,数据的键通过哈希槽分配到不同的主节点。每个主节点负责一定数量的哈希槽,确保数据均匀分布在集群中。)
重定向: 当请求的目标无法在当前节点找到时,将请求引导到其他节点的过程。
(当客户端请求一个键,而该键并不存储在当前节点上时,Redis会返回一个 MOVED 错误并提供目标节点的地址,客户端根据这个地址重定向请求到正确的节点。)
故障转移: 指在主节点发生故障时,从节点自动接管主节点的角色,确保集群继续提供服务。
(edis集群中的每个主节点都由从节点备份。当主节点发生故障时,集群会自动通过选举机制将从节点提升为主节点,保证集群的高可用性。)
集群总线: 集群总线是Redis集群内各节点之间通信的传输通道。它用于传递集群的状态信息、故障检测和节点配置更新等。
(集群总线使得Redis集群中的各个节点能够相互协调,共享信息。当集群状态发生变化时,节点通过集群总线通知其他节点。服务端口+10000 是用来区分 数据端口 和 集群总线端口 的,确保数据访问和集群内部通信使用不同的端口,服务端口和集群通信端口都需要映射主机端口,映射时在主机上端口不唯一即可)
复制: 指将一个节点的数据同步到另一个节点的过程,通常用于备份和高可用性。
(Redis集群支持主从复制,每个主节点都有一个或多个从节点作为备份。当主节点发生故障时,从节点可以自动接管,保证数据不会丢失。在主节点故障时。如果从节点的复制延迟较高,可能导致故障恢复时数据不一致的问题)
二、操作步骤
1、安装Docker Desktop
首先开启虚拟化和适用于Linux的window子系统功能并安装WSL2,然后下载安装Docker Desktop,地址https://www.docker.com/products/docker-desktop/,如果Docker Desktop打开报错,参考解决wsl 无法升级 wsl2 以及windows 下的Docker 打开报错_当前计算机配置不支持 wsl2-CSDN博客,bcdedit /set hypervisorlaunchtype Auto 后重启并重新wsl --install
(通过Docker Desktop能够在Windows 10上创建、管理并运行Redis等容器化服务)
2、拉取redis镜像
在Docker Desktop或命令行窗口拉取redis的镜像
(可供后续创建相同的Redis版本的容器实例并进行管理)
3、配置并创建redis节点实例
3.1、创建redis节点配置文件
创建redis-6379.conf、redis-6380.conf、redis-6381.conf、redis-6382.conf、redis-6383.conf、redis-6384.conf内容基本为:
port 6379 #服务端口,其他可设置为6380、6381、6382、6383、6384
cluster-enabled yes #启用 Redis 集群模式
cluster-config-file nodes.conf #指定集群节点配置文件,确保 Redis 节点重启后能恢复集群信息
cluster-node-timeout 5000 #设置 Redis 集群节点通信的超时时间
cluster-announce-ip 192.168.11.34 #指定节点向集群中其他节点及客户端广播的 IP 地址
appendonly yes #启用 AOF持久化。
bind 0.0.0.0 #监听所有可用的网络接口,允许远程客户端或其他节点通过网络访问该实例
protected-mode no #禁用保护模式,使得Redis 可以接受来自远程客户端的连接(开发环境用途)
(节点配置文件可以使得每个节点按照特定的配置行为运行,尤其是集群相关配置,它是后续创建集群节点和集群的基础)
3.2、启动redis实例
在配置文件的目录下打开powershell执行命令
docker network create redis-cluster-net(创建一个自定义的 Docker 网络,如果想在同一网络下创建集群实例时,可用于连接不同的 Redis 容器,以确保它们之间能够互相通信,避免其他容器的影响。由于容器可以识别,因此可以通过容器名称+端口创建集群,否则需要用ip+端口创建)
docker run -d --name redis-6379【 --net redis-cluster-net 非同一网络可不写】-v "${PWD}/redis-6379.conf:/usr/local/etc/redis/redis.conf" -p 6379:6379 -p 16379:16379 redis:7 redis-server /usr/local/etc/redis/redis.conf
docker run -d --name redis-6380【 --net redis-cluster-net 非同一网络可不写】-v "${PWD}/redis-6380.conf:/usr/local/etc/redis/redis.conf" -p 6380:6380 -p 16380:16380 redis:7 redis-server /usr/local/etc/redis/redis.conf
docker run -d --name redis-6381【 --net redis-cluster-net 非同一网络可不写】-v "${PWD}/redis-6381.conf:/usr/local/etc/redis/redis.conf" -p 6381:6381 -p 16381:16381 redis:7 redis-server /usr/local/etc/redis/redis.conf
docker run -d --name redis-6382【 --net redis-cluster-net 非同一网络可不写】-v "${PWD}/redis-6382.conf:/usr/local/etc/redis/redis.conf" -p 6382:6382 -p 16382:16382 redis:7 redis-server /usr/local/etc/redis/redis.conf
docker run -d --name redis-6383【 --net redis-cluster-net 非同一网络可不写】-v "${PWD}/redis-6383.conf:/usr/local/etc/redis/redis.conf" -p 6383:6383 -p 16383:16383 redis:7 redis-server /usr/local/etc/redis/redis.conf
docker run -d --name redis-6384【 --net redis-cluster-net 非同一网络可不写】-v "${PWD}/redis-6384.conf:/usr/local/etc/redis/redis.conf" -p 6384:6384 -p 16384:16384 redis:7 redis-server /usr/local/etc/redis/redis.conf
参数解析 :
-d
:以守护模式运行容器,容器将在后台运行。
--name redis-7000
:为容器命名为 redis-7000
,便于管理和识别。
--net redis-cluster-net
:将容器加入 redis-cluster-net
网络,以便 Redis 节点间的通信。
-v "${PWD}/redis-7000.conf:/usr/local/etc/redis/redis.conf"
:将当前目录的 redis-7000.conf
文件挂载到容器中的 /usr/local/etc/redis/redis.conf
路径。用途:为 Redis 容器提供启动配置文件。
-p 6379:6379 -p 16379:16379
:将宿主机的 6379 和 16379 端口映射到容器内的对应端口。用途:6379:供客户端连接 Redis 服务。16379:供 Redis 集群内部节点通信使用。
redis:7
:使用 redis:7
镜像启动容器。redis-server /usr/local/etc/redis/redis.conf
:指定 Redis 使用配置文件 /usr/local/etc/redis/redis.conf
启动。用途:以集群模式运行 Redis 节点。
(创建各集群节点实例,是后续创建这些节点集群的基础。)
4、创建redis集群
进入任意一个容器进行管理
docker exec -it redis-6379 bash
同一Docker网络下:
redis-cli --cluster create redis-6379:6379 redis-6380:6380 redis-6381:6381 redis-6382:6382 redis-6383:6383 redis-6384:6384 --cluster-replicas 1
否则:
redis-cli --cluster create 192.168.11.34:6379 192.168.11.34:6380 192.168.11.34:6381 192.168.11.34:6382 192.168.11.34:6383 192.168.11.34:6384 --cluster-replicas 1
命令解析 :
docker exec
:这个命令用于在一个运行中的容器内执行命令,而不需要停止容器。
-it
:这是两个参数组合:-i
:代表 interactive,即启动一个交互式会话。-t
:代表 tty,即为容器分配一个伪终端(类似于终端窗口),使得命令的输出能够格式化显示,允许你与容器进行交互。
redis-6379
:这是容器的名字或 ID,指定要进入的容器。在这个例子中,容器名是 redis-6379
,表示一个运行 Redis 实例的容器。
bash
:在容器内部启动一个 Bash shell(如果容器中安装了 Bash)。这会将你带入该容器的命令行界面,使你可以在容器内执行命令。
(redis集群自带数据分片和故障转移高可用,因此就直接可以通过redis-cli或redis insight进行这些功能的验证)
5、验证
5.1、通过redis-cli工具验证
redis-cli -h 192.168.11.34 -p 6379
查看集群整体信息:cluster info
查看集群节点信息:cluster nodes
故障转移,高可用:可通过cluster nodes查看每个从节点对应的主节点,并尝试当停止某个主节点时,会发现所配的从节点变为主节点,并管理原先主节点的哈希槽,当get 某个原先主节点的键时也依然可以获取值。
重定向:当对某一个节点set key value时,如果键不在当前节点的哈希槽范围内,则会出现MOVED错误,并引导显示新节点。
主从复制:当给某个节点set key value时,如果可set,在从节点中也可以get到该key的值
5.2、通过Redis Insight工具验证
通过redis insight可视化工具连接集群任意一节点查看集群信息
验证类似上述在命令行窗口的操作,在redis insight的workbench中输入命令并验证,区别是即使当前节点不可插入某个键,也会显示插入成功,这是因为redis insight自动在底层重定向,将其插入到了对应的节点中。可以在Analysis Tools的Overview中查看主节点状态及其键的数量
总结
redis集群实现就是按照一定配置的完成多节点实例的启动以创建集群。关键点在于具体的集群配置规则
三、额外补充
1、redis持久化配置
Redis 提供了两种主要的持久化机制,以保证数据在服务重启或故障后能够恢复:RDB(Redis Database ,在指定的时间间隔将内存中的数据生成快照并保存到磁盘上来实现)快照持久化和AOF(Append-Only File ,将每个写操作记录到日志文件来实现)日志持久化。
在 redis.conf
中增加以下配置:
RDB配置:
save 900 1 # 如果 900 秒内至少有 1 次写操作,则触发快照
save 300 10 # 如果 300 秒内至少有 10 次写操作,则触发快照
save 60 10000 # 如果 60 秒内至少有 10000 次写操作,则触发快照
dbfilename dump.rdb # 快照文件名
dir ./ # 快照路径,默认在当前安装目录下
AOF配置:
appendonly yes #启用AOF
appendfilename "appendonly.aof" # 指定 AOF 文件名和路径
appendfsync always # 同步策略:每次写操作后立即同步,最安全但性能最差
appendfsync everysec # 同步策略:每秒同步一次,默认值,性能与安全的平衡
appendfsync no # 同步策略:由操作系统决定何时同步,性能最高但最不安全
auto-aof-rewrite-percentage 100 # 重写策略:AOF文件的大小等于或超过上次重写后大小两倍的比例时触发重写
auto-aof-rewrite-min-size 64mb # 重写策略:当 AOF 文件的当前大小达到或超过指定的值(如 64MB)时,Redis 才会检查是否满足触发 AOF 重写的其他条件
RDB 和 AOF 的混合模式:
aof-use-rdb-preamble yes #Redis 4.0 开始支持混合持久化模式,将 RDB 和 AOF 的优点结合,兼顾性能和数据安全
可以通过分别删除rdb或aof文件并重启redis查看数据,确认redis的持久化方式
2、使用docker compose部署集群
Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。(通过使用 docker-compose.yml文件来配置应用程序的服务、网络和卷,然后使用docker-compose up(可以带上 - d表示程序以在后台运行的非守护模式运行)命令就可以从配置中启动所有服务。)
docker-compose文件配置:
XML
services:
redis-6379:
image: redis:7
container_name: redis-6379
ports:
- "6379:6379"
- "16379:16379"
volumes:
- ./redis-6379.conf:/usr/local/etc/redis/redis.conf
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
redis-6380:
image: redis:7
container_name: redis-6380
ports:
- "6380:6380"
- "16380:16380"
volumes:
- ./redis-6380.conf:/usr/local/etc/redis/redis.conf
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
redis-6381:
image: redis:7
container_name: redis-6381
ports:
- "6381:6381"
- "16381:16381"
volumes:
- ./redis-6381.conf:/usr/local/etc/redis/redis.conf
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
redis-6382:
image: redis:7
container_name: redis-6382
ports:
- "6382:6382"
- "16382:16382"
volumes:
- ./redis-6382.conf:/usr/local/etc/redis/redis.conf
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
redis-6383:
image: redis:7
container_name: redis-6383
ports:
- "6383:6383"
- "16383:16383"
volumes:
- ./redis-6383.conf:/usr/local/etc/redis/redis.conf
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
redis-6384:
image: redis:7
container_name: redis-6384
ports:
- "6384:6384"
- "16384:16384"
volumes:
- ./redis-6384.conf:/usr/local/etc/redis/redis.conf
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
(使用docker compose启动多容器简化了上述操作步骤中的"3.2、启动redis实例"部分,使得对于多redis节点得操作和管理更加方便了。在docker-compose.yml
文件中,如果没有定义自定义网络。这意味着 Docker Compose 会使用默认的网络设置,它会创建一个专用的桥接网络,命名为 <项目名>_default,
所有在同一个 docker-compose.yml
文件中定义的服务都会自动连接到这个网络,服务之间可以通过服务名互相访问,无需额外配置)
然后打开powershell窗口中执行创建集群的命令:
docker exec -it redis-6379 bash
redis-cli --cluster create 192.168.11.34:6379 192.168.11.34:6380 192.168.11.34:6381 192.168.11.34:6382 192.168.11.34:6383 192.168.11.34:6384 --cluster-replicas 1
3、windows版redis
目前维护的windows版本的redis最新为3.0.504,不支持创建集群,在使用redis-cli创建集群的时候会报错,提示Unrecognized option or bad number of args for --cluster
需要安装Ruby 环境,通过redis-trib.rb 脚本工具创建集群
4、spring boot集成
引入依赖
XML
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.3.1</version>
</dependency>
修改配置文件
XML
spring:
redis:
cluster:
nodes:
- 192.168.11.34:6379
- 192.168.11.34:6380
- 192.168.11.34:6381
- 192.168.11.34:6382
- 192.168.11.34:6383
- 192.168.11.34:6384
timeout: 5000
创建 RedisTemplate Bean
java
@Configuration
public class RedisTemplateConfig {
@Bean
public JedisConnectionFactory jedisConnectionFactory() {
RedisClusterConfiguration clusterConfig = new RedisClusterConfiguration()
.clusterNode("192.168.11.34", 6379)
.clusterNode("192.168.11.34", 6380)
.clusterNode("192.168.11.34", 6381);
return new JedisConnectionFactory(clusterConfig);
}
@Bean
public RedisTemplate<Object, Object> redisTemplate() {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(jedisConnectionFactory());
return template;
}
}
然后在代码中就可以注入使用
java
@Resource
private RedisTemplate<Object, Object> redisTemplate;
5、redis哨兵
哨兵就像一名放哨的"守卫",始终监控 Redis 实例(包括主节点和从节点)的运行状态。一旦它监测到主节点不可用,它便会触发自动故障转移,将其中一个从节点提升为新的主节点,从而保持 Redis 服务的高可用性。
(哨兵适合简单的主从架构中实现高可用,而 Redis 集群则在规模化、分片扩展和自动故障转移方面更为全面。)
配置结构如图
C:\Program Files\Docker\redis-sentinel\redis-master\redis-master.conf
port 6380
bind 0.0.0.0
appendonly yes
protected-mode no
C:\Program Files\Docker\redis-sentinel\redis-slave1
port 6381
bind 0.0.0.0
appendonly yes
protected-mode no
replicaof 192.168.11.34 6380
C:\Program Files\Docker\redis-sentinel\redis-slave2\redis-slave2.conf
port 6382
bind 0.0.0.0
appendonly yes
protected-mode no
replicaof 192.168.11.34 6380
C:\Program Files\Docker\redis-sentinel\sentinel1\sentinel1.conf
C:\Program Files\Docker\redis-sentinel\sentinel2\sentinel2.conf
C:\Program Files\Docker\redis-sentinel\sentinel3\sentinel3.conf
port 26379
bind 0.0.0.0
protected-mode no
sentinel monitor mymaster 192.168.11.34 6380 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
C:\Program Files\Docker\redis-sentinel\docker-compose.yml
services:
redis-master:
image: redis:latest
container_name: redis-master
volumes:
- ./redis-master:/usr/local/etc/redis
ports:
- "6380:6380"
command: ["redis-server", "/usr/local/etc/redis/redis-master.conf"]
redis-slave1:
image: redis:latest
container_name: redis-slave1
ports:
- "6381:6381"
depends_on:
- redis-master
volumes:
- ./redis-slave1/redis-slave1.conf:/usr/local/etc/redis/redis-slave1.conf
command: ["redis-server", "/usr/local/etc/redis/redis-slave1.conf"]
redis-slave2:
image: redis:latest
container_name: redis-slave2
depends_on:
- redis-master
ports:
- "6382:6382"
volumes:
- ./redis-slave2/redis-slave2.conf:/usr/local/etc/redis/redis-slave2.conf
command: ["redis-server", "/usr/local/etc/redis/redis-slave2.conf"]
sentinel1:
image: redis:latest
container_name: sentinel1
depends_on:
- redis-master
volumes:
- ./sentinel1:/usr/local/etc/redis
ports:
- "26379:26379"
restart: always
command: ["redis-sentinel", "/usr/local/etc/redis/sentinel1.conf"]
sentinel2:
image: redis:latest
container_name: sentinel2
depends_on:
- redis-master
volumes:
- ./sentinel2:/usr/local/etc/redis
ports:
- "26380:26379"
restart: always
command: ["redis-sentinel", "/usr/local/etc/redis/sentinel2.conf"]
sentinel3:
image: redis:latest
container_name: sentinel3
depends_on:
- redis-master
volumes:
- ./sentinel3:/usr/local/etc/redis
ports:
- "26381:26379"
restart: always
command: ["redis-sentinel", "/usr/local/etc/redis/sentinel3.conf"]
命令解析 :
image: 使用最新版本的 Redis 镜像。
container_name: 分别命名为 sentinel1
, sentinel2
, 和 sentinel3
。
depends_on:确保 redis-master
容器先于哨兵启动。
volumes:将主机目录(如 ./sentinel1
)挂载到容器内的 /usr/local/etc/redis
,以加载各自的 Sentinel 配置文件。
ports:sentinel1
映射主机的 26379
端口到容器的 26379
端口。sentinel2
和 sentinel3
分别映射主机的 26380
和 26381
端口到容器的 26379
端口。注意,这样配置的目的是让每个哨兵实例通过不同的主机端口访问,而容器内部仍使用标准的 Sentinel 端口 26379
。
restart:设置为 always
,确保哨兵容器在停止后自动重启,增加系统的稳定性和可用性。
command:启动 Redis Sentinel,并指定各自的配置文件 sentinel1.conf
, sentinel2.conf
, 和 sentinel3.conf
。
验证用到的命令 :
docker exec -it sentinel1 redis-cli -h 192.168.11.34 -p 26379(进入哨兵节点)
SENTINEL MASTER mymaster(当 flags 中出现 s_down 时,表示该哨兵已同意主节点"看起来像"(subjectively)下线。如果后续达到仲裁(即其他哨兵也同意主节点下线),那么会出现 o_down(objectively down)的状态,继而触发故障转移过程)
SENTINEL CKQUORUM mymaster(则表示达到了足够的哨兵数量同意下线状态。)
SENTINEL slaves mymaster(查看从节点信息)
info sentinel(关于哨兵系统的详细信息,可以看到主节点的状态和连接的节点是哪个。哨兵节点的配置文件中会记录从节点的信息,假如停止从节点后再启动,则需要还原清理哨兵配置文件,否则显示的slaves会增多超过实际运行的从节点数量。因为哨兵节点会给其配置文件中写入内容,因此需要设置挂载的配置文件权限是可写入的,比如设置Everyone 完全控制)