使用 Docker Compose 创建一个 Redis 集群并暴露外部接口需要配置 docker-compose.yml 文件。以下是一个基本的步骤,包括 Redis 集群的创建和外部接口的暴露。
1、创建 docker-compose.yml
首先,您需要创建一个 docker-compose.yml 文件,配置 Redis 服务。这里是一个创建 Redis 集群的示例:
yaml
version: '3'
services:
redis-1:
image: redis:latest
container_name: redis-1
ports:
- "7001:6379" # 暴露端口7001,内部端口6379
- "17001:16379"
volumes:
- ./redis-1.conf:/usr/local/etc/redis/redis.conf # 挂载自定义配置
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis-net
restart: always
redis-2:
image: redis:latest
container_name: redis-2
ports:
- "7002:6379" # 暴露端口7002,内部端口6379
- "17002:16379"
volumes:
- ./redis-2.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis-net
restart: always
redis-3:
image: redis:latest
container_name: redis-3
ports:
- "7003:6379" # 暴露端口7003,内部端口6379
- "17003:16379"
volumes:
- ./redis-3.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis-net
restart: always
redis-4:
image: redis:latest
container_name: redis-4
ports:
- "7101:6379" # 暴露端口7003,内部端口6379
- "17101:16379"
volumes:
- ./redis-4.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis-net
restart: always
redis-5:
image: redis:latest
container_name: redis-5
ports:
- "7102:6379" # 暴露端口7004,内部端口6379
- "17102:16379"
volumes:
- ./redis-5.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis-net
restart: always
redis-6:
image: redis:latest
container_name: redis-6
ports:
- "7103:6379" # 暴露端口7005,内部端口6379
- "17103:16379"
volumes:
- ./redis-6.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
networks:
- redis-net
restart: always
networks:
redis-net:
driver: bridge
- 创建 Redis 服务:在该 docker-compose.yml 文件中,我们定义了 6 个 Redis 实例(redis-1, redis-2, ..., redis-6),每个实例都运行一个 Redis 容器,并且映射外部端口(7001-7003,7101~7103)到内部端口 6379。
- 挂载配置文件:每个 Redis 服务都挂载了自定义的 redis.conf 配置文件。您可以根据需要在该配置文件中设置集群相关的配置(如启用集群、设置密码等)。
- 设置集群网络:所有 Redis 实例都在 redis-net 网络下运行,这意味着它们可以互相通信。
- 暴露外部接口:通过 ports 配置将 Redis 容器的端口映射到宿主机端口,使外部可以通过宿主机 IP 访问 Redis 服务。
- 自动重启:容器设置为自动重启,以保证 Redis 服务持续运行。
2、 配置文件
redis-1.conf
conf
# 启用集群模式
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
# 设置 AOF 持久化
appendonly yes
# 设置密码
requirepass 123123
masterauth 123123
# 关闭保护模式,允许外部访问
protected-mode no
# 在集群模式下,指定外部 IP 和端口
cluster-announce-ip 192.168.188.101
cluster-announce-port 7001
cluster-announce-bus-port 17001
# 启用连接的最大客户端数
maxclients 10000
redis-2.conf
conf
# 启用集群模式
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
# 设置 AOF 持久化
appendonly yes
# 设置密码
requirepass 123123
masterauth 123123
# 关闭保护模式,允许外部访问
protected-mode no
# 在集群模式下,指定外部 IP 和端口
cluster-announce-ip 192.168.188.101
cluster-announce-port 7002
cluster-announce-bus-port 17002
# 启用连接的最大客户端数
maxclients 10000
redis-3.conf
conf
# 启用集群模式
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
# 设置 AOF 持久化
appendonly yes
# 设置密码
requirepass 123123
masterauth 123123
# 关闭保护模式,允许外部访问
protected-mode no
# 在集群模式下,指定外部 IP 和端口
cluster-announce-ip 192.168.188.101
cluster-announce-port 7003
cluster-announce-bus-port 17003
# 启用连接的最大客户端数
maxclients 10000
redis-4.conf
conf
# 启用集群模式
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
# 设置 AOF 持久化
appendonly yes
# 设置密码
requirepass 123123
masterauth 123123
# 关闭保护模式,允许外部访问
protected-mode no
# 在集群模式下,指定外部 IP 和端口
cluster-announce-ip 192.168.188.101
cluster-announce-port 7101
cluster-announce-bus-port 17101
# 启用连接的最大客户端数
maxclients 10000
redis-5.conf
conf
# 启用集群模式
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
# 设置 AOF 持久化
appendonly yes
# 设置密码
requirepass 123123
masterauth 123123
# 关闭保护模式,允许外部访问
protected-mode no
# 在集群模式下,指定外部 IP 和端口
cluster-announce-ip 192.168.188.101
cluster-announce-port 7102
cluster-announce-bus-port 17102
# 启用连接的最大客户端数
maxclients 10000
redis-6.conf
conf
# 启用集群模式
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
# 设置 AOF 持久化
appendonly yes
# 设置密码
requirepass 123123
masterauth 123123
# 关闭保护模式,允许外部访问
protected-mode no
# 在集群模式下,指定外部 IP 和端口
cluster-announce-ip 192.168.188.101
cluster-announce-port 7103
cluster-announce-bus-port 17103
# 启用连接的最大客户端数
maxclients 10000
3、 启动集群
sh
docker-compose up -d
4、创建 Redis 集群
启动容器后,您可以通过以下命令连接到容器并创建 Redis 集群:
bash
[root@localhost redis-cluster]# docker exec -it redis-1 redis-cli -a 123123 --cluster create 192.168.188.101:7001 192.168.188.101:7002 192.168.188.101:7003 192.168.188.101:7101 192.168.188.101:7102 192.168.188.101:7103 --cluster-replicas 1
此命令将会创建一个有 3 个主节点和 3 个副本节点的 Redis 集群。
bash
\Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> 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.188.101:7102 to 192.168.188.101:7001
Adding replica 192.168.188.101:7103 to 192.168.188.101:7002
Adding replica 192.168.188.101:7101 to 192.168.188.101:7003
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: 84147aee87f743a6af916d0003ee35ae2555f662 192.168.188.101:7001
slots:[0-5460] (5461 slots) master
M: e62aafbdf2bca9d616d0ae9513023d4843d5713c 192.168.188.101:7002
slots:[5461-10922] (5462 slots) master
M: f28d1338ab896db913b6154bbef95119b86fc25c 192.168.188.101:7003
slots:[10923-16383] (5461 slots) master
S: 7d59a668d0f37d29de8ef1975939737a52363cbb 192.168.188.101:7101
replicates f28d1338ab896db913b6154bbef95119b86fc25c
S: 37bde0f815fd4742ec9e7ed70ea36023734af0ff 192.168.188.101:7102
replicates 84147aee87f743a6af916d0003ee35ae2555f662
S: 10fe40aff0430597c2157367e53ef0e4dbf09077 192.168.188.101:7103
replicates e62aafbdf2bca9d616d0ae9513023d4843d5713c
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.
>>> Performing Cluster Check (using node 192.168.188.101:7001)
M: 84147aee87f743a6af916d0003ee35ae2555f662 192.168.188.101:7001
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: f28d1338ab896db913b6154bbef95119b86fc25c 192.168.188.101:7003
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 7d59a668d0f37d29de8ef1975939737a52363cbb 192.168.188.101:7101
slots: (0 slots) slave
replicates f28d1338ab896db913b6154bbef95119b86fc25c
S: 37bde0f815fd4742ec9e7ed70ea36023734af0ff 192.168.188.101:7102
slots: (0 slots) slave
replicates 84147aee87f743a6af916d0003ee35ae2555f662
S: 10fe40aff0430597c2157367e53ef0e4dbf09077 192.168.188.101:7103
slots: (0 slots) slave
replicates e62aafbdf2bca9d616d0ae9513023d4843d5713c
M: e62aafbdf2bca9d616d0ae9513023d4843d5713c 192.168.188.101:7002
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
输入命令后,输入yes,将执行对应集群创建,看到上面的日志输出说明集群已经搭建完成。
5、验证集群状态
创建集群后,您可以使用以下命令验证集群状态:
bash
docker exec -it redis-1 redis-cli -a 123123 cluster info
如果集群设置成功,应该会看到集群的状态信息。
6、使用外部程序来验证链接
go
package main
import (
"context"
"flag"
"fmt"
"github.com/redis/go-redis/v9"
"log"
"strings"
)
func main() {
// 定义命令行参数
var clusterAddrs string
var password string
// 使用 flag 包解析命令行参数
flag.StringVar(&clusterAddrs, "addrs", "192.168.188.101:7001,192.168.188.101:7002,192.168.188.101:7003,192.168.188.101:7101,192.168.188.101:7102,192.168.188.101:7103", "Redis 集群地址")
flag.StringVar(&password, "password", "123123", "Redis 集群密码")
flag.Parse()
// 将集群地址字符串转换为切片
addrs := strings.Split(clusterAddrs, ",")
// 创建 Redis 集群客户端配置
rdb := redis.NewClusterClient(&redis.ClusterOptions{
Addrs: addrs, // 从命令行参数获取的 Redis 集群地址
Password: password, // 从命令行参数获取密码
})
// 确保 Redis 连接成功
ctx := context.Background()
err := rdb.Ping(ctx).Err()
if err != nil {
log.Fatalf("连接到 Redis 失败: %v", err)
}
fmt.Println("成功连接到 Redis 集群")
// 设置一个键值对
err = rdb.Set(ctx, "example_key", "Hello Redis", 0).Err()
if err != nil {
log.Fatalf("设置键值对失败: %v", err)
}
fmt.Println("成功设置键值对")
// 获取一个键的值
val, err := rdb.Get(ctx, "example_key").Result()
if err != nil {
log.Fatalf("获取键值对失败: %v", err)
}
fmt.Printf("获取到的键值对: %v\n", val)
}
运行main函数
输出:
txt
成功连接到 Redis 集群
成功设置键值对
获取到的键值对: Hello Redis
7、小结
使用 Docker Compose 配置 Redis 集群并暴露外部接口是一个高效的方式。通过 docker-compose.yml 文件,我们定义了多个 Redis 实例并暴露了外部接口,便于从外部进行访问和管理。确保每个 Redis 实例的配置文件正确,特别是集群相关的配置。