Redis cluster搭建三主三从+哨兵模式+整合spring boot+整合Redisson

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


搭建环境

提示:环境可供参考:

#系统版本
[root@iZ2ze44d9k2nxfqo6q098gZ data]# cat /etc/redhat-release
CentOS Linux release 8.5.2111
[root@iZ2ze44d9k2nxfqo6q098gZ data]# cat /proc/version
Linux version 4.18.0-348.2.1.el8_5.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 8.5.0 20210514 (Red Hat 8.5.0-4) (GCC)) #1 SMP Tue Nov 16 14:42:35 UTC 2021

#Redis版本
wget -P /usr/local/src -c  http://download.redis.io/releases/redis-6.2.6.tar.gz

#spring boot版本
:: Spring Boot ::       (v2.3.12.RELEASE)

#Redisson版本
org.redisson.Version - Redisson 3.16.8

提示:以下是本篇文章正文内容,下面案例可供参考

一、Redis cluster三主三从

1.下载解压安装

wget -P /usr/local/src -c  http://download.redis.io/releases/redis-6.2.6.tar.gz
cd /usr/local/src
tar -zxvf redis-6.2.6.tar.gz
cd redis-6.2.6
make && make PREFIX=/usr/local/redis install
#返回0代表成功
echo $? 

2.环境变量

vim /etc/profile


export REDIS_HOME=/usr/local/redis
export PATH=$PATH:$REDIS_HOME/bin

执行 source /etc/profile 使修改立即生效

3.搭建节点

以一台为例子,其他可以节点一样,重复操作即可。建议在三台机器上搭建,一台机器一主一从

①创建文件夹

mkdir -p /usr/local/redis/redis_cluster/6380/conf/
mkdir -p /usr/local/redis/redis_cluster/6380/logs/
mkdir -p /usr/local/redis/redis_cluster/6380/data/

mkdir -p /usr/local/redis/redis_cluster/6381/conf/
mkdir -p /usr/local/redis/redis_cluster/6381/logs/
mkdir -p /usr/local/redis/redis_cluster/6381/data/

②创建配置文件

6380节点
vim /usr/local/redis/redis_cluster/6380/conf/redis.conf

# 绑定服务器域名或IP地址,注意这个bind是绑定节点的IP,而不是允许访问的IP,填写内网地址
bind 192.168.0.10
# 设置端口,区分集群中Redis的实例
port 6380
# 后台运行
daemonize yes
# pid进程文件名,以端口号命名
pidfile /var/run/redis-6380.pid
# 日志文件名称,以端口号为目录来区分
logfile /usr/local/redis/redis_cluster/6380/logs/redis.log
# 数据文件存放地址,以端口号为目录名来区分
dir /usr/local/redis/redis_cluster/6380/data
# 启用集群
cluster-enabled yes
# 配置每个节点的配置文件,同样以端口号为名称
cluster-config-file nodes_6380.conf
# 配置集群节点的超时时间
cluster-node-timeout 15000
# 启动AOF增量持久化策略
appendonly yes
# 发生改变,则记录日志
appendfsync always

#900 秒内至少有 1 个 key 被改变
save 900 1
#300 秒内至少有 300 个 key 被改变
save 300 10
#60 秒内至少有 10000 个 key 被改变
save 60 10000
#  后台存储错误停止写。
stop-writes-on-bgsave-error yes
#  存储至本地数据库时(持久化到 rdb 文件)是否压缩数据,默认为 yes
rdbcompression yes
# RDB 文件的是否直接偶像 chcksum
rdbchecksum yes
#  本地持久化数据库文件名,默认值为 dump.rdb
dbfilename dump.rdb
# 密码,注意集群各节点密码要保持一致
requirepass 123456789

6381节点
vim /usr/local/redis/redis_cluster/6381/conf/redis.conf

# 绑定服务器域名或IP地址,注意这个bind是绑定节点的IP,而不是允许访问的IP,填写内网地址
bind 192.168.0.11
# 设置端口,区分集群中Redis的实例
port 6381
# 后台运行
daemonize yes
# pid进程文件名,以端口号命名
pidfile /var/run/redis-6381.pid
# 日志文件名称,以端口号为目录来区分
logfile /usr/local/redis/redis_cluster/6381/logs/redis.log
# 数据文件存放地址,以端口号为目录名来区分
dir /usr/local/redis/redis_cluster/6381/data
# 启用集群
cluster-enabled yes
# 配置每个节点的配置文件,同样以端口号为名称
cluster-config-file nodes_6381.conf
# 配置集群节点的超时时间
cluster-node-timeout 15000
# 启动AOF增量持久化策略
appendonly yes
# 发生改变,则记录日志
appendfsync always

