【docker13】Redis面试题

news2024/11/29 4:05:08

面试题

问题: 1~2亿条数据需要缓存,请问如何设计这个存储案例?
回答: 单机单台不可能的,肯定是分布式存储(那如何用redis实现呢?)

解决1: 哈希取余分区

哈希取余分区
优点: 简单粗暴,直接有效,只需要预估规划好节点,例如3台、8台、10台,就能保住一段时间的数据支撑。使用Hash算法让固定的一部分请求落在同一台服务器上,这样每台服务器固定处理一部分请求(并维护这些请求的信息),起到负载均衡和分而治之的作用
缺点: 原来规划好的节点,进行扩容或者缩容就比较麻烦了,不管扩缩,每次数据变动都会导致节点有变动,映射关系需要重新进行计算,在服务器个数固定不变的时候没有问题,如果需要弹性扩容或故障停机的情况下,原来的取余公式就会发生变化:Hash(key)/3会变成Hash(key)/?。此时地址经过取余运算的结果将发生很大变化,根据公式获取的服务器也会变得不可控。
某个redis机器宕机了,由于台数数量发生变化,会导致hash取余全部数据重新洗牌。

解决2:一致性Hash算法背景

一致性哈希算法在1997年由MIT提出,设计目的是为了解决分布式缓存数据变动和映射问题,某个机器宕机了,分母数量改变了,自然取余数就不可靠了
目的: 当服务器个数发生变动时,尽量减少影响客户端服务器的映射关系

三大步骤:

  1. 算法构建一致性哈希环

    一致性哈希算法必然有个hash函数并按照算法产生的hash值,这个算法的所有可能的哈希值会构成一个全量集,这个集合可以成为一个hash空间[0,232-1],这是一个线性空间,但是在算法中,我们通过适当的逻辑控制将它首位相连(即0 = 232),这样让它在逻辑上形成了一个环形的空间

    它也是按照使用取模的方法,前面笔记介绍的节点取模算法是对服务器的数量进行取模,而一致性Hash算法是对232取模,简单来说,一致性Hash算法将整个哈希值空间组织成一个虚拟的圆环,如假设哈希函数的值空空间为[0,232 -1](即哈希值是一个32位的无符号整型),整个哈希环如下图:整个空间按顺时针方向组织,圆环的正上方的点代表0,0点的右侧的第一个点代表1,以此类推2、3、4、…直到232-1,也就是说0点左侧的第一个点代表232-1,0和232-1在零点方向中重合,我们把这个由232组成的圆环称为Hash环
    算法构建一致性哈希环

  2. 服务器IP节点映射
    将集群中的各个IP节点映射到环的某一个位置
    将各个服务器使用Hash进行一个哈希,具体可以选择服务器的IP或主机名作为关键字进行哈希,这样每台机器就能确定在其哈希环上的位置。假如4个节点NodeA、B、C、D,能过IP地址的哈希函数计算(hash(ip)),使用IP地址哈希后在环空间的位置如下:

服务器IP节点映射

  1. key落到服务器的落键规则

当我们需要存储一个kv键值对时,首先计算key的hash值,hash(key),这个key使用相同的函数Hash计算出哈希值并确定此数据在环上的位置,从此位置沿环顺时针”行走“,第一台遇到的服务器就是其应该定位到的服务器,并将该键值对存储在该节点上
如我们有ObjectA、ObjectB、ObjectC、ObjectD四个数据对象,经过哈希计算后,在环空间上的位置如下:根据一致性Has,A会被定位到Node A上算法,数据B会被定位到Node B上,C会被定位到Node C上,D会被定位到Node D上。
key落到服务器的落键规则
优点:

  • 一致性哈希算法的容错性
    假设NodeC宕机,可以看到此时对象A、B、D不会受到影响,只有C对象被重新定位到Node D,在一致性Hash算法中,如果一台服务器不可用,则受影响的数据仅仅是此服务器到环空间中前一台服务器(即沿着逆时针方法行走遇到的第一台服务器)之间的数据,其他不会受到影响。简单而言,就是C宕机了,受到影响的只是B、C之间的数据,并且这些数据会转移到D进行存储
    一致性哈希算法的容错性

  • 一致性哈希算法的扩展性
    数据量增加了,需要增加一台Node X,X的位置在A和B之间,那受到影响的也就是A到X之间的数据,重新把A到X的数据录入到X上即可,不会导致hash取余全部数据重新洗牌
    一致性哈希算法的扩展性
    缺点:

  • 一致性哈希算法的数据倾斜问题
    一致性Hash算法在服务节点太少时,容易因为节点分布不均匀而造成数据倾斜(被缓存的大部分集中缓存在某一台服务器上)的问题,例如系统中只有两台服务器
    一致性哈希算法的数据倾斜问题

总结:

  • 为了在节点数目发生改变时尽可能少的迁移
  • 将所有的存储节点排列在首尾相接的Hash 环上,每个key在计算Hash后会顺时针找到临近的存储节点存放。
  • 而当有节点加入或退出时仅影响该节点在Hash环上顺时针相邻的后续节点

