redis总结--常见问题与解决办法,推荐等级

因为csdn只支持这种文档形式:不支持思维导图:

更好友好的阅读:可以看我的飞书--------思维导图(这样食用更加):


缓存穿透问题原因每次从缓存中都查不到数据,而需要查询数据库,同时数据库中也没有查到该数据,也没法放入缓存如何解决布隆过滤器原理:布隆过滤器可以用于检索一个元素是否在一个集合中。结构:概率型数据结构使用方式一:通过自己写算法实现布隆过滤器方式二:使用网上存在的开源包推荐指数:⭐⭐⭐(这个技术有些过时了,但是可以用)优点:算法简单,可以自己配置缺点:存在一定的误判率不支持删除操作查找性能比布谷鸟底空间利用率低布谷鸟过滤器要求条件:适用于对误判率要求较高的场景。如网络路由、存储系统等原理:最简单的布谷鸟哈希结构是一维数组结构,会有两个 hash 算法将新来的元素映射到数组的两个位置。如果两个位置中有一个位置为空,那么就可以将元素直接放进去。但是如果这两个位置都满了,它就不得不「鸠占鹊巢」,随机踢走一个,然后自己霸占了这个位置。近似集合数据结构如何使用方式一:自己写一个算法(我试过,比较复杂)方式二:调用别人写的库情况优点:相较于布隆过滤器具有更低的误判率支持删除操作查找性能高空间利用率高缺点:删除不完美,存在误删的概率。删除的时候只是删除了一份指纹副本,并不能确定此指纹副本是要删除的key的指纹。同时这个问题也导致了假阳性的情况。插入复杂度比较高随着插入元素的增多,复杂度会越来越高,因为存在桶满,踢出的操作,所以需要重新计算,但综合来讲复杂度还是常数级别。存储空间的大小必须为2的指数让空间效率打了折扣同一个元素最多插入kb次(k指哈希函数的个数,b指的桶中能装指纹的个数)如果布谷鸟过滤器支持删除,则必须存储同一项的多个副本。 插入同一项kb+1次将导致插入失败。 这类似于计数布隆过滤器,其中重复插入会导致计数器溢出。推荐指数:⭐⭐⭐⭐⭐(绝对好用)缓存空对象方案一要求条件:适中推荐指数:⭐⭐⭐⭐(很常见的方式)设置缓存的时候,同时设置一个过期时间,这样过期之后,就会重新去数据库查询最新的数据并缓存起来方案二要求条件:实时性要求非常高推荐指数:⭐⭐⭐(要结合实际情况,考虑双写一致性的问题)如果对的话,那就写数据库的时候,同时写缓存。这样可以保障实时性方案三要求条件:实时性要求不是那么高推荐指数:⭐⭐⭐⭐(非常实用的方式)那就写数据库的时候给消息队列发一条数据,让消息队列再通知处理缓存的逻辑去数据库取出最新的数据校验参数原理:我们可以对用户id做检验。(请求合法性校验)比如权限管理推荐指数:⭐⭐⭐⭐⭐(这个必须做)缓存击穿问题原因缓存击穿问题是由于key过期了导致的如何解决加锁原理:在缓存失效的瞬间,通过加锁机制来保证只有一个请求能够访问数据库,其他请求等待获取缓存数据。使用:同一时刻只有一个请求才能访问某个信息并且另一个线程将数据库中查询到的结果,又重新放入缓存中推荐指数:⭐⭐⭐(非必要不加锁)自动续期原理:在key快要过期之前,就自动给它续期推荐指数:⭐⭐⭐(本来要过期,但是续期的指令如何识别)缓存不失效原理:对于很多热门key,其实是可以不用设置过期时间,让其永久有效的。推荐指数:⭐⭐⭐⭐(正对某些业务可以设置)缓存雪崩
原因:有多个热门key同时失效(非常严重):归根结底都是有大量的请求,透过缓存,而直接访问数据库了有大量的热门缓存,同时失效。会导致大量的请求,访问数据库。而数据库很有可能因为扛不住压力,而直接挂掉。缓存服务器宕机了,可能是机器硬件问题,或者机房网络问题。总之,造成了整个缓存的不可用。解决办法过期时间加随机数推荐指数:⭐⭐⭐⭐(较为安全)要求不要设置相同的过期时间即使在高并发的情况下,多个请求同时设置过期时间,由于有随机数的存在,也不会出现太多相同的过期key高可用(分布式部署)推荐指数:⭐⭐⭐⭐(能在源头处理最好)深层原因:针对缓存服务器宕机的情况,原理:通过多个节点来分担缓存的压力,提高系统的容灾性解决办法:在前期做系统设计时,可以做一些高可用架构redis可以使用哨兵模式,或者集群模式,避免出现单节点故障导致整个redis服务不可用的情况服务降级(备份机制)推荐指数:⭐⭐⭐⭐(做一个数据兜底)更深的原因:做了高可用架构,redis服务还是挂了,该怎么办呢?解决办法:配置一些默认的兜底数据。程序中有个全局开关,比如有10个请求在最近一分钟内,从redis中获取数据失败,则全局开关打开。就直接从配置中心中获取默认的数据。还需要有个线程,每隔一定时间去从redis中获取数据数据预热原理:数据预热就是系统上线后,将相关的缓存数据直接加载到缓存系统,这样就可以避免在用户请求的时候先查询数据库方式:在系统低峰期,提前对热点数据进行加载和缓存,避免大量数据同时失效推荐指数:⭐⭐⭐⭐(不要等高峰了做预案)双层缓存策略C1为原始缓存,C2为拷贝缓存,C1失效时可以访问C2,C1缓存失效时间设置为短期,C2缓存失效时间设置为长期推荐指数:⭐⭐⭐(万一都宕机就完蛋了)定时更新缓存策略原理:失效性要求不高的缓存,容器启动初始化加载,采用定时任务更新或移除缓存使用:另起一个线程,去做任务处理推荐指数:⭐⭐⭐⭐⭐(前期预防永远比后期解决来的好)双写一致性(redis与mysql)
原因:分布式常见问题数据库和缓存双写,就必然会存在不一致的问题最终一致性:要保证数据库与缓存可以先后一致强一致性:有强一致性要求的数据,不能放缓存解决方法:更新缓存先写缓存,写数据库问题程度:上上(很严重)问题原因:刚写完缓存,突然网络出现了异常,导致写数据库失败了推荐指数:⭐⭐(用的不多)造成影响:容易诞生假数据先写数据库,在写缓存问题情况:写缓存失败了问题程度:上 (严重)问题原因:写数据库和写缓存,都属于远程操作。(通常建议写数据库和写缓存不要放在同一个事务中)写数据库成功了,但写缓存失败了,数据库中已写入的数据不会回滚推荐指数:⭐⭐ ⭐(接口性能要求不太高的系统)造成影响:数据库是新数据,而缓存是旧数据,两边数据不一致的情况问题情况:高并发先写数据库,在写缓存问题程度:上上 (很严重)问题原因:请求b在缓存中的新数据,被请求a的旧数据覆盖了。(请求互相覆盖)推荐指数:⭐⭐(高并发场景,不适合)造成影响:可能会出现数据库是新值,而缓存中是旧值,两边数据不一致的情况问题情况:浪费系统资源问题程度:上(严重)问题原因:每写一次缓存,都需要经过一次非常复杂的计算推荐指数:⭐⭐(计算要求低的情况)造成影响:浪费cpu和内存资源删除缓存先删缓存,在写数据库高并发下,单删问题程度:中上(适度)问题原因:请求A删除完缓存数据Data后,网络卡顿,写入数据库操作暂停。请求B读数据Data,缓存中没有,去数据库读,读的是旧数据。请求A网络好了,写入新数据到数据库推荐指数:⭐⭐⭐(低并发下)造成影响:请求A的新值并没有被请求B写入缓存,同样会导致缓存和数据库的数据不一致的情况高并发下,缓存双删问题程度:中下 (良好)问题原因:写数据库之前删除缓存一次,写完数据库后,再删除缓存一次推荐指数:⭐⭐⭐⭐(看情况推荐使用)使用要点:第二次删除缓存,并非立马就删,而是要在一定的时间间隔之后。原因:在另一个请求未生效前,删除这就没有意义了造成影响:第二次删除可能失败解决办法:重试机制原理:更新了数据库成功了,但更新缓存失败了,可以立刻重试N次。如果其中有任何一次成功,则直接返回成功。如果N次都失败了,则写入数据库,准备后续再处理。同步重试推荐指数:⭐⭐⭐()原因:接口并发量比较高的时候,可能有点影响接口性能异步重试推荐指数:⭐⭐⭐⭐⭐方式一:每次都单独起一个线程,该线程专门做重试的工作推荐指数:⭐⭐⭐原因:在高并发的场景下,可能会创建太多的线程,导致系统OOM问题方式二:将重试的任务交给线程池处理推荐指数:⭐⭐⭐⭐原因:如果服务器重启,部分数据可能会丢失方式三:将重试数据写表存入数据库(定时任务)推荐指数:⭐⭐⭐⭐(不适合实时性要求特别高的业务场景)使用:定时任务进行重试重试表(至少得有一下字段):重试次数字段是否成功的状态字段原理:设置初始值,每次删除重试次数字段加1,只要任意有一次成功就返回成功,同时修改状态,等待后续进一步处理缺点:实时性没那么高优点:数据是落库的,不会丢数据方式四:将重试的请求写入mq等消息中间件推荐指数:⭐⭐⭐⭐⭐(实时性还是比较高的)使用:mq的consumer中处理原理:操作写完数据库,但删除缓存失败了,产生一条mq消息,发送给mq服务器mq消费者读取mq消息,如果其中有任意一次成功了,则返回成功。重试N此后还是失败,写入死信队列中,后续需要人工处理优点:mq的实时性还是比较高的优化:删除缓存可以完全走异步。即用户的写操作,在写完数据库之后,不用立刻删除一次缓存。而直接发送mq消息,到mq服务器,然后有mq消费者全权负责删除缓存的任务。方式五:订阅mysql的binlog推荐指数:⭐⭐⭐⭐⭐(强烈推荐)原理:订阅者中,如果发现了更新数据请求,则删除相应的缓存(监听binlog)使用:canal等中间件,实现原理:业务接口中写数据库之后,就不管了,直接返回成功,mysql服务器会自动把变更的数据写入binlog中,binlog订阅者获取变更的数据,然后删除缓存问题:也会删除失败解决办法:重试机制推荐使用方式三和方式四(当推荐方式四)先写数据库,再删缓存问题程度:下上 (优秀)问题原因:缓存过期失效,请求A查询数据发现缓存没有,去数据库查询,但是网络原因,没有及时更新缓存。请求B先写数据库,然后删除缓存。请求A恢复,更新缓存。诞生条件(同时满足概率小)缓存刚好自动失效请求A查询数据库旧值以及更新缓存数据的时间,比请求B写入数据库以及删除缓存数据的时间长一般数据库查询比数据库写入时间短(那种复合,聚合查询就不好说了)推荐指数:⭐⭐⭐⭐⭐ (推荐使用)使用指南:请求查询不要太过复杂造成影响:最差的情况就是读取到旧数据(问题不算太大,刷新一下,重新请求,数据就对了),删除可能失效解决办法:重试机制原理:更新了数据库成功了,但更新缓存失败了,可以立刻重试N次。如果其中有任何一次成功,则直接返回成功。如果N次都失败了,则写入数据库,准备后续再处理。同步重试推荐指数:⭐⭐⭐(适合低并发)原因:接口并发量比较高的时候,可能有点影响接口性能异步重试推荐指数:⭐⭐⭐⭐⭐(常见操作)方式一:每次都单独起一个线程,该线程专门做重试的工作推荐指数:⭐⭐⭐原因:在高并发的场景下,可能会创建太多的线程,导致系统OOM问题方式二:将重试的任务交给线程池处理推荐指数:⭐⭐⭐⭐原因:如果服务器重启,部分数据可能会丢失方式三:将重试数据写表存入数据库(定时任务)推荐指数:⭐⭐⭐⭐(不适合实时性要求特别高的业务场景)使用:定时任务进行重试重试表(至少得有一下字段):重试次数字段是否成功的状态字段原理:设置初始值,每次删除重试次数字段加1,只要任意有一次成功就返回成功,同时修改状态,等待后续进一步处理缺点:实时性没那么高优点:数据是落库的,不会丢数据方式四:将重试的请求写入mq等消息中间件推荐指数:⭐⭐⭐⭐⭐(实时性还是比较高的)使用:mq的consumer中处理原理:操作写完数据库,但删除缓存失败了,产生一条mq消息,发送给mq服务器mq消费者读取mq消息,如果其中有任意一次成功了,则返回成功。重试N此后还是失败,写入死信队列中,后续需要人工处理优点:mq的实时性还是比较高的优化:删除缓存可以完全走异步。即用户的写操作,在写完数据库之后,不用立刻删除一次缓存。而直接发送mq消息,到mq服务器,然后有mq消费者全权负责删除缓存的任务。方式五:订阅mysql的binlog推荐指数:⭐⭐⭐⭐⭐(强烈推荐)原理:订阅者中,如果发现了更新数据请求,则删除相应的缓存(监听binlog)使用:canal等中间件,实现原理:业务接口中写数据库之后,就不管了,直接返回成功,mysql服务器会自动把变更的数据写入binlog中,binlog订阅者获取变更的数据,然后删除缓存问题:也会删除失败解决办法:重试机制推荐使用方式三和方式四(当推荐方式四)缓存的并发竞争
原因:多个redis的client同时set key引起的并发问题多客户端同时并发写一个key,一个key的值是1,本来按顺序修改为2,3,4,最后是4,但是顺序变成了4,3,2,最后变成了2。解决方案:乐观锁推荐指数:⭐⭐⭐(乐观锁适用于大家一起抢着改同一个key)使用:watch 命令可以方便的实现乐观锁缺点:如果 redis 使用了数据分片的方式,那么这个方法就不适用了什么是数据分片?原理:Redis的分片机制允许数据拆分存放在不同的Redis实例上,每个Redis实例只包含所有键的子集优点:可以减轻单台Redis的压力,提升Redis扩展能力和计算能力分布式锁+时间戳原理:加锁的目的实际上就是把并行读写改成串行读写的方式,从而来避免资源竞争用一个状态值表示锁,对锁的占用和释放通过状态值来标识加锁使用方法:使用:使用redis中setnx()函数返回1,则客户端获得锁,把锁的键值设置为时间值,表示该键已经被锁定,可以通过DEL lock.foo来释放该锁返回 0 ,则表明该锁已经被其他客户端取得,这时返回重试等待对方完成,或者等待锁超时,在或者返回推荐指数:⭐⭐⭐⭐(适合分布式环境)优点:不用关心 redis 是否为分片集群模式时间戳使用:(适合有序场景)原理:系统B先抢到锁,将key1设置为{ValueB 7:05}。接下来系统A抢到锁,发现自己的key1的时间戳早于缓存中的时间戳(7:00<7:05),那就不做set操作了推荐指数:⭐⭐⭐(适合对于有序情况)优点:业务处理有序消息队列原理:把Redis.set操作放在队列中使其串行化,及一个一个执行(较为通用的解决方案)推荐指数:⭐⭐⭐⭐(高并发场景中)优点:串行化

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

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

