Redis系列 使用docker部署redis集群模式-cluster

本文实测环境 redis:latest 拉取的Redis版本 - 7.0.11 ;

前言

上一章我们讲了redis主从+哨兵模式的搭建和理论,也提到了该模式适用于写少读多的场景,那本文就讲一下当我们项目读多写多,并有高并发的情况我们该如何使用redis的第三个模式 - cluster(集群)模式来实现项目的高可用高并发!

创建redis集群网络环境

为了主从环境的隔离性和安全性,我们先创建一个独立的docker网络区域(网段)来部署redis主从

docker network create --driver bridge --subnet 172.12.1.0/16 --gateway 172.12.1.1 redis-clusternet

上面命令的各参数解释已经在该文章详细解释,这里将不在过多叙述了!
查看网络是否新建成功

docker network ls

image

网络创建成功以后创建redis各个节点的配置文件

创建redis配置文件

使用脚本 创建6个redis配置文件,**注意:**cluster-announce-ip以下的配置,我是根据内网来的,如果你需要外网访问看注释进行修改配置!

for int in $(seq 1 6); \
do \
mkdir -p /var/redis/node-${int}/
touch /var/redis/node-${int}/redis.conf
cat << EDF >/var/redis/node-${int}/redis.conf
#端口号
port 6379
#网关绑定地址
bind 0.0.0.0
protected-mode no
loglevel notice
logfile /var/log/redis/node-${int}.log
dir /var/redis/node-${int}/
dbfilename dump_637${int}.rdb
requirepass 123456
#主节点密码
masterauth 123456
#是否开始 aof 持久化模式
appendonly yes
#集群开关,默认是不开启集群模式
cluster-enabled yes
#集群配置文件的名称,这个文件redis会自己生成更新
cluster-config-file nodes.conf
#集群节点超时的阀值,毫秒值
cluster-node-timeout 5000
#下面的配置是redis专门适用于docker才有得,使用docker安装部署的需要细看我的解释
#声明本节点的ip地址,如果需要外网访问就写自己服务器的外网地址,要不会外网访问不通;
cluster-announce-ip 172.12.1.10${int}
#声明本节点单机端口,如果上述填写的是外网地址,那这里就是每个节点映射到你宿主机上的端口了,就应该是 637+int变量,如果为内网地址直接就填6379,因为每个docker都算一个系统都有一个6379端口
cluster-announce-port 6379
#声明本节点集群端口,如果cluster-announce-ip是外网地址,这里就写成 1637+int变量,也是如此
cluster-announce-bus-port 16379
EDF
done

image

修改redis日志文件夹权限和数据文件夹的权限,让docker内的数据和日志可以生成文件!生成的数据文件和日志文件不会是 777权限,放心!

