1、前言

本文主要针对M2下,相应进行开发环境搭建,然后做一个文档记录,是第二弹文章,搭建是采用docker compose文件。
 希望对相关人有帮助。如果只想要Docker-Compose文件,请转到第三节的单机模式和第四节的集群模式。

原本是打算使用redis-commander进行docker集群内访问redis cluster,但是很可惜,官方似乎在docker compose组建的运行环境下是存在问题的,Issue看这

2、官方文档重点信息提取

redis的docker镜像官网地址在此处点击

2.1、创建redis实例

docker run --name some-redis -d redis

如果想持久化,则是如下命令:

docker run --name some-redis -d redis redis-server --save 60 1 --loglevel warning

redis-server --save 60 1 --loglevel warning,这是传递给 Redis 服务器的参数,它告诉 Redis 服务器在后台每隔 60 秒检查一次数据库,如果有至少一个键被修改,则将其写入磁盘。后面的 1 表示如果至少有一个键被修改,则每秒进行一次检查。–loglevel warning 设置 Redis 服务器的日志级别为 “warning”,表示只记录警告级别的日志。

2.2、使用自己的redis.conf文件。

创建自己的Dockerfile文件,将上下文中的redis.conf添加到/data/中,如下所示

FROM redis
COPY redis.conf /usr/local/etc/redis/redis.conf
CMD [ "redis-server", "/usr/local/etc/redis/redis.conf" ]

也可以使用docker命令

docker run -v /myredis/conf:/usr/local/etc/redis --name myredis redis redis-server /usr/local/etc/redis/redis.conf

其中/myredis/conf/是包含redis.conf文件的本地目录。使用这种方法意味着你不需要为你的redis容器创建Dockerfile。
映射的目录应该是可写的,因为根据配置和操作模式,Redis可能需要创建额外的配置文件或重写现有的配置文件。

3、单机版redis搭建

先创建redis单机版的目录。

mkdir redis-single

然后在redis-single目录下,创建两个目录,一个是conf,一个是data

mkdir conf data

在conf目录下创建redis.conf文件

# redis-single.conf
# 允许来自任何IP的连接
bind 0.0.0.0
# 设置启动保护模式
# protected-mode yes
# 设置密码
requirepass test123

save 900 1      # 在900秒(15分钟)内,如果至少有1个键被修改,就创建一个RDB快照
save 300 10       # 在300秒(5分钟)内,如果至少有10个键被修改,就创建一个RDB快照
save 60 10000     # 在60秒内,如果至少有10000个键被修改,就创建一个RDB快照

appendonly yes # 启用了 AOF 持久化
appendfsync everysec   # 将写操作追加到AOF文件并在每秒同步一次

上述配置为aof持久化的时机,解释如下:

然后回退到上一级目录,即redis-single目录下,创建docker-compose.yml文件,文件内容如下所示:

version: '3.1'

services:
  redis-single:
    image: redis:latest
    restart: always
    ports:
      - "6379:6379"
    volumes:
      - /Users/tanqiwei/docker-dev/redis-single/data:/data
      - /Users/tanqiwei/docker-dev/redis-single/conf/redis-single.conf:/etc/redis/redis.conf
    command: ["redis-server", "/etc/redis/redis.conf"]

然后输入下面命令启动:

docker compose up

【Docker-Dev】Mac M2 搭建docker的redis环境-LMLPHP
然后外部用一些redis的可视化客户端连接进行连接,然后进行key的创建和更新都是正常的。
【Docker-Dev】Mac M2 搭建docker的redis环境-LMLPHP

4、redis集群版

redis集群版,最开始写的很顺利,而且成功运行,但是目前为止,我依旧没找到任何可以通过外部手段连接该集群的方式,等待后续更新,集群是正常创建的。

由于使用redis cluster,创建3节点主,3节点副本,所以一共是6个节点。

首先创建redis-cluster目录

mkdir redis-cluster

同样是在这个目录下,创建conf data两个文件夹。

mkdir conf data

然后进入conf目录,创建redis-master.conf文件,内容如下:

# redis-cluster.conf
# 启用集群模式
bind 0.0.0.0
cluster-enabled yes
cluster-node-timeout 5000
requirepass test123
cluster-config-file nodes.conf
masterauth test123

