面试Redis篇

news2024/9/17 7:39:55

        本篇主要总结一下面试官可能会在Redis上询问的主要问题。

Redis的使用场景

        问:你的项目中哪些场景中用到了Redis?

        答:根据你的项目回答,一般会在一下几个部分缓存、分布式锁......

缓存

 缓存穿透

        查询一个不存在的数据,mysql查询不到数据也不会直接写入缓存,就会导致每次请求都查到数据库

  如何解决缓存穿透

        解决方案1:布隆过滤器

          首先解释一下布隆过滤器:它的作用主要是为了判断一个数据是否存在一个集合中,本身是一个数组(单位为bit),只能存放0或1。初始值都为0.

          工作流程:当存储数据时,先通过三次不同的hash算法得到不同的hash值,并在对应hash值数组下标的位置,将0改为1。当查找数据时,通过三次不同的hash算法得到不同的hash值,还是根据hash值找到对应的3个下标,如果都为1,则判断其存在,进行之后的操作。

        整个流程:

         优点:内存占用较少,没有多余的key。

         缺点:实现复杂,存在误判

        解决方案2:缓存空数据(将查询到的空结果进行缓存,一般不使用这个方法)

          优点:实现简单

          缺点:消耗内存,可能会造成数据不一致问题

 缓存击穿

  什么是缓存击穿?

      给某个key设置了过期时间,当key过期的时候,恰好这个时间点对这个key有大量的并发请求过来,这些并发的请求可能会瞬间把DB压垮。

 解决方案

        1.互斥锁:强一致,性能差

        2.逻辑过期:高可用、性能优,不能保证数据的绝对一致

                

 缓存雪崩

  什么是缓存雪崩?

        和缓存击穿相反,指在同一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力。

  • 解决方案:
    • 给不同的Key的TTL添加随机值
    • 利用Redis集群提高服务的可用性(哨兵模式、集群模式)
    • 给缓存业务添加降级限流策略(nginx或者spring cloud gateway):降级可做为系统的保底策略,适用于穿透、击穿、雪崩
    • 给业务添加多级缓存(Guava或Caffeine)

双写一致性

  Redis作为缓存,mysql数据如何与Redis进行同步呢(双写一致性)?

  • 双写一致性:当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致
    • 读操作:缓存命中,直接返回;缓存未命中查询数据库,写入缓存,设定超时时间
    • 写操作:延迟双删
      • 删除缓存-->修改数据库--(延时)-->删除缓存
      • 是先删除缓存还是先修改数据库呢
        • 都有问题(缓存和数据库开始都是10)

      • 为什么删除两次缓存
        • 降低脏数据的出现
      • 为什么要延时双删
        • 一般数据库是主从的,需要一定时间让数据库中的数据同步
  • 根据业务给答案
    • 强一致性高的业务解决方案
      • 采用互斥锁
      • 在此基础上可以优化一下(采用Redisson提供的读写锁方式)
        • 这种情况下的放入缓存中的数据一般都是读多写少
        • 共享锁(读锁readLock,加锁之后,其他线程可以共享读操作)
        • 排他锁(独占锁writeLock,加锁之后,阻塞其他线程读写操作)

    • 允许延迟一致的(异步的方案)
      • 利用MQ中间件,更新数据之后,通知缓存删除
      • 基于Canal的异步通知:利用canal中间件,不需要修改业务代码,伪装为mysql的一个从节点,canal通过读取binlog数据更新缓存

持久化

     redis作为缓存,数据的持久化是怎么做的?

  • 两种方式
    • RDB
      • bgsave开始时会fork主进程得到子进程,子进程共享主进程的内存数据。完成fork后读取内存数据并写入RDB文件
    • RDB(Redis数据备份文件)
      • 人工备份
      • Redis内部有触发RDB的机制,可以在redis.conf文件中找到
    • AOF
      • AOF(默认是关闭的)
      • 在配置中打开

      • AOF重写
        • 针对与某个key的写操作,最后一步才有意义,所以为了减小占有的空间,会采用AOF的重写

