Redis面试(三)

news2024/12/29 10:57:20

1.Redis报内存不足怎么处理

Redis内存不足的集中处理方式:

  • 修改配置文件redis.cof的maxmemory参数,增加Redis的可用内存
  • 通过命令修改set maxmemory动态设置内存上限
  • 修改内存淘汰策略,及时释放内存
  • 使用Redis集群,及时进行扩容

2.Redis的过期回收策略

  • 惰性删除: 惰性删除是指当我们查询key的时候才对key进行检测,如果已经达到过期时间,则删除,显然有一个缺点就是如果过期的key没有被访问,那么就会一直不被删除,而一直占用内存。
  • 定期删除:定期删除是指Redis每隔一段时间对数据库做一次检查,删除里面的过期key,由于不可能做轮询key,所以Redis是每次随机抽取一下key做检查

3.Redis有哪些内存溢出控制策略

内存达到maxmemory上限时候会触发响应的控制策略,Redis支持6种策略

  • noeviction: 默认策略,不会删除任何数据,拒绝写入任何数据并且返回错误信息,此时Redis只响应读操作
  • volatile-lru:根据lru算法设置了超时属性的值,知道腾出足够的空间为止,如果没有可删除的健对象,回退到noeviction策略。
  • allkeys-lru:根据LRU算法删除健,不管数据有没有设置超时属性,直到特腾出足够空间为止
  • allkeys-random:随机删除所有的健,直到腾出空间为止。
  • volatile-random:随机删除过期的健,直到腾出足够的空间
  • volatile-ttl:根据键值属性,删除最近将要过期的数据,如果没有回退到noeviction策略。

4.Redis阻塞?怎么解决

在这里插入图片描述

  • API或者数据结构不合理
    通常Redis执行命令速度非常快,但是不合理的使用命令,可能会导致执行速度变慢,导致阻塞,特别在高并发的时候,应该尽量避免在大对象执行算法复杂度超过O(n)的。
    对慢查询的处理分为两步
    1.使用查询show log get{n}命令可以获取最近的n条慢查询命令
    2.发现慢查询后可从以下两个方向优化
    - 修改为低算法的复杂度的命令,如hgetall改为hmget等,禁用keys,sort命令等
    - 调整大对象:缩短大对象数据或者把大对象进行拆分为多个小对象,防止一次命令操作过多的数据。

  • CPU饱和问题
    单线程的Redis处理命令时候只使用一个CPU,CPU饱和是指Redis单核CPU使用率接近100%。
    处理步骤如下:
    1.判断当前Redis并发量是否已经到达极限
    2.如果当前并发QPs是已经几万+,那么可能已经到极限,可能需要做集群的水平化扩容来分担压力。
    3.如果QPS只有几十,几百那么可能就要排查命令和内存的使用。

  • 持久化相关的阻塞
    对于开起了持久化功能的Redis节点,需要排查是否是持久化导致的阻塞。
    1.fork阻塞:fork发生在RDB和AOF重写的时,Redis主线程调用fork操作产生共享,由子进程完成持久化文件重写工作,如果fork操作本身耗时长,必然会导致主线程的阻塞。
    2.AOF刷盘阻塞:当我们开启AoF持久化的时候,文件的刷盘方式一般采用每秒一次,后台线程每秒对AOF文件做fsync操作,当硬盘压力过大,fsync需要等待直到写入完成,如果主线程发现距离上一次的fsync成功超过两秒,为了安全性它会阻塞直到后台线程完成fsync操作。
    3.Hugepage写操作阻塞:对于开启Transparent HugePages的 操作系统,每次写命令引起的复制内存页单位由4K变为2MB,放大了512 倍,会拖慢写操作的执行时间,导致大量写操作慢查询

5.大key问题

大key情况:

  • 单个key存储的value很大,超过10KB
  • hash,set,zset,list储存过多的元素(以万为单位)

