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

Redis的dev环境docker搭建

1、前言

本文主要针对M2下,相应进行开发环境搭建,然后做一个文档记录,是第二弹文章,搭建是采用docker compose文件。

希望对相关人有帮助。如果只想要Docker-Compose文件,请转到第三节的单机模式和第四节的集群模式。

针对第四节集群模式,这里有个地方需要提前说明,目前redis cluster的搭建模式,存在一个问题无法解决,即无法通过Docker暴露出的端口进行宿主机的外部访问连接,后续只能看看是否研究开启tsl或者其他方式允许访问。从内部各种方式可以验证出,集群状态是正常的,而且数据能正常访问。

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

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

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

hub地址是需要翻墙访问

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/中,如下所示

bash 复制代码
FROM redis
COPY redis.conf /usr/local/etc/redis/redis.conf
CMD [ "redis-server", "/usr/local/etc/redis/redis.conf" ]

也可以使用docker命令

bash 复制代码
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单机版的目录。

bash 复制代码
mkdir redis-single

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

bash 复制代码
mkdir conf data

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

bash 复制代码
# 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持久化的时机,解释如下:

关键字 持久化时机 解释
appendfsync always 每执行一次更新命令,持久化一次
appendfsync everysec 每秒钟持久化一次
appendfsync no 不会主动执行持久话,依赖于操作系统的空闲调用

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

yaml 复制代码
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"]

然后输入下面命令启动:

bash 复制代码
docker compose up

然后外部用一些redis的可视化客户端连接进行连接,然后进行key的创建和更新都是正常的。

4、redis集群版

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

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

首先创建redis-cluster目录

bash 复制代码
mkdir redis-cluster

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

bash 复制代码
mkdir conf data

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

bash 复制代码
# 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个文件(文件内容一模一样)。

bash 复制代码
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):

bash 复制代码
tanqiwei@tanqiweideMacBook-Pro data % ls
master	node1	node2	node3	slave1	slave2

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

yaml 复制代码
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,所以我采用了子网的方式。

yaml 复制代码
networks:
  redis_cluster_subnet:
    driver: bridge
    ipam:
      config:
        - subnet: 198.20.0.0/24

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

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

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

4.1、一些验证

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

输出如下所示:

bash 复制代码
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.

redis-cluster-redis-master-1是启动后的redis服务名,按docker ps查询得到。

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

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

然后进行一些集群信息访问:

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

4.2、一些问题

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

bash 复制代码
[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目录下时执行这个命令。

bash 复制代码
rm -rf data/*/*

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

这个问题找了半天都没有头绪,后续有时间研究出来了,再更新文档

结语

目前搭建redis单机是没问题的,按自己思路搭建集群也没问题,后面发现无法通过宿主机外部连接访问,进行了各种查询,也尝试过海外其他人的方案,都无法让外部宿主机进行访问。

我认为可能有其他方式,或者配置上的问题,目前研究时间有限,等后续抽时间研究好了,再更新文档。

相关推荐
两点王爷1 小时前
IDEA中springboot项目中连接docker
spring boot·docker·intellij-idea
家庭云计算专家1 小时前
还没用过智能文档编辑器吗?带有AI插件的ONLYOFFICE介绍
服务器·人工智能·docker·容器·编辑器
孤的心了不冷4 小时前
【Docker】CentOS 8.2 安装Docker教程
linux·运维·docker·容器·eureka·centos
头疼的程序员5 小时前
docker学习与使用(概念、镜像、容器、数据卷、dockerfile等)
学习·docker·容器
IT小郭.5 小时前
使用 Docker Desktop 安装 Neo4j 知识图谱
windows·python·sql·docker·知识图谱·database·neo4j
淡水猫.5 小时前
hbit资产收集工具Docker(笔记版)
运维·docker·容器
laocooon5238578866 小时前
一台入网的电脑有6要素, 机器名,mac,ip,俺码,网关,dns,分别有什么作用
网络协议·tcp/ip·macos
dddaidai12313 小时前
分布式ID和分布式锁
redis·分布式·mysql·zookeeper·etcd
旧故新长13 小时前
访问 Docker 官方镜像源(包括代理)全部被“重置连接”或超时
运维·docker·容器
white.tie14 小时前
Docker部署单节点Elasticsearch
elasticsearch·docker·jenkins