什么是Redis

  • 基于key-value存储结构的NoSQL数据库
  • 提供了String, Map, Set, ZSet, List等多种数据类型
  • 功能丰富:支持发布订阅模式,能够为数据设置过期时间,能够对数据进行持久化,支持分布式存储和读写分离,支持创建事务
  • 性能高:基于内存操作、对数据结构进行优化
  • 问题:容量小,可能出现缓存击穿、缓存雪崩等问题,可能出现线程安全问题

数据类型

简述

字符串

  • 最基本的数据类型
  • 可以存储任意类型的数据,例如文本、数字、序列化的对象
  • 支持字符串追加、获取子串、计数器等操作

哈希

  • 键值对的集合,适用于存储对象的属性

列表

  • 维护插入顺序
  • 允许在列表两端进行元素的插入与删除,可以通过索引访问、获取、修改和删除列表中的元素,支持范围操作如获取片段、修剪等

集合

  • 无序不重复的字符串元素的集合
  • 可以对集合添加、删除、查找、计数
  • 支持集合运算

有序集合

  • 有序的字符串元素集合,每个元素关联一个分数(score),用于排序和唯一性标识
  • 可以对有序集合进行添加、删除、查找、范围查询
  • 支持根据分数范围进行检索和排名

缓存击穿

概念

在高并发场景下,当非常热门的缓存键过期时,大量请求无法访问该键,进而直接访问数据库,从而给数据库带来巨大压力,甚至导致数据库宕机。

发生场景:

  • 键过期
  • 键不存在

解决方案:

  • 热点数据预加载
  • 互斥锁
  • 限流与熔断

热点数据预加载解决缓存击穿

在缓存键失效之前,提前异步加载热点数据到缓存中,确保缓存不会在关键时刻失效。

可以创建定时任务,每次判断是否为热点数据,如果是就读取后添加到缓存。

互斥锁解决缓存击穿

基于Redis的SETNX指令实现分布式锁。

取值时首先到缓存中判断,若缓存中存在则直接获取。

缓存中不存在时,尝试获取分布式锁。

若获取成功,再次判断缓存中是否存在数据,避免在其他客户端的请求已经触发了缓存的写入的情况下再次读取。

若缓存仍不存在,从数据库读入数据并写入缓存。

若获取分布式锁不成功,则等待一段时间后再判断。

注意事项:

  • 对锁设置超时时间
  • 获取锁后尽快释放锁

通过限流与熔断解决缓存击穿问题

限流:

  • 限制单位时间内的请求数,超出此范围的请求被丢弃或延迟处理
  • 有多种限流算法可供选择,如令牌桶算法或漏桶算法

熔断:

  • 是一种故障保护机制,基于一定的条件或阈值判断是否熔断
  • 有多个熔断库可供选择,如Hystrix、Resilience4j等

缓存穿透

概念:某个key在Redis与MySQL中均不存在,对于这一key的查询请求会经历Redis与MySQL的查询,最终返回空值。

解决方案:

  • 缓存空值
  • 布隆过滤器

缓存空值解决Redis缓存穿透

将请求的key加入缓存,设置值为空,并设置过期时间。则过期前的请求均会停留与Redis层。

缺点:

  • 额外占用空间
  • 会造成数据不一致

布隆过滤器解决Redis缓存穿透

布隆过滤器:

  • 由位数组和一组哈希函数组成,用于快速判断某个元素是否在集合里
  • 判断时,由哈希函数求出多个索引位置,分别检测每个位置的位值是否为1,全1则可能存在,不全为1则必定不存在
  • 插入时,将对应的多个位置置位为1
  • 删除时无法维护
  • 存在误判率

布隆过滤器在这种场景下主要用于判断一个键(key)是否存在于应用内部的多个数据存储层中,包括数据库和Redis等。达到的效果是,如果一个key在数据库中根本不存在,那么就不会在数据库中进行查询,若key可能存在,则先在Redis中取值,Redis中不存在时再查表。

缓存雪崩

缓存中大量key同时过期,或Redis宕机,导致大量请求同时打入Mysql。

解决方案:

  • 将key的过期时间打散
  • 部署Redis高可用
  • 多级缓存

多级缓存策略

Nginx缓存

JVM缓存:Caffeine等

延迟双删

延迟双删是高并发场景下一定程度上避免mysql与redis数据不一致的一种手段。

为什么要延迟双删?

设想以下场景:我们要对数据库中的数据进行修改,并将缓存中的旧数据删除。

有两种可能的方案:

  1. 先update,再删缓存
  2. 先删缓存,再update

两种方案均存在一定问题。

方案一:update后,删缓存前的这段时间,请求会直接从缓存获取旧数据。删缓存后,缓存中没有查到,再到mysql中查询,并同步到缓存。即在update后、删缓存前这段时间数据不一致。由于这段时间长度较小,故影响较小,但若缓存删除失败,则会导致长时间的数据不一致,并且由于不断请求删除缓存,导致响应变慢。

方案二:删缓存后,update前,请求在缓存中没有获取到数据,便到mysql中查询,查到了旧数据,同时同步到缓存中。update以后,缓存中仍然存放旧数据。这会导致比较严重的数据不一致。

延迟双删流程:

先删缓存,再update,update后等待一段足够写入的时间,再删一次缓存。

伪代码:

def(cache)
update(mysql)
sleep()
def(cache)

效果:类似于方案二,但是解决了update后缓存没有同步的问题。

