17 redis集群方案

1、RedisCluster分布式集群解决方案

为了解决单机内存,并发等瓶颈,可使用此方案解决问题.
Redis-cluster是一种服务器Sharding技术,Redis3.0以后版本正式提供支持。

这里的集群是指多主多从,不是一主多从。

2、redis集群的目标
1.高性能可线性扩展至最多1000节点
2.集群中没有代理,(集群节点间)使用异步复制,没有归并操作。

可以接受的写入丢失
在发生failover之前的小段时间窗内的写操作可能在failover中丢失)。而在(网络)分区故障下,对少数派master的写入,发生写丢失的时间窗会很大。
可用性:
Redis Cluster在以下场景下集群总是可用:大部分master节点可用,并且对少部分不可用的master,每一个master至少有一个当前可用的slave。更进一步,通过使用 replicas migration 技术,当前没有slave的master会从当前拥有多个slave的master接受到一个新slave来确保可用性。

3、Redis Cluster的日常工作
1.负责维护数据,和获取集群状态,包括将keys映射到正确的节点。
2.集群节点同样可以自动发现其他节点、检测不工作节点、以及在发现故障发生时晋升slave节点到master
3.所有集群节点通过由TCP和二进制协议组成的称为 Redis Cluster Bus 的方式来实现集群的节点自动发现、故障节点探测、slave升级为master等任务。
4.每个节点通过cluster bus连接所有其他节点。
5.节点间使用gossip协议进行集群信息传播,以此来实现新节点发现,发送ping包以确认对端工作正常,以及发送cluster消息用来标记特定状态。
6.cluster bus还被用来在集群中创博Pub/Sub消息,以及在接收到用户请求后编排手动failover。

17 redis集群方案_第1张图片

4、分片模块

哈希槽(Hash Slot)

1.Redis-cluster没有使用一致性hash,而是引入了哈希槽的概念
2.Redis-cluster中有16384(214次方)个哈希槽,每个key通过CRC16校验后对16383取模来决定放置哪个槽。
3.Cluster中的每个节点负责一部分hash槽(hash slot)。

例如、集群中存在三个节点:

1.节点A包含05500号哈希槽;
2.节点B包含550111000号哈希槽;
3.节点C包含1100116384号哈希槽。

为啥是16384个slot?

1.基于网络带宽的考虑,节点众多的话,即使redis内部的局域网之间的节点之间的网络通讯,也是会导致带宽吃紧,更别提异地之间的网络通讯,对运营商之间的网络要求很高。
2.哈希slot,是通过bitmap来保存数据的,在传输过程中会对bitmap进行压缩,压缩算法涉及Node的数量,如果节点数量很高,那么压缩算法的效率会很低,所以redis的作者不建议redis的节点超过1000个节点.

在redis节点发送心跳包时需要把所有的槽放到这个心跳包里,以便让节点知道当前集群信息,16384=16k,在发送心跳包时使用char进行bitmap压缩后是2k(2 * 8 (8 bit) * 1024(1k) = 16K),也就是说使用2k的空间创建了16k的槽数。

虽然使用CRC16算法最多可以分配65535(2^16-1)个槽位,65535=65k,压缩后就是8k(8 * 8 (8 bit) * 1024(1k) =65K),也就是说需要8k的心跳包,作者认为这样不值得;并且一般情况下一个redis集群不会有超过1000个master节点,所以16k的槽位是个比较合适的选择.

Keys hash tags
Hash tags提供了一种途径,用来将多个(相关的)key分配到相同的hash slot中。这时Redis Cluster中实现multi-key操作的基础.

hash tag规则如下:
如果满足如下规则,{和}之间的字符将用来计算HASH_SLOT,以保证这样的key保存在同一个slot中。

1.key包含一个{字符
2.并且 如果在这个{的右面有一个}字符
3.并且 如果在{}之间存在至少一个字符

例如:

1.{user1000}.following和{user1000}.followers这两个key会被hash到相同的hash slot中,因为只有user1000会被用来计算hash slot值。
2.foo{}{bar}这个key不会启用hash tag因为第一个{}之间没有字符。

Cluster nodes属性
每个节点在cluster中有一个唯一的名字。这个名字由160bit随机十六进制数字表示,并在节点启动时第一次获得(通常通过/dev/urandom)。

节点ID被用来在整个cluster中标识每个节点。一个节点可以修改自己的IP地址而不需要修改自己的ID。

Cluster总线
每个Redis Cluster节点有一个额外的TCP端口用来接受其他节点的连接。这个端口与用来接收client命令的普通TCP端口有一个固定的offset。该端口等于普通命令端口加上10000.例如,一个Redis街道口在端口6379坚挺客户端连接,那么它的集群总线端口16379也会被打开。

节点到节点的通讯只使用集群总线,同时使用集群总线协议:有不同的类型和大小的帧组成的二进制协议。

集群拓扑
Redis Cluster是一张全网拓扑,节点与其他每个节点之间都保持着TCP连接。 在一个拥有N个节点的集群中,每个节点由N-1个TCP传出连接,和N-1个TCP传入连接。 这些TCP连接总是保持活性(be kept alive)。当一个节点在集群总线上发送了ping请求并期待对方回复pong,(如果没有得到回复)在等待足够成时间以便将对方标记为不可达之前,它将先尝试重新连接对方以刷新与对方的连接。 而在全网拓扑中的Redis Cluster节点,节点使用gossip协议和配置更新机制来避免在正常情况下节点之间交换过多的消息,因此集群内交换的消息数目(相对节点数目)不是指数级的。

各种分区方案
17 redis集群方案_第2张图片
RedisCluster采用虚拟槽分区,所有的键根据哈希函数(CRC16[key]&16383)映射到0-16383槽内

17 redis集群方案_第3张图片

你可能感兴趣的:(redis,redis,数据库,缓存)