Redis-1

news2024/12/25 8:50:41

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 {
    @Autowired
    private 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,也删除对应的 value
        if(exists(key)) redisTemplate.delete(key);
    }
    public boolean exists(String key){// 判断缓存中是否有对应的 value
    return 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 模板的所有 key
        return 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.coloradmin.cn/o/831904.html

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

相关文章

【从零开始学习JAVA | 第三十七篇】初识多线程

目录 前言&#xff1a; ​编辑 引入&#xff1a; 多线程&#xff1a; 什么是多线程&#xff1a; 多线程的意义&#xff1a; 多线程的应用场景&#xff1a; 总结&#xff1a; 前言&#xff1a; 本章节我们将开始学习多线程&#xff0c;多线程是一个很重要的知识点&#xff…

Java泛型(Generic)

文章目录 泛型概述泛型的引入 使用泛型举例集合中使用泛型 比较器中使用泛型相关使用说明自定义泛型结构自定义泛型类或泛型接口3.2.1 说明 自定义泛型方法举例练习 泛型在继承上的体现通配符的使用使用注意点有限制的通配符泛型应用举例 泛型概述 举例1&#xff1a;中药店&am…

第一章:继承

系列文章目录 文章目录 系列文章目录前言继承的概念及定义继承的概念继承定义定义格式继承关系和访问限定符继承基类成员访问方式的变化 基类和派生类对象赋值转换&#xff08;公有继承&#xff09;继承中的作用域派生类的默认成员函数继承与友元继承与静态成员不能被继承的类复…

学习系统编程No.35【基于信号量的CP问题】

引言&#xff1a; 北京时间&#xff1a;2023/8/2/12:52&#xff0c;时间飞逝&#xff0c;恍惚间已经来到了八月&#xff0c;给我的第一感觉就是快开学了&#xff0c;别的感觉其实没有&#xff0c;哈哈&#xff01;看着身边的好友网络相关知识都要全部学完了&#xff0c;就好像…

Linux系统---进程概念

文章目录 冯诺依曼体系结构操作系统(OS)进程的理解 进程状态 进程优先级 环境变量 进程地址空间 一、冯诺依曼体系结构 我们常见的计算机&#xff0c;如笔记本。我们不常见的计算机&#xff0c;如服务器&#xff0c;大部分都遵守冯诺依曼体系。 如图为冯诺依曼体系结构图&…

【BEV感知】2-BEV感知算法数据形式

文章目录 1 图像1.1 如何获取图像特征&#xff1f; 2 点云2.1 稀疏性2.2 无序性2.3 为什么要用点云&#xff1f;2.4 如何提取点云特征&#xff1f;Point-basedVoxel-based 3 图像点云 1 图像 图像是由相机生成的&#xff0c;是将三维世界中的坐标点&#xff08;单位为米&#…

I- yh的线段(2023河南萌新联赛第(四)场:河南大学)

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 yh喜欢好线段&#xff0c;好线段即两条线段相交且不与其他线段重合的线段。 两条线段[l1,r1]和[l2,r2]相交(如果存在至少一个x&#xff0c;使得l1≤x≤r1和l2≤x≤r2&#xff0c;则认为两个线段…

Linux运维面试题(四)之Linux服务管理

Linux运维面试题&#xff08;四&#xff09;之Linux服务管理 4.1 SSHSSH的登录验证方式SSH的登陆端口&#xff08;默认22&#xff09;和监听设置&#xff08;/etc/ssh/sshd_config&#xff09;SSH的登录用户限制(/etc/ssh/sshd_config PermitRootLogin)SSH的登录超时设置(/etc/…

软件测试之Docker常见问题汇总!附解决方法!

1、配置国内源进行docker安装&#xff0c;报错 HTTP Error 404 - Not Found 【整整200集】超超超详细的Python接口自动化测试进阶教程&#xff0c;真实模拟企业项目实战&#xff01;&#xff01; 原因&#xff1a; 由于配置国内镜像源时&#xff0c;把地址写错了&#xff0c;导…

使用火山云搜索ESCloud服务构建图文检索应用(以文搜图/以图搜图)

图文检索在生活中具有广泛的应用&#xff0c;常见的图片检索包括基于文本内容搜索和基于图片内容搜索。用户通过输入文字描述或上传图片就可以在海量的图片库中快速找到同款或者相似图片&#xff0c;这种搜索方式被广泛应用于电商、广告、设计以及搜索引擎等热门领域。 本文基…

Windows服务器中IIS部署图片文件夹—超详细图文

Windows服务器中IIS部署图片文件夹—超详细图文 注意&#xff1a;部署前请先安装IIS IIS安装步骤可参照&#xff1a;win11安装IIS步骤—图解_win11 iis_咏絮v的博客-CSDN博客 1、打开 IIS管理器—选择【网站】后右键【添加站点】 2、【添加网站】(填写网站名称/物理路径/IP地…

2023华数杯数学建模C题思路代码 母亲身心健康影响

C 题 母亲身心健康对婴儿成长的影响 母亲是婴儿生命中最重要的人之一&#xff0c;她不仅为婴儿提供营养物质和身体保护&#xff0c; 还为婴儿提供情感支持和安全感。母亲心理健康状态的不良状况&#xff0c;如抑郁、焦虑、 压力等&#xff0c;可能会对婴儿的认知、情感、社会行…

【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 配置…

计算机网络(4) --- 协议定制

计算机网络&#xff08;3&#xff09; --- 网络套接字TCP_哈里沃克的博客-CSDN博客https://blog.csdn.net/m0_63488627/article/details/132035757?spm1001.2014.3001.5501 目录 1. 协议的基础知识 TCP协议通讯流程 ​编辑 2.协议 1.介绍 2.手写协议 1.内容 2.接口 …

Vulnhub: blogger:1靶机

kali&#xff1a;192.168.111.111 靶机&#xff1a;192.168.111.176 信息收集 端口扫描 nmap -A -sC -v -sV -T5 -p- --scripthttp-enum 192.168.111.176 在80端口的/assets/fonts/目录下发现blog目录&#xff0c;访问后发现为wordpress 利用wpscan发现wordpress插件wpdisc…

WiFi爆破实战

提示&#xff1a;本文记录了博主的一次WiFi爆破实战 文章目录 写在前面一、将网卡连接Kali虚拟机二、网卡配置骤2.1 识别网卡2.2 净化环境2.3 启动监听2.4 探测周边WiFi 三、实施攻击3.1 对选定的目标WiFi实施监听3.2 发起DOS攻击3.3 实施爆破 写在最后 写在前面 提示&#xf…

LNMP搭建及论坛搭建

一、LNMP LNMP架构是目前成熟的企业网站应用模式之一&#xff0c;指的是协同工作的一整套系统和相关软件&#xff0c; 能够提供动态Web站点服务及其应用开发环境。LNMP是一个缩写词&#xff0c;具体包括Linux操作系统、nginx网站服务器、MySQL数据库服务器、PHP&#xff08;或…

实用,3分钟免费生成中小学新生录取查询系统

在新学期开始之际&#xff0c;作为招生负责人&#xff0c;您是否已经做好准备来迎接新学年的招生工作呢&#xff1f;录取新生所需的任务包括成绩信息的录入、招生要求的核对以及新生录取信息的查询公布&#xff0c;这些繁重的工作给负责招生的老师带来了巨大的压力和挑战。 为…

Dockerfile构建LNMP镜像

建立工作目录 [rootlocalhost ~]# mkdir lnmp [rootlocalhost ~]# cd lnmp/ 编写Dockerfile文件 [rootlocalhost lnmp]# vim Dockerfile [rootlocalhost lnmp]# ll 总用量 4 -rw-r--r--. 1 root root 774 8月 3 14:54 Dockerfile [rootlocalhost lnmp]# vim Dockerfile #基础…

2023年华数杯A题

A 题 隔热材料的结构优化控制研究 新型隔热材料 A 具有优良的隔热特性&#xff0c;在航天、军工、石化、建筑、交通等 高科技领域中有着广泛的应用。 目前&#xff0c;由单根隔热材料 A 纤维编织成的织物&#xff0c;其热导率可以直接测出&#xff1b;但是 单根隔热材料 A 纤维…