【八股文】Redis

1.Redis有哪些数据类型

  • 常用的数据类型,String,List,Set,Hash和ZSet(有序)
    • String:Session,Token,序列化后的对象存储,BitMap也是用的String类型,
      • BitMap:不仅可以用做布隆过滤器,也经常用于记录签到打卡,方便记录打卡的连续天数。
    • ZSet:微信步数排行榜,段位排行榜,可以用Redis里的相关命令解决,底层用的是跳表,实现简单,插入删除快,区间查询快。
    • Set的应用场景:存放的数据不重复,文章和动态点赞

2.Redis内存管理(数据淘汰策略)

  • 为什么要数据淘汰策略:会给缓存数据设置一个过期时间,如果一直查询数据,存入到内存里面,会导致out of memory。比如expire key 60,60秒过后过期。还有比如验证码60秒失效,也可以用过期时间。
  • Redis的内存淘汰机制
    • volatile-lru(业务中有置顶数据,例如博客置顶),从已设置过期时间的数据集中选择最近最少使用的淘汰。
    • volatile-ttl,从已设置过期时间的数据集中挑选将要过期的数据淘汰
    • volatile-lfu(有短时高频访问的数据),从已设置过期时间的数据集中挑选最不常用的key。
    • volatile-random,从已设置过期时间的数据集中随机挑选
    • allkeys(所有的缓存数据中,当内存不足时),allkeys-lru(业务没有冷热区分),allkeys-random,allkeys-lfu
    • noeviction(默认):禁止驱除数据,当内存不足时,新写入的操作会报错。

3.Redis生产问题

  • 缓存穿透:就是大量请求的key不合理,当我们查询数据库时,会先去查询缓存,缓存没有,再去查数据库,但数据库也没有,这样会对数据库造成很大的压力。(穿透就是有些能过去,有些过不去)

    • 场景:比如黑客估计创造了一些非法的key,导致大量请求落到数据库
    • 解决一:布隆过滤器,将所有可能得到的值先放到布隆过滤器中(位数组和随机映射函数),当用户请求过来,先判断用户发来的请求值是否存在布隆过滤器中。不存在直接返回错误信息,如果存在则判断缓存中是否有数据,没有就去数据库查,然后插入到缓存,并返回给用户。
    • 解决二:接口限流,对异常频繁访问的行为,直接将ip拉入黑名单
  • 缓存击穿:在请求大量的热点数据,但这部分数据在缓存中已经失效,然后会将大量的请求打在数据库上,给数据库带来巨大的压力。(这部分热点数据都失效了)

    • 场景:比如秒杀活动,某个秒杀商品的数据在缓存中突然过期,就会大量的线程对该商品请求落到数据库上。
    • 解决一:设置过期时间长,逻辑过期,高可用,不保证数据绝对一致
    • 解决二:设置热点数据提前预热,将其放到缓存并设置合理过期时间
    • 解决三:在请求数据库写数据到缓存之前,先获取互斥锁,保证只有一个请求落到数据库上。强一致,性能差。
  • 缓存雪崩:缓存在同一时间大面积失效,导致大量请求直接落到数据库上,对数据库造成了巨大的压力。
    - 解决一:采用Redis集群(哨兵模式)
    - 解决二:限流,Nginx和Spring cloud gateway
    - 解决三:缓存预热,程序启动或在运行中,主动将热点数据加载到缓存中,(使用定时任务Spring Task,定时出发缓存预热逻辑)
    - 解决四:给不同的key的TTL添加随机值。这样不会同一时间大面积失效。

  • 如何做到数据库和Redis缓存里面的数据库一致:(强一致性的业务)

    • 延迟双删:
      • 定义:延迟双删是一种用于处理高并发场景下缓存与数据库数据一致性的策略。它的核心思想是在更新数据库之前,先从缓存中删除旧数据,然后更新数据库,最后经过一段延迟时间后再次尝试删除缓存中的数据。
      • 原因:在高并发场景下,直接更新数据库后立即删除缓存可能会导致读请求在缓存未更新前获取到脏数据。延迟双删通过引入延迟机制,给数据库更新留出时间,减少脏数据的产生。
    • 分布式:读多写少的业务
      • 共享锁:读锁readmeLock,加锁之后,其他线程可以共享读操作,但不能写操作
      • 排他锁:独占锁writerLock,加锁之后,其他线程阻塞读写操作
      • 读数据时添加共享锁,写数据时添加排他锁。
  • 异步通知保证数据的最终一致性(短暂不一致是允许的),也可以用Canal的异步通知。

    • 使用MQ中间件,更新数据之后,通知缓存删除。保证MQ的可靠性。
    • 利用Canal中间件,不需要修改业务代码,伪装为MySQL的一个从节点,Canal通过读取binlog数据更新缓存。
  • Redis 持久化

    • RDB(Redis数据快照),把内存中的所有数据记录到磁盘中,当Redis出现故障重启后,从磁盘读取快照文件,恢复数据。Redis内部有触发RDB机制,save 900 1,900秒内,如果至少有一个key被修改,就执行bgsave。
      • RDB执行原理,bgsave开始时会fork主进程得到子进程,子进程共享主进程的内存数据(页表)。完成fork后读取内存数据并写入RDB文件。
        • fork技术采用copy-on-write技术:当进程执行读操作时,访问共享内存。当主进程执行写操作时,则会拷贝一份数据,执行写操作。
      • 页表:记录虚拟地址与物理地址的映射关系,因为主进程不能直接访问物理内存,只能通过页表来访问。
    • AOP(追加文件),Redis处理的每个写命令都会记录到AOF文件,可以看作命令日志文件。但是AOF文件默认是关闭的,需要修改redis.conf配置文件来开启AOF。
      • appendonly yes 开启AOF
      • appendsync always 表示每次执行一次写命令,同步刷新新盘,可靠性高,性能差
      • appendsync everysec,性能适中,会丢失1s数据
      • appendsync no 操作系统控制何时将缓冲区内存写回磁盘,性能最好,可能会丢失大量数据
      • 缺点:AOF文件会比RDB文件大的多
        • 解决办法:使用bgrewriteaof命令,让AOF文件执行重写功能,用最少的命令达到相同的效果。

        #AOF文件比上次文件增长超过多少百分比则触发重写
        auto-aof-rewrite-percentage 100
        #AOF文件体积最小多大以上才触发重写
        auto-aof-rewrite-min-size 64mb

  • 数据过期策略

    • set name heima 10(10秒后过期)
    • 惰性删除
      • 设置了key的过期时间后,在需要key时,检查是否过期,如果过期直接删除
      • 对CPU友好,只有使用到key的时候才会去检查key
      • 对内存不友好,如果一个key已经过期,但是一直没有使用,那么会一直存在内存中
    • 定期删除
      • 每过一段时间,对一些key进行检查,删除过期的key
      • 定期清理的两种模式,FAST模式(不固定,两次清理时间不超过2ms,一次清理不超过1ms)和SLOW模式(定时任务,每次清理不超过25ms)。
      • 惰性删除配合定期删除
    • RDB和AOF各有优点,如果对数据安全性要求较高,会结合使用,下面是他们的对比