对比

 数据过期策略

        两种删除策略

        惰性删除:设置该key过期时间后,我们不去管他,当需要该key时,我们在检查其是否过期,如果过期,我们就删掉它,反之返回该key。

        优点:对CPU比较友好,很多用不到的key不用浪费时间进行过期检查

        缺点:对内存不友好,很多已过期的key因为没有使用到而导致一直占用内存空间,内存永不释放

        定期删除:每隔一段时间,我们就对一些key进行检查,删除里面过期的key(从一定数量的数据库中取出一定数量的随机key进行检查)

        定期删除的两种模式

  • SLOW模式(慢)
  • FAST模式(快)

         优点:可以通过限制删除操作执行的频率和时长减少对CPU的影响,另外也能有效过期key占用的内存。

        缺点:难以确定删除操作的时长和频率额

        Redis的删除策略:惰性删除+定期删除两种策略进行配合使用

数据淘汰策略

        8中淘汰策略

noeviction:不淘汰任何key,但是当缓存满的时候就不允许写入新的数据,默认就是这种策略

volatile-ttl:对设置了任何TTL的key,比较key的剩余TTL值,TTL越小,删除优先级越高

allkeys-random:对全体key进行随即淘汰。

volatile-random:对设置了TTL的key进行随即淘汰。

allkeys-lru:对所有的key,基于LRU算法进行淘汰。

volatile-lru:对设置了TTL的key,基于LRU算法进行淘汰。

allkeys-lfu:对所有的key,基于LFU算法进行淘汰。

volatile-lfu:对设置了TTL的key,基于LFU算法进行淘汰。

LRU算法

        最近最少使用,用当前时间减去最后一次访问的时间,这个值越大淘汰的优先级越高。

LFU算法

        最少频率使用,统计每个key的访问频率,值越小的淘汰优先级越高

分布式锁

使用场景

        通常情况下:集群情况下的定时任务、抢单、幂等性场景

        举例抢卷场景:

        正常情况:

         特殊情况:

解决方案:互斥锁,在查询剩余库存前,先获取互斥锁,如果获取就正常进行,如果没获取到就一直等待

但是服务往往是集群部署,每个进程的都有一个锁,这时就要用到分布式锁

实现原理

        Redis实现分布式锁主要利用Redis的setnx命令。setnx是SET if not exists(如果不存在,则SET)的简写。设置失效时间是为了在服务宕机后,依然可以释放锁,避免造成死锁

        Redis实现分布式锁如何控制锁的有效时长:

  • 根据业务执行时间预估
  • 给锁续期
    • 我们自己实现很麻烦,市面上已经有成熟的技术了

redisson实现的分布式锁-执行流程(看门狗机制)

这个看门狗会每隔一段时间给锁续期

  • redissson实现的分布式锁能解决主从一致性吗?
    • 若主节点宕机

    • 会在从节点中选出一个当主节点(哨兵模式)
    • 这时出现两个线程同时拥有同1把锁
    • Redisson提供红锁来解决主从一致性的问题
      • 但是实现复杂,性能差,运维繁琐
    • 保证强一致性
      • CP思想:zookeeper实现的分布式锁

其他

Reids集群有哪些方案?

        主从同步、哨兵模式、分片集群

介绍一下主从同步:

        单节点Redis的并发能力是有上限的,要更进一步提供Redis的并发能力,就需要搭建主从集群,实现读写分离。

主从数据同步的原理:

        

  • 主从全量同步
    • 新概念
    • 是第一次吗?
      • 根据relid判断,replid不同,是,正常进行
      • 不是,返回主节点的replid、offeset,根据offset从节点更新信息
  • 主从增量同步(slave重启或者后期数据变化)

怎么保证Reids的高并发高可用

        Redis提供了哨兵(Sentinel)机制来实现主从集群的自动故障恢复(监控、自动故障恢复、通知)。哨兵的结构和作用如下:

        监控:Sentinel会不断检查你的master和slave是否按预期工作。

        自动故障恢复:如果master故障,Sentinel会将一个slave提升为master,故障恢复后也会是以新的master为主

        通知:当集群发送故障时,会将最新消息推送给Redis客户端。