# 在900秒(15分钟)内,如果至少有1个键被修改,就创建一个RDB快照
save 900 1   
# 在300秒(5分钟)内,如果至少有10个键被修改,就创建一个RDB快照
save 300 10  
# 在60秒内,如果至少有10000个键被修改,就创建一个RDB快照     
save 60 10000     

# 启用了 AOF 持久化
appendonly yes
# 将写操作追加到AOF文件并在每秒同步一次
appendfsync everysec   

然后使用cp命令创建另外5个文件(文件内容一模一样)。

tanqiwei@tanqiweideMacBook-Pro conf % ls
redis-master.conf	redis-node2.conf	redis-slave1.conf
redis-node1.conf	redis-node3.conf	redis-slave2.conf

然后回到上一层下的data目录,分别创建如下六个文件夹(文件夹名分别为master、node1、node2、node3、slave1、slave2):

tanqiwei@tanqiweideMacBook-Pro data % ls
master	node1	node2	node3	slave1	slave2

接着回到redis cluster,创建下面的docker-compose文件。

version: '3.1'

services:
  redis-cluster:
    image: 'redis:latest'
    entrypoint: /bin/sh -c
    command: >
      "echo yes | redis-cli --cluster create
      198.20.0.31:6379
      198.20.0.32:6379
      198.20.0.33:6379
      198.20.0.34:6379
      198.20.0.35:6379
      198.20.0.36:6379
      --cluster-replicas 1 --pass test123"
    networks:
      redis_cluster_subnet:
        ipv4_address: 198.20.0.30
    depends_on:
      - redis-master
      - redis-slave1
      - redis-slave2
      - redis-node1
      - redis-node2
      - redis-node3


  redis-master:
    image: redis:latest
    restart: always
    ports:
      - "7001:6379"
    volumes:
      - /Users/tanqiwei/docker-dev/redis-cluster/data/master:/data
      - /Users/tanqiwei/docker-dev/redis-cluster/conf/redis-master.conf:/etc/redis/redis.conf
    command: ["redis-server", "/etc/redis/redis.conf"]
    networks:
      redis_cluster_subnet:
        ipv4_address: 198.20.0.31

  redis-slave1:
    image: redis:latest
    restart: always
    ports:
      - "7002:6379"
    volumes:
      - /Users/tanqiwei/docker-dev/redis-cluster/data/slave1:/data
      - /Users/tanqiwei/docker-dev/redis-cluster/conf/redis-slave1.conf:/etc/redis/redis.conf
    command: ["redis-server", "/etc/redis/redis.conf"]
    networks:
      redis_cluster_subnet:
        ipv4_address: 198.20.0.32

  redis-slave2:
    image: redis:latest
    restart: always
    ports:
      - "7003:6379"
    volumes:
      - /Users/tanqiwei/docker-dev/redis-cluster/data/slave2:/data
      - /Users/tanqiwei/docker-dev/redis-cluster/conf/redis-slave2.conf:/etc/redis/redis.conf
    command: ["redis-server", "/etc/redis/redis.conf"]
    networks:
      redis_cluster_subnet:
        ipv4_address: 198.20.0.33


  redis-node1:
    image: redis:latest
    restart: always
    ports:
      - "7004:6379"
    volumes:
      - /Users/tanqiwei/docker-dev/redis-cluster/data/node1:/data
      - /Users/tanqiwei/docker-dev/redis-cluster/conf/redis-node1.conf:/etc/redis/redis.conf
    command: ["redis-server", "/etc/redis/redis.conf"]
    networks:
      redis_cluster_subnet:
        ipv4_address: 198.20.0.34      

  redis-node2:
    image: redis:latest
    restart: always
    ports:
      - "7005:6379"
    volumes:
      - /Users/tanqiwei/docker-dev/redis-cluster/data/node2:/data
      - /Users/tanqiwei/docker-dev/redis-cluster/conf/redis-node2.conf:/etc/redis/redis.conf
    command: ["redis-server", "/etc/redis/redis.conf"]
    networks:
      redis_cluster_subnet:
        ipv4_address: 198.20.0.35 

  redis-node3:
    image: redis:latest
    restart: always
    ports:
      - "7006:6379"
    volumes:
      - /Users/tanqiwei/docker-dev/redis-cluster/data/node3:/data
      - /Users/tanqiwei/docker-dev/redis-cluster/conf/redis-node3.conf:/etc/redis/redis.conf
    command: ["redis-server", "/etc/redis/redis.conf"]
    networks:
      redis_cluster_subnet:
        ipv4_address: 198.20.0.36     