相关文章

Kafka-消费者-KafkaConsumer分析-ConsumerCoordinator

在前面介绍了Kafka中Rebalance操作的相关方案和原理。 在KafkaConsumer中通过ConsumerCoordinator组件实现与服务端的GroupCoordinator的交互&#xff0c;ConsumerCoordinator继承了AbstractCoordinator抽象类。 下面我们先来介绍AbstractCoordinator的核心字段&#xff0c;如…

GO——与PHP的并发对比

背景 go比php可支持的并发数更高&#xff0c;为什么 目标 分析点&#xff1a; 系统的并发瓶颈go语言的并发瓶颈php语言的并发瓶颈 系统并发 参考&#xff1a;https://juejin.cn/post/6844904025553534990 提到并发&#xff0c;我们这里指的是web服务web系统的第一层&…

如何在Linux上安装Stable Diffusion WebUI

Stable Diffusion WebUI是一个基于AUTOMATIC1111的stable-diffusion-webui仓库的项目&#xff0c;允许用户通过web界面轻松地生成AI驱动的图像。本文将指导您在Linux系统上完成Stable Diffusion WebUI的安装过程。 准备工作 在安装Stable Diffusion WebUI之前&#xff0c;请确…

Apache JMeter 3.1压力测试监控服务器数据(cpu、内存、磁盘io等)

