redis集群是一个由多个主从节点群组成的分布式服务器群,它具有复制、高可用和分片特性,不需要sentinel哨兵也能完成节点移除和故障转移的功能。需要将每个节点设置成集群模式,这种集群模式没有中心节点,可水平扩展。
redis下载安装
参考<Redis使用>
Redis集群搭建
redis集群需要至少要三个master节点,并且给每个master再搭建一个slave节点,总共至少6个redis节点。
创建好目录结构,指定数据文件存放位置,为每个节点创建独立的数据存放文件夹。
$mkdir -p /usr/local/redis-cluster
$mkdir 8001
把之前的redis.conf配置文件copy到8001下,修改如下内容:
daemonize yes
port 8001 (分别对每个机器的端口号进行设置)
dir /usr/local/redis-cluster/8001/ (指定数据文件存放位置,必须要指定不同的目录位置,不然会丢失数据)
cluster-enabled yes ( 启动集群模式)
cluster-config-file nodes-8001.conf(集群节点信息文件,这里800x最好和port对应上)
cluster-node-timeout 5000
# bind 127.0.0.1 (去掉bind绑定访问ip信息)
protected-mode no (关闭保护模式)
appendonly yes
#设置密码
requirepass cvccy (设置redis访问密码)
masterauth cvccy (设置集群节点间访问密码,跟上面一致)
把修改后的配置文件分别copy到所有节点,修改port等信息。
分别启动6个redis实例,然后检查是否启动成功
$/usr/local/redis/src/redis-server /usr/local/redis-cluster/800*/redis.conf
#查看是否启动成功
$ps -ef | grep redis
用redis-cli创建整个redis集群
cluster-replicas 1:每个创建的主服务器节点创建一个从服务器节点
执行这条命令需要确认redis实例之间要能相互访问,需要打开redis服务端口和集群节点gossip通信端口16379=10000+port(默认是在redis端口号上加1W)
关闭防火墙
systemctl stop firewalld # 临时关闭防火墙
systemctl disable firewalld # 禁止开机启动
$src/redis-cli -a cvccy --cluster create 127.0.0.1:8001 127.0.0.1:8002 127.0.0.1:8003 127.0.0.1:8004 127.0.0.1:8005 127.0.0.1:8006 --cluster-replicas 1
验证集群:
连接任意一个客户端:./redis-cli -c -h -p (-a访问服务端密码,-c表示集群模式,指定ip地址和端口号)
进行验证: cluster info(查看集群信息)、cluster nodes(查看节点列表)
关闭集群则需要逐个进行关闭
src/redis-cli -a 123++abc -c -p 8001
集群原理
slots
  Redis Cluster 将所有的数据key通过Hash函数划分为16384个slots,每个Master负责一部分,当 Redis Cluster 的客户端来连接集群时,它也会得到一份集群的槽位配置信息并将其缓存在客户端本地。这样要查找某个key时,可以直接定位到目标节点。同时因为槽位的信息可能会存在客户端与服务器不一致的情况,还需要纠正机制来实现槽位信息的校验调整。
slots定位算法
  Cluster默认会对key使用crc16运算得到hash值,再对16384取模得到具体slots信息。`HASH_SLOT = CRC16(key) mod 16384`
跳转定位
  节点收到不属于自己的key信息后,会向客户端发送一个特殊的`跳转指令`携带目标操作的节点地址,客户端收到指令后除了跳转到正确的节点上去操作,会同步更新纠正本地的槽位映射表缓存。
通信机制
  Redis Cluster节点通过Gossip协议通信,元数据维护方式有集中式和gossip通信方式。
集中式
  元数据的更新和读取,时效性非常好
* 快速感知:元数据出现变更立即就会更新到集中式的存储中,其他节点读取的时候立即就可以立即感知到
* 存储压力:所有的元数据的更新压力全部集中在一个地方,可能导致元数据的存储压力。
gossip
  gossip包含多种消息
ping:节点之间频繁发送,包含自己的状态、维护的集群元数据,通过ping交换元数据
pong:返回ping和meet,包含自己的状态和其他信息,也可以用于信息广播和更新
fail:发现并通知其他节点,指定的节点宕机
Redis集群选举原理分析
  当slave发现自己的master变为FAIL状态时,便尝试进行Failover,多个slave竞争成为master节点的过程:
slave发现自己的master变为FAIL
将自己记录的集群currentEpoch加1,并广播FAILOVER_AUTH_REQUEST 信息
其他节点收到该信息,只有master响应,判断请求者的合法性,并发送FAILOVER_AUTH_ACK,对每一个epoch只发送一次ack
尝试failover的slave收集master返回的FAILOVER_AUTH_ACK
slave收到超过半数master的ack后变成新Master(这里解释了集群为什么至少需要三个主节点,如果只有两个,当其中一个挂了,只剩一个主节点是不能选举成功的)
slave广播Pong消息通知其他集群节点。
  从节点并不是在主节点一进入 FAIL 状态就马上尝试发起选举,而是有一定延迟,一定的延迟确保我们等待FAIL状态在集群中传播,slave如果立即尝试选举,其它masters或许尚未意识到FAIL状态,可能会拒绝投票
• 延迟计算公式:`DELAY = 500ms + random(0 ~ 500ms) + SLAVE_RANK * 1000ms`
• SLAVE_RANK表示此slave已经从master复制数据的总量的rank。Rank越小代表已复制的数据越新。理论上,持有最新数据的slave将会首先发起选举。
Cluster数量
至少需要三个master节点,并且推荐节点数为奇数
新master的选举需要大于半数的集群master节点同意才能选举成功,如果只有两个master节点,当其中一个挂了,是达不到选举新master的条件的。奇数个master节点可以在满足选举该条件的基础上节省一个节点。
集群批量操作
集群只支持所有key落在同一slot的情况,可以在key的前面加上{XX},这样参数数据分片hash计算的只会是大括号里的值。
mset {user1}:name zhuge {user1}:age 18