当前位置: 首页 > news >正文

Redis-1

Redis 理论部分

redis 速度快的原因

1、纯内存操作

2、单线程操作,避免了频繁的上下文切换和资源争用问题,多线程需要占用更多的 CPU 资源

3、采用了非阻塞 I/O 多路复用机制

4、提供了非常高效的数据结构,例如双向链表、压缩页表和跳跃表等,可以根据实际数据类型选择合理的数据编码

Redis 是基于内存的操作,CPU 一般不会是 Redis 的瓶颈,Redis 的瓶颈最有可能是机器内存的大小或者网络宽带。既然单线程容易实现,而且 CPU 不会成为瓶颈,那么采用单线程的方案。

注意:本质上 Redis 并不是单纯的单线程服务模型,一些辅助工作比如持久化刷盘、惰性删除等任务是由 BIO线程来完成的,这里说的单线程主要是说与客户端交互完成命令请求和回复的工作线程。重点:执行命令的核心模块是单线程的。新的命令并不会立即被执行,而是统一的放到了队列中,一条一条的执行。

单线程还有一个问题:就是对于每个命令的执行时间是有要求的,如果其中的某一个命令执行过长,会造成其他命令的阻塞,这对于 Redis 这种高性能的服务来说是致命的,记住 Redis 是面向快速执行场景的数据库

充当缓存的 Redis 和 Memcached

1、存储方式上:Memcache 会把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。Redis 有部分数据存在硬盘上,这样能保证数据的持久性。

2、数据支持类型上:Memcache 对数据类型的支持简单,只支持简单 key-value,而 Redis 最基本都要支持五种数据类型。

3、使用底层模型不同:它们之间底层实现方式以及与客户端之间通信的应用协议不一样。Redis 直接自己构建了 VM 机制,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。

4、值大小:Redis 可以达到 1GB,而 Memcache 只有 1MB。

Redis 缓存使用场景

1、降低后端负载

2、加速请求响应

3、大量写合并为批量写

Redis 缓存策略

1、LRU、LFU、FIFO

2、超时剔除

3、主动更新

内存淘汰策略:

1、volatile-lru 从已设置过期时间的数据集中挑选最近最少使⽤的数据淘汰

2、volatile-random 从已设置过期时间的数据集中任意选择数据淘汰

3、allkeys-lru 当内存不⾜以容纳新写⼊数据时,在键空间中,移除最近最少使⽤的 key,常用

4、allkeys-random 从数据集中任意选择数据淘汰

5、volatile-ttl 从已设置过期时间的数据集中挑选将要过期的数据淘汰

6、no-eviction 禁止驱逐数据,也就是说当内存不⾜以容纳新写⼊数据时,新写⼊操作会报错 OOM。

4.0 版本后增加两种:

7、volatile-lfu 从已设置过期时间的数据集中挑选最不经常使⽤的数据淘汰

8、allkeys-lfu 当内存不⾜以容纳新写⼊数据时,在键空间中,移除最不经常使⽤的 key。

常见选择:

  • allkeys-lru 用于应用对缓存的访问符合幂律分布,也就是存在相对热点数据,或者不太清楚应用的缓存访问分布状况,可以选择 allkeys-lru 策略。

  • allkeys-random 应用对于缓存 key 的访问概率相等,则可以使用这个策略。

  • volatile-ttl 策略使得可以向 Redis 提示哪些 key 更适合被移除

Redis 删除策略:

redis 开辟了一个空间用来存放值的地址和其过期时间,删除策略是为了在内存和 cpu 之间找到一个平衡,过期数据通常是在 cpu 闲暇之余被删除的。

Redis 中的过期数据删除情况:redis 服务器当中有很多的操作需要被执行,执行会导致 CPU 的工作大大的增加,当内存的空间还足够时,已被删除的数据的内存空间并未直接释放,而是对客户端的指令先执行,redis 中的数据删除策略包括定时删除、惰性删除、定期删除。

