面试集中营—Redis面试题

一、Redis的线程模型

        Redis是基于非阻塞的IO复用模型,内部使用文件事件处理器(file event handler),这个文件事件处理器是单线程的,所以Redis才叫做单线程的模型,它采用IO多路复用机制同时监听多个socket,根据socket上的事件来选择对应的事件处理器进行处理。

        文件事件处理器的结构包括四个部分

       1、多个socket;

       2、IO多路复用程序

       3、文件事件分排器

       4、事件处理器(连接应答处理器、命令请求处理器、命令回复处理器)

       多个 socket 可能会并发产生不同的操作,每个操作对应不同的文件事件,但是 IO 多路复用程 序会 监听多个 socket,会将 socket 产生的事件放入队列中排队,事件分派器每次从队列中取出一个事件,把该事件交给对应的事件处理器进行处理

二、客户端与Redis服务器的一次通讯过程

        一次通讯的过程如下图所示:

       1、客户端socket01发起建立连接的请求,此时Server Socket会产生一个AE_READABLE事件,IO多路复用程序监听到这个事件后把事件压入事件队列中;

       2、文件事件分派器从队列中拿到事件,根据事件的类型分发给连接应答处理器,创建socket01,并将socket01的AE_READABLE事件与命令请求处理器关联,这样下次的AE_READABLE事件就不是由连接应答处理器处理而是由命令请求处理器处理;

       3、连接建立成功后,客户端发送set key  value 请求,Server Socket会再产生一个AE_READABLE事件,IO多路复用程序监听到这个事件后把事件压入事件队列中,文件事件分派器从队列中拿到事件,交由命令请求处理器处理;

       4、命令请求处理器从socket01中的读取key value请求,并完成key value的设置,将socket01的AE_WRITABLE事件与命令回复处理器关联;

       5、如果此时客户端准备好接收返回结果了,那么Server Socket会产生AE_WRITABLE事件,同样压入队列中,事件分派器找到相关联的命令回复处理器,向socket01输出本次操作的一个结果,最后将AE_WRITABLE事件与命令回复处理器解除关联;

       本次请求完成

三、Redis Cluster的原理

        Redis集群中内置了16384个哈希槽,当需要在Redis集群中放置一个key-value时,redis先对key使用crc16算法算出一个结果,然后把结果对16384求余数,这样每个key都会对应一个编号0-16384之间的哈希槽,redis会根据节点数量大致均等的将哈希槽映射到不同的节点上。

        1、所有节点相互是连接的,客户端连接任意节点都可以操作所有的数据;

        2、集群消息通信通过集群总线通信,集群总线端口大小为客户端服务端口 + 10000;

3、 节点与节点之间通过二进制协议进行通信
        4、数据按照 Slot 存储分布在多个 Redis 实例上
 
        5、集群节点挂掉会自动故障转移
        6、可以相对平滑扩/ 缩容节点

四、如果有大量的key需要设置同一时间过期,需要注意什么

        如果有大量的 key 在同一时间过期,那么可能同一秒都从数据库获取数据,给数据库造成很大的压力,导致数据库崩溃,系统出现 502 问题。也有可能同时失效,那一刻不用都访问数据库,压力不够大的话,那么 Redis 会出现短暂的卡顿问题。所以为了预防这种问题的发生,最好给 数据的过期 时间加一个随机值,让过期时间更加分散。

五、缓存和数据库的读写一致性问题

        这里比较简单的方法就是当一个更新请求过来的时候,先删除缓存数据,再更新数据库,最后再更新缓存。

        写请求删除缓存成功,则更新数据库,如果更新数据库失败,则直接返回,写请求结束,此 时数据库中的值依旧是旧值,读请求过来后,发现缓存中没有数据, 则会直接向数据库中请求, 同时将数据写入到缓存中,此时也不会出现数据一致性的问题。

        更新数据成功之后,再更新缓存,如果此时更新缓存失败,则缓存中没有数据,数据库中是 新值,写请求结束,此时读请求还是一样,发现缓存中没有数据,同样会从数据库中读取数据, 并且存入到缓存中,其实这里不管更新缓存成功还是失败,都不会出现数据一致性的问题。

       以上其实没啥问题,问题在于,如果一个更新请求还没有结束,比如刚删了缓存,读请求进来了,此时数据库还没有更新,那么读取的就是老的数据,这就要看是否容忍这种问题。如果不能容忍那么就必须要针对同id数据的读写请求进行排队,写请求进来先进入队列,读请求排在后面等写请求完成了,再处理读请求。

六、缓存雪崩、缓存穿透、缓存预热