Apache JMeter 3.1压力测试 Apache JMeter 3.1压力测试监控cpu、内存情况1.下载Apache JMeter 3.11.1 添加线程组1.2 添加http请求1.3 增加http请求头设置1.4 添加csv配置1.5 添加测试结果监控配置 2. 监控插件下载3. 服务端插件下载并启动3.1 下载3.2 解压并启动3.3 增加服务器…

渗透测试之Kali如何利用CVE-2019-0708漏洞渗透Win7

环境: 1.攻击者IP:192.168.1.10 系统: KALI2022(vmware 16.0) 2.靶机IP:192.168.1.8 系统:Windows 7 6.1.7601 Service Pack 1 Build 7601 已开启远程协助RDP服务开启了3389端口 问题描述: KALI 如何利用CVE-2019-0708漏洞渗透Win7 解决方案: 1.打开kali,msf搜索…

最新React面试题:说说对React的理解?有哪些特性?

最新React面试题&#xff1a;说说对React的理解&#xff1f;有哪些特性&#xff1f; 回答思路&#xff1a;是什么&#xff1f;---》特性---》优势是什么&#xff1f;特性声明式编程Component组件的特点 优势 回答思路&#xff1a;是什么&#xff1f;—》特性—》优势 是什么&a…

【每周AI简讯】GPT-5将有指数级提升,GPT Store正式上线

