redis做缓存(cache)

什么是缓存

缓存(Cache)的核心思路就是把一些常用的数据放到访问速度更快的地方,方便获取。
关于硬件的访问速度来说

CPU寄存器>内存>硬盘>网络

因此常见使用内存作为硬盘的缓存,例如redis。使用硬盘作为网络的缓存,例如浏览器通过http/https从服务器上获取到数据(html,css,js,图片,视频,音频,文字)像这种体积大,又不太会改变的数据,就可以保存到浏览器本地,后续在打开该网页,就不必重新从网络获取上述数据了。
根据“二八原则”,20%的热点数据,能够应对80%的访问场景。因此只需要把这些少量的热点数据缓存起来,就可以应对大多数的场景,从而在整体上有明显的性能提升。

使用redis作为缓存

在网站开发中,我们经常使用mysql来存储数据。mysql虽然功能强大,但是有一个致命的缺点,就是性能不高(进行一次查询操作要消耗很多系统硬件资源)。
:::info
为什么关系型数据库性能不高?

  1. 硬件原因
    1. 数据库把数据存储在硬盘上,硬盘的IO速度不快,尤其是随机访问
    2. 如果查询不能命中索引,就需要进行表的遍历,这就会增加磁盘IO次数
  2. 软件原因
    1. 关系型数据库对于sql的执行会做一系列解析,校验,优化工作
    2. 对于复杂查询,比如联合查询,需要进行笛卡尔积,效率很低
      :::
      因此,如果访问数据库的并发量很高,对于数据库的压力就很大,容易使数据库宕机。
      :::success
      为什么并发量高了就会宕机?
      服务器每次处理一个请求,就需要消耗一定的硬件资源,例如cpu,内存,硬盘,网络带宽。
      而一个服务器的资源是有限的,一个请求消耗一份资源,当把资源耗尽,后续请求就没有资源可用,就无法正确处理,更严重的还会导致服务器程序的代码崩溃。
      :::
      如何让数据库能够承担更大的并发量?
  • 开源:引入更多机器,部署更多数据库,构成数据库集群(主从复制,分库分表)
  • 节流:引入缓存,使用其他方式保存经常访问的热点数据,从而降低直接访问数据库的请求数量

实际开发中两种方案搭配使用

image.png

缓存更新策略

缓存更新策略

定期生成

访问的数据会以日志的形式记录下来,我们可以写个程序(如python,shell脚本代码),针对这些日志进行统计,统计这一天/周/月,每个词出现的频率,在根据频率降序排序,取出前20%的词,就是“热点词”。将这些“热点词”放大redis中

实时生成

如果在redis中查到,就直接返回;如果redis中不存在,就从数据库查,把查到的结果同时写到redis中。经过一段时间“动态平衡”,redis中的key就逐渐变成热点数据了。

内存淘汰机制

不停的写入redis,就会使redis的内存占用越来越多,当达到内存上限,就会触发redis的“内存淘汰机制”。

  1. FIFO(first in first out)先进先出:把缓存中存在时间最久的(先来的数据)淘汰掉
  2. LRU(least recently used)淘汰最久未使用:记录每个key的最近访问时间,把最近访问时间最老的key淘汰掉
  3. LFU(least frequently used)淘汰访问次数最少的:记录每个key最近一段时间的访问次数,把访问次数最少的淘汰掉
  4. Random随机淘汰:随机抽取key删除掉

redis配置文件中内置的淘汰策略

  • volatile-lru 当内存不⾜以容纳新写⼊数据时,从设置了过期时间的key中使⽤LRU算法(最近最少使⽤)进⾏淘汰
  • allkeys-lru 当内存不⾜以容纳新写⼊数据时,从所有key中使⽤LRU算法(最近最少使⽤)进 ⾏淘汰.
  • volatile-lfu4.0版本新增,当内存不⾜以容纳新写⼊数据时,在过设置了过期时间的key中,使⽤LFU算法 进⾏删除key.
  • allkeys-lfu 4.0版本新增,当内存不⾜以容纳新写⼊数据时,从所有key中使⽤LFU算法进⾏淘汰
  • volatile-random 当内存不⾜以容纳新写⼊数据时,从设置了过期时间的key中,随机淘汰数 据.
  • allkeys-random 当内存不⾜以容纳新写⼊数据时,从所有key中随机淘汰数据
  • volatile-ttl 在设置了过期时间的key中,根据过期时间进⾏淘汰,越早过期的优先被淘汰. (相当于 FIFO, 只不过是局限于过期的 key)
  • noeviction 默认策略,当内存不⾜以容纳新写⼊数据时,新写⼊操作会报错

缓存常见问题

缓存预热