大key会造成什么情况

  • 客户端耗时增加,甚至超时
  • 对大key进行IO操作时,会严重占用带宽和CPU造成Redis集群中数据倾斜。
  • 主动删除,被动删除可能会造成阻塞。

如何找到大key

  • bigkeys命令:使用bigkeys命令以遍历的方式分析Redis实例中的所有key,并返回整体统计信息并返回每个数据类型中Top1的大key
  • redis-db-tools::redis-rdb-tools是由Python写的用来分析Redis的rdb快照文件用的工具,它可以把rdb快照文件生
    成json文件或者生成报表用来分析Redis的使用详情

如何处理大key
在这里插入图片描述
删除大key

  • 当Redis版本大于4.0时,可使用UNLINK命令安全地删除大Key,该命令能够以非阻塞的方式,逐步地清理
    传入的Key。
  • 当Redis版本小于4.0时,避免使用阻塞式命令KEYS,而是建议通过SCAN命令执行增量迭代扫描key,然后判
    断进行删除。
    压缩和拆分key
  • 当vaule是string时,比较难拆分,则使用序列化、压缩算法将key的大小控制在合理范围内,但是序列化和
    反序列化都会带来更多时间上的消耗。
  • 当value是string,压缩之后仍然是大key,则需要进行拆分,一个大key分为不同的部分,记录每个部分的
    key,使用multiget等操作实现事务读取。
  • 当value是list/set等集合类型时,根据预估的数据规模来进行分片,不同的元素计算后分到不同的片。

6.使用Redis如何实现异步队列

  • 使用list作为消息队列,lpush生产消息,rpop消费消息
    这种方式,消费者死循环rpop从队列中消费消息,即使队列里面没有消息,也会进行rpop,导致redis的CPU消耗;可以通过让消费者休眠的方式来处理,但是这样又会有消息延迟的问题。
    在这里插入图片描述
  • 使用list作为消息队列,lpush生产消息,brpop进行消费消息
    brpop是rpop的阻塞版本,list为空的时候,他会一直阻塞,直到list中有消息或者超时,但这种方式只能进行一对一的消息队列。
    在这里插入图片描述
  • 使用Redis的pub/sub来进行消息的发布/订阅
    发布/订阅模式可以1:N的消息发布/订阅,发布者将消息发布到指定的频道,订阅响应频道的客户端都能收到消息。
    在这里插入图片描述
    但是这种消息是不可靠的,不保证订阅者一定能收到消息,也不进行消息的存储,所以一般的异步消息队列还是交给专业的消息队列。

7.Redis支持事务吗

Redis提供了简单的事务,但是它对事务ACID的支持并不完备。
multi命令表示事务的开始,exec命令表示事务结束。Redis事务的原理,是所有的指令在 exec 之前不执行,而是缓存在
服务器的一个事务队列中,服务器一旦收到 exec 指令,才开执行整个事务队列,执行完毕后一次性返回所有指令的运
行结果
Redis事务为什么不支持回滚
Redis的事务不支持回滚
如果执行的命令有语法错误,Redis 会执行失败,这些问题可以从程序层面捕获并解决。但是如果出现其他问题,则
依然会继续执行余下的命令。
这样做的原因是因为回滚需要增加很多工作,而不支持回滚则可以保持简单、快速的特性。

8.Redis实现分布式了解吗

Redis是分布式锁本质上要实现的目标就是在 Redis 里面占一个“茅坑”,当别的进程也要来占时,发现已经有人蹲
在那里了,就只好放弃或者稍后再试。

  • V1:setnx命令
    占坑一般使用的是setnx(set if not exists)指令,只允许被一个客户端占,用完了在调用对del指令释放。
    但是有个问题如果逻辑执行到中间出现了异常,可能会导致del指令没有被调用,陷入了死锁。

  • V2锁超时释放
    所以在拿到锁之后,再给锁加上一个过期时间,比如5秒,这样即使服务中间出现异常也可以保证5秒之后锁会自动释放。

  • V3:set指令
    这个问题在Redis 2.8版本中得到了解决,这个版本加入了set 指令的扩展参数,使得 setnx和expire指令可以一起执