缓存雪崩

        缓存雪崩就是大量的key在同一时间过期,此时大部分请求都打到了数据库上,造成了数据库CPU和内存的压力过大可能成为数据库宕机,此时会造成更大面积的系统瘫痪,就好像雪崩一样。

        解决的方法第一种就是在读数据的时候先加一层锁,比如redis的分布式锁,只让一个请求进入数据库去查询。第二种方法就是尽量不让大量的key在同一时间过期,比如过期时间上增加一个随机时间;

缓存穿透

        缓存穿透就是指查询一个在缓存中不存在的key,由于不存在会去查询数据库,如果大量的查询不存在的key,还是会对数据库造成大量的压力。

        解决的方法第一种是如果发现数据库中不存在的key,也在redis中缓存一份,过期时间5分钟,这样5分种内同样的key查询就不会进入数据库了;第二种方式是使用布隆过滤器,这需要将所有可能的数据都存到了一个足够大的bitmap中,通过布隆过滤器可以确定请求的key是否合法;

缓存预热

        缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户
请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!

七、过期策略以及内存淘汰机制

过期策略        

        针对Key过期的情况,redis采用了定期删除配合惰性删除的策略;

        定期删除:每个100ms检查过期的key,如果由过期的key就删除,但每次不是全量的检查,而是随机抽取进行检查,比如抽取100个,发现其中由20个过期了,就把这20个key删除掉。如果过期 key 的占比超过可接受的过期 key 的百分比(比如20%),则重复删除的过程,直到过期key的比例降至可接受的过期 key 的百分比以下。

        惰性删除:惰性删除是指当客户端请求某个key的时候,会检查这个key是否过期,如果过期了就删除掉;

 内存淘汰机制      

        内存总会有用完的时候,如果内存已经占满了,怎么办呢?这就需要淘汰一部分的key,那么怎么淘汰呢?     

8种内存淘汰策略

1.noeviction(默认策略): 不会删除任何数据,拒绝所有写入操作并返回客户端错误消息(error)OOM command not allowed when used memory,此时 Redis 只响应删和读操作;

2.allkeys-lru: 从所有 key 中使用 LRU 算法进行淘汰(LRU 算法:最近最少使用算法);

3.allkeys-lfu: 从所有 key 中使用 LFU 算法进行淘汰(LFU 算法:最不常用算法,根据使用频率计算,4.0 版本新增);

4.volatile-lru: 从设置了过期时间的 key 中使用 LRU 算法进行淘汰;

5.volatile-lfu: 从设置了过期时间的 key 中使用 LFU 算法进行淘汰;

6.allkeys-random: 从所有 key 中随机淘汰数据;

7.volatile-random: 从设置了过期时间的 key 中随机淘汰数据;

8.volatile-ttl: 在设置了过期时间的key中,淘汰过期时间剩余最短的。

注意: 当使用 volatile-lru、volatile-lfu、volatile-random、volatile-ttl 这四种淘汰策略时,如果没有 key 可以淘汰,则和 neoviction 一样返回错误。

怎么选择淘汰策略

一般根据经验来说:

使用 allkeys-lru 策略场景:

        1.当你期望元素的子集将比其他元素更频繁地被访问时,比如幂律分布,20%的数据占有80%的使用次数;

        2.当你不确定使用哪种策略时。

使用 allkeys-random 策略场景:

        1.当你有一个循环访问,其中所有 key 进行会被连续地访问;

        2.当你希望所有 key 的分布比较均匀。

使用 volatile-ttl 策略场景:

        1.当你大部分缓存都设有不同的 ttl 值,向 Redis 提供过期候选的提示时。

八、Redis的数据类型及使用场景

1、字符串

        String类型是一种最基本的数据类型,它是一个键值对的存储结构,其中键和值都是字符串类型。String类型的特点是快速存储和读取,适用于存储一些简单的数据,如字符串、整数或浮点数等。        

使用场景

  • 缓存:经典使用场景,把常用信息,字符串,图片或者视频等信息放到Redis中,Redis作为缓存层,MySQL做持久化层,降低MySQL的读写压力
  • 计数器:Redis是单线程模型,一个命令执行完才会执行下一个,同时数据可以一步落地到其他的数据源。
  • Session:常见方案Spring Session + Redis实现Session共享。

