返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >为什么RedisCluster设计成16384个槽
  • 265
分享到

为什么RedisCluster设计成16384个槽

2024-04-02 19:04:59 265人浏览 八月长安
摘要

目录一、数据分片策略二、Redis的分片机制三、Redis 虚拟槽分区的特点四、 Redis 集群伸缩的原理1.集群扩容2.集群收缩五、总结面试问题:为什么RedisCluster会

亲爱的同学们,你是否使用过Redis集群呢?那Redis集群的原理又是什么呢?记住下面两句话:

  • Redis Sentinal着眼于高可用,在master宕机时会自动将slave提升为master,继续提供服务。
  • Redis Cluster着眼于扩展性,在单个redis内存不足时,使用Cluster进行分片存储。

一、数据分片策略

布式数据存储方案中最为重要的一点就是数据分片,也就是所谓的 Sharding。为了使得集群能够水平扩展,首要解决的问题就是如何将整个数据集按照一定的规则分配到多个节点上,常用的数据分片的方法有:范围分片,哈希分片,一致性哈希算法和虚拟哈希槽等。

范围分片假设数据集是有序,将顺序相临近的数据放在一起,可以很好的支持遍历操作。范围分片的缺点是面对顺序写时,会存在热点。比如日志类型的写入,一般日志的顺序都是和时间相关的,时间是单调递增的,因此写入的热点永远在最后一个分片。对于关系型的数据库,因为经常性的需要表扫描或者索引扫描,基本上都会使用范围的分片策略。

我们为了将不同的 key 分散放置到不同的 redis 节点,通常的做法是获取 key 的哈希值,然后根据节点数来求模,但这种做法有其明显的弊端,当我们需要增加或减少一个节点时,会造成大量的 key 无法命中,这种比例是相当高的,所以就有人提出了一致性哈希的概念。

一致性哈希有四个重要特征:

  • 均衡性:也有人把它定义为平衡性,是指哈希的结果能够尽可能分布到所有的节点中去,这样可以有效的利用每个节点上的资源。
  • 单调性:当节点数量变化时哈希的结果应尽可能的保护已分配的内容不会被重新分派到新的节点。
  • 分散性和负载:这两个其实是差不多的意思,就是要求一致性哈希算法对 key 哈希应尽可能的避免重复。

二、Redis的分片机制

但是:Redis 集群没有使用一致性hash, 而是引入了哈希槽的概念。

Redis Cluster 采用虚拟哈希槽分区,所有的键根据哈希函数映射到 0 ~ 16383 整数槽内,每个key通过CRC16校验后对16384取模来决定放置哪个槽(Slot),每一个节点负责维护一部分槽以及槽所映射的键值数据。

计算公式:slot = CRC16(key) & 16383。

这种结构很容易添加或者删除节点,并且无论是添加删除或者修改某一个节点,都不会造成集群不可用的状态。使用哈希槽的好处就在于可以方便的添加或移除节点。

  • 当需要增加节点时,只需要把其他节点的某些哈希槽挪到新节点就可以了;
  • 当需要移除节点时,只需要把移除节点上的哈希槽挪到其他节点就行了。

三、Redis 虚拟槽分区的特点

  • 解耦数据和节点之间的关系,简化了节点扩容和收缩难度。
  • 节点自身维护槽的映射关系,不需要客户端或者代理服务维护槽分区元数据
  • 支持节点、槽和键之间的映射查询,用于数据路由,在线集群伸缩等场景。

四、 Redis 集群伸缩的原理

Redis 集群提供了灵活的节点扩容和收缩方案。在不影响集群对外服务的情况下,可以为集群添加节点进行扩容也可以下线部分节点进行缩容。可以说,槽是 Redis 集群管理数据的基本单位,集群伸缩就是槽和数据在节点之间的移动。

1.集群扩容

当一个 Redis 新节点运行并加入现有集群后,我们需要为其迁移槽和数据。首先要为新节点指定槽的迁移计划,确保迁移后每个节点负责相似数量的槽,从而保证这些节点的数据均匀。

  • 首先启动一个 Redis 节点,记为 M4。
  • 使用 cluster meet 命令,让新 Redis 节点加入到集群中。新节点刚开始都是主节点状态,由于没有负责的>槽,所以不能接受任何读写操作,后续我们就给他迁移槽和填充数据。
  • 对 M4 节点发送 cluster setslot { slot } importing { sourcenodeId } 命令,让目标节点准备导入槽的数据。 >4) 对源节点,也就是 M1,M2,M3 节点发送 cluster setslot { slot } migrating { targetNodeId } 命令,让源节>点准备迁出槽的数据。
  • 源节点执行 cluster geTKEysinslot { slot } { count } 命令,获取 count 个属于槽 { slot } 的键,然后执行步骤>六的操作进行迁移键值数据。
  • 在源节点上执行 migrate { targetNodeIp} " " 0 { timeout } keys { key... } 命令,把获取的键通过 pipeline 机制>批量迁移到目标节点,批量迁移版本的 migrate 命令在 Redis 3.0.6 以上版本提供。
  • 重复执行步骤 5 和步骤 6 直到槽下所有的键值数据迁移到目标节点。
  • 向集群内所有主节点发送 cluster setslot { slot } node { targetNodeId } 命令,通知槽分配给目标节点。为了>保证槽节点映射变更及时传播,需要遍历发送给所有主节点更新被迁移的槽执行新节点。

