Redis集群搭建(基于6.2.6版本)

前言

Redis 在我们工作中使用非常广泛,之前在掘金平台上写过一篇Redis集群的搭建,但是是基于4.0.14版本的,使用的是redis-trib.rb进行搭建的,Redis5之后 推荐使用 redis-cli 命令进行集群搭建,因此本篇使用redis6.2.6在进行一下集群搭建。其他内容基本相同,因此我把文章进行搬运,原文请访问Redis进群搭建(基于Redis4版本)

简介

Redis 集群是一个提供在多个Redis节点间共享数据的程序集。

Redis 集群通过分区来提供一定程度的高可用性,在实际环境中,当某个节点宕机或者不可达的情况下能够继续提供服务;
Redis 集群的优势:

1、自动分割数据到不同的节点上。

2、在整个集群的部分节点宕机或者不可达的情况下能够继续处理命令对外提供服务。

集群的数据分片

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

Redis 集群有16384个哈希槽,每个key通过CRC16算法校验后对16384取模来决定放置在哪个槽。公式为 CRC16(Key) % 16384 , 集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么:

  • 节点 A 包含 0 到 5500号哈希槽;
  • 节点 B 包含5501 到 11000 号哈希槽;
  • 节点 C 包含11001 到 16384号哈希槽;

这种结构很容易添加或者删除节点. 比如如果我想新添加个节点D, 我需要从节点 A, B, C中得部分槽到D上. 如果我想移除节点A,需要将A中的槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可。 由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态。
redis集群的架构是这样的:
Redis集群搭建(基于6.2.6版本)_第1张图片
细节描述:

(1) 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。

(2) 节点的fail是通过集群中超过半数的节点检测失效时才生效。

(3) 客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。

(4) redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster 负责维护node–>slot–>value

Redis 集群的主从复制模型

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

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

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

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

集群投票:容错

Redis集群搭建(基于6.2.6版本)_第2张图片
(1)、集群中所有master参与投票,如果半数以上master节点与其中一个master节点通信超过(cluster-node-timeout),认为该master节点挂掉。

(2)、什么时候整个集群不可用(cluster_state:fail)

如果集群任意master挂掉,且当前master没有slave,则集群进入fail状态。也可以理解成集群的[0-16383]slot映射不完全时进入fail状态。
如果集群超过半数以上master挂掉,无论是否有slave,集群进入fail状态。

Redis 一致性保证

Redis 并不能保证数据的强一致性。 这意味这在实际中集群在特定的条件下可能会丢失写操作。

第一个原因是因为集群是采用了异步复制。 写操作过程:

  • 客户端向主节点B写入一条命令;
  • 主节点B向客户端回复命令状态;
  • 主节点将写操作复制给他得从节点 B1, B2 和 B3;

主节点对命令的复制工作发生在返回命令回复之后, 因为如果每次处理命令请求都需要等待复制操作完成的话, 那么主节点处理命令请求的速度将极大地降低 —— 我们必须在性能和一致性之间做出权衡。 注意:Redis 集群可能会在将来提供同步写的方法。 Redis 集群另外一种可能会丢失命令的情况是集群出现了网络分区, 并且一个客户端与至少包括一个主节点在内的少数实例被孤立。

举个例子 假设集群包含 A 、 B 、 C 、 A1 、 B1 、 C1 六个节点, 其中 A 、B 、C 为主节点, A1 、B1 、C1 为A,B,C的从节点, 还有一个客户端 Z1 假设集群中发生网络分区,那么集群可能会分为两方,大部分的一方包含节点 A 、C 、A1 、B1 和 C1 ,小部分的一方则包含节点 B 和客户端 Z1 .

Z1仍然能够向主节点B中写入, 如果网络分区发生时间较短,那么集群将会继续正常运作,如果分区的时间足够让大部分的一方将B1选举为新的master,那么Z1写入B中得数据便丢失了。

注意, 在网络分裂出现期间, 客户端 Z1 可以向主节点 B 发送写命令的最大时间是有限制的, 这一时间限制称为节点超时时间(node timeout), 是 Redis 集群的一个重要的配置选项。
注意, 在网络分裂出现期间, 客户端 Z1 可以向主节点 B 发送写命令的最大时间是有限制的, 这一时间限制称为节点超时时间(node timeout), 是 Redis 集群的一个重要的配置选项。

搭建Redis集群

说明