优点:
加入和删除节点只影响哈希环中顺时针方向相邻的节点,对其他节点无影响
缺点:
数据的分布和节点位置有关,因为这些节点不是均匀分布在哈希环上的,所以在数据在进行存储时达不到均匀分布的效果

解决3:哈希槽分区

1. 为什么出现

为了解决一致性哈希算法的数据倾斜问题
哈希槽实际上就是一个数组,数组[0,214-1]形成hash slot空间

2. 能干什么

解决均匀分配的问题,在数据和节点之间又加入了一层,把这层称为哈希槽(slot),用于管理数据和节点之间的关系,现在就相当于节点上放的是槽,槽里放的是数据
哈希槽分区
槽解决的是粒度问题,相当于把粒度变大了,这样便于数据移动。
哈希解决的是映射问题,使用key的哈希值来计算所在的槽,便于数据分配。
3. 多少个hash槽
一个集群只能有16384个槽,编号0 ~ 16383(0 ~ 214-1)。这些槽会分配给集群中的所有主节点,分配策略没有要求,可以指定哪些编号的槽分配给哪个主节点。集群会记录节点和槽的对应关系。解决了节点和槽的关系后,接下来就需要对key求哈希值,然后对16384取余,余数是几key就落入对应的槽里。slot=CRC16(key)%16384。以槽为单位移动数据,因为槽的数目是固定的,处理起来比较容易,这样数据移动问题就解决了。

**问题:为什么redis集群最大的槽数是16384个?**
**原理:** Redis集群并没有使用一致性hash而是引入了哈希槽的概念,`Redis集群有16384个哈希槽`,每个key通过CRC16校验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分hash槽。但为什么哈希槽的数量是16384(2^14^)个呢?
**解答:** CRC16算法产生的hash值有16bit,该算法可以产生2^16^=65536个值。换句话说是分布在0~65535之间,那作者在做mod运算的时候为什么不mod65536,而选择mod16384?
**说明1:** 这意味着他们包含原始节点的插槽配置,该节点使用2K的空间和16K的插槽,但是会使用8K的空间(使用65K的插槽 )。
同时,优于其他设计,Redis集群不太可能扩展到1000个以上的主节点。
因此16k处于正确的范围内,以确保每个主机具有足够的插槽,最多可容纳1000个矩阵,但数量足够少,可以轻松地将配置作为原始位图传播。请注意,在小型集群中,位图将难以压缩,因为当N较小时,位图将设置的slot/N位占设置位的很大百分比。
![说明1](https://img-blog.csdnimg.cn/324e5855dbda418fb4a264d13425e845.png)

说明2:

  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的压缩率就很低。

3.哈希槽的计算

Redis集群中内置了16384个哈希槽,redis会根据节点数量大致均等的将哈希槽映射到不同的节点。当需要在Redis集群中放置一个key-value时,redis先对key使用CRC16算法算出一个结果,然后把结果对16384求余数,这样每个key都会对应一个在0~16383之间的哈希槽,也就是映射到某个节点上。如下代码,key之A、B在Node2,key之C落在Node 3上
哈希槽的计算

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/152857.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

项目管理系统的类型

“系统”一词有两个不同的定义:一、定义某事如何完成的原则和程序,二、复杂整体的部分。因此,根据所使用的定义,项目管理系统也可以有两种不同的含义。 第一个是指定义如何执行项目的完整过程和原则系统。此定义包括所有项目管理以…

windows10上安装Python3.11.1

1)下载Python3.11.1 Python官网下载地址:https://www.python.org/ package意思是下载压缩安装包,installer是.exe的安装程序。 根据自己电脑需求选择,这里我选择的是64位 2)安装 双击安装包,进行安装。…

VScode编译调试C++环境

首先去官网下载vscodehttps://code.visualstudio.com/ 为了编译C/C,要使用gcc,Windows本身不支持gcc,所以有了MinGW,我用的是dev带的MinGW,也可以自己安装MinGW,或者用VS的编译器(MinGW gcc下载…

喜报!COSCon'22中国开源年会获评 2022 中国最受开发者欢迎的技术活动

