分区是将数据分布在多个Redis实例(Redis主机)上,以至于每个实例只包含一部分数据。
分区的意义:
1,性能的提升,单机Redis的网络I/O能力和计算资源是有限的,将请求分散到多台机器,充分利用多台机器的计算能力可网络带宽,有助于提高Redis总体的服务能力。
2,存储能力的横向扩展,即使Redis的服务能力能够满足应用需求,但是随着存储数据的增加,单台机器受限于机器本身的存储 容量,将数据分散到多台机器上存储使得Redis服务可以横向扩展。
根据id数字的范围比如1--10000、100001--20000.....90001-100000,每个范围分到不同的Redis实例中。
Redis实例=hash(key)%N
客户端选择算法:普通hash算法、一致性hash、hash(服务器的IP地址) % 2^32
在客户端和服务器端引入一个代理或代理集群,客户端将命令发送到代理上,由代理根据算法,将命令 路由到相应的服务器上。常见的代理有Codis(豌豆荚)和TwemProxy(Twitter)。
Redis3.0之后,Redis官方提供了完整的集群解决方案。 方案采用去中心化的方式,包括:sharding(分区)、replication(复制)、failover(故障转移)。 称为RedisCluster。
一个节点周期性(每秒)随机选择一些节点,并把信息传递给这些节点。 这些收到信息的节点接下来会做同样的事情,即把这些信息传递给其他一些随机选择的节点。 信息会周期性的传递给N个目标节点。这个N被称为fanout(扇出) gossip协议包含多种消息,包括meet、ping、pong、fail、publish等等。
【通过gossip协议,cluster可以提供集群间状态同步更新、选举自助failover等重要的集群功能。】
redis-cluster把所有的物理节点映射到[0-16383]个slot上,基本上采用平均分配和连续分配的方式。
*slot槽必须在节点上连续分配,如果出现不连续的情况,则RedisCluster不能工作
RedisCluster的优势:
不同节点分组服务于相互无交集的分片(sharding),Redis Cluster 不存在单独的proxy或配置服务 器,所以需要将客户端路由到目标的分片。
客户端路由 Redis Cluster的客户端相比单机Redis 需要具备路由语义的识别能力,且具备一定的路由缓存能力。
moved重定向(如果是在node1节点上插入数据,但是通过计算slot应该插入到node3,则会触发重定向)
ask重定向
在对集群进行扩容和缩容时,需要对槽及槽中数据进行迁移 当客户端向某个节点发送命令,节点向客户端返回moved异常,告诉客户端数据对应的槽的节点信息 如果此时正在进行集群扩展或者缩空操作,当客户端向正确的节点发送命令时,槽及槽中数据已经被迁 移到别的节点了,就会返回ask,这就是ask重定向机制
Smart智能客户端-JedisCluster
JedisCluster是Jedis根据RedisCluster的特性提供的集群智能客户端 JedisCluster为每个节点创建连接池,并跟节点建立映射关系缓存(Cluster slots) JedisCluster将每个主节点负责的槽位一一与主节点连接池建立映射缓存 JedisCluster启动时,已经知道key,slot和node之间的关系,可以找到目标节点 JedisCluster对目标节点发送命令,目标节点直接响应给JedisCluster 如果JedisCluster与目标节点连接出错,则JedisCluster会知道连接的节点是一个错误的节点 此时节点返回moved异常给JedisCluster JedisCluster会重新初始化slot与node节点的缓存关系,然后向新的目标节点发送命令,目标命令执行 命令并向JedisCluster响应 如果命令发送次数超过5次,则抛出异常"Too many cluster redirection!
故障检测
从节点选举 (自动主从切换)
RedisCluster失效的判定:
从节点选举(手动切换)
人工故障切换是预期的操作,而非发生了真正的故障,目的是以一种安全的方式(数据无丢失)将当前 master节点和其中一个slave节点(执行cluster-failover的节点)交换角色
1、向从节点发送cluster failover 命令(slaveof no one)
2、从节点告知其主节点要进行手动切换(CLUSTERMSG_TYPE_MFSTART)
3、主节点会阻塞所有客户端命令的执行(10s)
4、从节点从主节点的ping包中获得主节点的复制偏移量
5、从节点复制达到偏移量,发起选举、统计选票、赢得选举、升级为主节点并更新配置
6、切换完成后,原主节点向所有客户端发送moved指令重定向到新的主节点
以上是在主节点在线情况下。 如果主节点下线了,则采用cluster failover force或cluster failover takeover 进行强制切换。
副本漂移
在一主一从的情况下,如果主从同时挂了,那整个集群就挂了。 为了避免这种情况我们可以做一主多从,但这样成本就增加了。 Redis提供了一种方法叫副本漂移,这种方法既能提高集群的可靠性又不用增加太多的从机。
如图所示,也就是说如果那个主节点下的slave比较多,少的那个快要达到峰值了,会去将其他主节点的Slave节点转变成自己的。
Master1宕机,则Slaver11提升为新的Master1 集群检测到新的Master1是单点的(无从机) 集群从拥有最多的从机的节点组(Master3)中,选择节点名称字母顺序最小的从机(Slaver31)漂移 到单点的主从节点组(Master1)。
具体流程如下(以上图为例):
1、将Slaver31的从机记录从Master3中删除
2、将Slaver31的的主机改为Master1
3、在Master1中添加Slaver31为从节点
4、将Slaver31的复制源改为Master1
5、通过ping包将信息同步到集群的其他节点