Docker安装redis集群

1. Redis集群介绍

  Redis 集群是一个提供在多个Redis间节点间共享数据的程序集。它并不像Redis主从复制模式那样只提供一个master节点提供写服务,而是会提供多个master节点提供写服务,每个master节点中存储的数据都不一样,这些数据通过数据分片的方式被自动分割到不同的master节点上。

  Redis 集群的优势:

  • 自动分割数据到不同的节点上。
  • 整个集群的部分节点失败或者不可达的情况下能够继续处理命令。

2. Redis 集群的数据分片

  Redis 集群没有使用一致性hash, 而是引入了 哈希槽的概念.

  在数据和节点之间又加入了一层,把这层称为哈希槽(slot),用于管理数据和节点之间的关系,现在就相当于节点上放的是槽,槽里放的是数据。

  一个集群只能有16384个槽,编号0-16383(0-2^14-1)。这些槽会分配给集群中的所有主节点,分配策略没有要求。可以指定哪些编号的槽分配给哪个主节点。集群会记录节点和槽的对应关系。解决了节点和槽的关系后,接下来就需要对key求哈希值,然后对16384取余,余数是几key就落入对应的槽里。slot = CRC16(key) % 16384。以槽为单位移动数据,因为槽的数目是固定的,处理起来比较容易,这样数据移动问题就解决了。

  举个例子,比如当前集群有3个节点,那么:

在这里插入图片描述

  这种结构很容易添加或者删除节点. 比如如果我想新添加个节点D, 我需要从节点 A, B, C中得部分槽到D上. 如果我想移除节点A,需要将A中的槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可. 由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态.

3. Redis 集群的主从复制模型

  为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有N-1个复制品.

  在我们例子中具有A,B,C三个节点的集群,在没有复制模型的情况下,如果节点B失败了,那么整个集群就会以为缺少5501-11000这个范围的槽而不可用.

  然而如果在集群创建的时候(或者过一段时间)我们为每个节点添加一个从节点A1,B1,C1,那么整个集群便有三个master节点和三个slave节点组成,这样在节点B失败后,集群便会选举B1为新的主节点继续服务,整个集群便不会因为槽找不到而不可用了

  不过当B和B1 都失败后,集群是不可用的.