2.集群收缩

收缩节点就是将 Redis 节点下线,整个流程需要如下操作流程。

  • 首先需要确认下线节点是否有负责的槽,如果是,需要把槽迁移到其他节点,保证节点下线后整个集群槽节点映射的完整性。
  • 当下线节点不再负责槽或者本身是从节点时,就可以通知集群内其他节点忘记下线节点,当所有的节点忘记改节点后可以正常关闭。

下线节点需要将节点自己负责的槽迁移到其他节点,原理与之前节点扩容的迁移槽过程一致。

迁移完槽后,还需要通知集群内所有节点忘记下线的节点,也就是说让其他节点不再与要下线的节点进行 Gossip 消息交换。

Redis 集群使用 cluster forget { downNodeId } 命令来讲指定的节点加入到禁用列表中,在禁用列表内的节点不再发送 Gossip 消息。

五、总结

Redis Cluster 是Redis的集群实现,内置数据自动分片机制,集群内部将所有的key映射到16384个Slot中,集群中的每个Redis Instance负责其中的一部分的Slot的读写。集群客户端连接集群中任一Redis Instance即可发送命令,当Redis Instance收到自己不负责的Slot的请求时,会将负责请求Key所在Slot的Redis Instance地址返回给客户端,客户端收到后自动将原请求重新发往这个地址,对外部透明。一个Key到底属于哪个Slot由crc16(key) % 16384 决定。

面试问题:为什么RedisCluster会设计成16384个槽呢?

这个问题,作者是给出了回答的!

地址如下:https://GitHub.com/antirez/redis/issues/2576

作者原版回答如下: The reason is:

NORMal heartbeat packets carry the full configuration of a node, that can be replaced in an idempotent way with the old in order to update an old config. This means they contain the slots configuration for a node, in raw form, that uses 2k of space with16k slots, but would use a prohibitive 8k of space using 65k slots.At the same time it is unlikely that Redis Cluster would scale to more than 1000 mater nodes because of other design tradeoffs.

So 16k was in the right range to ensure enough slots per master with a max of 1000 maters, but a small enough number to propagate the slot configuration as a raw bitmap easily. Note that in small clusters the bitmap would be hard to compress because when N is small the bitmap would have slots/N bits set that is a large percentage of bits set.

1.如果槽位为65536,发送心跳信息的消息头达8k,发送的心跳包过于庞大。

如上所述,在消息头中,最占空间的是myslots[CLUSTER_SLOTS/8]。 当槽位为65536时,这块的大小是:65536÷8÷1024=8kb因为每秒钟,redis节点需要发送一定数量的ping消息作为心跳包,如果槽位为65536,这个ping消息的消息头太大了,浪费带宽。

2.redis的集群主节点数量基本不可能超过1000个。

如上所述,集群节点越多,心跳包的消息体内携带的数据越多。如果节点过1000个,也会导致网络拥堵。因此redis作者,不建议redis cluster节点数量超过1000个。 那么,对于节点数在1000以内的redis cluster集群,16384个槽位够用了。没有必要拓展到65536个。

3.槽位越小,节点少的情况下,压缩率高

Redis主节点的配置信息中,它所负责的哈希槽是通过一张bitmap的形式来保存的,在传输过程中,会对bitmap进行压缩,但是如果bitmap的填充率slots / N很高的话(N表示节点数),bitmap的压缩率就很低。 如果节点数很少,而哈希槽数量很多的话,bitmap的压缩率就很低。

而16384÷8÷1024=2kb,怎么样,神奇不!

综上所述,作者决定取16384个槽,不多不少,刚刚好!

到此这篇关于为什么RedisCluster设计成16384个槽的文章就介绍到这了,更多相关RedisCluster 16384槽内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 为什么RedisCluster设计成16384个槽

