14redis主从集群结构

1.什么是主从集群分布

一个负责写,其余负责读,这样的redis就是主从分布形式,可以有效降低读写压力。
主从分布除了性能上的优势外,还能有效应该redis宕机的问题。如果主节点(负责写操作的节点)宕机后,可以在几个从节点中选一个当作新的主节点。

但是如何实现重新选择主节点呢?需要使用哨兵机制,使用之前学过的sentinel。

Sentinel基于心跳机制监测服务状态,每隔1秒向集群的每个实例发送ping命令:

  • 主观下线:如果某sentinel节点发现某实例未在规定时间响应,则认为该实例主观下线
  • 客观下线:若超过指定数量(quorum)的sentinel都认为该实例主观下线,则该实例客观下线。quorum值最好超过Sentinel实例数量的一半。

一旦发现master故障,sentinel需要在salve中选择一个作为新的master,选择依据是这样的:

  • 首先会判断slave节点与master节点断开时间长短,如果超过指定值(down-after-milliseconds * 10)则会排除该slave节点
  • 然后判断slave节点的slave-priority值,越小优先级越高,如果是0则永不参与选举
  • 如果slave-prority一样,则判断slave节点的offset值,越大说明数据越新,优先级越高
  • 最后是判断slave节点的运行id大小,越小优先级越高。

当选出一个新的master后,该如何实现切换呢?

流程如下:

  • sentinel给备选的slave1节点发送slaveof no one命令,让该节点成为master
  • sentinel给所有其它slave发送slaveof 192.168.150.101 7002 命令(这个ip根据实际情况改变),让这些slave成为新master的从节点,开始从新的master上同步数据。
  • 最后,sentinel将故障节点标记为slave,当故障节点恢复后会自动成为新的master的slave节点

2.在项目中搭建主从集群分布

2.1创建redis-slave和sentinel文件结构

我们在/root/redis中添加两个slave文件夹,三个sentinel文件夹

slave中的文件结构如下(data文件夹中没有内容,conf中有redis.conf文件)

redis.conf文件内容如下:(slave1中的replica-announce-port是6380,slave2中replica-announce-port是6381)

# 允许从库使用密码连接主库
masterauth 123456
requirepass 123456
replica-announce-ip 39.107.193.66
replica-announce-port 6380

sentinel中的文件结构如下(data中什么都没有)

sentinel.conf:(这个sentinel monitor mymaster的0.0.0.1需要改成自己的redis主节点的IP地址)

port 26379
dir /data
sentinel resolve-hostnames yes
sentinel monitor mymaster 0.0.0.1 6379 2
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel parallel-syncs mymaster 1

2.2创建容器

docker run -d \
  --name redis-slave1 \
  --network hm-net \
  -p 6380:6379 \
  -v /root/redis/slave1/conf/redis.conf:/etc/redis/redis.conf \
  -v /root/redis/slave1/data:/data \
  redis redis-server /etc/redis/redis.conf \
  --appendonly yes \
  --requirepass 123456 \
  --masterauth 123456 \
  --replica-announce-ip 39.107.193.66 \
  --replica-announce-port 6380
docker run -d \
  --name redis-slave2 \
  --network hm-net \
  -p 6381:6379 \
  -v /root/redis/slave2/conf/redis.conf:/etc/redis/redis.conf \
  -v /root/redis/slave2/data:/data \
  redis redis-server /etc/redis/redis.conf \
  --appendonly yes \
  --requirepass 123456 \
  --masterauth 123456 \
  --replica-announce-ip 39.107.193.66 \
  --replica-announce-port 6381
docker run -d \
  --name redis-sentinel1 \
  --network hm-net \
  --add-host=redis:$REDIS_IP \
  -p 26379:26379 \
  -v /root/redis/sentinel1/sentinel.conf:/etc/redis/sentinel.conf \
  -v /root/redis/sentinel1/data:/data \
  redis redis-sentinel /etc/redis/sentinel.conf
docker run -d \
  --name redis-sentinel2 \
  --network hm-net \
  --add-host=redis:$REDIS_IP \
  -p 26380:26379 \
  -v /root/redis/sentinel2/sentinel.conf:/etc/redis/sentinel.conf \
  -v /root/redis/sentinel2/data:/data \
  redis redis-sentinel /etc/redis/sentinel.conf
docker run -d \
  --name redis-sentinel3 \
  --network hm-net \
  --add-host=redis:$REDIS_IP \
  -p 26381:26379 \
  -v /root/redis/sentinel3/sentinel.conf:/etc/redis/sentinel.conf \
  -v /root/redis/sentinel3/data:/data \
  redis redis-sentinel /etc/redis/sentinel.conf

2.3修改nacos配置文件

shared-redis.yaml文件修改为:

spring:
  redis:
    password: 123456
    sentinel:
      master: mymaster
      nodes: 0.0.0.1:26379,0.0.0.1:26380,0.0.0.1:26381
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0
        max-wait: 100ms

2.4项目中配置读写分离

common模块中RedisConfig.java文件中添加一个新的Bean

@Bean
  public LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer() {
    // 可选:ReadFrom.REPLICA_PREFERRED、MASTER、MASTER_PREFERRED、REPLICA
    return clientConfigurationBuilder -> clientConfigurationBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);
  }

这个bean中配置的就是读写策略,包括四种:

  • MASTER:从主节点读取
  • MASTER_PREFERRED:优先从master节点读取,master不可用才读取replica
  • REPLICA:从slave(replica)节点读取
  • REPLICA _PREFERRED:优先从slave(replica)节点读取,所有的slave都不可用才读取master

项目下载地址

gupengzu/high-concurrency-project at 14redis-Master-Slave-Cluster

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注