当前位置: 首页 > news >正文

面试集中营—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博客

相关文章:

面试集中营—Redis面试题

一、Redis的线程模型 Redis是基于非阻塞的IO复用模型,内部使用文件事件处理器(file event handler),这个文件事件处理器是单线程的,所以Redis才叫做单线程的模型,它采用IO多路复用机制同时监听多个socket&a…...

关于使用git拉取gitlab仓库的步骤(解决公钥问题和pytho版本和repo版本不对应的问题)

先获取权限,提交ssh-key 虚拟机连接 GitLab并提交代码_gitlab提交mr-CSDN博客 配置完成上诉步骤之后,执行下列指令进行拉去仓库的内容 sudo apt install repo export PATHpwd/.repo/repo:$PATH python3 "实际路径"/repo init -u ssh://gitxx…...

Django图书馆综合项目-学习(2)

接下来我们来实现一下图书管理系统的一些相关功能 1.在书籍的book_index.html中有一个"查看所有书毂"的超链接按钮,点击进入书籍列表book_list.html页面. 这边我们使用之前创建的命名空间去创建超连接 这里的book 是在根路由创建的namespacelist是在bo…...

vue3+ts 获取input 输入框中的值

从前端input 输入框获取值&#xff0c;通过封装axios 将值传给后端服务 数据格式为json html <el-form> <el-form-item label"域名"><el-input v-model"short_url" style"width: 240px"type"text"placeholder&quo…...

Gin框架返回Protobuf类型:提升性能的利器

在构建高效、高性能的微服务架构时&#xff0c;数据序列化和反序列化的性能至关重要。Protocol Buffers&#xff08;简称Protobuf&#xff09;作为一种轻量级且高效的结构化数据存储格式&#xff0c;已经在众多领域得到广泛应用。Gin框架作为Go语言中流行的Web框架&#xff0c;…...

HTML满屏漂浮爱心

目录 写在前面 满屏爱心 代码分析 系列推荐 写在最后 写在前面 小编给大家准备了满屏漂浮爱心代码&#xff0c;一起来看看吧~ 满屏爱心 文件heart.svg <svg xmlns"http://www.w3.org/2000/svg" width"473.8px" height"408.6px" view…...

爬虫应该选择住宅ip代理还是数据中心代理?

住宅代理 住宅代理是互联网服务提供商 (ISP) 提供的 IP 地址&#xff0c;它们是附加到实际物理位置的真实IP地址。住宅代理允许用户通过目标区域内的真实IP地址连接到互联网。 数据中心代理 数据中心代理是指是使用数据中心拥有并管理IP的代理&#xff0c;IP地址来源于数据中…...

百面算法工程师目录 | 深度学习目标检测、语义分割、分类上百种面试问答技巧

本文给大家带来的百面算法工程师是深度学习面试目录大纲&#xff0c;文章内总结了常见的提问问题&#xff0c;旨在为广大学子模拟出更贴合实际的面试问答场景。在这篇文章中&#xff0c;可以点击题目直达问题答案处&#xff0c;方便查找问题寻找答案。节约大家的时间。通过对这…...

Java中Maven的依赖管理

依赖介绍 是指当前项目运行所需要的jar包&#xff0c;一个项目中可以引入多个依赖 配置 在pom.xml中编写<dependencies>标签 在<dependencies>中使用<dependency>引入标签 定义坐标的groupId、rtifactId、version 点击刷新按钮、引入新坐标 例如引入下…...

Github新手入门使用方法

**存在问题&#xff1a;**新手如何快速入门github&#xff0c;能够下载开源文件&#xff0c;并且修改后更新远程github仓库&#xff1b; 解决方案&#xff1a; 参考&#xff1a; http://www.360doc.com/content/24/0301/12/60419_1115656653.shtml https://blog.csdn.net/gongd…...

期权隐含波动率到底是什么意思?

今天期权懂带你了解期权隐含波动率到底是什么意思&#xff1f;期权隐含波动率解析。通俗的说&#xff0c;期权隐含波动率是在期权市场中买家和卖家对于&#xff0c;某一期权合约价格变动幅度大小的判断。 期权隐含波动率到底是什么意思&#xff1f; 隐含波动率是根据期权市场价…...

