Redis经典面试题-卷2

前言

继续上一篇《Redis经典面试题-卷1》,今天整理一下关于redis的第2卷面试题。废话不多说,直接看干货

热Key问题

如果单单从工作的角度的话,面试官一般会问下面两个内容:

  • 什么是热Key问题?
  • 如何解决热key问题?

(1)热key的定义
:在Redis中,我们把访问频率高的key,称为热点key

(2)需求产生的背景:

如果某一热点key的请求到服务器主机时,由于请求量特别大,可能会导致主机资源不足,甚至宕机,从而影响正常的服务。


(3)热key产生的原因:

  • 用户消费的数据远大于生产的数据,如秒杀、热点八卦等读多写少的场景。
  • 请求分片集中,超过单Redi服务器的性能,比如固定名称key,Hash落入同一台服务器,瞬间访问量极大,超过机器瓶颈,产生热点Key问题。

(4)实际应用中如何识别到热点key呢?

  • 凭经验判断哪些是热Key;
  • 客户端统计上报;
  • 服务代理层上报

(5) 如何解决热key问题?(这个问题要重点理解,而不是背诵,实际工作场景最终是要你有解决问题的思路和方案)

  • Redis集群扩容:增加分片副本,均衡读流量;
  • 将热key分散到不同的服务器中;
  • 使用二级缓存,即JVM本地缓存,减少Redis的读请求。

Redis有哪些过期策略和淘汰策略

说明:这个是原理性的东西,说他重要也重要,你只要理解原理了,才能更好地应用redis

过期策略

开发的时候,我们在set key的时候,可以给它设置一个过期时间,比如expire key 60。指定这key60s后过期,60s后,redis是如何处理的嘛?我们先来介绍几种过期策略:

  • 定时过期

每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即对key进行清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。

  • 惰性过期

只有当访问一个key时,才会判断该key是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。

  • 定期过期(跟第一个有点区别)

每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。expires字典会保存所有设置了过期时间的key的过期时间数据,其中,key是指向键空间中的某个键的指针,value是该键的毫秒精度的UNIX时间戳表示的过期时间。键空间是指该Redis集群中保存的所有键。

Redis中使用了什么过期策略? (常见的坑)

Redis中同时使用了惰性过期和定期过期两种过期策略。

  • 假设Redis当前存放30万个key,并且都设置了过期时间,如果你每隔100ms就去检查这全部的key,CPU负载会特别高,最后可能会挂掉。
  • 因此,redis采取的是定期过期,每隔100ms就随机抽取一定数量的key来检查和删除的。但是呢,最后可能会有很多已经过期的key没被删除。这时候,redis采用惰性删除。
  • 在你获取某个key的时候,redis会检查一下,这个key如果设置了过期时间并且已经过期了,此时就会删除。

小结: 但是呀,如果定期删除漏掉了很多过期的key,然后也没走惰性删除。就会有很多过期key积在内存内存,直接会导致内存爆的。或者有些时候,业务量大起来了(假设是在半夜),redis的key被大量使用,内存直接不够了,运维在睡觉也赶不上加大内存了。难道redis直接这样挂掉?不会的!Redis用8种内存淘汰策略保护自己。

Redis有哪些内存淘汰策略?

  • volatile-lru:当内存不足以容纳新写入数据时,从设置了过期时间的key中使用LRU(最近最少使用)算法进行淘汰;
  • allkeys-lru:当内存不足以容纳新写入数据时,从所有key中使用LRU(最近最少使用)算法进行淘汰。
  • volatile-lfu:4.0版本新增,当内存不足以容纳新写入数据时,在过期的key中,使用LFU算法进行删除key。
  • allkeys-lfu:4.0版本新增,当内存不足以容纳新写入数据时,从所有key中使用LFU算法进行淘汰;
  • volatile-random:当内存不足以容纳新写入数据时,从设置了过期时间的key中,随机淘汰数据;。
  • allkeys-random:当内存不足以容纳新写入数据时,从所有key中随机淘汰数据。
  • volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的key中,根据过期时间进行淘汰,越早过期的优先被淘汰;
  • noeviction:默认策略,当内存不足以容纳新写入数据时,新写入操作会报错。