#900 秒内至少有 1 个 key 被改变
save 900 1
#300 秒内至少有 300 个 key 被改变
save 300 10
#60 秒内至少有 10000 个 key 被改变
save 60 10000
#  后台存储错误停止写。
stop-writes-on-bgsave-error yes
#  存储至本地数据库时(持久化到 rdb 文件)是否压缩数据,默认为 yes
rdbcompression yes
# RDB 文件的是否直接偶像 chcksum
rdbchecksum yes
#  本地持久化数据库文件名,默认值为 dump.rdb
dbfilename dump.rdb
# 密码,注意集群各节点密码要保持一致
requirepass 123456789

4、设置开机启动

每台机器设置开机启动
vim /etc/rc.local


/usr/local/redis/bin/redis-server /usr/local/redis/redis_cluster/6380/conf/redis.conf
/usr/local/redis/bin/redis-server /usr/local/redis/redis_cluster/6381/conf/redis.conf

如果开机启动不生效,可以执行 chmod +x /etc/rc.d/rc.local

5、启动各个节点,创建集群,检查状态

redis-server /usr/local/redis/redis_cluster/6380/conf/redis.conf
redis-server /usr/local/redis/redis_cluster/6381/conf/redis.conf

查看启动情况

[root@iZ2ze3pdypz126y1bxp4xfZ data]# ps -ef|grep redis
root     1535085       1  0 18:05 ?        00:00:32 redis-server 172.26.67.38:6380 [cluster]
root     1535625       1  2 18:08 ?        00:01:22 redis-server 172.26.67.38:6381 [cluster]
root     1546480   19893  0 19:10 pts/0    00:00:00 grep --color=auto redis

创建集群,这里的IP是外网IP,-a后面是密码,2>/dev/null 是将标准错误忽略。要确保加入的节点是empty。如果不为空,连接节点执行flushall \ flushdb\ cluster reset


redis-cli --cluster create 192.168.0.11:6380 192.168.0.11:6381 192.168.0.12:6380 192.168.0.12:6381 192.168.0.13:6380 192.168.0.13:6381 --cluster-replicas 1 -a 123456789  2>/dev/null

检查状态

redis-cli --cluster check 192.168.0.11:6380 -a 123456789  2>/dev/null

xxx.xxx.xxx.xxx:6379 (3a81002e...) -> 0 keys | 5461 slots | 1 slaves.
xxx.xxx.xxx.xxx:6380 (dfe7994a...) -> 0 keys | 5461 slots | 1 slaves.
xxx.xxx.xxx.xxx:6380 (c4e9009c...) -> 0 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node xxx.xxx.xxx.xxx:6379)
M: 3a81002e6a20133d44895f3f0e72e0ee16028ccf xxx.xxx.xxx.xxx:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 57bfa604ff4c27de83a5c37540078d4262b293fc xxx.xxx.xxx.xxx:6381
   slots: (0 slots) slave
   replicates 3a81002e6a20133d44895f3f0e72e0ee16028ccf
S: baabb58a937192d87dbc83518da94f990c9533a6 xxx.xxx.xxx.xxx:6381
   slots: (0 slots) slave
   replicates c4e9009cbe6ea4c2a439777d16021fecd754a2ba
M: dfe7994a2457a87fec7409064358d750d48e8e39 xxx.xxx.xxx.xxx:6380
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: c4e9009cbe6ea4c2a439777d16021fecd754a2ba xxx.xxx.xxx.xxx:6380
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 7ba2ab130e5c6917635888ee8577fa5cf3ea2838 xxx.xxx.xxx.xxx:6382
   slots: (0 slots) slave
   replicates dfe7994a2457a87fec7409064358d750d48e8e39
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

状态OK,集群搭建完成

二、哨兵模式

1.创建sentinel相关的文件夹


mkdir -p /usr/local/redis/redis_cluster/27001/conf/
mkdir -p /usr/local/redis/redis_cluster/27001/logs/
mkdir -p /usr/local/redis/redis_cluster/27001/data/

