分布式缓存Redis_7 Redis Cluster去中心化分片集群

                                            分布式缓存Redis

                                        7 Redis Cluster去中心化分片集群

                                                                                                                                                                                                田超凡

                                                                                                                                                                                           20191130

 

转载请注明原作者

1 Redis传统集群和分片集群

Redis传统集群都是基于主从复制+哨兵模式实现的,采用不同的主从复制策略(如一主多从、树状主从)搭建Redis集群实现高可用,使用哨兵模式来进行Redis主机宕机之后的投票选举,实现自动化故障发现和转移,从而更好地保护Redis集群,最大化保证集群高可用。

在传统Redis集群模式中,也存在一些问题:

  1. 一般都是使用一主多从或者树状主从的方式来搭建Redis集群的,始终只有一个Redis主机来接收和处理写请求,并且Redis主机和从机数据始终是保持完全同步的,随着业务复杂度升级,如果从机比较多的情况下,由于每个Redis从机本身的持久化机制,再加上Redis主机定时的数据同步,数据同步效率必然会降低,并且从机和主机数据始终是同步的,存在大量冗余数据,浪费内存空间,从而会对运行的Redis集群中的每个Redis服务器运行性能造成影响。

(2) 根据主从复制的读写分离原则,主机只能负责写操作,传统Redis集群只有一个主机,如果是高并发请求的情况下,那么就会导致这个Redis主机写操作的压力非常大,同时还会加重同步数据到从机的负荷,并且Key也不能分摊到其他Redis主机,一旦出现缓存雪崩问题就会导致大量Key同时失效,丢失很多重要的数据。

传统Redis集群任何时候都要保证至少有一个Redis主机在正常运行(除了Redis主机宕机后,哨兵模式正在投票选举的情况之外,因为投票选举结束之前,谁也不知道主机和从机是谁,此时Redis也会开启保护机制,禁止写操作,直到选举出了新的Redis主机),是一种中心化的集群实现方案,每个从机和主机的耦合度很高。

 

Redis分片集群对Redis集群进行分片,采用多主多从的方式实现Redis集群,每一个分片都是由一个Redis主机和多个从机组成,片区和片区之间是相互平行的,Redis Cluster就是Redis 3.0+版本之后官方推荐的一种分片集群实现方式,主要是基于Hash卡槽(slot)和crc16(key)算法的实现策略来实现Redis集群分片和数据跨主机转移、共享。这是一种去中心化的集群解决方案,可以实现Redis动态扩容和缩容,但是缺点就是集群环境比较复杂,搭建成本高

 

2 Redis Cluster去中心化分片集群

Redis 3.0+版本开始官方推出了去中心化分片集群Redis Cluster,原理采用hash槽的概念预先分配16384个卡槽并且将该卡槽分配给提供具体服务的Redis片区节点用来存放每个Redis主机对应卡槽范围的数据

需要注意的是:

(1) hash卡槽只会分配给每个片区的主机,从机不会分配卡槽

(2) 每个hash卡槽可以存放多个Key

(3) hash卡槽的目的是确认数据存放到哪个片区的Redis主机,实现Redis集群分摊Key,减少缓存雪崩导致数据丢失带来的意外风险。