AI7 - Chat中文版最强人工智能 OpenAI的CEO奥特曼表示GPT-5将有指数级提升 GPT奥特曼参加Y-Combinator W24启动会上表示&#xff0c;我们已经非常接近AGI。GPT-5将具有更好的推理能力、更高的准确性和视频支持。 GPT Store正式上线 OpenAI正式推出GPT store&#xff0c;目前…

​一套uni-app + .net医院线上预约挂号系统源码(公众号+小程序预约挂号)

线上预约挂号系统构建了医院和患者的连接&#xff0c;通过改善患者院内的就医服务流程&#xff0c;以微信公众号、支付宝小程序为患者服务入口&#xff0c;为居民提供导诊、预约、支付、报告查询等线上线下一体化的就医服务&#xff0c;缩短患者就诊环节&#xff0c;提高医疗机…

springboot第50集:File类,IO流,网络编程,反射机制周刊

image.png FileReader、FileWriter的使用 FileInputStream、FileOutputStream的使用 image.png image.png image.png image.png image.png image.png image.png image.png image.png image.png image.png image.png 服务器内存优化是一个复杂的过程&#xff0c;通常需要综合考虑…

09前后端分离+SSM整合的小案例

前端的Node 后端的Tomcat&#xff0c;是前端程序的容器。前端的npm 后端的maven 1. 导入前端项目 node版本&#xff1a;16.16.0 配置阿里镜像 npm config set registry https://registry.npmjs.org/ 更新npm版本 npm install -g npm9.6.6 用vscode打开解压后的项目 , 右上角…

