redis 数据分区--一致性hash&&虚拟槽分区

redis 数据分区--一致性hash&&虚拟槽分区,第1张

1节点区域分区:

使用特定的数据,如redis的键或用户ID,再根据节点数量N使用公式:hash(key)%N计算出hash值,用来决定数据映射到哪一个节点上

这种方案的问题是:

当节点数量变化时,需要重新计算hash,会导致数据的重新迁移

2一致性hash算法

一致性hash算法实现思路是为系统中每一个节点分配一个token,范围在0~2^32,这些token构成一个hash环数据的读写执行节点查找 *** 作时,先根据key计算hash值,然后顺时针找到第一个大于等于该hash的token节点

好处:

这种方式最大的好处就是,在加入或删除节点时,只影响hash环中相邻的两个节点,对其他节点无影响

问题:

3虚拟槽算法

使用分散度较好的hash函数,将所有的数据映射到 比如0~16383(2^14)范围的槽中(slot)这个槽的数量一般远远大于实例的数量

槽是集群数据管理和迁移的基本单位采用大范围槽的主要目的是为了方便数据拆分和集群扩展

每一个实例会映射一部分范围的槽

特点:

1解耦数据和节点之间的关系,简化扩容和锁容的难度

2节点自身维护槽的映射关系,不需要客户端或代理服务维护槽分区的元数据

3支持节点,槽,键之间的映射查询,用于数据路由,在线伸缩灯场景

HashTags(面试)

Mset k1 v1 k2 v2 k3 v3

通过分片手段,可以将数据合理的划分到不同的节点上,这本来是一件好事。但是有的时候,我们希望对相关联的业务以原子性方式进行 *** 作。举个简单的例子

我们在单节点上执行MSET (m表示多个,一次向redis设置多个key和值), 它是一个原子性的 *** 作,我们要求所有给定的key要在同一时间内被设置,不能出现某些指定的key被更新另一些指定的key没有被更新的情况。但是在集群环境下,我们仍然可以执行MSET命令,但它的 *** 作不在是原子 *** 作,会存在某些指定的key被更新,而另外一些指定的key没有改变,原因是多个key可能会被分配到不同的机器上。

所以,这里就会存在一个矛盾点,及要求key尽可能的分散在不同机器,又要求某些相关联的key分配到相同机器。

这个也是在面试的时候会容易被问到的内容。怎么解决呢?

从前面的分析中我们了解到,分片其实就是一个hash的过程,对key做hash取模然后划分到不同的机器上。所以为了解决这个问题,我们需要考虑如何让相关联的key得到的hash值都相同呢?如果key全部相同是不现实的,所以怎么解决呢?在redis中引入了HashTag的概念,可以使得数据分布算法可以根据key的某一个部分进行计算,然后让相关的key落到同一个数据分片;

举个简单的例子,假如对于用户的信息进行存储,

redis:store:1001、redis:store:1002

那么通过hashtag的方式,

redis:{store}:1001、redis:{store}:1002; 表示

当一个key包含 {} 的时候,就不对整个key做hash,而仅对 {} 包括的字符串做hash。

redis哨兵和集群的区别如下。

监控(Monitoring):Sentinel会不断地检查你的主服务器和从服务器是否运作正常,提醒(Notification):当被监控的某个Redis服务器出现问题时,Sentinel可以通过API向管理员或者其他应用程序发送通知。

集群即使使用哨兵,redis每个实例也是全量存储,每个redis存储的内容都是完整的数据,浪费内存且有木桶效应。为了最大化利用内存,可以采用集群,就是分布式存储。

即每台redis存储不同的内容,共有16384个slot。每个redis分得一些slot,hash_slot = crc16(key) mod 16384找到对应slot,键是可用键,如果有{}则取{}内的作为可用键,否则整个键是可用键。

主从、哨兵、集群各自架构的优点和缺点对比

优点:·架构简单,部署方使。高性价比:缓存使用时无需备用节点(单实例可用性可以用supervisor或crontab保证),当然为了满足业务的高可用性,也可以牺牲一个备用节点,但同时刻只有一个实例对外提供服务,高性能。

缺点:·不保证数据的可靠性。在缓存使用,进程重启后,数据丢失,即使有备用的节点解决高可用性,但是仍然不能解决缓存预热问题,因此不适用于数据可靠性要求高的业务。

高性能受限于单核CPU的处理能力(Redis是单线程机制),CPU为主要瓶颈,所以适合 *** 作命令简单,排序、计算较少的场景。也可以考虑用Memcached替代。

Redis部署模式有单机,主从,哨兵和集群多种部署模式。

缓存服务中只有一台机器部署Redis服务来给我们的应用提供读写 *** 作的服务。如下所示,这样部署的缺点是一旦Redis服务宕机,我们就无法使用缓存服务。还有就是单机的服务吞吐量比较低。

主从模式的部署就针对单机模式的问题做了改进,以常见的一主多从为例,主Redis提供写 *** 作,从Redis提供读 *** 作,这样实现了读写分离,减轻了单台Redis服务的压力。

这个模式还是存在着一旦主Redis宕机,需要重新选主,这期间服务仍然是不可用的。

针对以上的问题,又提出了一种哨兵模式,哨兵模式是主从模式的改进,就是在主从模式的基础上引入了哨兵监控主从Redis服务的状态,如果主Redis宕机了会在从Redis中选择一个作为主Redis继续提供服务。

这种模式解决了可用性问题,唯一的缺点就还是只有一个主Redis对外提供服务,还是没法抗住大量写 *** 作的压力(超过10w/s)。

我们这里要看一下哨兵模式的部署,我们在配置哨兵信息时,需要用到下面这个配置项:

sentinel monitor <master-name> <ip>

可以看到哨兵只是配置了自己的地址,彼此之间不知道对方的地址信息的,这里就涉及到了Redis的pub/sub(发布/订阅)机制。

Redis为了区分不同应用的消息,还会以频道的形式,对消息进行分门别类的管理。这样同一个应用的消息在一个频道,只有订阅了同一个频道的应用,才能通过发布的消息进行信息交换。

集群模式简单来说就是多主多从模式,集群模式解决了可用性和大规模写 *** 作吞吐量的问题。集群模式有多个可用独立工作的主从Redis对外提供服务,至于外部应用具体使用哪个Redis主从。

集群模式下有16384个Hash Slot(哈希槽)分别分布在主从上,选取hash_slot是通过crc算法取模来确定,具体说就是hash_slot=crc16(key)mod 16384。

以上就是关于redis 数据分区--一致性hash&&虚拟槽分区全部的内容,包括:redis 数据分区--一致性hash&&虚拟槽分区、redis哨兵和集群区别是什么、Redis的部署模式等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9486191.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存