RDBAOF
持久化方式定时对整个内存做快照记录每一次执行的命令
数据完整性不完整,两次备份之间会丢失相对完整,取决于刷盘策略
文件大小会有压缩,文件体积小记录命令,文件体积大
宕机恢复速度很快
数据恢复优先级低,因为数据完整性不如AOF高,因为数据完整性更高
系统资源占用高,大量CPU和内存消耗低, 主要是磁盘IO资源,但AOF重写时占用大量CPU和内存资源
使用场景可以容忍分钟的数据丢失,追求更快的启动速度对数据安全性要求较高

4.Redis 分布式锁

  • 如何实现:
    • 背景:集群情况下的定时任务、抢单、幂等性场景。
    • 出现异常的情况,当两个线程同时查询库存时,刚好库存有一张优惠卷,然后都判断是否需要扣减库存,判断通过库存变为-1,存在的超卖现象。
      在这里插入图片描述
    • 不能使用synchronized锁,synchronized锁可以解决同一个JVM下的线程互斥,解决不了多个JVM下的线程互斥,如果通过Nginx反向代理部署到多个服务器上,用synchronized锁不能解决问题。
    • 分布式锁:如果获取锁成功,则会在分布式锁中添加一条记录,证明线程1中已经有锁了,其他线程会出现阻塞状态,直到释放锁,其他线程才能获取锁。形成互斥的效果
    • 实现:setnx命令,set if not exists如果不存在就set
      • 获取锁:set Lock value NX EX 10,添加锁,NX互斥,EX是过期时间(设置值和过期时间放在一条命令一起执行,因为执行该命令不保证原子性。加上失效时间避免死锁)
      • 释放锁:del key
      • 如何设置控制锁的有效时长,也就是当业务执行完成时,才释放锁,而不是还没执行完就释放了锁。
        • 给锁续期:Redisson实现分布式锁,会另外开一个线程去监控watch dog(看门狗),是否需要给过期时间给续期。如果锁的过期时长是releaseTime=30s,则会每隔releaseTime / 3,也就是10s都会重新续期30s。默认是每个10秒续期一次。
        • 同时Redisson还会设置一个while循环来等待该锁释放后,其他线程不断尝试获取锁。这样在高并发的情况下,增加分布式锁的使用性。lua脚本保证命令执行的原子性。在这里插入图片描述
        • 分布式锁是可重入的,多个锁重入需要判断是否是当前线程,在Redis中使用的hash结构来存储线程信息和重入的次数,value值存的是线程id和重入次数。
        • 解决主从数据一致性的问题:RedLock红锁(不推荐,性能太低)。如果业务中的强一致性,使用zookeeper来实现分布式锁。