chmod -R 777 /var/log/redis
chmod 777 /var/redis/*

根据以上生成的配置文件启动各对应的redis实例

启动redis实例

启动第一个redis实例

docker run -p 6371:6379 -p 16371:16379 --name node-1 \
 -v /var/redis/node-1/:/var/redis/node-1/ \
 -v /var/log/redis/:/var/log/redis/ \
 -d --net redis-clusternet --ip 172.12.1.101 redis:latest redis-server /var/redis/node-1/redis.conf

启动第二个redis实例

docker run -p 6372:6379 -p 16372:16379 --name node-2 \
 -v /var/redis/node-2/:/var/redis/node-2/ \
 -v /var/log/redis/:/var/log/redis/ \
 -d --net redis-clusternet --ip 172.12.1.102 redis:latest redis-server /var/redis/node-2/redis.conf

启动第三个redis实例

docker run -p 6373:6379 -p 16373:16379 --name node-3 \
 -v /var/redis/node-3/:/var/redis/node-3/ \
 -v /var/log/redis/:/var/log/redis/ \
 -d --net redis-clusternet --ip 172.12.1.103 redis:latest redis-server /var/redis/node-3/redis.conf

启动第四个redis实例

docker run -p 6374:6379 -p 16374:16379 --name node-4 \
 -v /var/redis/node-4/:/var/redis/node-4/ \
 -v /var/log/redis/:/var/log/redis/ \
 -d --net redis-clusternet --ip 172.12.1.104 redis:latest redis-server /var/redis/node-4/redis.conf

启动第五个redis实例

docker run -p 6375:6379 -p 16375:16379 --name node-5 \
 -v /var/redis/node-5/:/var/redis/node-5/ \
 -v /var/log/redis/:/var/log/redis/ \
 -d --net redis-clusternet --ip 172.12.1.105 redis:latest redis-server /var/redis/node-5/redis.conf

启动第六个redis实例

docker run -p 6376:6379 -p 16376:16379 --name node-6 \
 -v /var/redis/node-6/:/var/redis/node-6/ \
 -v /var/log/redis/:/var/log/redis/ \
 -d --net redis-clusternet --ip 172.12.1.106 redis:latest redis-server /var/redis/node-6/redis.conf

查看生成的6个redis实例,检查容器是否启动成功

docker ps

image

建立集群(方案1-简单)

建立集群的方案1也就是最简单的建立方法,那个当主机那个当从机还有哈希槽的分配全部都由redis自己自动分配!

当我们6个节点都启动成功后,我么先随便进入一个redis节点容器的内部

docker exec -it node-1 /bin/bash

然后创建集群

redis-cli --cluster create 172.12.1.101:6379 172.12.1.102:6379 172.12.1.103:6379 172.12.1.104:6379 172.12.1.105:6379 172.12.1.106:6379 --cluster-replicas 1 -a 123456
  • --cluster create 创建集群 , 注意 : 后面填每个redis节点配置文件中声明的ip地址和端口号 cluster-announce-ip 和cluster-announce-port,如果不一致集群创建不成功一直卡着Waiting for cluster to join
  • --cluster-replicas 告诉redis一个主机需要配置几个从机 1代表一个主机需要分配1个从机
  • -a 就是每个redis节点的密码

image

输出[OK] All 16384 slots covered. (已全部覆盖16384个插槽),集群就建立完毕了

查看集群

#进入集群 , 注意后面的-c , 没有-c 进入的是单机,有-c进入的集群
redis-cli -c
#输入节点密码,没有密码就跳过
auth 123456
#查看集群信息
cluster info
#查看集群节点信息
cluster nodes

image

可以看见有三个从机(slave) 还有三个主机(master)

建立集群(方案2)

方案1为redis自动分配哈希槽和主从节点,一般适用于我们的每个服务器节点性能都相差不大的情况,如果我们有的服务器性能会差点我想让他当从机,性能好点我想让他当主机这种情况的话,我们就需要手动分配主机从机和哈希槽了

  1. 还是先进入任意一个节点内部
docker exec -it node-1 /bin/bash
  1. 我们先创建主节点,把自己希望成为主节点的节点ip+端口写上,我们就主机号为101,102,105的当主节点吧
redis-cli --cluster create 172.12.1.101:6379 172.12.1.102:6379 172.12.1.105:6379
  1. 创建成功后,然后我们查看集群的节点信息
#进入集群 , 注意后面的-c , 没有-c 进入的是单机,有-c进入的集群
redis-cli -c
#输入节点密码,没有密码就跳过
auth 123456
#查看集群信息
cluster info
#查看集群节点信息
cluster nodes

image

可以看见我们3个节点全是主节点,然后我们把这3个主节点的id都记下来,也就是绿框框里面的数据;

  1. 给主节点去分配从机
#先退出redis集群
exit
#然后在执行一下命令
redis-cli --cluster add-node 172.12.1.103:6379 172.12.1.101:6379 --cluster-slave --cluster-master-id af687d309ab97676a9baf73d30db58b4ea357388 -a 123456
  • --cluster add-node : 意思就是让172.12.1.103:6379 加入到172.12.1.101:6379所处的集群中
  • --cluster-slave : 并成为这个集群的从机
  • --cluster-master-id : 指定成为那个主节点的从机 , 如果不指定该主节点id,会被随机分配,这里就是填上面记录的主节点id的

image

[OK]New node added correctly. - 正确添加了新节点

  1. 再去查看集群节点信息

image

新添加的103节点已经成为id为af687开头的节点(105节点)的从机了,那我们也就可以自由分配redis集群中的主从机了,具体如何自由分配哈希槽方案1和方案2创建的集群都可以自由分配,细听分说!

操作集群指令

注意下列的命令都是进入集群中任意一个节点进行指令发送!

如何手动给master节点分配哈希槽

  1. 进入redis集群的哈希槽分配模式,后面的ip和端口填 当前集群下的任意一个节点的ip和端口即可,有节点密码记得-a+密码
redis-cli --cluster reshard  127.12.1.101:6379 -a 123456

会列出来你当前集群节点的信息,并提问你想移动多少个哈希槽

image

  1. 然后在最后一行的How many slots do you want to move (from 1 to 16384)? 后面输入你想移动多少个插槽,我这里填2000个

image

  1. 然后在What is the receiving node ID?后面填你想把这2000个哈希槽分配给那个master节点,输入该节点id,节点id上面节点信息有记录,我们这里就随便填一下,就把这2000个分配给101主机吧

image

  1. 接着就会问我们你要将那些节点的槽位移动给101主机,这里可以填 all ,all就是redis会自动在其他所有节点的哈希槽里面去提取凑够2000槽位给101主机,也可以自定义要提取那些主机的哈希槽位,可以输入多个容器id回车分割,输入done结束输入,并执行迁移

image

  1. 然后会询问你是否要继续执行重新分配计划,输入yes即可

image

  1. 然后就等待着哈希槽的迁移了,迁移完毕后我们再看一下节点信息,看一下哈希槽是否迁移成功了

image

可以看见 主机101覆盖的哈希槽为 0-6461 10923-11921 之前为0-5460 , 计算后就会发现101主机多了2000个哈希槽的覆盖

删除节点

可以指定一个节点的 ip+端口号+节点id去删除该节点

redis-cli --cluster del-node 172.12.1.103:6379 ab4929d85062baced5d63ff90771768489d175de -a 123456

image

最后可以看见103节点已经被成功删除了

一些比较常用的命令

集群状态检查

redis-cli --cluster check 172.12.1.101:6379 --cluster-search-multiple-owners -a 123456

image

英语好的可以自己翻译着理解,以上都表示的是我自己对此翻译的理解

集群基本信息查看

redis-cli --cluster info 172.12.1.101:6379 -a 123456

image

修复集群

修改集群和槽的重复分配问题

redis-cli --cluster fix 172.12.1.101:6379 --cluster-search-multiple-owners -a 12345

设置集群超时时间

在最初的每个redis节点配置中就可以配置,一般需要及时进行时间扩张的时候才会用到该命令!

redis-cli --cluster set-timeout 172.12.1.101:6379 -a 123456 10000

集群测试

#首先进入集群
redis-cli -c
#输入密码
auth 123456
#新增一条数据
set test 111000

image

SpringBoot连接redis集群

pom配置

注意 : 如果你使用的springboot为2.1.4-2.1.6的话不可以使用下述这样子的pom依赖,具体请看问题汇总中的问题1;

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

yml配置

spring:
  redis:
    password: 123456  #如果有密码的话 这里就redis的密码
    cluster:
      nodes: # 集群下每个节点的ip地址:端口
        - 120.27.239.99:6371
        - 120.27.239.99:6372
        - 120.27.239.99:6373
        - 120.27.239.99:6375

springboot连接redis的问题汇总

问题1 :

关于SpringBoot版本与redis版本冲突问题,如果你使用的SpringBoot为2.1.4或者2.1.6,其他版本暂时还不知道,redis版本用的7.0以上,那么当你SpringBoot连接redis单机进行写读操作他是没有问题的,也就是和你说哈希槽不合适,但是如果你连接redis集群他就会出一个很坑爹的错误 : java.lang.UnsupportedOperationException: null

image

出现这个问题应该就是你springboot里lettuce连接池版本和redis版本的冲突问题了,那springboot肯定不能随便换版本,一换问题比这个都多,那我们只有将springboot2.1.6版本中的lettuce给排除然后使用比较高版本boot的lettuce版本,也就是如下pom

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <!--去掉springboot2.1.6自带的lettuce版本-->
            <exclusions>
                <exclusion>
                    <groupId>io.lettuce</groupId>
                    <artifactId>lettuce-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--依赖springboot2.6.1自带的lettuce版本-->
        <dependency>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
            <version>6.1.5.RELEASE</version>
            <scope>compile</scope>
        </dependency>

然后再去请求就搞定了!

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