2、List

        列表是简单的字符串列表,按照插入顺序排序,底层是双向列表(压缩列表),一种快速、高效、可靠的数据存储结构,适用于实现队列、栈等常见的数据结构。

  • 消息队列:List类型的lpop和rpush(或者反过来,lpush和rpop)能实现队列的功能,故而可以用Redis的List类型实现简单的点对点的消息队列。

  • 排行榜:List类型的range命令可以分页查看队列中的数据,但是只有顶式计算的排行榜才适合使用List类型存储。

  • 最新列表:List类型的lpush命令和range命令能实现最新列表的功能.每次通过lpush的命令往列表里插入新的元素,然后通过lrange命令读取最新元素列表,如朋友圈的点赞列表、评论列表。

3、Set

        Set对外提供的功能与List类似是一个列表的功能,特殊之处在于Set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,Set是一个很好的选择,并且Set提供了判断某个成员是否在一个Set集合内的重要接口,这个也是List所不能提供的。Redis的Set是String类型的无序集合。它底层其实是一个Value为Null的Hash表,所以添加,删除,查找的复杂度都是O(1)

  • 推荐:通过sinter命令计算交集,比如美团给你推荐附近外卖时就可以根据你的外卖记录与附近商家计算交集推送安全提示:
  • 集合保存:微信群成员保存在一个set中,用户好友也保存在Set中。当用户加入群聊时可以提醒非好友用户注意安全

4、Hash

        hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。

  • 结构化存储场景:一个hash结构中存储某个商品所有sku

5、ZSet(sortedSet)

        Zset与普通集合Set非常相似,是一个没有重复元素的字符串集合。不同之处是有序集合的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高分的方式排序集合中的成员。集合的成员是唯一的,但是评分是可以重复的 。因为元素是有序的, 所以你也可以很快的根据评分(score)或者次序(position)来获取一个范围的元素。访问有序集合的中间元素也是非常快的,因此你能够使用有序集合作为一个没有重复成员的智能列表。

        排行榜:一个销量排行榜,就可以使用店家的订单做score,这个查询出来的结果就是有序的权重队列:score作为优先级,这样取出来的数据权重都是最大优先执行的

        延时任务:score作为任务启动执行时间,取值时判断该值执行即可。

        

 参考:

Redis学习(六)8种内存淘汰机制_redis淘汰策略-CSDN博客

redis的过期键删除策略_redis过期键删除策略-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Obsidian/Typora设置图床

在obsidian中默认图片是保存在本地的,但是在要导出文档上传到网上时,由于图片保存在本地,会出现无法加载图片的问题。 这里引用的一段话: 这里使用picgo-core和gitee实现图床功能, 参考1: Ubuntu下PicGO配…

【半个月我拿下了软考证】软件设计师高频考点--系统化教学-关系模式

👨‍💻 收录于专栏:软件设计师考点暴击 ⭐🅰️进入狂砍分⭐ ⭐软件设计师高频考点文档, ⭐软件设计师高频考点专栏 ⭐软件设计师高频考点⭐ 🎶(A) 考点1,关系模式 考点: 三个模式相…

AI算法-高数5-线性代数1-基本概念、向量

线性代数:主要研究1、张量>CV计算机视觉 2、研究张量的线性关系。 深度学习的表现之所以能够超过传统的机器学习算法离不开神经网络,然而神经网络最基本的数据结构就是向量和矩阵,神经网络的输入是向量,然后通过每个矩阵对向量…

Calendar 366 II for Mac v2.15.5激活版:智能日历管理软件

在繁忙的工作和生活中,如何高效管理日程成为了许多人的难题。Calendar 366 II for Mac,作为一款全方位的日历管理软件,以其独特的功能和优秀的用户体验,成为您的日程好帮手。 Calendar 366 II for Mac支持多种视图模式&#xff0c…

【Android学习】简单的登录页面和业务逻辑实现

实现功能 1 登录页&#xff1a;密码登录和验证码登录 2 忘记密码页&#xff1a;修改密码 3 页面基础逻辑 java代码 基础页面 XML login_main.xml <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.and…

2-6 任务 猜数小游戏(单次版)

本任务要求编写一个猜数小游戏&#xff08;单次版&#xff09;&#xff0c;游戏规则是计算机产生一个0到100之间的随机整数&#xff0c;用户通过输入猜测的数字进行猜测&#xff0c;根据猜测情况给出提示&#xff0c;直到猜对为止。编程思路是利用while循环和多分支结构实现永真…

DELL T630服务器iDRAC分辨率调整办法

对于Dell T630服务器的iDRAC分辨率调整&#xff0c;您需要登录到iDRAC的Web界面。以下是详细的步骤&#xff1a; 登录iDRAC&#xff1a;在浏览器中输入iDRAC的IP地址&#xff0c;然后使用用户名&#xff08;通常是“root”&#xff09;和密码登录。 导航到虚拟控制台&#xff…

