3主3从的redis docker集群

本文详细解析了Redis中键(key)在不同槽(slot)及节点间的分布情况,展示了keya和key aa分别存储在特定槽及对应IP地址的实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<think>我们正在部署一个包含3节点的Redis集群。注意:Redis集群至少需要3节点,每个节点至少有一个从节点,但用户要求只有3节点(没有从节点),这在实际生产环境中是不推荐的,因为缺乏高可用性。但既然用户明确要求,我们可以只创建3节点。 不过,根据Redis集群的要求,即使没有从节点,3节点也是可以运行的(但这样任何一个节点故障都会导致集群不可用)。因此,我们将创建3个独立的Redis实例作为节点,并将它们组成集群。 步骤: 1. 创建一个自定义的Docker网络,以便容器间可以通信。 2. 创建3Redis配置文件,并修改配置以支持集群3. 启动3Redis容器,每个容器使用不同的端口(例如7001,7002,7003)和配置文件。 4. 使用redis-cli创建集群。 由于用户没有要求持久化,我们可以不配置持久化,但为了完整性,我们可以在配置文件中配置RDB或AOF。但根据引用[3],AOF模式可以提供更好的持久性。不过,用户需求中未明确,我们可以选择默认配置。 具体步骤: 1. 创建网络 docker network create redis-cluster-net 2. 为每个节点创建目录,用于存放配置和数据 mkdir -p /myredis/cluster/node1/{data,conf} mkdir -p /myredis/cluster/node2/{data,conf} mkdir -p /myredis/cluster/node3/{data,conf} 3. 在每个节点的配置目录中创建redis.conf配置文件,内容如下(以node1为例,端口7001): port 7001 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes # 如果需要外部访问,需要绑定0.0.0.0 bind 0.0.0.0 protected-mode no # 关闭保护模式,允许外部访问 注意:其他节点只需修改端口为7002、7003。 4. 启动容器,将宿机的目录挂载到容器内,并连接到同一个网络。 节点1: docker run -d --name redis-node1 --net redis-cluster-net -v /myredis/cluster/node1/data:/data -v /myredis/cluster/node1/conf/redis.conf:/usr/local/etc/redis/redis.conf -p 7001:7001 redis redis-server /usr/local/etc/redis/redis.conf 节点2: docker run -d --name redis-node2 --net redis-cluster-net -v /myredis/cluster/node2/data:/data -v /myredis/cluster/node2/conf/redis.conf:/usr/local/etc/redis/redis.conf -p 7002:7002 redis redis-server /usr/local/etc/redis/redis.conf 节点3docker run -d --name redis-node3 --net redis-cluster-net -v /myredis/cluster/node3/data:/data -v /myredis/cluster/node3/conf/redis.conf:/usr/local/etc/redis/redis.conf -p 7003:7003 redis redis-server /usr/local/etc/redis/redis.conf 5. 进入其中一个容器,执行集群创建命令: docker exec -it redis-node1 bash 然后执行: redis-cli --cluster create 172.18.0.2:7001 172.18.0.3:7002 172.18.0.4:7003 --cluster-replicas 0 注意:这里的IP地址是容器在redis-cluster-net网络中的IP,我们可以使用容器名代替IP,但需要Redis 6以上版本支持。如果使用容器名,需要确保在容器内可以解析。或者我们可以使用宿机的IP和映射的端口,但这样需要确保宿机防火墙允许。 由于我们使用的是自定义网络,容器之间可以通过容器名通信。因此,我们可以这样写: redis-cli --cluster create redis-node1:7001 redis-node2:7002 redis-node3:7003 --cluster-replicas 0 注意:--cluster-replicas 0 表示每个节点没有从节点。 6. 如果一切顺利,集群会创建成功。 注意:在创建集群时,会提示分配槽(slot)和节点。因为我们只有3节点,所以每个节点会分配16384个槽中的一部分(大约5461个槽)。 但是,在实际操作中,我们可能会遇到容器名解析的问题。在Docker自定义网络中,容器名自动解析为IP。因此,使用容器名是可行的。 然而,在redis-cli创建集群时,它可能会使用容器内部的IP地址(172.x.x.x)来记录节点信息。这样,当容器重启时IP可能改变,但Redis集群会尝试使用配置的IP,这可能导致问题。为了避免这个问题,我们可以使用宿机的IP地址(固定IP)或者使用Docker的host网络模式?但host模式会占用宿机端口,且配置复杂。 另一种方法是使用固定的容器名,并在Redis配置中设置集群通告IP为宿机的IP(或域名),但这里我们使用容器网络,所以建议使用容器IP(因为容器IP在同一个网络中重启后可能会变,但容器名解析的IP会更新,所以Redis集群会使用容器名解析的IP,因此应该没问题?)。不过,Redis集群配置中存储的是我们在创建集群时指定的地址(即容器名或IP)。如果使用容器名,那么只要容器名解析正确就可以。 因此,我们使用容器名来创建集群。 但是,在容器内部,redis-cli命令可能无法直接使用容器名,因为Redis集群创建命令需要能够解析这些容器名为IP。在Docker自定义网络中,容器名会自动解析,所以应该没问题。 如果遇到无法解析容器名的问题,可以在每个容器的/etc/hosts文件中添加映射,但Docker已经自动管理了,所以通常不需要。 我们按照上述步骤操作。 另外,如果用户需要外部客户端访问,那么客户端需要能够访问宿机的7001、7002、7003端口,并且集群中的节点通告的地址应该是宿机IP(因为客户端连接的是宿机端口,然后通过端口映射到容器)。但这样配置比较复杂,因为容器内部并不知道宿机的IP。因此,我们可以在创建集群时指定使用宿机的IP和映射的端口,但这样就需要在启动容器时使用宿机的IP来创建集群。 为了解决外部访问的问题,我们可以在Redis配置文件中设置集群通告的IP为宿机的IP(假设为x.x.x.x),然后使用宿机的IP和端口来创建集群。但这样配置需要知道宿机的IP,并且如果宿机IP变化,集群就需要重新创建。 因此,有两种方案: 方案一:只允许集群内部通信,外部通过一个代理(如redis-proxy)访问,或者外部客户端直接连接每个节点(但需要知道所有节点地址,并且集群重定向时使用容器IP,外部无法访问)。 方案二:配置集群节点通告地址为宿机的IP和映射端口。 这里我们采用方案二,因为用户可能希望从外部访问。 修改每个节点的配置文件,添加: cluster-announce-ip <宿机IP> cluster-announce-port <映射端口> # 例如节点1的cluster-announce-port 7001 这样,在容器内部,Redis节点会使用宿机的IP和指定的端口来通告自己。 因此,步骤调整为: 1. 创建网络(可选,如果外部访问则不需要容器间网络?但容器间通信需要,所以还是创建网络,同时使用端口映射让外部可以访问) 2. 创建目录和配置文件,在配置文件中添加: port 7001 # 节点1,节点2改为7002,节点3改为7003 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes bind 0.0.0.0 protected-mode no cluster-announce-ip 192.168.1.100 # 这里替换为宿机的实际IP cluster-announce-port 7001 # 节点1为7001,节点2为7002,节点3为7003 cluster-announce-bus-port 17001 # 集群总线端口,通常为客户端端口+10000,所以节点1为17001,节点2为17002,节点3为17003 3. 启动容器时,除了映射客户端端口(7001),还需要映射集群总线端口(17001,17002,17003),因为集群节点之间通信使用总线端口。 节点1: docker run -d --name redis-node1 --net redis-cluster-net -v /myredis/cluster/node1/data:/data -v /myredis/cluster/node1/conf/redis.conf:/usr/local/etc/redis/redis.conf -p 7001:7001 -p 17001:17001 redis redis-server /usr/local/etc/redis/redis.conf 同样,节点2和节点3分别映射7002:7002和17002:17002,7003:7003和17003:17003。 4. 创建集群时,使用宿机的IP和端口(因为通告地址是宿机IP,所以客户端连接也是宿机IP,这样集群重定向时也会使用宿机IP和端口): redis-cli --cluster create 192.168.1.100:7001 192.168.1.100:7002 192.168.1.100:7003 --cluster-replicas 0 注意:这里使用宿机的IP(192.168.1.100)和端口。 这样,外部客户端就可以通过宿机IP和端口(7001,7002,7003)来访问集群了。 但是,如果宿机有防火墙,需要开放这些端口(7001-7003, 17001-17003)。 总结步骤: 1. 创建网络(可选,但为了容器间通信,建议创建): docker network create redis-cluster-net 2. 创建目录和配置文件(三个节点): node1: /myredis/cluster/node1/conf/redis.conf node2: /myredis/cluster/node2/conf/redis.conf node3: /myredis/cluster/node3/conf/redis.conf 配置文件内容(以node1为例,注意替换宿机IP和端口): port 7001 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes bind 0.0.0.0 protected-mode no cluster-announce-ip 192.168.1.100 # 宿机的IP cluster-announce-port 7001 cluster-announce-bus-port 17001 3. 启动容器(三个节点,注意映射两个端口:客户端端口和总线端口): 节点1: docker run -d --name redis-node1 --net redis-cluster-net \ -v /myredis/cluster/node1/data:/data \ -v /myredis/cluster/node1/conf/redis.conf:/usr/local/etc/redis/redis.conf \ -p 7001:7001 -p 17001:17001 \ redis redis-server /usr/local/etc/redis/redis.conf 节点2和节点3类似,修改端口和目录。 4. 使用redis-cli创建集群(在宿机上执行,或者在一个容器中执行,但需要安装redis-cli): 在宿机上执行(假设宿机安装了redis-cli): redis-cli --cluster create 192.168.1.100:7001 192.168.1.100:7002 192.168.1.100:7003 --cluster-replicas 0 如果宿机没有安装redis-cli,可以进入一个Redis容器执行(因为容器内有redis-cli): docker exec -it redis-node1 bash redis-cli --cluster create 192.168.1.100:7001 192.168.1.100:7002 192.168.1.100:7003 --cluster-replicas 0 5. 测试集群redis-cli -c -h 192.168.1.100 -p 7001 执行 cluster info 和 cluster nodes 注意:如果宿机有多个IP,需要确保cluster-announce-ip设置的是客户端能够访问的那个IP。 由于用户要求3节点,没有从节点,所以创建集群时使用--cluster-replicas 0。 如果用户后续需要添加从节点,可以再添加。 以上步骤即可完成部署。 注意:如果宿机IP发生变化,需要重新创建集群(或者修改每个节点的nodes.conf文件,但比较麻烦)。 因此,建议在稳定的网络环境中使用固定IP。 最后,生成相关问题。</think>### 在Docker中部署3节点Redis集群的步骤 #### 1. **创建自定义网络** ```bash docker network create redis-cluster-net ``` #### 2. **准备节点配置** 为每个节点创建配置文件(以7001-7003端口为例): ```bash mkdir -p /redis-cluster/conf cat > /redis-cluster/conf/redis-7001.conf <<EOF port 7001 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes cluster-announce-ip 宿机的公网IP # 替换为实际IP cluster-announce-port 7001 cluster-announce-bus-port 17001 EOF ``` 重复步骤创建 `redis-7002.conf` 和 `redis-7003.conf`,修改端口号为7002/7003和17002/17003[^3]。 #### 3. **启动容器** ```bash # 节点1 docker run -d --name redis-node1 \ --net redis-cluster-net \ -v /redis-cluster/conf/redis-7001.conf:/usr/local/etc/redis/redis.conf \ -p 7001:7001 -p 17001:17001 \ redis redis-server /usr/local/etc/redis/redis.conf # 节点2(修改端口和名称) docker run -d --name redis-node2 \ --net redis-cluster-net \ -v /redis-cluster/conf/redis-7002.conf:/usr/local/etc/redis/redis.conf \ -p 7002:7002 -p 17002:17002 \ redis redis-server /usr/local/etc/redis/redis.conf # 节点3(修改端口和名称) docker run -d --name redis-node3 \ --net redis-cluster-net \ -v /redis-cluster/conf/redis-7003.conf:/usr/local/etc/redis/redis.conf \ -p 7003:7003 -p 17003:17003 \ redis redis-server /usr/local/etc/redis/redis.conf ``` #### 4. **初始化集群** ```bash docker exec -it redis-node1 redis-cli \ --cluster create \ 宿机的公网IP:7001 \ 宿机的公网IP:7002 \ 宿机的公网IP:7003 \ --cluster-replicas 0 # 明确指定无副本节点 ``` 输入 `yes` 确认槽分配方案,系统会自动分配16384个槽到3个节点[^1]。 #### 5. **验证集群状态** ```bash docker exec -it redis-node1 redis-cli -p 7001 cluster nodes ``` 输出应包含3个 `master` 节点,类似: ``` d186... 宿机的公网IP:7001@17001 master - 0 1620000000000 1 connected 0-5460 a1c2... 宿机的公网IP:7002@17002 master - 0 1620000000000 2 connected 5461-10922 f3b9... 宿机的公网IP:7003@17003 master - 0 1620000000000 3 connected 10923-16383 ``` #### 关键配置说明 - `cluster-enabled yes`:启用集群模式 - `cluster-announce-ip`:客户端访问的IP(需替换为公网IP) - `cluster-announce-bus-port`:节点通信端口(客户端端口+10000) - `--cluster-replicas 0`:明确指定无副本节点[^3] > ⚠️ **注意**:生产环境建议每个节点至少配置1个从节点(使用 `--cluster-replicas 1` 需6个节点),否则节点故障将导致数据不可用。 --- ### 相关问题 1. Redis集群节点故障如何处理? 2. 如何扩展Redis集群的容量? 3. DockerRedis集群的持久化配置有哪些最佳实践? 4. Redis集群的槽(slot)分配原理是什么? 5. 如何监控DockerRedis集群的运行状态? [^1]: Docker容器创建和基本操作参考 [^2]: 持久化存储和目录配置建议 [^3]: Redis集群配置及AOF持久化说明
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值