转载一篇博客
原地址node
1 Redis传统集群和分片集群web
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动态扩容和缩容,可是缺点就是集群环境比较复杂,搭建成本高。并发
Redis 3.0+版本开始官方推出了去中心化分片集群Redis Cluster,原理采用hash槽的概念,预先分配16384个卡槽,而且将该卡槽分配给提供具体服务的Redis片区节点用来存放每一个Redis主机对应卡槽范围的数据。svg
须要注意的是:高并发
(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动态扩容、缩容,把缓存雪崩数据丢失的风险降到最小。
搭建思路:在考虑到服务器资源的状况下,可使用单机版服务器经过端口区分不一样的Redis节点,搭建Redis伪集群。
Redis伪集群指的是:在一台服务器上实现Redis集群,使用不一样的Redis配置文件启动不一样的Redis服务,使用端口区分不一样的Redis服务。
mkdir rediscluster
cd rediscluster/
mkdir redis7000
mkdir redis7001
mkdir redis7002
mkdir redis7003
mkdir redis7004
mkdir redis7005
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服务的日志文件)
/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
/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
转载请注明原做者