2.创建配置文件

cd /usr/local/redis/redis_cluster/27001/conf/
vim sentinel.conf
根据集群状态中的主节点来配置,即 M:开头的


bind 0.0.0.0
port 27001
daemonize yes
pidfile /var/run/redis-sentinel.pid
logfile  /usr/local/redis/redis_cluster/27001/logs/redis-sentinel.log
dir /usr/local/redis/redis_cluster/27001/data

sentinel monitor mymaster1 xxx.xxx.xxx.xxx 6379 2
sentinel monitor mymaster2 xxx.xxx.xxx.xxx 6380 2
sentinel monitor mymaster3 xxx.xxx.xxx.xxx 6380 2

sentinel down-after-milliseconds mymaster1 10000
sentinel down-after-milliseconds mymaster2 10000
sentinel down-after-milliseconds mymaster3 10000

sentinel parallel-syncs mymaster1 1
sentinel parallel-syncs mymaster2 1
sentinel parallel-syncs mymaster3 1

sentinel failover-timeout mymaster1 15000
sentinel failover-timeout mymaster2 15000
sentinel failover-timeout mymaster3 15000

启动哨兵
redis-sentinel /usr/local/redis/redis_cluster/27001/conf/sentinel.conf
查看redis-sentinel进程
ps -ef|grep sentinel

三、整合spring boot

修改配置文件

spring:
  redis:
    port: 6379 # Redis服务器连接端口
    password: xxxxxxxxx # Redis服务器连接密码(默认为空)
    timeout: 3000 # 连接超时时间(毫秒)
    cluster:
      max-redirects: 3
      nodes:
        - xxx.xxx.xxx.xxx:6379
        - xxx.xxx.xxx.xxx:6380
        - xxx.xxx.xxx.xxx:6381
        - xxx.xxx.xxx.xxx:6382
        - xxx.xxx.xxx.xxx:6380
        - xxx.xxx.xxx.xxx:6381
    jedis:
      pool:
        min-idle: 10
        max-idle: 20
        max-wait: -1ms
        max-active: 200

四、整合Redisson


import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.ClusterServersConfig;
import org.redisson.config.Config;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description: redisson配置
 * @Author: TianZhiHao
 */
@Configuration
public class RedissonConfig {
    @Resource
    private RedisProperties redisProperties;
    public static final String PREFIX = "LOCK:";

//    /**
//     * 单机版
//     */
//    @Bean
//    public RedissonClient redissonClient() {
//        String node1 = String.format("redis://%s:%s", redisProperties.getHost(), redisProperties.getPort());
//        Config config = new Config();
//        config.useSingleServer().setAddress(node1).setPassword(redisProperties.getPassword()).setPingConnectionInterval(1000);
//
//        return Redisson.create(config);
//    }

    /**
     * 集群版
     */
    @Bean
    public RedissonClient clusterRedissonClient() {
        List<String> clusterNodes = new ArrayList<>();
        for (int i = 0; i < redisProperties.getCluster().getNodes().size(); i++) {
            clusterNodes.add("redis://" + redisProperties.getCluster().getNodes().get(i));
        }
        Config config = new Config();
        String[] a = new String[clusterNodes.size()];
        ClusterServersConfig clusterServersConfig = config.useClusterServers()
                .addNodeAddress(clusterNodes.toArray(a));
        clusterServersConfig.setPassword(redisProperties.getPassword());//设置密码,如果没有密码,则注释这一行,否则启动会报错
        return Redisson.create(config);
    }

}

五、常见错误踩坑

1、Waiting for the cluster to join…

检查redis.conf 里面bind 的 IP,执行 redis-cli --cluster create 的时候要为外网IP,打开防火墙的与节点端口相关的端口,以及Redis集成总线的端口 Redis端口+10000 例如16379

2、Not all slots covered!

利用telnet ip port 检查各个节点的连接,如果有连接不上的就会出现该错误

3、Redis集群配置的公网,redisson 却连的内网

根据提示,检查 node 配置文件,例如 nodes_6381.conf ,修改里面的IP为可以连接到的IP

4、No more cluster attempts left.

检查节点的redis.conf 里面的bind,注意要为内网地址,修改节点配置文件里面的myself的IP ,例如nodes_6381.conf