MyBatis——在WEB中使用MyBatis(MVC架构模式)

一、在 Web 应用中使用 MyBatis 项目目录结构 pojo package org.qiu.bank.pojo;/*** 账户类&#xff0c;封装账户数据* author 秋玄* version 1.0* package org.qiu.bank.pojo* date 2022-09-27-20:31* since 1.0*/ public class Account {private Long id;private String …

数据分析的统计推断

数据分析的统计推断 前言一、提出问题二、统计归纳方法三、统计推断四、统计推断步骤如何进行统计推断统计推断的基本问题点估计区间估计总体方差已知总体方差未知 假设检验假设检验的假设显著性水平 五、检验统计量常见的检验统计量 六、检验方法七、拒绝域八、假设检验步骤九…

报告!Golang冲上来啦!

今天又来讲Go语言&#xff0c;根据全球知名的编程语言排行榜TIOBE在4月份公布的最新的编程语言排名&#xff0c;令人瞩目的是&#xff0c;Go语言已经跃升至历史最高位&#xff0c;位列排行榜第七名&#xff0c;并且Go语言是前十榜单中最年轻的编程语言。这一成绩不仅彰显了Go语…

鲁教版六年级数学上册-笔记

文章目录 第一章 丰富的图形世界1 生活中的立体图形2 展开和折叠3 截一个几何体4 从三个方向看物体的形状 第二章 有理数及其运算1 有理数2 数轴3 绝对值4 有理数的加法5 有理数的减法6 有理数的加减混合运算7 有理数的乘法8 有理数的除法9 有理数的乘方10 科学计数法11 有理数…

CentOS7 安装 Kamailio

https://www.kamailio.org/wiki/packages/rpms 官方文档说 yum -y install yum-utils yum-config-manager --add-repo https://rpm.kamailio.org/centos/kamailio.repo 但目前这样其实行不通 需要这样做&#xff1a; yum install --disablerepokamailio --enablerepokamai…

Oracle 删除表中的列

Oracle 删除表中的列 CONN SCOTT/TIGER DROP TABLE T1; create table t1 as select * from emp; insert into t1 select * from t1; / / --到6000行&#xff0c;构造一个实验用大表T1。 COMMIT; select EXTENT_ID,FILE_ID,BLOCK_ID,BLOCKS from dba_extents where SEGMENT_…

字典是如何实现的?Rehash 了解吗?

字典是 Redis 服务器中出现最为频繁的复合型数据结构。除了 hash 结构的数据会用到字典外&#xff0c;整个 Redis 数据库的所有 key 和 value 也组成了一个 全局字典&#xff0c;还有带过期时间的 key 也是一个字典。(存储在 RedisDb 数据结构中) 字典结构是什么样的呢&#xf…

AI 重塑产品设计

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

【linux】linux工具使用

这一章完全可以和前两篇文件归类在一起&#xff0c;可以选择放一起看哦 http://t.csdnimg.cn/aNaAg http://t.csdnimg.cn/gkJx7 拖更好久了&#xff0c;抱歉&#xff0c;让我偷了会懒 1. 自动化构建工具 make , makefile make 是一个命令&#xff0c;makefile 是一个文件&…

C++笔记(体系结构与内核分析)

1.OOP面向对象编程 vs. GP泛型编程 OOP将data和method放在一起&#xff0c;目的是通过封装、继承、多态提高软件的可维护性和可扩展性GP将data和method分开&#xff0c;可以将任何容器与任何算法结合使用&#xff0c;只要容器满足塞饭所需的迭代器类型 2.算法与仿函数的区别 …

vue项目基于WebRTC实现一对一音视频通话

效果 前端代码 <template><div class"flex items-center flex-col text-center p-12 h-screen"><div class"relative h-full mb-4 fBox"><video id"localVideo"></video><video id"remoteVideo">…

C++STL初阶(1):string的使用及初阶原理

此文作为学习stl的笔记&#xff0c;许多普及、概念性的知识点将不再罗列&#xff08;如stl的发展、背景等&#xff09; 便于读者作为复习等方法了解。 0.STL简介&#xff08;笔记向&#xff09; STL不是祖师爷本贾尼实现的&#xff0c;是在惠普实验室中实现的。其作为一个数据结…

【强训笔记】day20

NO.1 思路&#xff1a;先判断能对砍几个回合&#xff0c;取最小值&#xff0c;因为回合数是整数&#xff0c;所以可能存在都大于0的情况&#xff0c;再判断一下如果都存活就再对砍一次&#xff0c;直到一家存活或者都死亡。 代码实现&#xff1a; #include<iostream>u…