Mac中使用Docker搭建Redis Cluster集群

【Docker的使用基础】Mac下利用Docker安装Redis Mac下利用Docker安装Redis 阅读详情

写在前面

免责声明:自己也是docker新人,主要是学习和记录
是真的脑抽才会用Docker搭redis集群,homebrew安装的redis配多个配置文件应该也可以直接搭建,时间全花在搞Docker上了,后续有时间了搞一下另一种搭建方式再写一篇博客。
真心建议不要用MacOS搭服务,很痛苦,有时候觉得还不如Windows。开发的话还可以

一、环境准备
1.系统版本

本文演示的系统版本是MacOS 13。

2.确认Docker已安装

在这里插入图片描述
并且,这里本人用的不是Docker Desktop,而是colima,因此使用Docker之前记得colima start启动Docker。

3.拉取Redis镜像
➜  ~ docker pull redis
Using default tag: latest
latest: Pulling from library/redis
d981f2c20c93: Pull complete 
5b8f51f5c4bb: Pull complete 
2d3d8bc9388e: Pull complete 
849e9b1b24f1: Pull complete 
6e2590bc72d8: Pull complete 
bdd261b6469d: Pull complete 
Digest: sha256:f9724694a0b97288d2255ff2b69642dfba7f34c8e41aaf0a59d33d10d8a42687
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest
二、创建Docker容器网络

注意:这里有一点需要说清楚,这也是在这篇博客快要结束的时候才发现的。
如果你要搭建的Redis集群需要对外提供服务,那么可以进行这一步。而如果你只是需要搭建一个本地的Redis集群,供自己本地开发使用,即使用127.0.0.1来访问,那么就不需要这一步了。在下文中,会有多处描述这种区别,会用“需要对外提供服务”和“不需要对外提供服务”的简述来区分上述两种情况,读者根据情况做不同的配置即可。

如果 不需要对外提供服务, 本章节不需要配置。

1.创建虚拟网卡
➜  ~ docker network create myredis
d4bece55cbc015be462605755377faa4a15694d815eb39f9fe2f973f5d8154e1
2.查看Docker网卡信息
➜  ~ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
3831cf1496c6   bridge    bridge    local
01f8f8a01a74   host      host      local
d4bece55cbc0   myredis   bridge    local
1fc0198954f8   none      null      local
3.查看Docker网络详细信息

在这里插入图片描述

4.补充(删除网卡信息、帮助命令)
docker network rm myredis #删除网卡命令 多个中间 空格隔开
docker network --help #显示可带参数等
三、编写配置文件

这里用一个脚本来生成多个配置文件,部分内容根据实际情况做更改
如果 需要对外提供服务,使用如下配置:

for port in $(seq 6379 6384);
do
mkdir -p /[你想设置的目录]/redis/node-${port}/conf
touch /[你想设置的目录]/redis/node-${port}/conf/redis.conf

docker volume create redis_${port};

cat << EOF > /[你想设置的目录]/redis/node-${port}/conf/redis.conf
port ${port}
requirepass 1234
bind 0.0.0.0
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip  [你的宿主机IP]
cluster-announce-port ${port}
cluster-announce-bus-port 1${port}
EOF
done

如果 不需要对外提供服务,可使用如下配置:

for port in $(seq 6379 6384);
do
mkdir -p /[你想设置的目录]/redis/node-${port}/conf
touch /[你想设置的目录]/redis/node-${port}/conf/redis.conf

docker volume create redis_${port};

cat << EOF > /[你想设置的目录]/redis/node-${port}/conf/redis.conf
port ${port}
requirepass 1234
bind 0.0.0.0
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip  127.0.0.1
cluster-announce-port ${port}
cluster-announce-bus-port 1${port}
EOF
done

将脚本写成脚本文件后执行,通过tree查看目录结构,目录结构如图
如果没有tree命令可以先安装tree(brew install tree)
在这里插入图片描述
命令解释:
port:节点端口;
requirepass:设置密码,访问时需要验证
protected-mode:保护模式,默认值 yes,即开启。开启保护模式以后,需配置 bind ip 或者设置访问密码;关闭保护模式,外部网络可以直接访问;
daemonize:是否以守护线程的方式启动(后台启动),默认 no;
appendonly:是否开启 AOF 持久化模式,默认 no;
cluster-enabled:是否开启集群模式,默认 no;
cluster-config-file:集群节点信息文件;
cluster-node-timeout:集群节点连接超时时间;
cluster-announce-ip:集群节点 IP
注意: 如果你想要你的redis集群可以供外网访问,这里直接填 服务器的IP 地址即可
如若为了安全,只是在服务器内部进行访问,这里还需要做一些修改。
cluster-announce-port:集群节点映射端口;
cluster-announce-bus-port:集群节点总线端口。