根据官网,搭建Redis集群需要三个主节点和三个从节点,即至少6个Redis节点。因为本人并没有那么多的机器,所以只能通过设置不同的端口号启动6个Redis节点来模拟Redis集群搭建。不过和生产上其实没有分别。

下载安装Redis

wget https://download.redis.io/releases/redis-6.2.6.tar.gz

下载完成后进行解压安装:

tar -zxvf redis-6.2.6.tar.gz
cd redis-6.2.6
make install PREFIX=/usr/local/redis/redis-6.2.6   #指定自己的安装路径

为了方便管理,我们创建一个集群目录cluster,进入到redis目录:

cd /usr/local/redis/redis-6.2.6
mkdir cluster
cd cluster
# 官网端口从7000~7005
mkdir 7000 7001 7002 7003 7004 7005

拷贝并修改配置文件

将redis目录下的redix.conf文件拷贝到7000~7005目录中并修改配置文件中的如下内容:

# 端口 98行
port 7000
# 后台启动  257行
daemonize yes
#pid 文件路径 289行 为了方便管理,创建了redis-data/pidfile目录
pidfile /var/run/redis-data/pidfile/redis_7000.pid
# 日志文件  302行 为了方便管理,创建了redis-data/logfile目录
logfile "/var/run/redis-data/logfile/7000.log"
# rdb文件 431行
dbfilename dump7000.rdb
# 开启aof  1252行
appendonly yes
# append only file 文件   1256行
appendfilename "appendonly7000.aof"
# 开启集群  1385行
cluster-enabled yes
#集群节点配置文件   1393行
cluster-config-file nodes-7000.conf
# 开启集群节点超时时间   1399行
cluster-node-timeout 15000

每个端口的配置文件都需要修改以上10项,根据行数进行查找修改,很快就能修改完成。
为了方便启动,我们在/usr/local/redis/redis-6.2.6目录下编写启动脚本 redis-start.sh:

#!/bin/bash
src/redis-server cluster/7000/redis.conf
src/redis-server cluster/7001/redis.conf
src/redis-server cluster/7002/redis.conf
src/redis-server cluster/7003/redis.conf
src/redis-server cluster/7004/redis.conf
src/redis-server cluster/7005/redis.conf

停止脚本:

#!/bin/bash
src/redis-cli -p 7000 shutdown
src/redis-cli -p 7001 shutdown
src/redis-cli -p 7002 shutdown
src/redis-cli -p 7003 shutdown
src/redis-cli -p 7004 shutdown
src/redis-cli -p 7005 shutdown

赋予脚本可执行的能力

#启动脚本
chmod 544 redis-start.sh
#关闭脚本
chmod 544 redis-stop.sh
# 运行启动脚本
sh redis-start.sh
# 查看redis进程
ps -ef | grep redis |grep -v grep

如果能看到如下信息。说明redis6个节点启动成功。注意:必须是以集群【cluster】方式启动

root     28493     1  0 16:47 ?        00:00:00 src/redis-server *:7000 [cluster]
root     28495     1  0 16:47 ?        00:00:00 src/redis-server *:7001 [cluster]
root     28497     1  0 16:47 ?        00:00:00 src/redis-server *:7002 [cluster]
root     28503     1  0 16:47 ?        00:00:00 src/redis-server *:7005 [cluster]
root     28505     1  0 16:47 ?        00:00:00 src/redis-server *:7003 [cluster]
root     28515     1  0 16:47 ?        00:00:00 src/redis-server *:7004 [cluster]

开启集群

因为我们的redis版本是6.2.6,根据redis官网,redis5及以上的版本可以使用redis-cli --cluster 命令创建集群:

redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 \
127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
--cluster-replicas 1

如果你的redis设置的有密码,在以上命令的后边加上密码即可

redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 \
127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
--cluster-replicas 1 -a 密码

如果要对集群设置密码:requirepass和masterauth 都需要进行设置,并且需要每个节点的密码都保持相同;
Redis集群搭建(基于6.2.6版本)_第3张图片
Redis集群搭建(基于6.2.6版本)_第4张图片
出现如上信息,说明16284个哈希槽已经全部分配完毕,此时集群搭建成功。

进行测试

通过如下命令进行连接:

./redis-cli -c -p 7000 -a 密码

Redis集群搭建(基于6.2.6版本)_第5张图片
经过测试,redis集群可以正常提供服务;

你可能感兴趣的:(Redis,java,redis)