28、Flink 为管理状态自定义序列化

为管理状态自定义序列化 a&#xff09;概述 对状态使用自定义序列化&#xff0c;包含如何提供自定义状态序列化程序、实现允许状态模式演变的序列化程序。 b&#xff09;使用自定义状态序列化程序 注册托管 operator 或 keyed 状态时&#xff0c;需要 StateDescriptor 来指…...

【强训笔记】day17

NO.1 思路&#xff1a;用一个字符串实现&#xff0c;stoi函数可以转化为数字并且去除前导0。 代码实现&#xff1a; #include <iostream> #include<string> using namespace std;string s;int main() {cin>>s;for(int i0;i<s.size();i){if(s[i]%20) s[…...

平滑 3d 坐标

3d平滑 import torch import torch.nn.functional as F import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3Dclass SmoothOperator:def smooth(self, vertices):# 使用一维平均池化进行平滑vertices_smooth F.avg_pool1d(vertices.p…...

Go解析的数据类型可能含有不同数据结构的处理方式

最近做一个需求&#xff0c;各种业务消息都会往我的消息队列中写各种类型的数据&#xff0c;服务端需要接受各种不同的参数然后转换为本地数据结构&#xff0c;Go语言不确定上游传过来的数值是什么类型&#xff0c;然后又下面四种解决方案。 1. 类型断言和类型切换 func (Mis…...

Java网络编程基础

Java网络编程基础主要涉及进程间通信、网络通信协议、IP地址和端口以及Java提供的网络应用编程接口等核心概念。 进程间通信是Java网络编程的基础。进程是运行中的程序&#xff0c;而进程间通信则是指不同进程之间进行数据交换和共享信息的过程。在Java中&#xff0c;进程间的…...

鸿蒙DevEco Studio 4.1 Release-模拟器启动方式错误

软件版本&#xff1a;DevEco Studio 4.1 Release 报错提示&#xff1a; 没有权限查看处理指导 Size on Disk 显示1.0MB 尝试方案&#xff08;统统无效&#xff09;&#xff1a; 1、“windows虚拟机监控程序平台”、"虚拟机平台"已开启 启用CPU虚拟化 2、C…...

Linux与windows网络管理

文章目录 一、TCP/IP1.1、TCP/IP概念TCP/IP是什么TCP/IP的作用TCP/IP的特点TCP/IP的工作原理 1.2、TCP/IP网络发展史1.3、OSI网络模型1.4、TCP/IP网络模型1.5、linux中配置网络网络配置文件位置DNS配置文件主机名配置文件常用网络查看命令 1.6、windows中配置网络CMD中网络常用…...

一站式、低成本 | 等保一体机安全解决方案

方案建设背景 等级保护是我国关于信息安全的基本政策&#xff0c;相关政策制度要求单位开展等级保护工作。单位信息系统存在的安全隐患和不足&#xff0c;进行安全整改之后&#xff0c;提高信息系统的信息安全防护能力&#xff0c;降低系统被攻击的风险&#xff0c;维护单位良…...

Grafana(CVE-2021-43798)、Apache Druid 代码执行漏洞

文章目录 一、Grafana 8.x 插件模块目录穿越漏洞&#xff08;CVE-2021-43798&#xff09;二、Apache Druid 代码执行漏洞&#xff08;CVE-2021-25646&#xff09; 一、Grafana 8.x 插件模块目录穿越漏洞&#xff08;CVE-2021-43798&#xff09; Grafana是一个系统监测工具。 利…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

HTML 列表、表格、表单

1 列表标签 作用&#xff1a;布局内容排列整齐的区域 列表分类&#xff1a;无序列表、有序列表、定义列表。 例如&#xff1a; 1.1 无序列表 标签&#xff1a;ul 嵌套 li&#xff0c;ul是无序列表&#xff0c;li是列表条目。 注意事项&#xff1a; ul 标签里面只能包裹 li…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...