内存占用CPU 占用特征
定时删除节约内存,无占用不分时段占用 CPU 资源,频度高时间换空间,适用于小内存,强 CPU
惰性删除内存占用严重延时执行,CPU 利用率高空间换时间,适用于大内存,弱 CPU
定期删除内存定期随机清理每秒花费固定的 CPU 资源维护内存随机抽查,重点抽查

定时删除是对 CPU 和内存消耗取得一个折中方案,通过每隔一段时间执行一次删除过期 key 的操作,并且通过限制删除操作执行的时长和频率来减少删除操作对 CPU 造成的影响;周期性轮询 redis 库中的时效性数据,采用随机抽取的策略,利用过期数据占比的方式控制删除频度。一般在 redis 应用中会使用惰性删除和定期删除两种方式

Redis 缓存问题:

1、缓存穿透:大量请求缓存中数据库并不存在的数据。

解决方案:1、布隆过滤器。2、缓存空对象

2、缓存击穿:大量请求缓存中同时访问一个过期数据。

解决方案:1、设置 key 永不过期和随机时间失效。2、互斥锁使访问有序

3、缓存雪崩:大量请求缓存中大面积失效的缓存数据。

解决方案:

1、缓存数据设置随机的过期时间,防止同一时间大量数据集合失效。

2、集群,将数据分布在不同的缓存数据库中。

3、限流,通过加锁或队列来控制读数据库写缓存的线程数量

redis 编程客户端

1、Jedis 是 Redis 的 Java 实现客户端,提供了比较全面的 Redis 命令的支持。

  • 优点:提供了比较全面的 Redis 操作特性的 API;API 基本与 Redis 的指令一一对应,使用简单易理解。

  • 缺点:同步阻塞 IO、不支持异步、线程不安全

2、Lettuce 支持同步、异步通信的方式 API 调用,也支持响应式编程 API,包括发布/订阅消息、高可用性服务部署架构。Lettuce 高级 Redis 客户端,用于线程安全同步,异步和响应使用,支持集群,Sentinel,管道和编码器。

  • 优点:线程安全;基于 Netty 框架的事件驱动的通信,可异步调用;适用于分布式缓存

  • 缺点:API 更抽象,学习使用成本高

使用 Jedis 和 lettuce 总结

1、调大连接池大小能够提高 jedis 的吞吐量,但是不能避免出现超时错误和长时间等待。jedis 连接方式最大连接数和最小、最大空闲连接数设置为一样有利于减少上下文切换时间,提升效率。

2、lettuce 调大连接池大小反而会影响性能,最佳个数=CPU 核数+1,lettuce 整体稳定性和性能优于 jedis 方式。

常见 value 的数据类型

在这里插入图片描述
在这里插入图片描述

典型工具类编程