c4e9009cbe6ea4c2a439777d16021fecd754a2ba xxx.xxx.xxx.xxx:6380@16380 master - 0 1653040382693 5 connected 5461-10922
3a81002e6a20133d44895f3f0e72e0ee16028ccf xxx.xxx.xxx.xxx:6379@16379 master - 0 1653040379000 1 connected 0-5460
57bfa604ff4c27de83a5c37540078d4262b293fc xxx.xxx.xxx.xxx:6381@16381 myself,slave 3a81002e6a20133d44895f3f0e72e0ee16028ccf 0 1653040380000 1 connected
baabb58a937192d87dbc83518da94f990c9533a6 xxx.xxx.xxx.xxx:6381@16381 slave c4e9009cbe6ea4c2a439777d16021fecd754a2ba 0 1653040381000 5 connected
dfe7994a2457a87fec7409064358d750d48e8e39 xxx.xxx.xxx.xxx:6380@16380 master - 0 1653040381689 2 connected 10923-16383
7ba2ab130e5c6917635888ee8577fa5cf3ea2838 xxx.xxx.xxx.xxx:6382@16382 slave dfe7994a2457a87fec7409064358d750d48e8e39 0 1653040382000 2 connected
vars currentEpoch 6 lastVoteEpoch 0

六、向集群中新增节点

按照第一章的方式1,2,3,4步添加并启动节点
执行 以下命令,add-node是加入集群节点,192.168.0.14:6380 为要加入的节点,192.168.0.11:6380 表示已经加入集群中的一个节点,用来识别集群,理论上集群的任意一个节点都可以 。

redis-cli --cluster add-node  192.168.0.14:6380 192.168.0.11:6380

七、利用redis-shake进行单机版向集群版的数据迁移

1、下载redis-shake

wget -P /usr/local/src -c  https://github.com/alibaba/RedisShake/releases/download/release-v2.1.2-20220329/release-v2.1.2-20220329.tar.gz

进入到文件所在目录 cd /usr/local/src
解压文件 tar -zxvf release-v2.1.2-20220329.tar.gz

2、修改redis-shake.conf

需要修改的部分

# 源端 Redis 的类型,可选:standalone sentinel cluster proxy
# 注意:proxy 只用于 rump 模式。
source.type = standalone
# 源端 redis 的地址
#   1. standalone 模式配置 ip:port, 例如: 10.1.1.1:20331
#   2. cluster 模式需要配置所有 nodes 的 ip:port, 例如: source.address = 10.1.1.1:20331;10.1.1.2:20441
source.address = xxx.xxx.xxx.xxx:6379
# 源端密码,留空表示无密码。
source.password_raw = xxxxxxxxx

# 目的redis的类型,支持standalone,sentinel,cluster和proxy四种模式。
target.type = cluster
# ip:port
# the target address can be the following:
#   1. single db address. for "standalone" type.
#   2. ${sentinel_master_name}:${master or slave}@sentinel single/cluster address, e.g., mymaster:master@127.0.0.1:26379;127.0.0.1:26380, or @127.0.0.1:26379;127.0.0.1:26380. for "sentinel" type.
#   3. cluster that has several db nodes split by semicolon(;). for "cluster" type.
#   4. proxy address. for "proxy" type.
#  注意:这里的ip:port 要么全是master,要么全是slave
target.address = xxx.xxx.xxx.xxx:6380;xxx.xxx.xxx.xxx:6379;xxx.xxx.xxx.xxx:6380

# target password, left blank means no password.
# 目的端密码,留空表示无密码。
target.password_raw = xxxxxxxxx
# 当源目的有重复 key 时是否进行覆写, 可选值:
#   1. rewrite: 源端覆盖目的端
#   2. none: 一旦发生进程直接退出
#   3. ignore: 保留目的端key,忽略源端的同步 key. 该值在 rump 模式下不会生效.
key_exists = rewrite


3、迁移数据

进入到已解压的目录
cd /usr/local/src/bin
启动redis-shake

./redis-shake.linux -type=sync -conf=redis-shake.conf

查看日志


总结

诗歌赏析

七律·人民解放军占领南京
作者:毛泽东

钟山风雨起苍黄,百万雄师过大江。 
虎踞龙盘今胜昔,天翻地覆慨而慷。 
宜将剩勇追穷寇,不可沽名学霸王。 
天若有情天亦老,人间正道是沧桑。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值