基于docker搭建Redis集群

Redis集群介绍

Redis集群选举算法决定了一个Redis集群至少需要3个master,同时每个master节点至少需要一个slave节点做备份,因此一个Redis集群至少需要6个节点。本文也正是在一台宿主机上使用docker构建一个有6个节点的Redis集群。

Redis使用槽(slot)指派的方式来进行数据在节点上的分配。一个Redis集群总共有16384(2^14)个槽,假设有3个master,平均每个master负责16384/3=5461个槽。key分配的算法是:对key进行CRC16算法,然后跟16384取模,得到的就是落在哪个槽位,然后根据槽在节点上的分配关系,最终得到这个key落在哪个节点的哪个槽上。槽公式如下:slot = CRC16(key) & 16383。

环境准备

宿主机(本文操作系统为MacOS 11.6,不同系统上docker安装和使用会有不同)

git

Homebrew

envsubst

docker

Mac安装git:

参考文章:Mac安装Git_rockvine的博客-CSDN博客_mac安装git

建议直接去Git官网下载官方安装包installer进行安装,比较方便。

Mac安装Homebrew:

参考文章:Mac安装brew_@单空的博客-CSDN博客_mac 安装brew

Mac安装envsubst:

参考文章:Mac 下安装 envsubst 命令 | 言曌博客

两行命令即可:

brew install gettext

brew link --force gettext

Mac安装docker

参考文章:MacOS Docker 安装 | 菜鸟教程

笔者选择的是手动下载安装Install Docker Desktop on Mac。

这里贴一下Redis的docker hub地址,可以看到Redis各个版本的镜像:Docker Hub

集群搭建

先找出本机的IP:192.168.31.230,后面会用到。

编写配置文件redis.conf

由于我在本机配置了6个服务,所以需要6份配置文件,为了提高效率,可以采用批量创建模版redis-cluster.tmpl

port ${PORT}
requirepass 1234
masterauth 1234
protected-mode no
daemonize no
appendonly yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
cluster-announce-ip 192.168.31.230
cluster-announce-port ${PORT}
cluster-announce-bus-port 1${PORT}

执行脚本文件redis-cluster.sh

#!/bin/bash
for port in `seq 6371 6376`; do \
  mkdir -p ${port}/conf \
  && PORT=${port} envsubst < redis-cluster.tmpl > ${port}/conf/redis.conf \
  && mkdir -p ${port}/data;\
done

配置说明

port:节点端口;
requirepass:添加访问认证;
masterauth:如果主节点开启了访问认证,从节点访问主节点需要认证;
protected-mode:保护模式,默认值 yes,即开启。开启保护模式以后,需配置 bind ip 或者设置访问密码;关闭保护模式,外部网络可以直接访问;
daemonize:是否以守护线程的方式启动(后台启动),默认 no;
appendonly:是否开启 AOF 持久化模式,默认 no;
cluster-enabled:是否开启集群模式,默认 no;
cluster-config-file:集群节点信息文件;
cluster-node-timeout:集群节点连接超时时间;
cluster-announce-ip:集群节点 IP,填写宿主机的 IP;
cluster-announce-port:集群节点映射端口;
cluster-announce-bus-port:集群节点总线端口。

每个Redis节点都需要建立两个TCP连接,一个用于为客户端提供服务的正常Redis TCP端口,例如 6379。还有一个基于6379端口加10000的端口,比如 16379。 第二个端口用于集群总线,节点使用集群总线进行故障检测、配置更新、故障转移授权等等。客户端一般只需要与Redis命令端口6379通信即可,但是请确保防火墙中的这两个端口都已经打开,否则Redis集群节点将无法通信。

docker-compose.yml编写

这里我们使用docker compose来编排服务。

