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 机制就使用到这种模式。

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

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

相关文章

QT以管理员身份运行

以下配置后&#xff0c;QT在QT Creator调试时&#xff0c;或者生成的.exe程序&#xff0c;都将会默认以管理员身份运行。 一、MSVC编译器 1、在Pro文件中添加以下代码&#xff1a; QMAKE_LFLAGS /MANIFESTUAC:\"level\requireAdministrator\ uiAccess\false\\" …

纯css实现登录表单动效

效果图&#xff1a; 代码展示 // 我这边用的是elementUI表单校验&#xff0c;更改的样式。 <el-form:model"form":rules"rules"ref"fromList":hide-required-asterisk"true"><el-form-item prop"account"><…

全网最强,Python接口自动化测试实战-接口参数关联(购物实例)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 什么是参数关联&a…

【2023年电赛国一必备】C题报告模板--可直接使用

任务 图1 任务内容 要求 图2 基本要求内容 图3 发挥部分内容 说明 图4 说明内容 评分标准 图5 评分内容 正文 &#xff08;部分&#xff09; 摘要 本实验基于TI公司的TM4C123GH6PM主控&#xff0c;结合OPA2337芯片和其他硬件模块&#xff0c;设计并制作了一种单相逆变器…

OceanBase上的泡泡玛特抽盒机,轻松应对百倍流量峰值

8月3日晚10点&#xff0c;近百万年轻人再次同时涌入泡泡玛特的抽盒机小程序&#xff0c;参加抢抽盲盒新品的狂欢。 每周四的这个时刻&#xff0c;都是对抽盒机系统的一次技术大考。这个考验不但影响着用户体验&#xff0c;也直接影响着泡泡玛特的业绩。据2022年年度财报&#…

EMS SQL Manager for MySQL Crack

EMS SQL Manager for MySQL Crack 用于MySQL的EMS SQL Manager是用于MySQL数据库管理和开发的高性能工具。它适用于4.1到最新版本的任何MySQL&#xff0c;并支持所有最新功能&#xff0c;包括MySQL触发器、视图、存储过程和函数、InnoDB外键、Unicode数据等。SQL Manager for M…

【java】【maven】【基础】MAVEN安装配置介绍

目录 1 下载 2 安装-windows为例 3 配置环境变量 3.1 JAVA_HOME 3.2 MAVEN_HOME 3.3 PATH 3.4 验证 4 MAVEN基础概念 4.1 仓库概念 4.2 坐标概念 4.2.1 打开网址 4.2.2 输入搜索内容junit 4.2.3 找到对应API名称点击 4.2.4 点击对应版本 4.2.5 复制MAVEN坐标 4.3 配置…

爬虫007_python中的输出以及格式化输出_以及输入---python工作笔记025

首先看输出 输出这里,注意不能直接上面这样,18需要转换成字符串 可以看到python中这个字符串和数字一起的时候,数字要转换一下成字符串. 然后这里要注意%s 和%d,这个s指的是字符串,d指的是数字 注意后面的内容前面要放个% ,然后多个参数的话,那么这里用(),里面用,号隔开 然…

windows服务器iis PHP套件出现FastCGI等错误解决方法汇总

如果您的服务器安装了PHP套件&#xff0c;出现了无法打开的情况&#xff0c;请参照如下办法解决&#xff1a; 首先&#xff0c;需要设置IIS允许输出详细的错误信息到浏览器&#xff0c;才好具体分析 错误一&#xff1a; 处理程序“FastCGI”在其模块列表中有一个错误模块“Fast…

新手用户选择阿里云服务器地域、实例、带宽、操作系统经验参考

无论是个人还是企业用户&#xff0c;部署自己的网站或者APP客户端、小程序等&#xff0c;都需要用到服务器&#xff0c;现在流行的都是使用云服务器&#xff0c;考虑到性价比大家现在都喜欢选择阿里云服务器。但是新手用户往往在面对阿里云服务器地域、实例、带宽、操作系统等众…

RTC晶振两端要不要挂电容