4. docker搭建Redis集群(3主3从)

  1. 环境准备

    这里准备了三台虚拟主机:192.168.80.131、192.168.80.132、192.168.80.133

    三台主机均是centos7系统

    均已安装并启动docker

    每台机器上有redis 6.0.8镜像

    在这里插入图片描述

    在这里插入图片描述

    机器IP端口
    node01192.168.80.1316381、6382
    node02192.168.80.1326383、6384
    node03192.168.80.1336385、6386
  2. 编写redis-cluster.tmpl配置文件

    node01服务器上面的redis-cluster.tmpl

    #端口号
    port ${PORT}
    #设置客户端连接后进行任何其他指定前需要使用的密码
    requirepass 1234
    # 当master服务设置了密码保护时(用requirepass制定的密码)
    # slav服务连接master的密码
    #
    masterauth 1234
    #daemonize no 将daemonize yes注释起来或者 daemonize no设置,因为该配置和docker run中-d参数冲突,会导致容器一直启动失败
    daemonize no
    # 任何主机都可以连接到redis
    bind 0.0.0.0
    #是否开启保护模式,默认开启。要是配置里没有指定bind和密码。开启该参数后,redis只会本地进行访问,拒绝外部访问。
    protected-mode no
    # 默认情况下,redis会在后台异步的把数据库镜像备份到磁盘,但是该备份是非常耗时的,而且备份也不能很频繁,如果发生诸如拉闸限电、拔插头等状况,那么将造成比较大范围的数据丢失。
    # 所以redis提供了另外一种更加高效的数据库备份及灾难恢复方式。
    # 开启append only模式之后,redis会把所接收到的每一次写操作请求都追加到appendonly.aof文件中,当redis重新启动时,会从该文件恢复出之前的状态。
    # 但是这样会造成appendonly.aof文件过大,所以redis还支持了BGREWRITEAOF指令,对appendonly.aof 进行重新整理。
    # 你可以同时开启asynchronous dumps 和 AOF
    appendonly yes
     #集群开关,默认是不开启集群模式。
    cluster-enabled yes
    ##集群配置文件的名称,每个节点都有一个集群相关的配置文件,持久化保存集群的信息。这个文件并不需要手动配置,这个配置文件有Redis生成并更新,每个Redis集群节点需要一个单独的配置文件,请确保与实例运行的系统中配置文件名称不冲突
    cluster-config-file nodes.conf
    #节点互连超时的阀值。集群节点超时毫秒数
    cluster-node-timeout 15000
    #在某些部署中,Redis群集节点地址发现失败,因为地址是NAT ted的,或者因为端口是转发的(典型情况是Docker和其他容器
    #为了使Redis集群在这样的环境中工作,静态每个节点都知道需要其公共地址的配置。这个
    cluster-announce-ip 192.168.80.131
    #客户端端口
    cluster-announce-port ${PORT}
    #总线端口 为 port+10000
    cluster-announce-bus-port 1${PORT}
    

    node02服务器上面的redis-cluster.tmpl

    #端口号
    port ${PORT}
    #设置客户端连接后进行任何其他指定前需要使用的密码
    requirepass 1234
    # 当master服务设置了密码保护时(用requirepass制定的密码)
    # slav服务连接master的密码
    #
    masterauth 1234
    #daemonize no 将daemonize yes注释起来或者 daemonize no设置,因为该配置和docker run中-d参数冲突,会导致容器一直启动失败
    daemonize no
    # 任何主机都可以连接到redis
    bind 0.0.0.0
    #是否开启保护模式,默认开启。要是配置里没有指定bind和密码。开启该参数后,redis只会本地进行访问,拒绝外部访问。
    protected-mode no
    # 默认情况下,redis会在后台异步的把数据库镜像备份到磁盘,但是该备份是非常耗时的,而且备份也不能很频繁,如果发生诸如拉闸限电、拔插头等状况,那么将造成比较大范围的数据丢失。
    # 所以redis提供了另外一种更加高效的数据库备份及灾难恢复方式。
    # 开启append only模式之后,redis会把所接收到的每一次写操作请求都追加到appendonly.aof文件中,当redis重新启动时,会从该文件恢复出之前的状态。
    # 但是这样会造成appendonly.aof文件过大,所以redis还支持了BGREWRITEAOF指令,对appendonly.aof 进行重新整理。
    # 你可以同时开启asynchronous dumps 和 AOF
    appendonly yes
     #集群开关,默认是不开启集群模式。
    cluster-enabled yes
    ##集群配置文件的名称,每个节点都有一个集群相关的配置文件,持久化保存集群的信息。这个文件并不需要手动配置,这个配置文件有Redis生成并更新,每个Redis集群节点需要一个单独的配置文件,请确保与实例运行的系统中配置文件名称不冲突
    cluster-config-file nodes.conf
    #节点互连超时的阀值。集群节点超时毫秒数
    cluster-node-timeout 15000
    #在某些部署中,Redis群集节点地址发现失败,因为地址是NAT ted的,或者因为端口是转发的(典型情况是Docker和其他容器
    #为了使Redis集群在这样的环境中工作,静态每个节点都知道需要其公共地址的配置。这个
    cluster-announce-ip 192.168.80.132
    #客户端端口
    cluster-announce-port ${PORT}
    #总线端口 为 port+10000
    cluster-announce-bus-port 1${PORT}
    

    node03服务器上面的redis-cluster.tmpl

    #端口号
    port ${PORT}
    #设置客户端连接后进行任何其他指定前需要使用的密码
    requirepass 1234
    # 当master服务设置了密码保护时(用requirepass制定的密码)
    # slav服务连接master的密码
    #
    masterauth 1234
    #daemonize no 将daemonize yes注释起来或者 daemonize no设置,因为该配置和docker run中-d参数冲突,会导致容器一直启动失败
    daemonize no
    # 任何主机都可以连接到redis
    bind 0.0.0.0
    #是否开启保护模式,默认开启。要是配置里没有指定bind和密码。开启该参数后,redis只会本地进行访问,拒绝外部访问。
    protected-mode no
    # 默认情况下,redis会在后台异步的把数据库镜像备份到磁盘,但是该备份是非常耗时的,而且备份也不能很频繁,如果发生诸如拉闸限电、拔插头等状况,那么将造成比较大范围的数据丢失。
    # 所以redis提供了另外一种更加高效的数据库备份及灾难恢复方式。
    # 开启append only模式之后,redis会把所接收到的每一次写操作请求都追加到appendonly.aof文件中,当redis重新启动时,会从该文件恢复出之前的状态。
    # 但是这样会造成appendonly.aof文件过大,所以redis还支持了BGREWRITEAOF指令,对appendonly.aof 进行重新整理。
    # 你可以同时开启asynchronous dumps 和 AOF
    appendonly yes
     #集群开关,默认是不开启集群模式。
    cluster-enabled yes
    ##集群配置文件的名称,每个节点都有一个集群相关的配置文件,持久化保存集群的信息。这个文件并不需要手动配置,这个配置文件有Redis生成并更新,每个Redis集群节点需要一个单独的配置文件,请确保与实例运行的系统中配置文件名称不冲突
    cluster-config-file nodes.conf
    #节点互连超时的阀值。集群节点超时毫秒数
    cluster-node-timeout 15000
    #在某些部署中,Redis群集节点地址发现失败,因为地址是NAT ted的,或者因为端口是转发的(典型情况是Docker和其他容器
    #为了使Redis集群在这样的环境中工作,静态每个节点都知道需要其公共地址的配置。这个
    cluster-announce-ip 192.168.80.133
    #客户端端口
    cluster-announce-port ${PORT}
    #总线端口 为 port+10000
    cluster-announce-bus-port 1${PORT}
    
  3. 创建redis.conf配置文件和data文件

    cd /cjz/docker/redis-cluster

    node01服务

    for port in `seq 6381 6382`; do \
    
      mkdir -p ${port}/conf \
    
      PORT=${port} envsubst < redis-cluster.tmpl > ${port}/conf/redis.conf \
    
      mkdir -p ${port}/data;\
    
    done
    

    在这里插入图片描述
    node02服务

    for port in `seq 6383 6384`; do \
    
      mkdir -p ${port}/conf \
    
      PORT=${port} envsubst < redis-cluster.tmpl > ${port}/conf/redis.conf \
    
      mkdir -p ${port}/data;\
    
    done
    

    在这里插入图片描述node03服务

    for port in `seq 6385 6386`; do \
    
      mkdir -p ${port}/conf \
    
      PORT=${port} envsubst < redis-cluster.tmpl > ${port}/conf/redis.conf \
    
      mkdir -p ${port}/data;\
    
    done
    

    在这里插入图片描述

  4. 创建redis容器

    node01服务器上创建容器

    docker run -d --name redis-6381 --net host --privileged=true \
    -v /cjz/docker/redis-cluster/6381/conf/redis.conf:/etc/redis/redis.conf \
    -v /cjz/docker/redis-cluster/6381/data:/data \
    redis:6.0.8 redis-server /etc/redis/redis.conf
    
    docker run -d --name redis-6382 --net host --privileged=true \
    -v /cjz/docker/redis-cluster/6382/conf/redis.conf:/etc/redis/redis.conf \
    -v /cjz/docker/redis-cluster/6382/data:/data \
    redis:6.0.8 redis-server /etc/redis/redis.conf
    

    node02服务器上创建容器

    docker run -d --name redis-6383 --net host --privileged=true \
    -v /cjz/docker/redis-cluster/6383/conf/redis.conf:/etc/redis/redis.conf \
    -v /cjz/docker/redis-cluster/6383/data:/data \
    redis:6.0.8 redis-server /etc/redis/redis.conf
    
    docker run -d --name redis-6384 --net host --privileged=true \
    -v /cjz/docker/redis-cluster/6384/conf/redis.conf:/etc/redis/redis.conf \
    -v /cjz/docker/redis-cluster/6384/data:/data \
    redis:6.0.8 redis-server /etc/redis/redis.conf
    

    node03服务器上创建容器

    docker run -d --name redis-6385 --net host --privileged=true \
    -v /cjz/docker/redis-cluster/6385/conf/redis.conf:/etc/redis/redis.conf \
    -v /cjz/docker/redis-cluster/6385/data:/data \
    redis:6.0.8 redis-server /etc/redis/redis.conf
    
    docker run -d --name redis-6386 --net host --privileged=true \
    -v /cjz/docker/redis-cluster/6386/conf/redis.conf:/etc/redis/redis.conf \
    -v /cjz/docker/redis-cluster/6386/data:/data \
    redis:6.0.8 redis-server /etc/redis/redis.conf
    
  5. 创建 Redis Cluster 集群

    随便进入一个容器并为6台机器构建集群关系

    redis-cli -a 1234 --cluster create 192.168.80.131:6381 192.168.80.131:6382 192.168.80.132:6383 192.168.80.132:6384 192.168.80.133:6385 192.168.80.133:6386 --cluster-replicas 1
    

    –cluster-replicas 1 表示为每个master创建一个slave节点
    在这里插入图片描述
    链接进入6381作为切入点,查看集群状态
    在这里插入图片描述