说说Redis的常用应用场景

  • 缓存
  • 排行榜
  • 计数器应用
  • 共享Session
  • 分布式锁
  • 社交网络
  • 消息队列
  • 位操作

缓存

首先大家都知道,redis是缓存技术之一,根本目的就是为了缓解直接查询数据库的压力。合理的利用缓存,比如缓存热点数据,不仅可以提升服务的访问速度,还可以降低数据库DB的压力。并且,Redis相比于memcached,还提供了丰富的数据结构,并且提供RDB和AOF等持久化机制,强的一批。

排行榜

现在很多网站和应用都有各种各样的排行榜,如电商网站的月度销量排行榜、社交APP的礼物排行榜、小程序的投票排行榜等等。Redis提供的zset数据类型能够实现这些复杂的排行榜。

  • 比如,用户每天上传视频,获得点赞的排行榜可以这样设计:

1.用户Jay上传一个视频,获得6个赞,可以酱紫:

zadd user:ranking:2024-03-13 Jay 3

2.过了一段时间,再获得一个赞,可以这样:

zincrby user:ranking:2024-03-13 Jay 1

3.如果某个用户John作弊,需要删除该用户:

zrem user:ranking:2024-03-13 John

4.展示获取赞数最多的3个用户

zrevrangebyrank user:ranking:2024-03-13 0 2

计数器应用

这个应用的范围很广,各大网站、APP应用经常需要计数器的功能,如短视频的播放数、电商网站的浏览数。这些播放数、浏览数一般要求实时的,每一次播放和浏览都要做加1的操作,如果并发量很大对于传统关系型数据的性能是一种挑战。Redis天然支持计数功能而且计数的性能也非常好,可以说是计数器系统的重要选择。

共享Session

如果一个分布式Web服务将用户的Session信息保存在各自服务器,用户刷新一次可能就需要重新登录了,这样显然有问题。实际上,可以使用Redis将用户的Session进行集中管理,每次用户更新或者查询登录信息都直接从Redis中集中获取。

分布式锁

现在只要是正常的互联网公司,应该都是使用分布式部署,分布式服务下,就会遇到对同一个资源的并发访问的技术难题,如秒杀、下单减库存等场景。

  • 用synchronize或者reentrantlock本地锁肯定是不行的。
  • 如果是并发量不大话,使用数据库的悲观锁、乐观锁来实现没啥问题。
  • 但是在并发量高的场合中,利用数据库锁来控制资源的并发访问,会影响数据库的性能。
  • 实际上,可以用Redis的setnx来实现分布式的锁。

社交网络

赞/踩、粉丝、共同好友/喜好、推送、下拉刷新等是社交网站的必备功能,由于社交网站访问量通常比较大,而且传统的关系型数据不太适保存 这种类型的数据,Redis提供的数据结构可以相对比较容易地实现这些功能。

消息队列

说明一下,这个只做科普,它是有这个功能,实际工作中很少用redis做消息队列,至少我目前经历过的工作中没有遇到过,因为现在有很多经历过大场景验证过的专业的中间件,足够满足业务需求,也更可靠。

消息队列是大型网站必用中间件,如ActiveMQ、RabbitMQ、Kafka等流行的消息队列中间件,主要用于业务解耦、流量削峰及异步处理实时性低的业务。Redis提供了发布/订阅及阻塞队列功能,能实现一个简单的消息队列系统。另外,这个不能和专业的消息中间件相比。了解一下就好,面试的时候可以不用说,要是傻子问你,你再秀一下。

位操作

