redis集群连不上(redis集群读不到)

redis集群连不上(redis集群读不到)宫粽号 堆栈 future Redis Cluster Hash Slot 和 Hash Tag 介绍 干货 宫粽号 堆栈 future Redis Cluster 介绍 Redis Cluster Hash Slot 原理 Redis Cluster Hash Tag 原理 Redis Cluster 集群介绍 你可以这么理解 就是切片集群或者分片集群 用来存储大量数据的 为什么 redis 要使用它呢

大家好,我是讯享网,很高兴认识大家。



宫粽号:堆栈future

Redis Cluster Hash Slot和Hash Tag介绍

干货:[宫粽号:堆栈future]

Redis Cluster介绍

Redis Cluster Hash Slot原理

Redis Cluster Hash Tag原理

Redis Cluster集群介绍

你可以这么理解,就是切片集群或者分片集群,用来存储大量数据的。为什么redis要使用它呢?redis的Master-Slave集群不行吗?这个也可以很简单的理解,因为后者是主备存储,前者是集群存储。

主备存储目的就是两个,一个就是防止主从任意一个节点挂掉而导致服务不可用;另一个作用就是缓解读写压力,所有的读取数据的操作不但master可以承担,所有的从节点也可以去承担,这样对于读多写少的场景非常适合,所有的写可以直接写入master节点,然后通过rdb和buffer模式同步给从节点,这样保证整个主备集群数据都是一致的。

但是主备有个缺陷就是无法保存大量数据,因为一旦Master数据超过几十G之后,那么不管是主从集群rdb同步还是命令写入都是非常高危的,严重的情况下会导致主备集群直接不可用,因此为了解决这个问题,redis官方引入了Redis Cluster,它完全可以解决大量数据存储问题。

1. Redis Cluster的目标

    2. Redis Cluster的命令集

    Redis Cluster实现了所有在非分布式Redis版本(单机或者主备)中出现的处理单一键值的命令。

    那些使用多个键值的复杂操作,比如set里的并集(unions)和交集(intersections)操作,就没有实现。

    Redis Cluster不像单机版本的Redis那样支持多个数据库,集群只有数据库0,而且也不支持SELECT命令。


    讯享网

    3. Redis Cluster 通信协议

    在 Redis Cluster中,节点负责存储数据、记录集群的状态(包括键值对到正确节点的映射)。集群节点同样能自动发现其他节点,检测出没正常工作的节点,并且在需要的时候在从节点中选出主节点。

    为了执行这些任务,所有的集群节点都通过TCP连接和一个二进制协议(集群连接,cluster bus)建立通信。这样每一个节点都通过集群连接(cluster bus)与集群上的其余每个节点连接起来。连接上之后所有节点使用一个来传播集群的信息,这样可以:发现新的节点、 发送ping包(用来确保所有节点都在正常工作中)、在特定情况发生时发送集群消息。集群连接也用于在集群中发布或订阅消息。

    由于集群节点不能代理请求,客户端可能被重定向到其他节点使用重定向错误-MOVED和-ASK。从理论上讲,客户端可以自由地向集群中的所有节点发送请求,并在需要时被重定向,因此客户端不需要保存集群的状态。然而,能够缓存键和节点之间的映射的客户端可以提高处理请求性能。

    4. Redis Cluster key如何存储

    Redis Cluster方案采用哈希槽(Hash Slot)来处理数据和实例之间的映射关系。在Redis Cluster方案中,一个切片集群共有16384个哈希槽,这些哈希槽类似于数据分区,每个键值对都会根据它的key被映射到一个哈希槽中。

    具体的映射过程分为两大步:首先根据键值对的key按照CRC16算法计算一个16bit的值;然后再用这个16bit值对16384取模,得到0~16383范围内的模数,每个模数代表一个相应编号的哈希槽。

    那么,这些哈希槽又是如何被映射到具体的Redis实例上的呢?

    我们在部署Redis Cluster方案时,可以使用cluster create命令创建集群,此时Redis会自动把这些槽平均分布在集群实例上。例如,如果集群中有N个实例,那么每个实例上的槽个数为16384/N个。当然我们也可以使用cluster meet命令手动建立实例间的连接,形成集群,再使用cluster addslots命令,指定每个实例上的哈希槽个数。

    一张图来解释一下,数据、哈希槽、实例这三者的映射分布情况:

    图中的切片集群一共有3个实例,同时假设有5个哈希槽,我们首先可以通过下面的命令手动分配哈希槽:实例1保存哈希槽0和1,实例2保存哈希槽2和3,实例3保存哈希槽4。

    在集群运行的过程中,key1和key2计算完CRC16值后,对哈希槽总个数5取模,再根据各自的模数结果,就可以被映射到对应的实例1和实例3上了。另外,在手动分配哈希槽时,需要把16384个槽都分配完,否则Redis集群无法正常工作。

    那客户端如何访问呢?

    我们上面说过了,Redis Cluster通过重定向错误来处理的。所谓的“重定向”,就是指,客户端给一个实例发送数据读写操作时,这个实例上并没有相应的数据,客户端要再给一个新实例发送操作命令。那客户端又是怎么知道重定向时的新实例的访问地址呢?当客户端把一个键值对的操作请求发给一个实例时,如果这个实例上并没有这个键值对映射的哈希槽,那么,这个实例就会给客户端MOVED命令响应结果,这个结果中就包含了新实例的访问地址。

    其中,MOVED命令表示,客户端请求的键值对所在的哈希槽13320,实际是在172.16.19.5这个实例上。通过返回的MOVED命令,就相当于把哈希槽所在的新实例的信息告诉给客户端了。这样一来,客户端就可以直接和172.16.19.5连接,并发送操作请求了。

    如果这个时候你访问的数正在做迁移,那么就会报错ASK:

    这个结果中的ASK命令就表示,客户端请求的键值对所在的哈希槽13320,在172.16.19.5这个实例上,但是这个哈希槽正在迁移。此时,客户端需要先给172.16.19.5这个实例发送一个ASKING命令。这个命令的意思是,让这个实例允许执行客户端接下来发送的命令。然后,客户端再向这个实例发送GET命令,以读取数据。

    5. Redis Cluster hash tag的作用

    Redis Cluster在计算hash slot的时候,会同时计算一个特例就是。这个作用是什么呢?是确保两个键都在同一个哈希槽里。那如何确保这个事情呢?先看一段C源码:

    这段代码不管你会不会C应该都能看懂,非常简单,大家跟着注释把它看完。

    大致作用如下:基本来说,如果一个键包含一个“{…}”这样的模式,只有{ 和 }之间的字符串会被用来做哈希以获取哈希槽。但是由于可能出现多个{ 或 },计算的算法如下:

      只有在第一个{ 和它右边第一个 }之间的内容会被用来计算哈希值,如果中间内容是空,那么整个键会被计算,来看如下例子:

        按照这个算法,如果一个键是以{}开头的话,那么就当作整个键会被用来计算哈希值。

        所以大家想把某个用户的所有相关的键映射到同一个哈希槽里的话,那么你按照这种方式就可以实现,是不是很简单!

                       

                                       堆栈future                                    

        使很多处于迷茫阶段的coder能从这里找到光明,堆栈创世,功在当代,利在千秋

        119篇原创内容                        

        宫粽号:堆栈future

        小讯
        上一篇 2025-05-01 15:48
        下一篇 2025-06-14 14:25

        相关推荐

        版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
        如需转载请保留出处:https://51itzy.com/kjqy/152468.html