发现GD32的RTC晶振两端需要挂电容&#xff0c;STM32的RTC晶振两端不需要挂电容。 STM32的RTC晶振两端&#xff0c;不需要挂电容&#xff0c;这样晶振启振很容易&#xff0c;挂大了&#xff0c;却难启动&#xff0c;且温度越低&#xff0c;启动越难。 有人说负载电容为6pF的晶振…

SQL分类及通用语法数据类型

一、SQL分类 DDL: 数据定义语言&#xff0c;用来定义数据库对象&#xff08;数据库、表、字段&#xff09;DML: 数据操作语言&#xff0c;用来对数据库表中的数据进行增删改DQL: 数据查询语言&#xff0c;用来查询数据库中表的记录DCL: 数据控制语言&#xff0c;用来创建数据库…

Go语言开发者的Apache Arrow使用指南:读写Parquet文件

Apache Arrow是一种开放的、与语言无关的列式内存格式&#xff0c;在本系列文章[1]的前几篇中&#xff0c;我们都聚焦于内存表示[2]与内存操作[3]。 但对于一个数据库系统或大数据分析平台来说&#xff0c;数据不能也无法一直放在内存中&#xff0c;虽说目前内存很大也足够便宜…

SpringBoot

SpringBoot 微服务阶段 javase&#xff1a; OOPmysql&#xff1a;持久化htmlcssjsjquery框架javaweb&#xff1a;MVC 三层架构 的网站ssm&#xff1a;简化了开发流程 配置也相对复杂Spring&#xff1a;SpringBoot&#xff1a;内嵌Tomact 微服务架构springCloud SpringBoot S…

云原生全栈体系(二)

Kubernetes实战入门 第一章 Kubernetes基础概念 一、是什么 我们急需一个大规模容器编排系统kubernetes具有以下特性&#xff1a; 服务发现和负载均衡 Kubernetes 可以使用 DNS 名称或自己的 IP 地址公开容器&#xff0c;如果进入容器的流量很大&#xff0c;Kubernetes 可以负…

CSS调色网有哪些

本文章转载于湖南五车教育&#xff0c;仅用于学习和讨论&#xff0c;如有侵权请联系 1、https://webgradients.com/ Wbgradients 是一个在线调整渐变色的网站 &#xff0c;可以根据你想要的调整效果&#xff0c;同时支持复制 CSS 代码&#xff0c;可以更好的与开发对接。 Wbg…

经典CNN(三):DenseNet算法实战与解析

&#x1f368; 本文为&#x1f517;365天深度学习训练营中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊|接辅导、项目定制 1 前言 在计算机视觉领域&#xff0c;卷积神经网络&#xff08;CNN&#xff09;已经成为最主流的方法&#xff0c;比如GoogleNet&#xff0c;…

opencv 30 -图像平滑处理01-均值滤波 cv2.blur()

什么是图像平滑处理? 图像平滑处理&#xff08;Image Smoothing&#xff09;是一种图像处理技术&#xff0c;旨在减少图像中的噪声、去除细节并平滑图像的过渡部分。这种处理常用于预处理图像&#xff0c;以便在后续图像处理任务中获得更好的结果。 常用的图像平滑处理方法包括…

C++ 左值和右值

C 左值和右值 左值、右值左值引用、右值引用std::move()std::move()的实现引用折叠 完美转发forward()的实现函数返回值是左值还是右值如何判断一个值是左值还是右值 左值、右值 在C11中所有的值必属于左值、右值两者之一&#xff0c;右值又可以细分为纯右值、将亡值。在C11中…

OpenShot 发布 2.3.2 版本啦!

导读OpenShot 2.3.3 发布了&#xff0c;Openshot 是 linux 的 Gnome 桌面一个非线性视频编辑器&#xff0c;有许多功能&#xff1a;你可以重划大小&#xff0c;修剪或者剪切视频&#xff0c;同时有实时的预览&#xff0c;图片覆盖&#xff0c;标题模板&#xff0c;视频解码&…