用于数据量上亿的场景下,例如几亿用户系统的签到,去重登录次数统计,某用户是否在线状态等等。腾讯10亿用户,要几个毫秒内查询到某个用户是否在线,能怎么做?千万别说给每个用户建立一个key,然后挨个记(你可以算一下需要的内存会很恐怖,而且这种类似的需求很多。这里要用到位操作——使用setbit、getbit、bitcount命令。原理是:redis内构建一个足够长的数组,每个数组元素只能是0和1两个值,然后这个数组的下标index用来表示用户id(必须是数字哈),那么很显然,这个几亿长的大数组就能通过下标和元素值(0和1)来构建一个记忆系统。

写在最后

好了,今天先到这里,篇幅长反而效果不好,剩下的内容更下在下一期,整理不易,觉得有点收获的话,帮忙点赞 + 在看。更多内容会第一时间更新在公众号,欢迎持续关注"安前码后",一个用心输出干货的号,下期再见。

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

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

相关文章

Android 摄像头等比例缩放 摄像头画面比例

在拍摄照片的时候我们往往会在后期进行二次构图,在裁剪的时候有不同的相片长宽比供我们选择,不同的长宽比带给观众的感受也不一样。这里为大家介绍一下照片拍摄中常用到长宽比例。 3:2(6:4) 这张照片是用Canon 50D拍摄的&#xf…

收藏贴!6个谈薪小技巧,助你拿到满意薪资

Salesforce的就业市场一直在迅猛发展,对Salesforce专业人士的需求持续不断,对优秀人才的需求更大。 本篇文章总结了6个谈薪小技巧,可以帮助SF从业者、求职者拿到满意的薪资。 01 了解市场价格 首先,需要了解当前就业市场的情况…

【Linux】进程控制与进程调度

Linux进程介绍 进程的基本概念 Linux是多用户、多任务的操作系统。在这样的环境中,各种计算机资源的分配和管理都是以进程为单位进行的。 Linux操作系统包括三种不同类型的进程: 1)交互进程:一种由Shell启动的进程。交互进程既可…

十、软考-系统架构设计师笔记-软件架构演化和维护

1、软件架构演化 软件架构的演化和维护的目的是为了使软件能够适应环境的变化而进行的纠错性修改和完善性修改。软件架构的演化和维护过程是一个不断迭代的过程,通过演化和维护,软件架构逐步得到完善,以满足用户需求。软件架构的演化就是软件…

JavaScript---VConsole插件配置使用,一步到位简单实用!

1. 寻找到自己需要的VConsole插件js文件 个人喜欢BootCDN这个平台(直接在线引用或者下载本地引入均可~) vConsole (v3.15.1) - A lightweight, extendable front-end developer tool for mobile web page. | BootCDN - Bootstrap 中文网开源项目免费 C…

浏览器的工作原理

从输入一个url到页面加载完成,中间都发生了什么? 参考原文地址 首先在浏览器地址栏输入一个地址并回车之后, 1. DNS查找 浏览器会进行DNS查找,把域名https://example.com转化为真实的IP地址10.29.33.xx,根据IP地址找…

探索C++中的动态数组:实现自己的Vector容器

🎉个人名片: 🐼作者简介:一名乐于分享在学习道路上收获的大二在校生 🙈个人主页🎉:GOTXX 🐼个人WeChat:ILXOXVJE 🐼本文由GOTXX原创,首发CSDN&…

Android Studio下运行java main 方法

方法一 修改项目的.idea中的gradle.xml文件&#xff0c;在GradleProjectSettings标签下添加一行代码 <option name"delegatedBuild" value"false" />方法二 main方法上右键选择Run ‘xxx’ with Coverage

视觉图像处理和FPGA实现第三次作业--实现一个加法器模块