9.假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如何将它们全部找出来

使用 keys 指令可以扫出指定模式的 key 列表。但是要注意 keys 指令会导致线程阻塞一段时间,线上服务会停
顿,直到指令执行完毕,服务才能恢复。这个时候可以使用 scan 指令, scan 指令可以无阻塞的提取出指定模式
的 key 列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用指
keys 令长。

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

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

相关文章

基于springboot的美发管理系统

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式 🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 &…

让Unity迭代器性能提升5倍

最近在研究Unity il2cpp的代码生成和编译优化,结合之前遇到过的一个优化案例,给大家讲讲在Unity中迭代器相关代码生成的底层原理,以及在写代码过程中需要注意的一些特殊情况。 案例 首先我们来看一个非常简单的案例,代码如下&am…

3338 蓝桥杯 wyz的数组IV 简单

3338 蓝桥杯 wyz的数组IV 简单 //C风格解法1&#xff0c;通过率50% #include<bits/stdc.h>int main(){std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cout.tie(nullptr);int n; std::cin >> n;int ans 0;std::vector<int>a(n);for(auto &am…

Docker本地部署APITable结合内网穿透实现公网访问

文章目录 前言1. 部署APITable2. cpolar的安装和注册3. 配置APITable公网访问地址4. 固定APITable公网地址 前言 vika维格表作为新一代数据生产力平台&#xff0c;是一款面向 API 的智能多维表格。它将复杂的可视化数据库、电子表格、实时在线协同、低代码开发技术四合为一&am…

【C语言】socket编程接收问题

一、recv()函数接收到的返回值为0表示对端已经关闭 在TCP套接字编程中&#xff0c;通过recv()函数接收到的返回值为0通常表示对端已经关闭了套接字的发送部分。这是因为TCP是一个基于连接的协议&#xff0c;其中有定义明确的连接建立和终止流程&#xff1b;当对端调用close()或…

C语言指针进阶(1)(超详细)

前言&#xff1a; 指针其实就是地址&#xff0c;而凡是存储在内存中的值都会有属于自己的地址&#xff0c;指针指向地址&#xff0c;这样我们就能通过指针间接操作变量。我们在指针初阶中介绍了指针的基本概念&#xff1a;如指针大小、野指针问题、指针间的关系运算等&#xff…

Hugging Face创始人分享:企业如何在ChatGPT浪潮下实现战略布局

Hugging Face创始人兼首席执行官 Clem Delangue在IBM一年一度的 THINK大会中研讨了当前人工智能发展趋势&#xff0c;特别是ChatGPT模型以及其对行业的影响。他的演讲还涉及到一个关键的议题&#xff0c;在ChatGPT这样的通用模型出现后&#xff0c;企业如何在人工智能领域找到自…

自定义vue通用左侧菜单组件(未完善版本)

使用到的技术: vue3、pinia、view-ui-plus 实现的功能: 传入一个菜单数组数据,自动生成一个左侧菜单栏。菜单栏可以添加、删除、展开、重命名,拖动插入位置等。 效果预览: 代码: c-menu-wrap.vue <template><div class="main-container">&l…

【嵌入式学习】C++QT-Day3-C++基础

笔记 见我的博客&#xff1a;https://lingjun.life/wiki/EmbeddedNote/19Cpp 作业 设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函…

当包容结构体遇见灵活的内存管理

&#x1f308;个人主页&#xff1a;小田爱学编程 &#x1f525; 系列专栏&#xff1a;c语言从基础到进阶 &#x1f3c6;&#x1f3c6;关注博主&#xff0c;随时获取更多关于c语言的优质内容&#xff01;&#x1f3c6;&#x1f3c6; &#x1f600;欢迎来到小田代码世界~ &#x…

课时7:shell基础_shell简介