本文链接: https://lsjlt.com/news/136416.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 为什么RedisCluster设计成16384个槽
    目录一、数据分片策略二、Redis的分片机制三、Redis 虚拟槽分区的特点四、 Redis 集群伸缩的原理1.集群扩容2.集群收缩五、总结面试问题:为什么RedisCluster会...
    99+
    2024-04-02
  • redis槽位为什么是16384
    redis 槽位数量为 16384,原因如下:均匀分配数据,避免数据偏斜。保证数据高可用性,即使一个节点宕机,其槽位也会转移到其他节点。方便伸缩,根据数据量动态添加或移除节点,重新分配槽...
    99+
    2024-04-08
    redis
  • 为什么redis集群的最大槽数是16384个
    为什么redis集群的最大槽数是16384个?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Redis 集群并没有使用一致性ha...
    99+
    2024-04-02
  • java为什么要设计异常?
    从业这么多年,每当谈起异常,都是懵懵懂懂,只是依稀记得它是处理错误的,当程序出错,日志里会有异常日志,可以查看异常定位错误。但是最近突然发现一个问题,那就是处理错误不一定非的要用异常啊,比如说参数合法性检查等等,判断是否为空后直接返回校验信...
    99+
    2019-06-27
    java教程 java 异常
  • 为什么设计师急需用git
    在过去的几十年中,设计工作一直处于人类文明的最前沿,随着技术的不断进步,设计的方式和方法也在不断发展。现在,设计师不仅需要掌握各种设计技巧和软件,还需要了解各种工具和平台,以提高生产效率和设计质量。其中,Git引起了更多的人的关注,它被设计...
    99+
    2023-10-22
  • Python干货(一):27个问题,告诉你 Python 为什么如此设计?
    ...
    99+
    2023-06-02
  • 详解Python为什么不用设计模式
    前言 刚刚看了EuroPython 2017一篇演讲,Why You Don't Need Design Patterns in Python,为什么python不用设计模式。演讲者...
    99+
    2024-04-02
  • 个人网站设计建设的流程是什么
    个人网站设计建设的流程一般分为以下几个步骤:1. 网站需求分析:了解客户的需求和目标,确定网站的定位、功能、内容等。2. 网站规划:...
    99+
    2023-06-05
    网站设计建设
  • 怎么用Java设计一个短链接生成系统
    这篇文章主要讲解了“怎么用Java设计一个短链接生成系统”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么用Java设计一个短链接生成系统”吧!引言相信大家在生活中,特别是最近的双十一活动期...
    99+
    2023-06-22
  • 为什么宁可用Lombok也不把成员设置为public
    这篇“为什么宁可用Lombok也不把成员设置为public”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“为什么宁可用Lomb...
    99+
    2023-07-05
  • 跳槽必备之你设计索引的原则是什么?怎么避免索引失效?
    目录主键索引为频繁查询的字段建立索引避免为"大字段"建立索引选择区分度大的列作为索引尽量为ORDER BY 和 GROUP BY 后面的字段建立索引不要在条件中使用函数不要建立太多的...
    99+
    2024-04-02
  • 浅析Java中为什么要设计包装类
    目录一、为什么需要包装类二、装箱与拆箱三、不简单的Integer.valueOf四、Object类可以接收所有数据类型五、包装类在集合中的广泛使用六、数据类型转换一、为什么需要包装类...
    99+
    2024-04-02
  • 网页设计中为什么要优化代码
    这篇文章主要介绍了网页设计中为什么要优化代码,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。由于网络是一个不断变化和不断发展的有机体,所以建立一个能和网络一起变化、成长的网站是...
    99+
    2023-06-12
  • 建表为什么还设置个自增 id
    这篇文章主要讲解了“建表为什么还设置个自增 id”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“建表为什么还设置个自增 id”吧!1.建表规约在工作中,创建表...
    99+
    2024-04-02
  • Apache Flink 为什么能够成为新一代大数据计算引擎?
    众所周知,Apache Flink(以下简称 Flink)最早诞生于欧洲,2014 年由其创始团队捐赠给 Apache 基金会。如同其他诞生之初的项目,它新鲜,它开源,它适应了快速转的世界中更重视的速度与灵活性。 大数据时代对人类的数据驾...
    99+
    2020-08-14
    Apache Flink 为什么能够成为新一代大数据计算引擎?
  • 为什么设计师需要学习编写代码
    这篇文章主要介绍了为什么设计师需要学习编写代码,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。做现实可行的设计有了一个最终产品将如何实现的明确印象,设计师将拿出更多实际可行的概...
    99+
    2023-06-08
  • 为什么说sap软件对ic设计企业重要呢?
    我们先来看下一下IC设计行业背景说明,IC设计业已成为半导体产业链中的明日之星,尤其在景气低迷之际,IC设计业的发展倍受瞩目,由于IC设计的脑力密集型特性,加上越来越多的IDM厂商也跨入Fabless模式...
    99+
    2024-04-02
  • 为什么Java编程中的算法设计如此重要?
    Java是一种广泛使用的编程语言,它被用于开发各种应用程序和网站。在Java编程中,算法设计是非常重要的一个方面,因为它可以帮助程序员更有效地解决问题,提高程序的效率和性能。在本文中,我们将探讨为什么Java编程中的算法设计如此重要,并演示...
    99+
    2023-09-12
    编程算法 unix path
  • 计算机中即可作为输入设备又可以作为输出设备的是什么
    这篇文章主要讲解了“计算机中即可作为输入设备又可以作为输出设备的是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“计算机中即可作为输入设备又可以作为输出设备的是什么”吧!计算机中即可作为输...
    99+
    2023-06-25
  • 亚马逊云服务器建设成本高吗为什么这么贵
    总的来说,亚马逊云服务器建设的成本非常高,主要是因为它提供了完整的IaaS、PaaS和SaaS服务,从硬件、带宽接入到操作系统和安全控制等方面都需要投入大量的资金,同时也需要投入大量的人力资源和技术资源。 ...
    99+
    2023-10-27
    亚马逊 成本 服务器
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作