networks:
  redis_cluster_subnet:
    driver: bridge
    ipam:
      config:
        - subnet: 198.20.0.0/24    

在这个docker compose文件里面,为了能6个节点互联,且能够固定IP,所以我采用了子网的方式。

networks:
  redis_cluster_subnet:
    driver: bridge
    ipam:
      config:
        - subnet: 198.20.0.0/24

然后每个redis集群,其实按照单机版的方式处理,只是加了网络的选项,而且配置文件设置了以集群方式开启。

最后定义了一个名为 redis-cluster 的服务,使用最新版本的 Redis 镜像。entrypoint 和 command 部分包含了在容器启动时执行的命令,用于初始化 Redis 集群。

然后执行docker compose up的命令就能启动成功。

【Docker-Dev】Mac M2 搭建docker的redis环境-LMLPHP

【Docker-Dev】Mac M2 搭建docker的redis环境-LMLPHP

4.1、一些验证

docker exec -it redis-cluster-redis-master-1 /usr/local/bin/redis-cli -c -a test123 --cluster check 198.20.0.31:6379

输出如下所示:

tanqiwei@tanqiweideMacBook-Pro data % docker exec -it redis-cluster-redis-master-1 /usr/local/bin/redis-cli -c -a test123 --cluster check 198.20.0.31:6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
198.20.0.31:6379 (b244b72f...) -> 0 keys | 5461 slots | 1 slaves.
198.20.0.33:6379 (183e2e42...) -> 0 keys | 5461 slots | 1 slaves.
198.20.0.32:6379 (cfcf1409...) -> 1 keys | 5462 slots | 1 slaves.
[OK] 1 keys in 3 masters.
0.00 keys per slot on average.

>>> Performing Cluster Check (using node 198.20.0.31:6379)
M: b244b72fc5375c7e559ccb02aff9992e0d1aa0d0 198.20.0.31:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 183e2e42276ab7a4dfdfb426cb3e01a65a038362 198.20.0.33:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 91c8156bd7afd58c252d09ea416b68abbd3ddb49 198.20.0.35:6379
   slots: (0 slots) slave
   replicates b244b72fc5375c7e559ccb02aff9992e0d1aa0d0
S: 7cf393d7371a927104ae861cdb8dc675f2a35281 198.20.0.36:6379
   slots: (0 slots) slave
   replicates cfcf14091a752771d47e092321e3f4ade75f6de7
S: df71e5c164e2f99e41b1a951d7bc60c6e9daa7eb 198.20.0.34:6379
   slots: (0 slots) slave
   replicates 183e2e42276ab7a4dfdfb426cb3e01a65a038362
M: cfcf14091a752771d47e092321e3f4ade75f6de7 198.20.0.32:6379
   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.

输入下面命令进入对应的docker服务:

docker exec -it redis-cluster-redis-master-1 /usr/local/bin/redis-cli -c -a test123 -h 198.20.0.31 -p 6379

【Docker-Dev】Mac M2 搭建docker的redis环境-LMLPHP

然后进行一些集群信息访问:
【Docker-Dev】Mac M2 搭建docker的redis环境-LMLPHP
【Docker-Dev】Mac M2 搭建docker的redis环境-LMLPHP

目前可以确认服务内部的ok的,至于最开始无法命令get是因为从节点一般做备份,不允许读取,所以得开readonly命令。

4.2、一些问题

在进行docker compose down或者docker compose stop命令后,再次重启会提示。

[ERR] Node XXX is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.

在google查了许久没有头绪,只能每次重启前进行数据清理。

删除每个redis下的appendonly.aof、dump.rdb、xxx.conf文件。
例如我在redis-cluster目录下时执行这个命令。

rm -rf data/*/*

第二个问题是无法进行外部连接访问,任何redis的连接器包括原生的redis-cli,在docker宿主机的情况下,无法连接内部集群,只能通过容器内部访问。

结语

目前搭建redis单机是没问题的,按自己思路搭建集群也没问题,后面发现无法通过宿主机外部连接访问,进行了各种查询,也尝试过海外其他人的方案,都无法让外部宿主机进行访问。
我认为可能有其他方式,或者配置上的问题,目前研究时间有限,等后续抽时间研究好了,再更新文档。

01-01 07:22