5. 主从容错切换迁移案例

  1. 数据读写存储

    防止路由失效加参数-c并新增两个key
    在这里插入图片描述
    在这里插入图片描述
    查看集群信息
    redis-cli -a 1234 --cluster check 192.168.80.131:6381
    在这里插入图片描述

  2. 容错切换迁移

    通过集群信息可以得到以下主从关系

    在这里插入图片描述

    本实例准备将主6381和6384 从机切换

    首先将6381容器停止
    在这里插入图片描述

    查看集群状态在这里插入图片描述 可以看见6381宕机,6384上位。成为master

    还原之前的3主3从
    先启动6381,再停止6384,再启动6385
    在这里插入图片描述

6. 主从扩容案例

  1. 在node03 新建目录 6387、6388目录跟上面步骤一样
    在这里插入图片描述

  2. 创建6387、6388容器

    docker run -d --name redis-6387 --net host --privileged=true \
    -v /cjz/docker/redis-cluster/6387/conf/redis.conf:/etc/redis/redis.conf \
    -v /cjz/docker/redis-cluster/6387/data:/data \
    redis:6.0.8 redis-server /etc/redis/redis.conf
    
    docker run -d --name redis-6388 --net host --privileged=true \
    -v /cjz/docker/redis-cluster/6388/conf/redis.conf:/etc/redis/redis.conf \
    -v /cjz/docker/redis-cluster/6388/data:/data \
    redis:6.0.8 redis-server /etc/redis/redis.conf
    

    在这里插入图片描述

  3. 进入6387容器实例内部,将新增的6387节点(空槽号)作为master节点加入原集群

    redis-cli --cluster add-node 自己实际IP地址:6387 自己实际IP地址:6381
    

    6387 就是将要作为master新增节点
    6381 就是原来集群节点里面的领路人,相当于6387拜拜6381的码头从而找到组织加入集群

    redis-cli -a 1234 --cluster add-node 192.168.80.133:6387 192.168.80.131:6381

    在这里插入图片描述

  4. 第一次查看集群情况

    redis-cli -a 1234 --cluster check 192.168.80.131:6381

    在这里插入图片描述

  5. 重新分配槽位

    redis-cli --cluster reshard IP地址:端口号

    在这里插入图片描述

  6. 第二次检查集群情况

    在这里插入图片描述
    重新分配成本太高,所以前3家各自匀出来一部分,从6381/6382/6383三个旧节点分别匀出1364个坑位给新节点6387

  7. 为主节点6387分配从节点6388

    redis-cli --cluster add-node ip:新slave端口 ip:新master端口 --cluster-slave --cluster-master-id 新主机节点ID
    

    redis-cli -a 1234 --cluster add-node 192.168.80.133:6388 192.168.80.133:6387 --cluster-slave --cluster-master-id 23e118e86aff828cc93a3357d8234d2486201203-------这个是6387的编号,按照自己实际情况

    在这里插入图片描述

  8. 第三次查看集群情况

    在这里插入图片描述