Scrum.org认证PSM官方认证班Professional Scrum Master™ (PSM)

课程简介 Scrum是目前运用最为广泛的敏捷开发方法&#xff0c;是一个轻量级的项目管理和产品研发管理框架&#xff0c;旨在最短时间内交付最大价值。根据2022年全球敏捷状态报告&#xff0c;Scrum的应用占比已经达到87%。 Scrum.org 由 Scrum 的联合创始人 Ken Schwaber 创立…

三、Redis命令

一、Redis客户端 Redis是一个客户端和服务器结构的程序&#xff0c;Redis的客户端有很多种形态 通过以下的方法实现Redis客户端和服务器交互&#xff0c;必须先进入Redis-cli客户端程序&#xff0c;才能输入Redis命令。 1、自带了命令行客户端 redis-cli //连接本地 redis-…

jQuery的选择器

目录 基本过滤选择器 层次选择器 简单过滤选择器 内容过滤选择器 可见性过滤器 子元素过滤器 表单对象属性顾虑器 表单选择器 jQuery的选择器分类都有哪些&#xff1f; 根据所获取页面中元素的不同&#xff0c;可以将jQuery选择器分为四大类&#xff1a;基本选择器…

深入了解 Pytest Markers:提升测试用例的组织和控制能力

​从这篇开始&#xff0c;逐一解决fixture是啥&#xff1f;mark是啥&#xff1f;参数request是啥&#xff1f;钩子函数是啥&#xff1f;parametrize参数化是啥&#xff1f;这些问题。本片先介绍一下mark是啥&#xff1f;以及如何使用 Markers有啥用&#xff1f; 当使用 Pytest…