其他考点

  • Redis集群有哪些方案?
    • 主从复制:主节点负责写操作,其他节点负责读操作,并且要保证主节点将数据同步给从节点。以提高Redis的并发能力。master主节点,slave从节点。
      • 主从全量同步:在这里插入图片描述
      • 主从增量同步(slave 重启或后期数据变化)在这里插入图片描述
    • 哨兵的作用:来实现主从集群的自动故障修复。主要是当主节点宕机后,就失去了写的操作。
      • 监控,Sentinel会不断检查主节点和从节点是否按预期工作
      • 自动故障修复:如果主节点出现故障,那么会将其中一个从节点升级为主节点。
      • 通知:会将故障信息推送给Redis客户端
      • 原理:在这里插入图片描述
    • 哨兵模式容易出现脑裂问题在这里插入图片描述
    • 总结在这里插入图片描述
  • 分片集群结构
    • 主从和哨兵模式可以解决高可用和高并发读的问题
      • 出现问题:不能解决海量数据存储和高并发写的问题。
      • 解决方案:集群中采用多个主节点,每个主节点保存不同数据。每个master可以有多个salve节点。master之间通过ping检测彼此之间的状态。在这里插入图片描述
      • 哈希槽(Redis分片集群中数据是怎样存储和读取的?)在这里插入图片描述
  • Redis是单线程的,但为什么还那么快?
    • Redis是纯内存操作的,而MySQL是存入磁盘,所以Redis执行速度非常快。
    • 采用单线程,避免不必要的线程上下文切换
    • 使用I/O多路复用模型,非阻塞IO
      • Redis的瓶颈是网络延迟,I/O多路复用模型主要实现了高校的网络请求。
      • 用户空间和内核空间:用户空间只能执行受限的命令,当要调用系统资源时,需要通过内核空间提供的接口访问。Linux为提高IO效率,会在用户空间和内核空间中加入缓存区,写数据:用户缓冲区-》内存缓存区-》硬件设备,读数据刚好相反。
      • 阻塞IO模型:阻塞等待数据,阻塞读数据
      • 非阻塞IO模型:recvfrom操作会理解返回结构,不会阻塞用户线程。(CPU使用率暴增)
      • IO多路复用模型:select,poll和epoll
    • Redis的网络模型在这里插入图片描述
    • 总结在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CCRC-CISAW信息安全保障人员证书含金量

在数字化时代背景下,CISAW认证受到越来越多个人的青睐。 特别是在互联网技术高速发展的今天,随着5G技术的广泛应用,市场对CISAW专业人才的需求急剧增加。 这种职业不仅地位显著,而且职业生涯相对较长。 目前市场上,…

【leetcode详解】覆盖所有点的最少矩形数目(C++思路详解)

思路详解: 0. 题目情境并未限制矩形高度,故矩形数目的判断只和点的横坐标有关 1. 为了不重不漏地考虑到所有点,故笔者选择首先将二维数组中的点按横坐标的大小排序 //说明:本来笔者以为需要自定义sort排序,后来发现…

《嵌入式 - 嵌入式大杂烩》ARM Cortex-M寄存器详解

1 ARM Cortex-M寄存器概述 ARM Cortex-M提供了 16 个 32 位的通用寄存器(R0 - R15),如下图所示。前15个(R0 - R14)可以用作通用的数据存储,R15 是程序计数器 PC,用来保存将要执行的指令。除了通用寄存器,还有一些特殊功能寄存器。特殊功能寄存器有预定义的功能,而且必须通…

GPU 片上调度系统

这篇文章分析和说明GPU 片上的kernel 通过stream 作为载体是如何分发到SM 处理器上,同时CUDA 所抽象的grid/block/thread 在GPU 设备层面是如何调度的。调度器通常是被忽略的一个部分,但对CUDA kernel 的编写和后期系统性能分析很有帮助,也可…

将 Tcpdump 输出内容重定向到 Wireshark

在 Linux 系统中使用 Tcpdump 抓包后分析数据包不是很方便。 通常 Wireshark 比 tcpdump 更容易分析应用层协议。 一般的做法是在远程主机上先使用 tcpdump 抓取数据并写入文件,然后再将文件拷贝到本地工作站上用 Wireshark 分析。 还有一种更高效的方法&#xf…

【HarmonyOS】鸿蒙应用实现截屏