@Slf4j
@Component
public class RedisUtil {@Autowiredprivate RedisTemplate redisTemplate;public boolean set(final String key, Object value){ //写入缓存boolean res=false;try{this.set(key,value,new Random().nextInt(60)+10); 1070 秒的随机数res=true;} catch (Exception e){log.debug("问题:"+e.getMessage()); }return res;}public boolean set(String key,Object value,int timeout){ 写入缓存设置时效时间boolean res=false;try{redisTemplate.opsForValue().set(key,value);redisTemplate.expire(key, Duration.ofSeconds(timeout));res=true;} catch (Exception e){log.debug("问题:"+e.getMessage()); }return res;}public Object get(String key){ //读取缓存Object res=null;try {res = redisTemplate.opsForValue().get(key);} catch (Exception e){log.debug("问题:"+e.getMessage()); }return res;}public void remove(String key){ //删除 key,也删除对应的 valueif(exists(key)) redisTemplate.delete(key);}public boolean exists(String key){// 判断缓存中是否有对应的 valuereturn redisTemplate.hasKey(key); }public long getExpire(String key) { //根据 key 获取过期时间,单位为秒return redisTemplate.getExpire(key, TimeUnit.SECONDS); }public boolean expire(String key, long time) { //指定缓存失效时间try {if (time > 0) redisTemplate.expire(key, time, TimeUnit.SECONDS);return true;} catch (Exception e) {log.debug("问题:"+e.getMessage());return false; }}public Set<String> keys(String keyPattern){ 获取指定对应 pattern 模板的所有 keyreturn redisTemplate.keys(keyPattern); }
}

Redis 序列化器

针对数据的序列化/反序列化提供了多种可选择策略 RedisSerializer

1、JdkSerializationRedisSerializer 用于 POJO 对象的存取场景,使用 JDK 本身序列化机制,将 pojo 类通过ObjectInputStream/ObjectOutputStream 进行序列化操作,最终 redis-server 中将存储字节序列。是目前最常用的序列化策略。

2、StringRedisSerializer用于Key和value为字符串的场景,根据指定的charset对数据的字节序列编码成string,是 new String(bytes, charset)和 string.getBytes(charset)的直接封装,是最轻量级和高效的策略。

3、JacksonJsonRedisSerializer 是 jackson-json 工具提供的 javabean 与 json 之间的转换能力,可以将 pojo 实例序列化成 json 格式存储在 redis 中,也可以将 json 格式的数据转换成 pojo 实例。因为 jackson 工具在序列

化和反序列化时,需要明确指定 Class 类型,因此此策略封装起来稍微复杂。

缓存与数据库双写不一致

缓存可以提升性能、缓解数据库压力,但是使用缓存也会导致数据不一致性的问题。一般写数据操作使用缓存有三种经典的缓存模式 Cache-Aside Pattern、Read-Through/Write through 和 Write behind,这三种常见的更

新策略实际上都是保证数据的最终一致性的方法,可以总结为

1、先更新数据库再更新缓存,后续线程会读取旧数据

2、先删除缓存再新数据库,并发线程读取旧数据并写到缓存

3、先更新数据库再删除缓存,后续线程会读取旧数据

常见解决方案是延时双删,但是延时的时长不好控制

总结:

1、并发几率很小的数据,几乎不用考虑,加上缓存过期时间,缓存失效后查询主动更新

2、业务上是否能容忍一定时间的不一致,如能容忍的话,加上缓存过期时间;如果不能容忍缓存数据不一致,可以通过加分布式读写锁保证并发读写或写写的时候按顺序排好队,读读的时候相当于无锁。

3、可以用阿里开源的 canal 通过监听数据库的 binlog 日志及时的去修改缓存,但是引入了新的中间件,增加了系统的复杂度。

Cache-Aside Pattern 即旁路缓存模式,读操作:读的时候,先读缓存,缓存命中的话,直接返回数据;缓存没有命中的话,就去读数据库,从数据库取出数据,放入缓存后,同时返回响应。写操作:更新的时候,先更新

数据库,然后再删除缓存。

Read-Through/Write-Through 读写穿透模式中,读操作:从缓存读取数据,读到直接返回;如果读取不到的话,从数据库加载,写入缓存后,再返回响应。写操作:Write-Through 模式下,当发生写请求时,也是由缓

存抽象层完成数据源和缓存数据的更新Write behind 异步缓存,一般写入是同步更新缓存和数据,Write Behind 则是只更新缓存,不直接更新数据库,

通过批量异步的方式来更新数据库。适合频繁写的场景,MySQL 的 InnoDB Buffer Pool 机制就使用到这种模式。

相关文章:

Redis-1

Redis 理论部分 redis 速度快的原因 1、纯内存操作 2、单线程操作&#xff0c;避免了频繁的上下文切换和资源争用问题&#xff0c;多线程需要占用更多的 CPU 资源 3、采用了非阻塞 I/O 多路复用机制 4、提供了非常高效的数据结构&#xff0c;例如双向链表、压缩页表和跳跃…...

【Linux】Linux服务器连接百度网盘:实现上传下载

【Linux】Linux服务器连接百度网盘&#xff1a;实现上传下载 文章目录 【Linux】Linux服务器连接百度网盘&#xff1a;实现上传下载1. 前言2. 具体过程2.1 pip 安装所需包2.2 认证&#xff08;第一次连接需要认证&#xff09;2.3 下载所需文件或者目录2.4 其他指令使用2.5 注意…...

ADC模拟看门狗

如果被ADC转换的模拟电压低于低阀值或高于高阀值&#xff0c;AWD模拟看门狗状态位被设置。阀值位 于ADC_HTR和ADC_LTR寄存器的最低12个有效位中。通过设置ADC_CR1寄存器的AWDIE位 以允许产生相应中断。通过以下函数可以进行配置 void ADC_AnalogWatchdogCmd(ADC_TypeDef* ADCx…...

google谷歌gmail邮箱账号注册手机号无法进行验证怎么办?此电话号码无法用于进行验证 或 此电话号码验证次数太多

谷歌gmail邮箱账号注册手机号无法进行验证怎么办? 使用手机号码注册谷歌gmail邮箱账号时会遇到&#xff1a;此电话号码无法用于进行验证 或 此电话号码验证次数太多。造成注册google谷歌gmail邮箱账号受阻&#xff0c;无法正常完成注册。 谷歌Gmail邮箱账号正确的注册方法与教…...

Spring:IOC技术、Bean、DI

前言 Spring是一个开源的项目&#xff0c;并不是单单的一个技术&#xff0c;发展至今已形成一种开发生态圈。也就是说我们可以完全使用Spring技术完成整个项目的构建、设计与开发。Spring是一个基于IOC和AOP的架构多层j2ee系统的架构。 SpringFramework&#xff1a;Spring框架…...

目标检测与跟踪 (2)- YOLO V8配置与测试

系列文章目录 第一章 目标检测与跟踪 &#xff08;1&#xff09;- 机器人视觉与YOLO V8 目标检测与跟踪 &#xff08;1&#xff09;- 机器人视觉与YOLO V8_Techblog of HaoWANG的博客-CSDN博客3D物体实时检测、三维目标识别、6D位姿估计一直是机器人视觉领域的核心研究课题&a…...

【Leetcode】56.合并区间

一、题目 1、题目描述 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [ s t a r t i start_i start...

设置系统编码 Beta

在yolov5环境搭建过程中会遇到如下的编码错误警告&#xff1a; 这时&#xff0c;按住“ctrlc”中止进程&#xff0c;然后设置系统编码&#xff1a; 电脑右键属性打开&#xff1a; 重启之后等安装好了&#xff0c;记得回去把bae键取消。...

phpunit

composer地址&#xff1a;phpunit/phpunit - Packagist 官方文档:PHPUnit文档 – PHP测试框架 PHPUnit是一个框架&#xff0c;最为hyperf学习的补充学习&#xff0c;就不写这么细了。 估计写下安装和使用&#xff0c;具体学习内容看文档。 一、安装 需安装扩展&#xff1a;…...

html学习9(脚本)

1、<script>标签用于定义客户端脚本&#xff0c;比如JavaScript&#xff0c;既可包含脚本语句&#xff0c;也可通过src属性指向外部文件。 2、JavaScript最常用于图片操作、表单验证及内容动图更新。 3、<noscript>标签用于在浏览器禁用脚本或浏览器不支持脚本&a…...

SpringBoot整合Caffeine

一、Caffeine介绍 1、缓存介绍 缓存(Cache)在代码世界中无处不在。从底层的CPU多级缓存&#xff0c;到客户端的页面缓存&#xff0c;处处都存在着缓存的身影。缓存从本质上来说&#xff0c;是一种空间换时间的手段&#xff0c;通过对数据进行一定的空间安排&#xff0c;使得下…...

元宇宙虚拟展厅的特点是什么呢?优势有哪些?

元宇宙是一个很广阔的虚拟世界&#xff0c;它可以创造出更为丰富、沉浸式的体验&#xff0c;这种全新的体验为展览和艺术领域带来了更多的可能性&#xff0c;元宇宙虚拟展厅以其多样化、互动性、沉浸式展示的特点&#xff0c;带领大家进入一个虚拟现实的全新世界。 元宇宙虚拟展…...

Day11-Webpack前端工程化开发

Webpack 一 webpack基本概念 遇到问题 开发中希望将文件分开来编写,比如CSS代码,可以分为头部尾部内容,公共的样式。 JS代码也希望拆分为多个文件,分别引入,以后代码比较好维护。 本地图片,希望可以实现小图片不用访问后端,保存在前端代码中就可以了 运行程序时我…...

什么是函数式编程,应用场景是什么

什么是函数式编程&#xff0c;应用场景是什么 函数式编程和面向对象编程一样&#xff0c;是一种编程规范。强调执行的过程而非结果&#xff0c;通过一系列的嵌套的函数调用&#xff0c;完成一个运算过程。它主要有以下几个特点&#xff1a; 1.函数是"一等公民"&…...

Vue3之路由认识

回顾&#xff1a; 原来的vue2路由是通过this. r o u t e 和 t h i s . route和this. route和this.router来控制的。现在vue3有所变化&#xff0c;useRoute相当于以前的this. r o u t e &#xff0c;而 u s e R o u t e r 相当于 t h i s . route&#xff0c;而useRouter相当于t…...

P1775 石子合并(弱化版)(内附封面)

石子合并&#xff08;弱化版&#xff09; 题目描述 设有 N ( N ≤ 300 ) N(N \le 300) N(N≤300) 堆石子排成一排&#xff0c;其编号为 1 , 2 , 3 , ⋯ , N 1,2,3,\cdots,N 1,2,3,⋯,N。每堆石子有一定的质量 m i ( m i ≤ 1000 ) m_i\ (m_i \le 1000) mi​ (mi​≤1000)。…...

jmeter之接口测试(http接口测试)

基础知识储备 一、了解jmeter接口测试请求接口的原理 客户端--发送一个请求动作--服务器响应--返回客户端 客户端--发送一个请求动作--jmeter代理服务器---服务器--jmeter代理服务器--服务器 二、了解基础接口知识&#xff1a; 1、什么是接口&#xff1a;前端与后台之间的…...

webpack基础知识二:说说webpack的构建流程?

一、运行流程 webpack 的运行流程是一个串行的过程&#xff0c;它的工作流程就是将各个插件串联起来 在运行过程中会广播事件&#xff0c;插件只需要监听它所关心的事件&#xff0c;就能加入到这条webpack机制中&#xff0c;去改变webpack的运作&#xff0c;使得整个系统扩展…...

PHP使用PhpSpreadsheet实现导出Excel时带下拉框列表 (可支持三级联动)

因项目需要导出Excel表 需要支持下拉 且 还需要支持三级联动功能 目前应为PHPExcel 不在维护&#xff0c;固采用 PhpSpreadsheet 效果如图&#xff1a; 第一步&#xff1a;首先 使用composer 获取PhpSpreadsheet 我这里PHP 版本 7.4 命令如下&#xff1a; composer r…...

Openssh高危漏洞CVE-2023-38408修复方案

0x01 漏洞简述 2023年07月21日&#xff0c;360CERT监测发现OpenSSH发布了OpenSSH的风险通告&#xff0c;漏洞编号为CVE-2023-38408&#xff0c;漏洞等级&#xff1a;高危&#xff0c;漏洞评分&#xff1a;8.1。 OpenSSH 是 Secure Shell (SSH) 协议的开源实现&#xff0c;提供…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...