赞
踩
redis cluster是Redis的分布式解决方案,在3.0版本推出后有效地解决了redis分布式方面的需求。
Redis自动将数据进行分片,每个master上放一部分数据提供内置的高可用支持,部分master不可用时,还是可以继续工作的,但是当超过一半的master结点挂掉后,集群将不再可用。
支撑N(N必须是奇数)个redis master node,每个master node都可以挂载多个slave node高可用,因为每个master都有salve节点,那么如果mater挂掉,redis cluster这套机制,就会自动将某个slave切换成master。
每个Redis都开放两个端口号,比如6379与6379+10000,其中10000是固定值。16379是用来进行节点间通信的,用来进行故障检测,配置更新,故障转移授权等等。也被称为Cluster Bus,它们使用的协议是gossip协议,用于在节点间进行高效的数据交换。
集群元数据的维护有两种,方式:集中式、Gossip协议。Redis-Cluster节点gossip协议进行通信。
集中式是将集群元数据(节点信息、故障等等)集中存储在某个节点上。集中式元数据集中存储的一个典型代表,就是大数据领域的 storm。它是分布式的大数据实时计算引擎,是集中式的元数据存储的结构,底层基于 zookeeper(分布式协调的中间件)对所有元数据进行存储维护。
redis 维护集群元数据采用另一个方式, gossip
协议,所有节点都持有一份元数据,不同的节点如果出现了元数据的变更,就不断将元数据发送给其它的节点,让其它节点也进行元数据的变更。
集中式的好处在于,元数据的读取和更新,时效性非常好,一旦元数据出现了变更,就立即更新到集中式的存储中,其它节点读取的时候就可以感知到;不好在于,所有的元数据的更新压力全部集中在一个地方,可能会导致元数据的存储有压力。
gossip 好处在于,元数据的更新比较分散,不是集中在一个地方,更新请求会陆陆续续打到所有节点上去更新,降低了压力;不好在于,元数据的更新有延时,可能导致集群中的一些操作会有一些滞后。
gossip 协议包含多种消息,包含 ping,pong,meet,fail 等等。
redis-trib.rb add-node
其实内部就是发送了一个 gossip meet 消息给新加入的节点,通知那个节点去加入我们的集群。
ping 时要携带一些元数据,如果很频繁,可能会加重网络负担。
每个节点每秒会执行 10 次 ping,每次会选择 5 个最久没有通信的其它节点。当然如果发现某个节点通信延时达到了 cluster_node_timeout / 2,那么立即发送 ping,避免数据交换延时过长,落后的时间太长了。
每次 ping,会带上自己节点的信息,还有就是带上 1/10 其它节点的信息,发送出去,进行交换。至少包含 3 个其它节点的信息,最多包含 总节点数减 2 个其它节点的信息。
来了一个 key,首先计算 hash 值,然后对节点数取模。然后打在不同的 master 节点上。一旦某一个 master 节点宕机,所有请求过来,都会基于最新的剩余 master 节点数去取模,尝试去取数据。这会导致大部分的请求过来,全部无法拿到有效的缓存,导致大量的流量涌入数据库。
一致性Hash算法将Hash值空间组织成一个虚拟的圆环,整个空间按顺时针方向组织,下一步将各个master节点(使用服务器的ip或主机名)进行hash,这样就能确定每个节点在其hash环上的位置。
来了一个key之后,会对这个keyh进行hash,然后顺时针找到离这个值最近的第一个master,这个master的位置就是key所在的位置。
在一致性hash算法中,节点太少时,容易因为节点分布不均,造成缓存热点的问题。为了解决这种热点问题,一致性hash算法引入虚拟节点机制,即第每个节点计算多个hash,每个计算结果的位置都放置一个虚拟节点。这样就实现了数据的均匀分布、负载均衡。
虚拟节点示意图
Redis Cluster有固定的16348个hash slot,对每个key计算CRC16 值,然后对16384取模,可以获取key对应的hash slot。Redis Cluster中的每个master都会持有部分slot,比如3个master,那么可能每个master都包含5000多个hash slot,每增加一个master就将其他master上的slot移一部分过去,每减少一个master就将其上的slot移到其他的master上去。
Redis-Cluster的的高可用的原理,几乎与哨兵是类似的。
如果一个节点认为另一个节点宕机,那么就是pfail
,主观宕机。如果多个节点都认为另一个节点宕机,那么就是fail
,客观宕机,跟哨兵的原理 ,几乎sdown、odown。
在cluster-node-timeout内,某个节点一直没有返回pong,那么就被认为pfail。
如果一个节点认为某个节点pfail了,那么会在gossip ping消息中,ping给其他节点,如果超过半数的节点都认为pfail了,那么就会编程fail。
对宕机的master node,从其所有的slave node 中,选择一个切换成 master node。检查每个slave node与master node断开连接的时间,如果超过了cluster-node-timeout * cluster-slave-validity-factor,那么久没资格切换成master。
每个从节点都根据自己对master复制数据的offset(子集),来设置一个选举时间,offset越大的从节点,选举时间越靠前。
所有master node开始slave选举投票,给要选举的slave,如果大部分(N/2+1)个master都投票给了某个从节点,则选举通过,那个从节点可以切换成master。
整个流程跟哨兵相比,非常类似,所以说,redis cluster 功能强大,直接集成了 replication 和 sentinel 的功能
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。