2023 年 1 月 5 日,中国技术先锋年度评选2022 中国最受开发者欢迎的技术活动榜单正式发布。作为中国领先的新一代开发者社区,SegmentFault 思否依托社区活动板块(https://segmentfault.com/events)及全站数百万开发者用户行为数据…

浏览器怎么录制网页视频?3种网页视频录制方法

我们每天都会在浏览器上观看大量的视频,尤其是在爱奇艺、腾讯、哔哩哔哩等网页上。有时候就会观看到一些精彩的视频画面,就想要将这些画面给下载。那怎么把网页视频录制下来?今天本文就给大家分享3种有效的网页视频录制方法,有需要…

Linux 环境使用定时任务执行shell脚本

前言:Linux添加定时任务需要依赖crond服务,如果没有该服务,需要先安装:yum -y install crontabs 1、crond服务相关命令介绍 启动crond服务:service crond start 停止crond服务:service crond stop 重启cro…

【NI Multisim 14.0原理图设计基础——放置元器件】

目录 序言 🍉 一、放置元器件 序言 NI Multisim最突出的特点之一就是用户界面友好。它可以使电路设计者方便、快捷地使用虚拟元器件和仪器、仪表进行电路设计和仿真。 首先启动NI Multisim 14.0,打开如图所示的启动界面,完成初始化后&…

第一行代码Androiod第三版 笔记 第九章丰富你的程序,运用手机多媒体

文章目录前言一、通知渠道是什么?二、快速入门1. 书写通知2.通知有了 ,点击也没动静啊- PendingIntent3 点击完之后,通知不消失怎么办4 通过setStyle() 来是实现长文字通知5 还想放张图6 不同通知之间也有等级差异三、 使用相机7 调用相机8 从…

Linux工具学习之【gcc/g++】

✨个人主页: Yohifo 🎉所属专栏: Linux学习之旅 🎊每篇一句: 图片来源 🎃操作环境: CentOS 7.6 阿里云远程服务器 Whatever is worth doing is worth doing well. 任何值得去做的事情&#xff0…

SpringBoot中使用Swagger详解

在Spring Boot中规范的使用Swagger进行接口测试 文章目录Swagger是什么?为什么要用Swagger?准备工作创建项目编写接口验证高级配置文档注释接口过滤自定义响应SwaggerUI的使用遇到的问题:Swagger是什么? Swagger是一套基于OpenAP…

【Kubernetes 企业项目实战】02、基于 Prometheus 和 K8s 构建智能化监控告警系统(上)

目录 一、Prometheus 基本介绍 二、Prometheus 特点 样本 三、Prometheus 组件介绍 四、Prometheus 工作流程 五、Prometheus 和 zabbix 对比分析 六、Prometheus 的几种部署模式 6.1 基本高可用模式 6.2 基本高可用 远程存储 6.3 基本 HA 远程存储 联邦集群方案…

Word文档内容如何添加双删除线

我们有时需要在Word里面添加双删除线,那么怎么添加呢?看看小编是怎么操作的吧。 首先,运行speedoffice并打开Word文件,选中需要添加双删除线的内容; 然后,点击鼠标右键,在右键菜单中选择“高级…

如何搭建云进销存-采购管理系统?

1、简介 1.1、案例简介 本文将介绍,如何搭建云进销存-采购管理。 1.2、应用场景 云进销存-采购管理应用支持多种商品特性管理,灵活适配不同主流行业商品管理要求,并可通过报表追溯查询,实现差异化的品类管理及分析。 2、设置…

【Linux】-- 进程终止进程等待

目录 深入理解fork 进程终止 进程常见退出场景 退出码 总结 进程等待 进程等待必要性 wait与waitpid 阻塞等待 非阻塞等待 总结 深入理解fork 在linux中fork函数时非常重要的函数,它从已存在进程中创建一个新进程。新进程为子进程,而原进程为…

Rhce第三次作业

1. 基于同一IP的不同端口访问不同的网站(可以通过域名去访问)ipport1 -> 对应一个域名ipport2 -> 对应一个域名使用域名1我应该访问到 ipport1对应的内容使用域名2我应该访问到 ipport2对应的内容/etc/hosts文件下写入ip和域名,进行域名解析写入192.168.137.1…

vue3学习笔记之TransitionTransitionGroup

文章目录Transition&TransitionGroup动画组件1. Transition1.1 Transition API1.2 基于CSS的过渡效果自定义过渡class Animate动画库同时使用 transition 和 animation深层级过渡与显式过渡时长duration(总持续时间)1.3 JavaScript 钩子 GreenSock…

FPGA知识汇集-GPGPU与FPGA

虽然FPGA的功能很强大,但是并非所有的设计都会使用到这样的芯片。很多系统架构师在开始的时候会斟酌到底是使用FPGA还是其他的代替方案,例如GPGPU(通用的图形处理单元)。 由于GPGPU特有的架构和处理能力,在很多现代的设…

SpringBoot+VUE前后端分离项目学习笔记 - 【20 权限菜单 上】

数据库 新建sys_role角色表 与sys_menu菜单表 CREATE TABLE sys_role (id int NOT NULL AUTO_INCREMENT COMMENT id,name varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 名称,description varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 描述…

【C++】list模拟实现

看源码观察结构 由源码可以得知,list的底层是带头双向循环链表 — 结点类模拟实现 list实际上是一个带头双向循环链表,要实现list,则首先需要实现一个结点类,而一个结点需要存储的信息为:数据、前驱指针、后继指针 而对于该结点类的成员函数来说,我们只需实现一个构造函数即…

Linux磁盘根目录扩容

Linux磁盘根目录扩容 1.输入命令:df -hl 红色框标记的呢就是服务器的主目录,我们能看到总容量17G ,已使用2.1G 可用15G 我们要扩张磁盘空间的就是挂载点为:/ (的这个) 2.查询磁盘分区 命令:fdisk -l 我们找到/dev/sdb 这个磁盘名称就是…