【Redis】八股文(一)的更多相关文章

  1. 三天吃透Redis八股文

    Redis连环40问,绝对够全! Redis是什么? Redis(Remote Dictionary Server)是一个使用 C 语言编写的,高性能非关系型的键值对数据库.与传统数据库不同的是,Re ...

  2. 《面试八股文》之 Redis 16卷

    微信公众号:moon聊技术 关注选择" 星标 ", 重磅干货,第一 时间送达! [如果你觉得文章对你有帮助,欢迎关注,在看,点赞,转发] 大家好,我是 moon. redis 作为 ...

  3. 三天吃透Redis面试八股文

    本文已经收录到Github仓库,该仓库包含计算机基础.Java基础.多线程.JVM.数据库.Redis.Spring.Mybatis.SpringMVC.SpringBoot.分布式.微服务.设计模式 ...

  4. 吃透Redis面试八股文

    Redis连环40问,绝对够全! Redis是什么? Redis(Remote Dictionary Server)是一个使用 C 语言编写的,高性能非关系型的键值对数据库.与传统数据库不同的是,Re ...

  5. 这可能是最全面的Redis面试八股文了

    Redis连环40问,绝对够全! Redis是什么? Redis(Remote Dictionary Server)是一个使用 C 语言编写的,高性能非关系型的键值对数据库.与传统数据库不同的是,Re ...

  6. 深入解读Redis分布式锁

    之前码甲哥写了两篇有关线程安全的文章: 你管这叫线程安全? .NET八股文:线程同步技术解读 分布式锁是"线程同步"的延续 最近首度应用"分布式锁",现在想想, ...

  7. Redis 面霸篇:高频问题横扫核心知识点

    「码哥字节」从高频面试问题跟大家一起横扫 Redis 核心知识点,从根本上理解 Redis ,不做八股文的工具人,做扭转乾坤的大神. 码哥到如今已经写了 9 篇 Redis 连载,后台有小伙伴也让我写 ...

  8. 面试问题记录 二 (数据库、Linux、Redis)

    面试问题记录 二 (数据库.Linux.Redis) 前言 接着上次的面试问题记录,在最后还有几道问的数据结构方面的知识点要补充 还是那句话:如果文中解释有明显错误,劳烦请及时指正我,在这不胜感激!! ...

  9. Redis挂了,流量把数据库也打挂了,怎么办?

    你好呀,我是歪歪. 是这样的,前几天有个读者给我发消息,说面试的时候遇到一个场景题: 他说他当时,一时间竟然找不到回答问题的角度,感觉自己没有回答到点子上. 我仔细想了一下,确实是感到这个问题有一丝丝 ...

  10. 除了背八股文,Java面试更该这样准备

    我可以这样说,哪怕你背了再多java八股文的答案,过面试也能靠运气,因为很多java面试的答案只限于技术理论说辞.但用我本文给出的方法去准备面试,能在不提升技术的前提下,大大提升你java面试的通过率 ...

随机推荐

  1. 目标检测(Object Detection)

    文章目录 目标检测(Object Detection) 一.基本概念 1. 什么是目标检测 2. 目标检测的核心问题 3. 目标检测算法分类 1)Tow Stage 2)One Stage 4. 目标 ...

  2. [OpenCV-Python] 22 直方图

    文章目录 OpenCV-Python:IV OpenCV中的图像处理 22 直方图 22.1 直方图的计算,绘制与分析 22.1.1 统计直方图 22.1.2 绘制直方图 22.1.3 使用掩模 22 ...

  3. Win YAPI + Jenkins 实现接口自动化测试

    自动化测试 传统的接口自动化测试成本高,大量的项目没有使用自动化测试保证接口的质量,仅仅依靠手动测试,是非常不可靠和容易出错的. 为了解决这个问题,使用YAPI接口自动化测试功能,只需要配置每个接口的 ...

  4. Flutter(十) 音频+视频播放

    在Flutter中,我们有各种插件可供使用,从而实现音频和视频的播放功能. 例如,可以使用"text_to_speech"插件来将文字转换为语音,使用内置的"video_ ...

  5. Prism Sample 13-IActiveAwareCommands

    本例和12的唯一区别,仅仅是在ViewModel中增加了一个IActiveAware,这决定了只有在Acitve状态的视图中才会执行自己ViewModel中的命令.

  6. 想打印k8s资源YAML结果搞懂了Client-Side & Server-Side Apply

    前言 由于查看k8s资源YAML时常看到沉长的YAML与手写的格式,相差甚远不利于阅读,经过探索官方文档,才理解什么是Client-Side & Server-Side Apply. 先看一下 ...

  7. 【Python基础】集合的基本使用

    Python中的集合是一种无序且唯一的数据结构.集合是通过花括号{}或者set()函数来创建的. 创建集合 s = set() 声明空集合 s = {1,2,3,4,5} 声明非空集合 添加元素 s. ...

  8. 2023-03-20:给定一个无向图,保证所有节点连成一棵树,没有环, 给定一个正数n为节点数,所以节点编号为0~n-1,那么就一定有n-1条边, 每条边形式为{a, b, w},意思是a和b之间的无

    2023-03-20:给定一个无向图,保证所有节点连成一棵树,没有环, 给定一个正数n为节点数,所以节点编号为0~n-1,那么就一定有n-1条边, 每条边形式为{a, b, w},意思是a和b之间的无 ...

  9. vue全家桶进阶之路16:自定义过滤器及开发插件

    过渡 过渡(transition)是Vue提供的一种在元素在插入.更新或移除时,自动添加动画效果的方式.Vue提供了多种过渡效果,其中包括基于CSS动画的过渡,以及JavaScript过渡. 过渡可以 ...

  10. CPU后面的字母含义

    M(Mobile):移动笔记本电脑标准电压,功耗小,适合笔记本,i5-4310M. U(Ultra Low Voltage):移动笔记本电脑超低电压,更小的功耗.如i5-8250U. H(Height ...