面试集中营—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.mfbz.cn/a/599206.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Richard 林旅强:说说社区的故事和对 RTE 社区的畅想

各位 RTE 开发者社区的小伙伴们,大家好: 我是 Richard 林旅强,今年起开始担任我们 RTE 社区联合主理人,很荣幸能在这里跟杜金房老师和陈靖老师一起做点事情,为社区的大家服务 😃 今天想跟各位分享&#x…

数据结构---动态数组

一、数据结构基本理论 数据结构是相互之间存在一种或多种特定关系的数据元素的集合。强调数据元素之间的关系 算法五个特性: 输入、输出、有穷、确定、可行 数据结构分类: 逻辑结构:集合、线性结构、树形结构、图形结构 物理…

Baidu Comate:你的智能编程伙伴,编程界的AI革命者

文章目录 Baidu Comate 介绍Baidu Comate下载安装Baidu Comate 实操体验代码解释函数注释行间注释调优建议生成单测注释生成实时续写常用快捷方式智能对话问答 Baidu Comate 建议改进Baidu Comate 体验总结 Baidu Comate 介绍 Baidu Comate 智能编码助手 是基于文心大模型&…

【nginx 开发】nginx安装,Nginx介绍

Nginx基础介绍 Nginx反向代理负载均衡动静分离 Nginx的安装NginxNginx常用命令Nginx配置文件 Nginx Nginx是一个高性能的Http和反向代理服务器,特点是占有内存少,并发能力强,Nginx可以作为静态页面的web服务器,Nginx专为性能优化…

4G工业路由器快递柜应用案例(覆盖所有场景)

快递柜展示图 随着电商的蓬勃发展,快递行业迎来高速增长。为提高快递效率、保障快件安全,智能快递柜应运而生。但由于快递柜部署环境复杂多样,网络接入成为一大难题。传统有线宽带难以覆盖所有场景,而公用WiFi不稳定且存在安全隐患。 星创易联科技有限公司针对这一痛点,推出了…

我独自升级崛起在哪下载 我独自升级崛起客户端下载教程

定于5月8日全球盛放的《我独自升级:崛起》——这一激动人心的动作角色扮演游戏巨作,汲取了同名动漫及网络漫画的精髓,誓将以其无与伦比的魅力,引领玩家迈入一个探索深远、规模宏大的奇幻之旅。游戏构筑在一个独一无二的网络武侠世…

JavaScript:正则表达式属于字符串吗-不属于/字符串转正则表达式的两种方法

一、需求描述 js 字符串转正则表达式 二、理解正则表达式属于字符串吗? 正则表达式不属于字符串,它是一种用于匹配、查找和操作文本的模式。正则表达式是一种特殊的语法,用于描述字符串的特征。通过使用正则表达式,可以检查一个字符串是否…

项目计划书(Word原件)

项目开发计划包括项目描述、项目组织、成本预算、人力资源估算、设备资源计划、沟通计划、采购计划、风险计划、项目过程定义及项目的进度安排和里程碑、质量计划、数据管理计划、度量和分析计划、监控计划和培训计划等。 软件资料清单列表部分文档: 工作安排任务书…

如何有效识别限界上下文?

在实施DDD的过程中,识别限界上下文是一大难点,但也并非无章可循。在本文内容中,我们将分别从业务维度、工作维度以及技术维度进行展开,讨论如何有效识别限界上下文的方法和技巧。 从业务维度识别限界上下文 从业务维度识别限界上…

羊大师解析,鲜为人知的羊奶冷知识

羊大师解析,鲜为人知的羊奶冷知识 羊奶的脂肪球更小:相较于牛奶,羊奶中的脂肪球直径更小,这有助于其更快地被人体消化和吸收。 羊奶含有更多的中链脂肪酸:羊奶中含有较多的中链脂肪酸(MCT)&am…

安装nginx-1.25.5与ngx_http_headers_more_filter_module模块

#下载nginx的代码 curl -O http://nginx.org/download/nginx-1.25.5.tar.gz #下载headers-more-nginx-module代码 git clone https://github.com/openresty/headers-more-nginx-module#解压 tar -xzf nginx-1.25.5.tar.gzcd nginx-1.25.5#--add-dynamic-module 下载下来的目录 …

Al Agent:开启智能化未来的关键角色,让机器更智能的为我们服务

文章目录 🚀Al Agent是什么📕Al Agent的工作原理与技术💪Al Agent应用领域🚀智能家居应用🌈医疗健康领域⭐金融服务行业🌂交通运输管理🎬教育培训应用 🔒Al Agent优势与挑战✊Al Age…

移动端自适应

基本实现核心思想 基本原则上是,布局更多地使用flex,然后尺寸使用rem,vw,vh为单位如果是根据不同的屏幕需要有不同的布局了,一般通过检测屏幕尺寸换不同的站点或者媒体查询使用css rem 以html字体太小为1rem的大小&…

LM4562NA 直插DIP8双运放 音频hifi运算放大器

LM4562NA是一款高性能音频运算放大器,其应用领域主要集中在音频和声音处理方面,包括但不限于: 1. 专业录音设备:在录音棚、广播电台和电视台等专业环境中,用于信号放大和处理,确保高质量的声音录制和传输…

揭秘数据可视化:五款利器助力决策

在当今这个数据驱动的时代,数据可视化已成为企业决策、数据分析不可或缺的一部分。通过直观、生动的图形、图像,数据可视化能够更快速、更准确地传达信息,帮助企业洞察数据背后的价值。本文将为您介绍几款优秀的数据可视化工具。 一、山海鲸…

docker-compose编排集成工具,consul服务更新与发现

一、引言 我们知道使用一个 Dockerfile 模板文件可以定义一个单独的应用容器,如果需要定义多个容器就需要服务编排。服务编排有很多种技术方案,今天给大家介绍 Docker 官方产品 Docker-Compose Dockerfile 可以定义一个单独的应用容器&#xff1…

图片编辑工具-Gimp

一、前言 GIMP(GNU Image Manipulation Program)是一款免费开源的图像编辑软件,具有功能强大和跨平台的特性。 GIMP作为一个图像编辑器,它提供了广泛的图像处理功能,包括但不限于照片修饰、图像合成以及创建艺术作品…

uni-app安卓本地打包个推图标配置

如果什么都不配置,默认的就是个推小鲸鱼图标 默认效果 配置成功效果 个推图标配置 新建目录 drawable-hdpi、drawable-ldpi、drawable-mdpi、drawable-xhdpi、drawable-xxhdpi、drawable-xxxhdpi 目录中存放图标 每个目录中存放对应大小的图标,大图…

Day28:ElasticSearch入门、Spring整合ES、开发社区搜索功能

ElasticSearch入门 Elasticsearch简介 一个分布式的、Restful风格的搜索引擎。支持对各种类型的数据的检索(非结构化的也可以)。搜索速度快,可以提供实时的搜索服务。便于水平扩展(集群式部署),每秒可以处…

分享三维地理模型制作实践

前言 地理信息系统(GIS)是一种用于捕获、存储、检查和显示与地球表面位置相关的数据的计算机系统。GIS可以在一张地图上显示许多不同类型的数据,如街道、建筑物和植被。这使人们能够更容易地看到、分析和理解模式和关系。 实践 从地理空间…
最新文章