【HarmonyOS】鸿蒙应用实现截屏 组件截屏 通过componentSnapshot的get函数,将需要截图的组件设置id传进去即可。 import { componentSnapshot } from kit.ArkUI; import { image } from kit.ImageKit;/*** 截图*/ Entry Component Preview struct SnapShotPage {S…

sheng的学习笔记-AI-层次聚类

AI目录:sheng的学习笔记-AI目录-CSDN博客 需要学习的前置知识:聚类,可参考:sheng的学习笔记-AI-聚类(Clustering)-CSDN博客 什么是层次聚类 层次聚类(hierarchical clustering)试图在不同层次对数据集进行划分,从而形…

【Python系列】使用 `isinstance()` 替代 `type()` 函数

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

国产版Sora复现——智谱AI开源CogVideoX-2b 本地部署复现实践教程

目录 一、CogVideoX简介二、CogVideoX部署实践流程2.1、创建丹摩实例2.2、配置环境和依赖2.3、上传模型与配置文件2.4、开始运行 最后 一、CogVideoX简介 智谱AI在8月6日宣布了一个令人兴奋的消息:他们将开源视频生成模型CogVideoX。目前,其提示词上限为…

thinkphp8开发的广告联盟网站系统源码

这款程序是采用国内主流的PHP框架,最新版本thinkphp8.0.4,也是目前市面上功能相对比较强大,界面比较好看的一款全开源的广告联盟系统,程序支持任意二开商业,并且代码无任何加密处理。 程序开发:PHPMySQL …

Windows使用wsl安装docker-desktop

一:修改Windows配置,启用相关功能。 1:启用硬件虚拟化VT-d 各品牌电脑的Bios设置都不一致,需要自行查找如何进入Bios开启VT-x功能,绝大部分电脑此功能默认情况下是直接开启的。 2:确定Windows系统的类别…

【全面介绍下Gitea,什么是Gitea?】

🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…

日常生活中的卡片写作素材

日常生活中,有哪些内容适合写卡片? ​​我认为有两类非常值得写卡片,一类是经常重复说的内容,一类是给其他人提供价值的信息。 ​ ​ ​ 重复说的内容: ​​比如,你在工作中经常解答同事一些问题&a…

怎么限制电脑不能打开某个网页或网站(四个方法你可一定要学会)

老板:我公司的员工真的很让人头疼。 朋友:怎么了? 老板:我一不在就有人偷偷打开某些违法网站,画面不可描述啊! 朋友:难道你还不知道可以禁止员工打开某个网站? 老板:…

C++ QT开发 学习笔记(3)

C QT开发 学习笔记(3) - WPS项目 标准对话框 对话框类说明静态函数函数说明QFileDialog文件对话框getOpenFileName()选择打开一个文件getOpenFileNames()选择打开多个文件getSaveFileName()选择保存一个文件getExistingDirectory()选择一个己有的目录getOpenFileUrl()选择打幵…

【优秀python大屏案例】基于python flask的前程无忧大数据岗位分析可视化大屏设计与实现

随着大数据和人工智能技术的迅猛发展,数据分析和可视化在各个行业中的应用越来越广泛。特别是在招聘领域,大数据分析不仅能够帮助企业更好地了解市场需求,还能为求职者提供科学的职业规划建议。本文探讨了基于Python Flask框架的前程无忧大数…

如何判断IP地址属于住宅IP还是机房IP

在数字化时代,IP地址作为互联网通信的基础标识,扮演着重要的角色。无论是网络管理、数据分析还是安全监控,正确识别IP地址的类型——尤其是区分是住宅IP还是机房IP,对于确保网络安全、优化网络性能以及合法合规运营具有重要意义。IPIDEA代理I…

小白入门机器学习被劝退的4大原因,你中了哪一个?

hi,喵老师🐱来啦。 很多小白朋友,尤其是准研究生、文科生,刚开始接触机器学习之后常常在短时间内就「入门即放弃」了。 其实背后主要的原因无非那么几个,今天喵老师就给大家盘一盘,看看你是哪一种&#x1…

BUUCTF [安洵杯 2019]easy_serialize_php 1

打开题目,看到一串php代码,试着代码审计一下,看一下有用信息 可以看出是通过$_SESSION[img]来读取文件 extract可以将数组中的变量导入当前变量表 也就是说我们可以伪造$_SESSION 数组中的所有数据 这里传递一个参数fphpinfo 先用hackbar进…

缺失的第一个正数

思路&#xff1a;我的初步想法是先对数组排序&#xff0c;然后找到第一个正数的位置&#xff0c;从1开始顺序比对&#xff1a;哪个没出现就是答案。 代码&#xff1a; class Solution { public:int firstMissingPositive(vector<int>& nums) {sort(nums.begin(),nums…