(4) 每个片区的Redis主机卡槽数都对应一个范围,多个片区之间卡槽数范围是等比分配的(1:1,比如存在3个片区对应3个Redis主机,那么3个Redis主机的卡槽总数分别是:16384/3。3个Redis主机的卡槽范围分别是:

第一台Redis主机:0~5460

第二台Redis主机:5461~10921

第三台Redis主机:10922~16383

 

(5) 对于每次读写操作的的Key值都会计算对应的卡槽数,根据计算出的卡槽数会把Key存入到卡槽区间范围包含这个卡槽数的Redis主机中,或者从包含这个Key卡槽数的卡槽范围的Redis主机中获取Key。

 

(6) Key的卡槽数计算是基于crc16算法实现的,根据每次写入/读取的Key的值不同,该算法会计算出不同的卡槽数,Key的卡槽数计算公式:

N(Key的卡槽数)=crc16(Key)%16384

如果写入的Key计算出的卡槽数不在当前操作的Redis主机的卡槽数范围内,那么会自动把这个Key转发到卡槽范围包含这个Key的卡槽数的Redis主机中进行写操作。

同理,如果需要获取的Key计算出的卡槽数也不在当前操作的Redis主机卡槽范围内(当前操作的Redis主机中没有这个Key),那么也会自动转发到包含这个Key的卡槽数的卡槽范围的Redis主机中去获取到这个Key。

 

Redis Cluster去中心化分片集群使用Hash卡槽来确定和定位Key的读写位置,最大的优点是有利于Redis动态扩容、缩容把缓存雪崩数据丢失的风险降到最小。

 

3 Redis Cluster去中心化分片集群环境搭建

搭建思路:在考虑到服务器资源的情况下,可以使用单机版服务器通过端口区分不同的Redis节点,搭建Redis伪集群。

Redis伪集群指的是:在一台服务器上实现Redis集群,使用不同的Redis配置文件启动不同的Redis服务,使用端口区分不同的Redis服务

 

  1. 批量复制redis解压目录

mkdir rediscluster

cd rediscluster/

mkdir redis7000

mkdir redis7001

mkdir redis7002

mkdir redis7003

mkdir redis7004

mkdir redis7005

 

 

  1. 修改每个Redis目录下的redis.conf配置文件

 

daemonize yes #设置后台启动

# bind 127.0.0.1 ##注释绑定的本机ip

protected-mode no ; ## 设置允许外部访问

port 7005 #修改端口号,从7000到7005(通过不同端口号区分不同Redis服务)

 

Redis Cluster去中心化分片集群相关配置:

cluster-enabled yes #开启cluster,去掉注释

cluster-config-file 7000nodes.conf #自动生成(端口号+nodes.conf,不能重复)

cluster-node-timeout 15000 #节点通信时间

logfile   /usr/rediscluster/redis7005/redis.log (日志目录,三级目录尽量不要重复,区分不同端口运行的Redis服务的日志文件)

 

 

  1. 通过指定不同的redis.conf配置文件,分别启动每个端口的redis服务

 

/usr/redis/bin/redis-server /usr/rediscluster/redis7000/redis.conf

/usr/redis/bin/redis-server /usr/rediscluster/redis7001/redis.conf

/usr/redis/bin/redis-server /usr/rediscluster/redis7002/redis.conf

/usr/redis/bin/redis-server /usr/rediscluster/redis7003/redis.conf

/usr/redis/bin/redis-server /usr/rediscluster/redis7004/redis.conf

/usr/redis/bin/redis-server /usr/rediscluster/redis7005/redis.conf

  1. 连接一个redis客户端,测试数据写入

/usr/redis/bin/redis-cli -h 127.0.0.1 -p 7000

注意:提示如下异常表示没有使用Redis Cluster命令分配Hash卡槽,需要先使用Redis Cluster官方命令分配卡槽(Redis 5.0+版本以上,低版本不兼容,需要自行安装低版本的Hash卡槽分配插件,建议使用Redis 5.0+版本)

 

(error) CLUSTERDOWN Hash slot not served  说明没有分配hash槽

 

解决方案:使用Redis Cluster命令分配Hash卡槽(默认分配16384个):

/usr/redis/bin/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

cluster-replicas 1 表示等比分配Hash卡槽和从机到每一个Redis主机

7000 Master 【0~5460 Hash slot(5461)】 - 7003 Slave
7001 Master 5461~10921 Hash slot(5461) - 7004 Slave
7002 Master 【10922~16383 Hash slot(5461)- 7005 Slave

 

注意:在使用命令进行Redis Cluster去中心化分片集群初始化的时候,建议最好使用真实服务器的ip地址搭建,否则如果客户端访问某个Redis主机的时候,如果指定的Key在这个Redis主机中不存在,那么根据Hash卡槽机制,会自动在服务器进行Redis主机转发和重定向,直到获取到Key。这样会导致客户端连接的Redis服务器ip地址全都变成127.0.0.1,再次连接就会失败。

 

执行Redis Cluster集群初始化命令的时候,会提示分配Redis Cluster去中心化分片集群中的主机、主机对应的卡槽、主机关联的从机:

M表示是Master主机,slots表示每个Redis主机分配的Hash卡槽范围

S表示是Slave从机,replicates 后面的id表示从机对应的主机id

Redis Cluster去中心化分片集群和环境搭建比手动配置主从复制实现传统Redis集群更加方便灵活,但是这种基于Redis Cluster命令的方式实现Redis Cluster仅限于Redis 5.0+版本以上,低版本Redis实现Hash卡槽分配还是比较复杂的,需要自己安装第三方插件实现。

 

再次运行,连接Redis客户端,发现还是报错

/usr/redis/bin/redis-cli -h 127.0.0.1 -p 7000

错误原因:需要使用Redis Cluster方式连接Redis服务器

 

解决方案:加入-c扩展参数,表示连接到Redis Cluster去中心化分片集群服务

/usr/redis/bin/redis-cli -h 127.0.0.1 -p 7000 –c

/usr/redis/bin/redis-cli --cluster help

 

 

转载请注明原作者

 

发布了100 篇原创文章 · 获赞 10 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/qq_30056341/article/details/103320138
今日推荐