坑一:redis 在官网上有说明为什么需要映射两个端口 :
在这里插入图片描述

四、创建并启动容器
1.启动Redis容器

使用如下shell脚本,一次性启动6个Redis容器:
如果 需要对外提供服务,且配置了docker虚拟网卡,使用如下配置:

for port in $(seq 6379 6384); do \
  docker run -it -d -p ${port}:${port} -p 1${port}:1${port} \
  --privileged=true -v /Users/sqs/Dev/redis/node-${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \
  --privileged=true -v redis_${port}:/data \
  --restart always --name redis-${port} --net myredis --sysctl net.core.somaxconn=1024 \
  redis redis-server /usr/local/etc/redis/redis.conf
done

如果 不需要对外提供服务,可使用如下配置:

for port in $(seq 6379 6384); do \
  docker run -it -d \
  --privileged=true -v /Users/sqs/Dev/redis/node-${port}/conf/redis.conf:/usr/local/etc/redis/redis.conf \
  --privileged=true -v redis_${port}:/data \
  --restart always --name redis-${port} --net host \
  redis redis-server /usr/local/etc/redis/redis.conf
done

这两个脚本的主要区别在于,第一脚本使用的端口映射,使用的网络模式是桥接模式;第二个脚本没有使用端口映射,使用的网络模式是host模式。

补充
如果使用的–net host网络模式,docker run命令中还做了端口映射的话,端口映射会被docker忽略,执行结果中会有相关提示,上面给出的脚本中已经去掉了端口映射的内容。
在这里插入图片描述

参数解释
-it:交互
-d:后台运行,容器启动完成后打印容器
–privileged:是否让docker 应用容器 获取宿主机root权限(特殊权限-)
-p :端口映射
-v:文件挂载
–sysctl参数来设置系统参数,通过这些参数来调整系统性能
–restart always:在容器退出时总是重启容器
–name :给容器取名
–net myredis :使用我们创建的虚拟网卡 (想详细了解,可以去看看Docker 网络方面知识)

如果 用的第一个脚本创建的容器,docker run成功后结果如下:
在这里插入图片描述
如果 用的第二个脚本创建的容器,docker run成功后结果如下:
在这里插入图片描述

坑二:关于脚本中为什么要创建Docker volume
在步骤三“编写配置文件”中可以看到,脚本中创建了docker volum,本质的原因就是在第四部创建并启动容器中,如果将宿主机的本地目录挂载到容器的/data目录,会出现如下的问题,所以干脆又创建了docker volume使得/data目录可以正常挂载,且能保证数据的持久化。
如果挂载的是宿主机本地的目录,执行脚本后出现如下错误:
在这里插入图片描述
查看了一下发现容器根本就没有起来
在这里插入图片描述
删除容器,重新执行脚本,发现容器没有正常运行:
在这里插入图片描述
容器的状态都是Restarting,这里真的是让人很郁闷了。
接下来使用docker logs -f [container id]来查看容器启动日志,发现如下错误:
在这里插入图片描述
从报错信息大致来看是因为没有权限,至于具体是哪里没有权限,还真的是让我一头雾水。
网上大概查了一下,主要就是因为容器没有权限操作宿主机的目录。如果是Linux环境,好像是关闭SELINUX即可,但是我这里是Mac环境,无法验证这种说法。至于MacOS环境下,有博主说是因为SIP的原因,说是需要关闭SIP,但是MacOS中SIP还是很不建议关闭的,因此这个说法也就不去实际操作验证了,所以还需要另想它法。
因此,就选择了使用docker volume来做映射的方法,命令已经写在了步骤三的脚本中,同样的也是需要创建6个。

docker volume create redis_${port};

问题:volume中的数据如何访问?
创建了volume之后,首先通过如下命令可以查看其挂载点

docker volume inspect redis_6379

在这里插入图片描述
如图所示,可以看到其挂载的目录是在/var/lib/docker/volumes下,但是在宿主机上,可以发现这个目录是不存在的。那么容器关闭后需要持久化的数据怎么办??
其实这里不用担心,虽然看不到这个目录,但是Redis的/data目录中的数据确实是持久化到我们创建的volume中的。想要访问这个目录,可以使用如下命令:

docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh

这里也是启动一个容器并进入其命令行(第一次执行需要下载debian的镜像),在其中就可以访问volume所在的目录了,并且也可以方便的其中的文件拷贝到宿主机的本地目录里。

参数解释:

-即使未连接也保持标准输入打开 + 分配伪 TTY
--privileged “给出了所有功能的容器。允许特殊情况下,像跑步泊坞窗”。
--pid定义使用主机 VM 命名空间。
debian要使用的实际映像。
nsenter一个debian 的工具来在不同的命名空间中运行程序
-t是目标PID
-m挂载提供的 PID 命名空间。
-u输入 Unix 时间共享 (UTS) 命名空间。
-n输入提供的 PID 网络命名空间。
-i输入提供的 PID IPC 命名空间。
2.创建Redis Cluster集群

如果 需要对外提供服务,且配置了docker虚拟网卡,使用如下步骤创建:

可以随意选择其中一个节点进入,创建Redis集群。这里以6379节点为例:
1.进入redis-6379容器

docker exec -it redis-6379 /bin/bash

![在这里插入图片描述](https://img-blog.csdnimg.cn/f9cebd89dc4142c587aaeebdd8c8fa1f.png =400xx)
2.创建集群
进入6379容器后,在命令行执行如下命令将所有节点组建成集群:
其中的IP地址就是在redis.conf文件中的cluster-announce-ip的IP地址,也是前面最开始创建的docker虚拟网卡的网关地址。

redis-cli -a <你设置的redis密码> --cluster create [宿主机IP]:6379 [宿主机IP]:6380 [宿主机IP]:6381 [宿主机IP]:6382 [宿主机IP]:6383 [宿主机IP]:6384 --cluster-replicas 1

执行上述命令后,显示如下内容,需要输入一个yes确认配置
在这里插入图片描述
最终出现这几行内容,就说明集群创建完成。
在这里插入图片描述

如果 不需要对外提供服务,直接使用如下步骤创建:
因为docker网络模式用的host模式,创建集群时可以直接使用IP 127.0.0.1

redis-cli -a 1234 --cluster create 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 --cluster-replicas 1

在这里插入图片描述
同样的,出现如下内容代表创建完成。
在这里插入图片描述

3.集群创建验证

可以继续在容器6379中执行:

redis-cli -c -a 1234

连接上redis后,执行cluster info,可以看到共6个节点
在这里插入图片描述
再执行cluster nodes,可以看到共六个节点,三个master,三个slave,验证没问题。
在这里插入图片描述
如果使用的是--net host网络模式及上述配置,验证截图如下:
在这里插入图片描述
在这里插入图片描述

五、集群测试
1.本地测试

我们就不在容器内测试了,直接在宿主机测试。
外网是无法测试的,因为目前是本地环境,没有公网IP。局域网也不测了先,没有那么多电脑。
主要测试逻辑就是:使用端口A set值,然后通过端口B get值,如果可以get到说明集群模式没有问题。
1.首先我们通过6380端口连接Redis集群,进行set操作,可以看到已经set成功
在这里插入图片描述
2.然后我们通过另一个master节点6381进行get操作
可以看到因为name所在的slot在6380节点上,这里会自动重定向到6380,且重定向成功
在这里插入图片描述

坑三:cluster-announce-ip如果设置的为docker内网关IP,会导致容器外部访问无法重定向
其实,之前踩坑的整个过程中,是用的docker虚拟网卡桥接的网络模式搭建一个本地可用的Redis Cluter模式集群,因为宿主机的IP也不固定,所以redis.conf文件中cluster-announce-ip设置的是docker虚拟网卡的网关地址,这样就造成了一个问题,如果进入到其中一个Redis节点的容器内,整个cluster集群是可用的。但是如果在宿主机访问这个Redis集群的时候,因为加了端口映射,6379-6384端口也都能通过127.0.0.1访问,不涉及重定向的get,set指令也都能正常执行,但是一旦涉及到slot的重定向,redis返回的重定向IP是docker容器内部的IP 172.18.0.1,这个IP在宿主机是无法访问的,因此会导致重定向失败。
在这里插入图片描述
所以,本文后来又在之前的基础上加了不需要对外提供服务的部分,即使用host网络模式搭建集群,这样就可以正常重定向了,也就可以在本地的项目中调用该redis集群了。
但是也导致了本文看起来有点复杂,有点混乱。暂时先这样吧,细心看应该还是能看懂的,毕竟也不是太难的东西。以后有时间可能改改吧,目前为止已经耗费了太多精力了。

参考资料

http://www.taodudu.cc/news/show-568884.html?action=onClick
https://www.cnblogs.com/mrhelloworld/p/docker12.html
https://blog.youkuaiyun.com/flyzing/article/details/113178480
https://zenn.dev/kentama/articles/5d79ba1e28cddd
https://qa.1r1g.com/sf/ask/2697273841/

MacOS系统Docker容器自动安装mysql和mongodb及redis conf为当前目录下的conf文件夹 :/etc/mysql/conf.d 为映射到容器中的目录。在容器中运行mysql服务器 , 3306为容器中的端口 33060为映射到外部的端口。1.先安装好Docker-Desktop并启动。mysql已成功运行于容器中。拉取mongodb镜像。2.安装mysql容器。拉mysql5.6镜像。mysql镜像成功拉取。 阅读详情

相关推荐

机械臂 关节电机选型计算

电机 机械臂

hisen92的专栏 8983

国家大地2000坐标系投影坐标转高德地图经纬度坐标-【高斯投影坐标】

国家大地2000坐标系投影坐标转换成高德经纬度坐标显示画图。

devil_zhuzhu的博客 1万+

px3 有感分析

px3 后续分析

qq_39707917的博客 3115

Synares病毒实战:如何从U盘感染中恢复你的Excel和EXE文件(附专杀工具推荐)

本文详细介绍了Synares感染型病毒的典型特征与传播机制,特别是其通过U盘感染Excel和EXE文件的行为。文章提供了一套从应急隔离、诊断到使用专杀工具进行深度清除与文件恢复的完整实战流程,并推荐了有效的安全软件和修复方法,旨在帮助用户最大程度救回重要数据并构建长效安全防护习惯。

weixin_29230649的博客 1818

C#利用最小二乘法拟合任意次函数曲线

给出一组离散点,确定一个函数逼近原函数,插值是这样的一种手段。在实际中,数据不可避免的会有误差,插值函数会将这些误差也包括在内。因此,我们需要一种新的逼近原函数的手段: ①不要求过所有的点(可以消除误差影响);②尽可能表现数据的趋势,靠近这些点。利用最小二乘法可以简便地求得未知的数据,并使得这些求得的数据与实际数据之间误差的平方和为最小 [1],其他一些优化问题也可通过最小化能量或最大化熵用最小二乘法来表达,具体可以查阅相关资料。最小二乘法(又称最小平方法)是一种数学技术。

qq_30725967的博客 3755

月薪30k+的工业视觉,必备Java+YOLO技能(工业级落地全拆解)

30k+工业视觉岗的核心不是算法调参,而是用Java把YOLO落地到工业场景的能力——稳运行、能对接、可管理是高薪的核心壁垒;必备技能分五层:模型工业级适配、Java推理核心、SpringBoot后端、工业部署运维、场景适配,每层都要练到“能落地、能讲清、能避坑”;学习路径的核心是“实战驱动”:不要只学理论,从一个完整的工业项目(如锂电缺陷检测)入手,练完就能对标高薪岗。

2601_94871597的博客 525

【应用】打造你的安全本地AI购物助手:OpenClaw + 淘宝MCP部署全攻略

本文介绍了在Ubuntu虚拟机中配置OpenClaw连接Windows宿主机的淘宝MCP服务的两种方案。核心原理是通过修改MCP服务监听地址或SSH隧道转发,实现跨网络访问。方案1推荐修改MCP服务绑定0.0.0.0并配置防火墙放行端口,适合长期使用;方案2通过SSH隧道转发,适合临时测试。文章详细说明了环境准备、配置文件修改及两种互通方案的具体实施步骤,重点解决了虚拟机与宿主机网络互通的关键问题。

海兰 1323

基于电阻分压 + 电压跟随器的直流母线电压采样电路

摘要:本文介绍了一种基于电阻分压和电压跟随器的直流母线电压采样电路设计。该电路通过R38(240kΩ)和R41(20kΩ)组成的分压网络将高电压(如48V)降至3V,再经GS8331运放构成的电压跟随器进行隔离缓冲,最后通过RC滤波输出给ADC采集。重点分析了关键元件的选型要求:分压电阻需高精度、低温度系数;运放需高输入阻抗、低失调电压;滤波电容需稳定性好。该设计适用于工业电源、新能源BMS、变频器等需要高精度电压采样的应用场景。

qq_37999850的博客 890

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

上一篇: HomeBrew安装的Redis,启动时的那些坑
下一篇: Mac安装zookeeper
Xeon-Shao
博客等级 码龄15年 4822粉丝 192原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值