缓存更新中,有定期更新,不需要预热;定期更新,需要预热。
在redis服务器首次接入的时候,服务器中没有数据。此时所有请求都会打给mysql,随着时间推移,redis上的数据越积累越多,mysql承担的压力逐渐变小。但就怕刚开始mysql就垮了,因此需要进行缓存预热(将定期生成和实时生成结合),先通过离线的方式,通过一些统计的途径,先把热点数据找到一批,导入到redis中,此时导入的这批热点数据,就能帮mysql承担很大的压力,随着时间推移,逐渐使用新的热点数据淘汰掉旧的数据。

缓存穿透(cache penetration)

查询某个key时,redis中没有,mysql中也没有。这次查询没有,下次查询还是没有,如果像这样的数据非常多,并且还反复查询,就会给mysql带来很大压力。
出现的可能原因

  1. 业务设计不合理,例如缺少必要的参数校验环节,导致非法的key也被进行查询
  2. 开发/运维误操作,不小心将部分数据从数据库上误删除
  3. 黑客攻击

解决方案

  1. 改进业务/加强监控报警(亡羊补牢)
  2. 如果发现这个key在redis和mysql中都不存在,仍然写入redis,value设成一个非法值如“”
  3. 引入布隆过滤器,每次查询redis/mysql之前都先判定key是否在布隆过滤器上存在。

布隆过滤器:结合了hash+bitmap,以比较小的空间,比较快的时间速度,实现对key是否存在的判定

缓存雪崩(cache avalanche)

短时间内,redis上大规模的key失效,导致缓存命中率陡降,并且mysql压力迅速上升,甚至导致宕机。
出现的可能原因

  1. redis挂了,redis宕机/redis集群模式下大量节点宕机
  2. redis正常,但是之前短时间内设置了很多key给redis,并且设置的过期时间正好相同

解决方案

  1. 加强监控报警,加强redis集群可用性的保证
  2. 不给key设置过期时间/设置过期时间的时候添加随机因子,避免同一时刻过期

缓存击穿(cache breakdown)

缓存雪崩的特殊情况,针对热点key突然过期,导致大量请求直接打到mysql上,甚至引起数据库宕机。
解决方案

  1. 基于统计方式发现热点key,并设置永不过期
  2. 进行必要的服务降级,例如访问数据库的时候使用分布式锁,限制同时请求的数据库的并发数

服务降级:本身服务器有十个功能,特定情况下,适当关闭一些不重要的功能,只保留核心功能(省点模式)

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

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

相关文章

数据库原理与分析实验三

目录 1、实验目的 2、实验预习与准备 3、实验内容及步骤 本博客为数据库课布置的实验二的作业。 1、实验目的 (1) 掌握Select子句的功能和检索数据的方法 (2) 掌握对查询结果排序的方法 2、实验预习与准备 &#xf…

通信协议:Uart的Verilog实现(上)

1、前言 调制解调器是主机/设备与串行数据通路之间的接口,以串行单比特格式发送和接收数据。它也被称为通用异步收发器(Uart, Universal Asynchronous Receiver/Transmitter),这表明该设备能够接收和发送数据,并且发送和接收单元不同步。 本节…

【re】BUUCTF Java逆向解密

题目:BUUCTF Java逆向解密 没壳,是java文件(大概) ida打开看不懂,找了网页上的java反编译 Decompiler.com 没用过java啊…暂且用sublime打开 还好还挺好懂的 import java.util.ArrayList; import java.util.Scanner;p…

【Spring MVC】Spring MVC如何处理跨域请求(CORS)

文章目录 1. Spring MVC如何处理跨域请求呢2. Spring MVC处理CORS的几个组件2.1. CorsFilter2.2. CrossOrigin 前言:请了解什么是CORS(跨域) 参考:https://gitee.com/firefish985/article-list/tree/master/Spring/Spring Web MVC…

Java开发需要的网络基础知识,搞清楚计算机网络底层原理

作者:逍遥Sean 简介:一个主修Java的Web网站\游戏服务器后端开发者 主页:https://blog.csdn.net/Ureliable 觉得博主文章不错的话,可以三连支持一下~ 如有需要我的支持,请私信或评论留言! 前言 计算机基础是…

手机基带芯片往事

手机基带芯片往事 手机基带芯片往事-虎嗅网 5G手机芯片简史-虎嗅网

Oracle拉链表

目录 -- 准备一个拉链表 -- 2.将所有的数据 同步到拉链表中 TEST_TARGET中 --3. 源表的数据发生了变化 --4. 将新增和修改的数据同步到拉链表 -- 开链的过程 -- 判断源表和目标表的数据,不同数据插入 --5. 修改拉链表中失效的时间和状态(将原本的开链时间,改为当前时间)-- …