ZooKeeper 实战(五) Curator实现分布式锁

文章目录 ZooKeeper 实战(五) Curator实现分布式锁1.简介1.1.分布式锁概念1.2.Curator 分布式锁的实现方式1.3.分布式锁接口 2.准备工作3.分布式可重入锁3.1.锁对象3.2.非重入式抢占锁测试代码输出日志 3.3.重入式抢占锁测试代码输出日志 4.分布式非可重入锁4.1.锁对象4.2.重入…

SAP PI之Rest adapter

一&#xff0c;简介 REST风格接口是以http为传输协议&#xff0c;以xml或json或text为有效负载。下图展示了REST到XI再返回的一个过程&#xff0c;一个REST接口包含的信息有&#xff1a;服务URL、URL中带的参数、http方法(post/get/put等)、http头部、body部分的有效载荷。而X…

Sentinel限流、熔断

1、限流 单个服务节点限流 sentinel 提供了两种不同的隔离机制&#xff1a;信号量隔离和线程池隔离&#xff0c;它们的主要区别如下&#xff1a; 信号量隔离&#xff08;Semaphore Isolation&#xff09;&#xff1a; 原理&#xff1a;信号量隔离基于计数器&#xff08;或称令…

React Hooks大全—useContext

在本文中&#xff0c;我们将重点介绍useContext这个Hook&#xff0c;它可以让你在函数组件中轻松地访问React Context&#xff0c;从而实现跨组件的状态共享。我们将从基本使用&#xff0c;实现原理&#xff0c;最佳实践&#xff0c;以及一些常见的问题和解决方案来探讨useCont…

域名群站开源系统分享开源域名授权系统

一、需要自己安装PHP和MYSQL服务器环境。 二、务必设置伪静态规则&#xff0c;否则将无法访问文章栏目页面。 三、启用伪静态功能&#xff0c;请在站点设置中选择使用thinkphp的伪静态规则。 四、在域名的根目录下找到”data/config.php”文件&#xff0c;填入数据库的账号和…

C++ 中 static 应用

static 实验介绍 在 C/C++ 中都可以使用 static 关键字,但是却需要注意在 C 与 C++ 的使用方法有差异。C++ 除了继承 C 中 static 的使用方法外还增加了新的使用方法。本次实验主要介绍 static 在 C++ 中的使用方法。 静态的成员在实例化对象之前已经产生,并将数据存放在全…