version: '3'
services:
  redis-cluster-01:
    image: redis:7.0.0
    container_name: redis-cluster-01
    environment:
      TZ: Asia/Shanghai
    networks:
      - default
    ports:
      - 6371:6371
      - 16371:16371
    volumes:
      - /Users/mucheng/Documents/docker/redis-docker/6371/conf:/etc/redis
      - /Users/mucheng/Documents/docker/redis-docker/6371/data:/data
    command: ["redis-server","/etc/redis/redis.conf"]

  redis-cluster-02:
    image: redis:7.0.0
    container_name: redis-cluster-02
    environment:
      TZ: Asia/Shanghai
    networks:
      - default
    ports:
      - 6372:6372
      - 16372:16372
    volumes:
      - /Users/mucheng/Documents/docker/redis-docker/6372/conf:/etc/redis
      - /Users/mucheng/Documents/docker/redis-docker/6372/data:/data
    command: ["redis-server","/etc/redis/redis.conf"]

  redis-cluster-03:
    image: redis:7.0.0
    container_name: redis-cluster-03
    environment:
      TZ: Asia/Shanghai
    networks:
      - default
    ports:
      - 6373:6373
      - 16373:16373
    volumes:
      - /Users/mucheng/Documents/docker/redis-docker/6373/conf:/etc/redis
      - /Users/mucheng/Documents/docker/redis-docker/6373/data:/data
    command: ["redis-server","/etc/redis/redis.conf"]

  redis-cluster-04:
    image: redis:7.0.0
    container_name: redis-cluster-04
    environment:
      TZ: Asia/Shanghai
    networks:
      - default
    ports:
      - 6374:6374
      - 16374:16374
    volumes:
      - /Users/mucheng/Documents/docker/redis-docker/6374/conf:/etc/redis
      - /Users/mucheng/Documents/docker/redis-docker/6374/data:/data
    command: ["redis-server","/etc/redis/redis.conf"]

  redis-cluster-05:
    image: redis:7.0.0
    container_name: redis-cluster-05
    environment:
      TZ: Asia/Shanghai
    networks:
      - default
    ports:
      - 6375:6375
      - 16375:16375
    volumes:
      - /Users/mucheng/Documents/docker/redis-docker/6375/conf:/etc/redis
      - /Users/mucheng/Documents/docker/redis-docker/6375/data:/data
    command: ["redis-server","/etc/redis/redis.conf"]

  redis-cluster-06:
    image: redis:7.0.0
    container_name: redis-cluster-06
    environment:
      TZ: Asia/Shanghai
    networks:
      - default
    ports:
      - 6376:6376
      - 16376:16376
    volumes:
      - /Users/mucheng/Documents/docker/redis-docker/6376/conf:/etc/redis
      - /Users/mucheng/Documents/docker/redis-docker/6376/data:/data
    command: ["redis-server","/etc/redis/redis.conf"]

networks:
  default:
    external:
      name: mynet

这里对compose脚本中几个比较重要的内容做个说明:

image:

docker镜像名,这里使用标签为7.0.0版本的镜像;

networks:

docker容器网络,跟宿主机网络做映射。在某些场景下可用于容器互联,和跨宿主机访问。

这里我们提前创建了一个名为mynet的自定义网络。

关于建立docker网络,参考这篇文章:如何创建Docker中的网络_Hemi Fate的博客-CSDN博客_docker 创建网络

ports:

宿主机端口和容器端口的映射,格式为<宿主机端口>:<容器端口>

command:

启动容器时执行的命令。

volumes:

数据卷,用于宿主机目录或文件跟容器目录做映射。Redis的配置文件就是放在宿主机目录上,然后在容器启动时加载到容器目录中。格式为<宿主机目录绝对路径>:<容器目录>,这里最好配置宿主机目录的绝对路径,不然容易出问题。

最终我的文件目录如下:

 

切换到redis-docker目录下,执行docker-compose up -d

这里如果执行失败,需要检查一下:

 需要在Preferences里把这个勾去掉(是去掉,不是勾上),否则可能会出现宿主机容器卷里的配置文件到了容器里变成了目录。

具体原因参考这篇文章:文件系统共享(osxfs) - Docker 中文文档 - 文江博客

到目前为止,6个容器都已经启动了,可以在docker桌面上查看:

 或者通过命令查看:

 但这个时候这些容器都是相互独立的,没有构成集群。

构造集群分三步:

节点之间通过握手建立连接;

进行槽分配;

指定节点主从关系;

构造集群的方式有两种:

一种是自动创建法,另一种是手动创建法。简便起见,本文采用自动创建法。

创建集群

# 选择一个容器节点进入
docker exec -it redis-cluster-01 /bin/sh

输入下面命令创建集群(由于我们只有6个节点,所以3主3从,每个主节点只有一个副本)

redis-cli -a 1234 --cluster create 192.168.31.230:6371 192.168.31.230:6372 192.168.31.230:6373 192.168.31.230:6374 192.168.31.230:6375 192.168.31.230:6376 --cluster-replicas 1

这里可能会创建失败:

 原因是本地容器卷没有建在一个共享目录下,容器启动时可能无权限加载容器卷中的配置文件redis.conf。

按照提示,找到当前可以挂载的目录:

 可以选择当前已经设置共享的目录,也可以自己添加共享目录。这里选择/Users,把之前的redis-docker整体复制到新目录下。

改完之后记得修改一下数据卷的绝对路径为新路径。

然后重新创建集群,出现如下信息,说明集群创建成功。

 这里可以看到槽分配过程以及节点主从关系。

使用刚刚的节点登录到集群:

redis-cli -c -a 1234 -h 192.168.31.230 -p 6371

查看集群状态

集群状态:cluster info;集群节点查询:cluster nodes;

做个简单的测试:

 

【欢迎关注我的公众号】

 

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值