一、adder模块 module adder(ina, inb, outa); input [5:0] ina ; input [5:0] inb ; output [6:0] outa ;assign outa ina inb; endmodule二、add模块 module add(a,b,c,d,e); input [5:0] a ; input [5:0] b ; input [5:…

1.1计算机系统构成及硬件系统知识(上)

基础知识部分----chap01 主要议题&#xff1a; 数制转换&#xff1a;一般会涉及存取的计算&#xff1b;ip地址中变长子网掩码的计算题&#xff1b;&#xff08;难度较大&#xff09; 数的表示&#xff1a;二进制、十六进制&#xff1b; 计算机的组成&#xff1a;考察的较为深入…

30天学会QT(进阶)--------------第二天(创建项目)

1、如何规范的创建一个项目 由于本人也是从其他的项目上学来的&#xff0c;所以也不算是业界规范&#xff0c;每个公司或者个人都有自己的方式去创建项目&#xff0c;项目的创建是本着简洁&#xff0c;明了&#xff0c;方便而言的&#xff0c;所以对于我来说&#xff0c;不繁琐…

nginx启动闪退

在nginx目录下cmd&#xff0c;nginx -t&#xff0c;找到原因是&#xff1a;“在端口80上运行NGINX时&#xff0c;因为端口80是HTTP默认端口&#xff0c;需要管理员权限才能访问” 所以修改端口号&#xff1a; 在nginx.conf文件中&#xff0c;修改listen&#xff1a;80为8080 …

【漏洞复现】网康科技 NS-ASG 应用安全网关 SQL注入漏洞(CVE-2024-2330)

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

2024年 JavaScript 最新功能一览

前言 随着 Web 技术的日新月异&#xff0c;JavaScript 也在不断地吸收新的特性和技术&#xff0c;以满足日益复杂和多样化的开发需求。在 2024 年&#xff0c;JavaScript 迎来了一系列令人瞩目的新功能&#xff0c;这些功能不仅提升了开发者的效率&#xff0c;也极大地丰富了 …

无缝集成 MongoDB Relational Migrator,Tapdata 提供关系型到 MongoDB 实时迁移优化方案

在去年的 MongoDB 用户大会纽约站上&#xff0c;MongoDB 正式宣布全面推出新工具 MongoDB Relational Migrator&#xff08;MongoDB RM&#xff09;&#xff0c;用以简化应用程序迁移和转换——即从传统关系型数据模型到现代的文档数据模型&#xff0c;助力组织快速提升运营效率…

Seata源码流程图

1.第一阶段分支事务的注册 流程图地址&#xff1a;https://www.processon.com/view/link/6108de4be401fd6714ba761d 2.第一阶段开启全局事务 流程图地址&#xff1a;https://www.processon.com/view/link/6108de13e0b34d3e35b8e4ef 3.第二阶段全局事务的提交 流程图地址…

考研失败, 学点Java打小工——Day2

1 关键字 标识符 基本数据类型 感觉和C没啥区别  1.1 关键字    public、static、void…  1.2 标识符    ①不能用关键字    ②由字母、数字、下划线、$组成&#xff0c;但是不能以数字开头    ③给变量起名字的时候要起有意义的名字&#xff1a;“见名知意” 1.…

常青内容与病毒式内容——哪个更适合 SEO?

常青内容是经得起时间考验的内容&#xff0c;而病毒式内容则是利用特定时代潮流的内容。 如果你曾经考虑过为网站添加内容&#xff0c;你可能听说过常青内容和病毒式内容这两个词。这两个词涵盖了网站所需的基本内容类型。 那么&#xff0c;这两者之间有什么区别&#xff1f;…

综合实验---Web环境搭建

题目&#xff1a; 服务器IP地址规划&#xff1a;client&#xff1a;12.0.0.12/24&#xff0c;网关服务器&#xff1a;ens36:12.0.0.1/24、ens33&#xff1a;192.168.10.1/24&#xff0c;Web1&#xff1a;192.168.10.10/24&#xff0c;Web2&#xff1a;192.168.10.20/24&#xf…

【网络安全】漏洞挖掘入门教程(非常详细)

温馨提示&#xff1a; 初学者最好不要上手就去搞漏洞挖掘&#xff0c;因为漏洞挖掘需要很多的系统基础知识和一些理论知识做铺垫&#xff0c;而且难度较大…… 较合理的途径应该从漏洞利用入手&#xff0c;不妨分析一些公开的CVE漏洞。很多漏洞都有比较好的资料&#xff0c;分…