1.3.1 shell简介 学习目标 这一节&#xff0c;我们从 运维、shell语言、小结 三个方面来学习。 运维 简介 运维是什么&#xff1f;所谓的运维&#xff0c;其实就是公司的内部项目当中的一个技术岗位而已&#xff0c;它主要做的是项目的维护性工作。它所涉及的内容范围非常…

方法、数组

方法 是语句的集合&#xff0c;在一起执行一个功能 它是解决一类问题的步骤的有序集合 包含于类或对象中 在程序中创建&#xff0c;在其他地方被引用 设计方法的原则&#xff1a;方法的本意是功能块&#xff0c;就是实现某一个功能的语句块的集合。设计时&#xff0c;最好保持…

基于go mod模式创建项目最佳实践

希望能带给你成功的喜悦&#xff01; 除go get、vendor这两种方式外&#xff0c;Go版本在1.11之后推出了go module模式来管理依赖&#xff0c;使用go mod时下载的依赖文件在$GOPATH/pkg/mod/下。本文以两种办法介绍如何创建go mod项目。 目录 goland开启玩法 本地手动创建项目…

###C语言程序设计-----C语言学习(6)#

前言&#xff1a;感谢老铁的浏览&#xff0c;希望老铁可以一键三连加个关注&#xff0c;您的支持和鼓励是我前进的动力&#xff0c;后续会分享更多学习编程的内容。 一. 主干知识的学习 1. while语句 除了for语句以外&#xff0c;while语句也用于实现循环&#xff0c;而且它…

shell脚本自动化备份网络设备配置教程

由于局域网内存在多台网络设备&#xff0c;如防火墙、路由器、交换机等&#xff0c;数量众多&#xff0c;且品牌不同&#xff0c;手工备份配置需要相当长的时间&#xff0c;现需要实现自动化导出备份配置。 经查询&#xff0c;该局域网内存在华为及阿尔卡特两种品牌&#xff0…

Android Studio 下载安装配置使用入门【2024年最新】

前言&#xff1a; Android Studio 是谷歌官方提供的主要集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为 Android 平台应用开发而设计。它基于 JetBrains 的 IntelliJ IDEA 软件&#xff0c;并在此基础上增加了大量针对 Android 开发的定制功能。Android Studio 通过…

CMake 完整入门教程(一)

1 前言 每一次学习新东西都是很有乐趣的&#xff0c;虽然刚开始会花费时间用来学习&#xff0c;但是实践证明&#xff0c;虽然学习新东西可能会花费一些时间&#xff0c;但是它们带来的好处会远远超过这些花费的时间。学习新东西是值得的&#xff0c;也是很有乐趣的。 网络上…

C语言二维数组的使用案列,来自C语言程序设计第五版本

感谢关注我的123个小伙伴&#xff0c;我会给大家带来更多的知识&#xff0c;但是C语言的学习&#xff0c;我准备今天学了这个月暂时停止更新了&#xff0c;下个月一号砸门又见面&#xff0c;休息两天弄其它的事情&#xff0c;也好几天没有看论文了。 二维数组的创建比较简单&am…

基于Python 爬虫的房地产数据可视化分析与实现

摘要&#xff1a; 过去&#xff0c;不管是翻阅书籍&#xff0c;还是通过手机&#xff0c;电脑等从互联网上手动点击搜索信息&#xff0c;视野受限&#xff0c;信息面太过于狭窄&#xff0c;且数据量大而杂乱&#xff0c;爆炸式信息的更新速度是快速且不定时的。要想手动获取到海…

算法沉淀——前缀和(leetcode真题剖析)

算法沉淀——前缀和 01.一维前缀和02.二维前缀和03.寻找数组的中心下标04.除自身以外数组的乘积05.和为 K 的子数组06.和可被 K 整除的子数组07.连续数组08.矩阵区域和 前缀和算法是一种用于高效计算数组或序列中某个范围内元素之和的技巧。它通过预先计算数组的前缀和&#xf…