Redis分片集群有什么作用?

        分片集群主要解决海量数据的存储问题:集群中有多个master,每个master中保存着不同的数据。并且给每个master设置多个slave节点,增大集群的高并发能力,同时每个master可以通过ping来互相检测彼此的健康状态,当客户请求访问到任意节点就会转发到正确的节点

分片集群中是怎么存储数据和读取的?

        

  • Redis分片集群引入了哈希槽的概念,Redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分hash槽。

redis是单线程,为什么还这么快

1.redis纯内存操作,执行速度很快

2.采用单线程避免上下文的切换

3.采用多路I/O复用模型,非阻塞IO

解释一下I/O多路复用模型

        用单个线程监听多个socket,并在某个socket可读、可写时得到通知,避免无效的等待。充分利用CPU资源。该模型目前基本采用epoll模式实现。通知用户Socker进程就绪的同时,将已就绪的Socket写入到用户空间中。提高了性能。

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

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

相关文章

黑马点评--给店铺类型查询添加缓存

controller/ShopTypeController.java /*** 店铺分类查询,用于展示首页头部店铺分类* return*/GetMapping("list")public Result queryTypeList() {return typeService.queryList();} service/IShopTypeService.java Result queryList(); service/impl/S…

4234324

作者主页: 作者主页 本篇博客专栏:C 创作时间 :2024年6月20日 最后: 十分感谢你可以耐着性子把它读完和我可以坚持写到这里,送几句话,对你,也对我: 1.一个冷知识: …

alg-in-go-1:动态连通性问题

前言: 有本算法书叫:Algorithms 4th Edition.pdf,它是用java实现的,但是算法的内核是一样,不在乎于语言,考虑到java当今的…, 咱们尝试用golang学习算法. 问题: 思考🤔&#xff…

弹幕背后:B站UP主创作服务解析

引言 在B站,每一条飘过的弹幕都是一个故事的碎片,它们汇聚成一幅幅生动的社交画卷。这里,不仅仅是一个视频分享平台,弹幕背后更是一个充满活力的创作者生态系统。B站以其独特的弹幕文化,为创作者和观众之间搭建起了一座…

【电控笔记-xuan】各种估测器扰动估计性能比较

各种扰动观测器观测结果 蓝色: 扰动值 隆博戈估测器扰动补偿 论文53disturb扰动补偿 2order eso 观测

《系统架构设计师教程(第2版)》第13章-层次式架构设计理论与实践-01-层次式体系结构概述