7. 主从缩容案例

  1. 检查集群情况获得6388的节点ID

    在这里插入图片描述

  2. 从集群中将4号从节点6388 删除

    redis-cli --cluster del-node ip:从机端口 从机6388节点ID
    

    redis-cli -a 1234 --cluster del-node 192.168.80.133:6388 8785cef3a48ada4c84037111846fe97bc22177ea

    在这里插入图片描述
    redis-cli -a 1234 --cluster check 192.168.80.131:6381

    检查发现从节点6388已被删除
    在这里插入图片描述

  3. 将6387的槽号清空,重新分配,本例将清出来的槽号都给6381

    redis-cli -a 1234 --cluster reshard 192.168.80.131:6381

    在这里插入图片描述

  4. 检查集群情况

    可以看见4096个槽位都指给6381,它变成了8192个槽位,相当于全部都给6381了,不然要输入3次
    

    在这里插入图片描述

  5. 将6387删除

    redis-cli --cluster del-node ip:端口 6387节点ID
    

    redis-cli -a 1234 --cluster del-node 192.168.80.133:6387 23e118e86aff828cc93a3357d8234d2486201203

    在这里插入图片描述

  6. 再次查看集群情况

    redis-cli -a 1234 --cluster check 192.168.80.131:6381

    在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值