1.文章说明
- 个人学习linux下单机redis伪集群,如有不足请多指教。
- 环境: linux centos7.8,docker-ce-18.06.3.ce,redis 6.0.6,gcc devtoolset 9等。
- redis多节点有三种,最小运行为:主从模式(一主一从)、哨兵模式(一哨兵一主两从)、集群模式(三主三从)。
- 本次学习搭建了三种集群模式(三主三从)。
2.环境准备
-
系统准备,使用了VMware建立linux虚拟机,使用centos7镜像。(准备两台虚拟机,一台用来编译源码测试,一台用来装docker,我的两台虚拟机IP 192.168.1.108 192.168.1.110)
#虚拟机及系统安装自行学习 #学习的时候完全关闭防火墙,生成环境谨慎使用 #防火墙状态 systemctl status firewalld #关闭防火墙 systemctl stop firewalld #关闭防火墙服务 systemctl disable firewalld
-
安装docker(虚拟机IP 192.168.1.110)。
#docker的详细配置大家自行学习。 #安装docker社区版 yum install docker-ce-18.06.3.ce #启动、自启 systemctl start docker systemctl enable docker
-
安装gcc,用于编译redis源码(虚拟机IP 192.168.1.108)。
#安装gcc yum install gcc # 升级gcc yum -y install centos-release-scl yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils #启用devtoolset-9 scl enable devtoolset-9 bash #设置系统默认 echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile
-
下载redis源码及编译等(虚拟机IP 192.168.1.108)。redis官方下载地址
#在linux根路径新建文件夹 mkdir /redis #如果没有安装wget yum install wget -y #下载redis源码到新建文件夹 wget http://download.redis.io/releases/redis-6.0.6.tar.gz #解压redis源码 tar -zxvf redis-6.0.6.tar.gz #进入源码文件夹 cd redis-6.0.6 #编译redis源码,等待编译完成 make
此工作主要是为了得到一个可以独立运行的redis-cli,在 /redis/redis-6.0.6/src 下:
-
编辑(/redis/redis-6.0.6/redis.conf)文件。为了简单(偷懒)所有的redis都将使用这个配置文件。
#编辑/redis/reids-6.0.6/redis.conf #我使用的是vim,原linux是没有vim的,可以自行安装或者使用vi vim redis.conf
注释掉bind 127.0.0.1,并添加 protected-mode no(关闭保护模式)################################## NETWORK ##################################### #By default, if no "bind" configuration directive is specified, Redis listens #for connections from all the network interfaces available on the server. #It is possible to listen to just one or multiple selected interfaces using #the "bind" configuration directive, followed by one or more IP addresses. # #Examples: # #bind 127.0.0.1 ::1 protected-mode no
打开集群设置
################################## INCLUDES ################################### #Normal Redis instances can't be part of a Redis Cluster; only nodes that are #started as cluster nodes can. In order to start a Redis instance as a #cluster node enable the cluster support uncommenting the following: # cluster-enabled yes #Every cluster node has a cluster configuration file. This file is not #intended to be edited by hand. It is created and updated by Redis nodes. #Every Redis Cluster node requires a different cluster configuration file. #Make sure that instances running in the same system do not have #overlapping cluster configuration file names. # cluster-config-file nodes-6379.conf #Cluster node timeout is the amount of milliseconds a node must be unreachable #for it to be considered in failure state. #Most other internal time limits are multiple of the node timeout. # cluster-node-timeout 15000
-
新建文件夹(按照个人习惯新建)
在192.168.1.110根目录新建redis文件夹统一存放,从192.168.1.108拷贝redis.conf。scp redis.conf root@192.168.1.110:/redis
在192.168.1.110的redis文件夹下新建datas,并创建端口对应的文件夹
cd /redis mkdir datas cd datas mkdir 6379 6380 6381 6382 6383 6384
3.Docker安装多节点redis
-
docker下载redis(虚拟机IP192.168.1.110)
#下载redis docker pull redis:6.0.6
这里是下载的reids镜像,后面要使用IMAGE ID -
启动redis节点
#启动第一个节点 docker run -itd --privileged=true -p 6379:6379 -p 16379:16379 --name redis_6379 -v /redis/redis.conf:/etc/redis/redis.conf -v /redis/datas/6379:/data {下载的IMAGE ID} redis-server /etc/redis/redis.conf #启动第二个节点 docker run -itd --privileged=true -p 6380:6379 -p 16380:16379 --name redis_6380 -v /redis/redis.conf:/etc/redis/redis.conf -v /redis/datas/6380:/data {下载的IMAGE ID} redis-server /etc/redis/redis.conf #启动第三个节点 docker run -itd --privileged=true -p 6381:6379 -p 16381:16379 --name redis_6381 -v /redis/redis.conf:/etc/redis/redis.conf -v /redis/datas/6381:/data {下载的IMAGE ID} redis-server /etc/redis/redis.conf #启动第四个节点 docker run -itd --privileged=true -p 6382:6379 -p 16382:16379 --name redis_6382 -v /redis/redis.conf:/etc/redis/redis.conf -v /redis/datas/6382:/data {下载的IMAGE ID} redis-server /etc/redis/redis.conf #启动第五个节点 docker run -itd --privileged=true -p 6383:6379 -p 16383:16379 --name redis_6383 -v /redis/redis.conf:/etc/redis/redis.conf -v /redis/datas/6383:/data {下载的IMAGE ID} redis-server /etc/redis/redis.conf #启动第六个节点 docker run -itd --privileged=true -p 6384:6379 -p 16384:16379 --name redis_6384 -v /redis/redis.conf:/etc/redis/redis.conf -v /redis/datas/6384:/data {下载的IMAGE ID} redis-server /etc/redis/redis.conf
-
查看宿主机和容器IP
#docker inspect {各个redis容器ID} | grep IPAddress docker inspect 7f6d209fe257 966b8ed724ce 75ff0495e6ec ff854f1832d9 25c27e97b5b1 ae7a2f763e8c | grep IPAddress
宿主机IP | 容器内IP |
---|---|
192.168.1.110:6379 | 172.17.0.2 |
192.168.1.110:6380 | 172.17.0.3 |
192.168.1.110:6381 | 172.17.0.4 |
192.168.1.110:6382 | 172.17.0.5 |
192.168.1.110:6383 | 172.17.0.6 |
192.168.1.110:6384 | 172.17.0.7 |
-
添加集群节点
进入其中一个容器docker exec -it ae7a2f763e8c bash cd /usr/local/bin/
执行如下命令# --cluster-replicas 参数为数字,1表示每个主节点需要1个从节点。 ./redis-cli --cluster create 172.17.0.2:6379 172.17.0.3:6379 172.17.0.4:6379 172.17.0.5:6379 172.17.0.6:6379 172.17.0.7:6379 --cluster-replicas 1
产生问题(未解决)
# 在 192.168.1.110和192.168.1.108容器内外的redis-cli都测试过 # 不成功!一直等待 Waiting for the cluster to join 很久都没有反应 ./redis-cli --cluster create 192.168.1.110:6379 192.168.1.110:6380 192.168.1.110:6381 192.168.1.110:6382 192.168.1.110:6383 192.168.1.110:6384 --cluster-replicas 1
-
此时查看集群状态
# 连接集群 ./redis-cli -c # 输入 cluster info
-
主从复制(三主三从)
# 输入 cluster nodes
4.主备测试
-
停止6370节点
docker stop redis_6384 # 查看所有容器 docker ps -a
-
查看redis集群
#在 /redis/redis-6.0.6/src 下 使用 ./redis-cli -p 6380 #输入cluster nodes查看节点ID cluster nodes
主节点自动降备,且slave失败,它之前的从节点自动升为主节点
重新启动6379,节点恢复正常,且主备互换
5.本地客户端读写测试
-
客户端连接(虚拟机IP192.168.1.110)容器内redis-cli
登录没有启动集群模式(命令缺少"-c"):
-
增删改查
-
集群同步测试
6.远程客户端测试(有问题)
-
虚拟机IP 192.168.1.108连接192.168.1.110上docker,使用源码编译后的redis-cli
说明:从上图出现连接超时,看出192.168.1.108不能访问192.168.1.110中docker中的redis集群
-
虚拟机IP192.168.1.110编译redis源码,容器外redis-cli
说明:从上图192.168.1.110中容器外redis-cli可以连接docker中的redis集群 -
产生的问题 (另一个虚拟机为什么不能访问redis集群)
docker有4种网络模式网络模式 配置 说明 host –net=host 容器和宿主机共享Network namespace。 container –net=container:NAME_or_ID 容器和另外一个容器共享Network namespace。 kubernetes中的pod就是多个容器共享一个Network namespace。 none –net=none 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair 和网桥连接,配置IP等。 bridge –net=bridge 容器和宿主机有各自独立的网段 个人猜测:192.168.1.110可以通过自身网卡docker0的虚拟网桥找到docker中的其他网卡,而192.168.1.108访问192.168.1.110物理网卡,并且redis集群是docker内loopback的,所以不能,如果想要访问通过设置docker网络模式(有待验证)。
下一步尝试三台虚拟机直接启动6节点,是否能够达到进一步伪集群。