文章目录 1. 常用层次是架构2. 层次式架构设计的注意点2.1 污水池反模式2.2 应用变得庞大 本章教材又赘述了一遍架构的定义和层次架构风格的概述,我之前的笔记都写了 架构的定义回看《第7章-系统架构设计基础知识-01-软件架构(Software Architecture&…

AD的问题

连续放置同规则元件:先选择再按Tab编辑放置; 拖动元件:(shift 空格 :旋转元件;原理图中按x水平,按y垂直翻转)按ctrl键可以丝滑流畅放置 测试距离:RM 距离单位转…

初学Mybatis之动态 SQL

动态 SQL 是指根据不同的条件生成不同的 SQL 语句 动态 SQL 详情请看链接 搭建环境: mysql 建立博客表 CREATE TABLE blog(id VARCHAR(50) NOT NULL COMMENT 博客id,title VARCHAR(100) NOT NULL COMMENT 博客标题,author VARCHAR(30) NOT NULL COMMENT 博客作者…

华为od机试真题:悄悄话(Python)

2024华为OD机试(C卷D卷)最新题库【超值优惠】Java/Python/C合集 题目描述 给定一个二叉树,每个节点上站一个人,节点数字表示父节点到该节点传递悄悄话需要花费的时间。 初始时,根节点所在位置的人有一个悄悄话想要传…

windows家庭版安装Hyper-V

uniapp开发鸿蒙需要开启Hyper-V,但家庭版默认没有,去网上搜索整理了一下。 1.检查是否安装过Hyper-V 直接搜索 Hyper-V,如果出现就代表有,如果没出现,就搜索 启用或关闭windows功能 。 如果有Hyper-V这一项&…

eclipse手动安装Ivy插件

1、下载四个文件 (1)从这个网址选择一个自己需要的版本的“ivy-”开头的文件夹进去(是“ivy”开头,不是“ivyde”) https://archive.apache.org/dist/ant/ivyde/updatesite/ 我这里选的是“ivy-2.5.0.final_201910201…

TortoiseSVN迁移到本地git

TortoiseSVN迁移到本地git 文章目录 TortoiseSVN迁移到本地git0 背景1 环境准备2 SVN库迁移到VisualSVN2.1 导出dump2.2 将dump文件灌入VisualSVN2.3 获取SVN仓最新URL 3 迁移到Git库中4 迁移分支到Git库 0 背景 之前在前东家工作都是采用git进行项目管理,高效便捷…

大模型应用中常听说的投毒实验是什么?

大模型应用中常听说的投毒实验是什么? 大模型投毒实验是指在训练或使用大规模人工智能模型(如GPT-4等)时,通过有意加入恶意数据或修改训练过程,使模型产生不正确或有害输出的行为。随着人工智能技术的快速发展&#x…

【深度学习】声码器(Vocoder),Vocos 论文

Vocos: Closing the gap between time-domain and Fourier-based neural vocoders for high-quality audio synthesis https://arxiv.org/abs/2306.00814 https://github.com/gemelo-ai/vocos?tabreadme-ov-file 文章目录 Vocos:弥合时域和基于傅里叶的神经声码器…

必看!50个ChatGPT顶尖学术论文指令,助你高效学术研究

随着人工智能技术的进步,AI已成为学术创作的重要工具。本文将为您展示如何利用AI来润色您的论文。我们精心整理了50个顶级ChatGPT学术论文指令,强烈建议您加以利用! 这些指令不仅实用,还能大幅提升您的写作效率。无论是翻译难懂的…

高效的知识付费SaaS平台构建:探索Spring Cloud结合Spring Boot的最佳实践

知识付费平台:引领在线教育的未来 在数字化教育的浪潮中,知识付费平台以其便捷、高效的学习方式,迅速成为教育领域的新宠。该平台围绕用户需求构建,提供职业技能、生活兴趣、人文社科等多领域的专业知识,并通过视频播…

【时时三省】(C语言基础)for循环

山不在高,有仙则名。水不在深,有龙则灵。 ——csdn时时三省 语法 fou(表达式1;表达式2;表达式3) 循环语句 表达式1 表达式1为初始化部分,用于初始化循环变量的。 表达式2 表达式2为条件判断部分,用于判…

Vue 中使用 InMap 创建动态轨迹地图

本文由ScriptEcho平台提供技术支持 项目地址:传送门 Vue 中使用 InMap 创建动态轨迹地图 应用场景介绍 动态轨迹地图广泛应用于物流追踪、车辆管理、人员定位等场景,可直观展示移动对象的历史轨迹和实时位置。本代码示例展示了如何使用 Vue 框架和 I…

vue3 antdv3 检测Modal的尺寸是否改变,全屏的时候获取Modal的width与height,然后我们就可以动态设置表格高度了。

1、先上个图,我们要实现如下的效果,中间的表格部分要自动随Modal的改变而改变。官方:Ant Design Vue — An enterprise-class UI components based on Ant Design and Vue.js 2、那我们一定要能够检测到Modal的宽高的改变才行,然后…

2024非常全的接口测试面试题及参考答案-软件测试工程师没有碰到算我输!

一、前言 接口测试最近几年被炒的火热了,越来越多的测试同行意识到接口测试的重要性。接口测试为什么会如此重要呢? 主要是平常的功能点点点,大家水平都一样,是个人都能点,面试时候如果问你平常在公司怎么测试的&#…