怎样提高外贸业务销售能力

怎样提高外贸业务销售能力 一、市场分析与研究1. 了解目标市场:2. 收集客户信息: 二、产品知识和差异化竞争1. 熟悉产品:2. 差异化竞争: 三、制定销售策略和计划1. 制定销售计划:2. 销售策略: 四、谈判技巧…

【插件】页面引导库driver.js:

文章目录 一、效果图:二、实现思路:三、实现代码:【1】Driver.js 的技术特性【2】安装依赖【3】代码实现【4】 配置相关参数 一、效果图: 二、实现思路: 【官网】https://driverjs.com/docs/installation 【npm】https://www.npmjs.com/package/driver.js 【案例】改造driver.j…

HAProxy Data Plane API 实现对 haproxy 的配置管理

文章目录 前言一、安装1. 下载HAProxy Data Plane API2. 创建 Data Plane API 配置文件 /etc/haproxy/dataplaneapi.hcl3. 修改haproxy的配置文件 二、简单使用1. 查询请求2. 提交修改请求 总结 前言 我们平时对 haproxy 配置的修改,往往是 SSH 连接进去节点&#…

C++之std::function类模板定义函数对象应用总结(二百三十八)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…

C#流Stream与IO详解(4)——如何更快的读写文件

【前言】 在我们追求更快读写速度时,通常都是为了读写二进制文件,而不是文本文件,所以这里只说FileStream、BinaryReader、BinaryWriter的使用。 从前文的源码解读中能看到使用BinaryReader和BinaryWriter进行IO读写时本质还是调用了FileSt…

如何使用canvas实现一个下雪的动效

下面是一个使用Canvas实现下雪动效的代码示例&#xff1a; <!DOCTYPE html> <html> <head><title>下雪特效</title><style>body {margin: 0;padding: 0;}canvas {display: block;background: black;}</style> </head> <bo…

.NET的键盘Hook管理类,用于禁用键盘输入和切换

一、MyHook帮助类 此类需要编写指定屏蔽的按键&#xff0c;灵活性差。 using System; using System.Runtime.InteropServices; using System.Diagnostics; using System.Windows.Forms; using Microsoft.Win32;namespace MyHookClass {/// <summary>/// 类一/// </su…

一文详解JDK8常用10个更新特性

今日一语&#xff1a;当你发现编程的规律就是世界的规律时&#xff0c;你就是一名真正的程序员 1 Lambda(蓝布达)表达式 编译后会产生一个$XXXImpl1的编译文件&#xff0c;与匿名内部类相似&#xff0c;但不等同于匿名内部类。 其原理是将方法作为参数进行传递&#xff0c; JV…

【深入浅出设计模式--命令模式】

深入浅出设计模式--命令模式 一、背景二、问题三、解决方案四、试用场景总结五、后记 一、背景 命令模式是一种行为设计模式&#xff0c;它可以将用户的命令请求转化为一个包含有相关参数信息的对象&#xff0c;命令的发送者不需要知道接收者是如何处理这条命令&#xff0c;多个…

php文件上传功能(文件上传)

实现文件上传是Web开发中常用的功能之一&#xff0c;而PHP也是支持文件上传的。那么&#xff0c;下面我们就来介绍一下常用的PHP实现文件上传的方法。 使用HTML表单实现文件上传 HTML表单是Web开发中最基本的元素之一&#xff0c;它可以接收用户输入的数据&#xff0c;并通过…

Python 笔记03(多线程)

一 打开命令行&#xff0c;查看本机IP windows r 命令行输入&#xff1a;cmd ipconfig 然后查看IPv4的地址&#xff1a;192.168.1*6.1 ipconfig 二 函数式多进程 from multiprocessing import Process import os, timedef func(name):print(进程的ID&#xff1a;, os.g…

大数据时代,数据治理

一、大数据时代还需要数据治理吗&#xff1f; 数据平台发展过程中随处可见的数据问题 大数据不是凭空而来&#xff0c;1981年第一个数据仓库诞生&#xff0c;到现在已经有了近40年的历史&#xff0c;相对数据仓库来说我还是个年轻人。而国内企业数据平台的建设大概从90年代末…

Docker 自动化部署(保姆级教程)

Docker 自动化部署 1. jenkins 介绍1.1 参考链接&#xff1a;1.2 jenkins 概述1.3 jenkins部署项目的流程 2. jenkins 安装2.1 基于docker 镜像2.2 启动 jenkins 后端服务2.3 登录 jenkins 服务后端 3. jenkins自动化部署开始3.1 下载需要的插件3.2 创建任务3.2.1 描述3.2.2 配…