复习第二章之Redis

news2024/11/17 16:54:39

一、什么是Redis

Redis 本质上是一个 Key-Value 类型的内存数据库,很像 memcached,整个 数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据 flush 到硬盘 上进行保存。因为是纯内存操作,Redis 的性能非常出色,每秒可以处理超过 10 万次读写操作,是已知性能最快的 Key-Value DB。

Redis 的出色之处不仅仅是性能,Redis 最大的魅力是支持保存多种数据结构,此外单 个 value 的最大限制是1GB,不像 memcached 只能保存 1MB 的数据,另外 Redis 也可以对存入的 Key-Value 设置 expire 时间。

Redis 的主要缺点是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此 Redis 适合的场景主要
局限在较小数据量的高性能操作和运算上。

二、Redis的数据类型

Redis 的数据结构有五种,分别是:

String——字符串
String 数据结构是简单的 key-value 类型,value 不仅可以是 String,也可以是数字(当数字类型用 Long 可以表示的时候 encoding 就是整型,其他都存储在 sdshdr 当做字符串)。

Hash——字典
在 Memcached 中,我们经常将一些结构化的信息打包成 hashmap,在客户端序列化后存储为一个字符串的值(一般是 JSON 格式),比如用户的昵称、年龄、性别、积分等。

List——列表
List 说白了就是链表(redis 使用双端链表实现的 List),相信学过数据结构知识的人都应该能理解其结构。

Set——集合
Set 就是一个集合,集合的概念就是一堆不重复值的组合。利用 Redis 提供的 Set 数据结构,可以存储一些集合性的数据。

Sorted Set——有序集合
和 Sets 相比,Sorted Sets 是将 Set 中的元素增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列,比如一个游戏的用户得分排行榜。
注意: 这里的Sorted Set有争议,也有人说是zset,但总的来说原理是一样的只是在叫法上有些不一样,也有可能是随着redis的更新所导致的名称的变换,有懂的人可以评论区留言交流一下。

2.1 Redis的使用场景

Redis(REmote DIctionary Server)是一个基于内存的高性能键值存储系统。由于其快速、可靠和灵活的特性,Redis 在各种场景下被广泛应用,包括以下几个常见的使用场景:

  1. 缓存(Caching):Redis 作为内存数据库,对于经常访问的数据进行缓存是它最常见的用途之一。通过将计算结果、数据库查询结果或经常使用的数据存储在 Redis 中,可以大大提高系统响应速度和吞吐量。Redis 提供了灵活的缓存策略和过期时间设置,以满足不同缓存需求。

  2. 分布式锁(Distributed Locking):Redis 提供了一种简单高效的方法来实现分布式锁。通过使用 Redis 的原子操作,比如 SETNX(set if not exist)命令,可以实现多个分布式节点之间的互斥访问,确保某个任务只能由一个节点处理。

  3. 会话存储(Session Storage):在分布式环境中,使用 Redis 储存和管理用户会话数据可以实现无状态应用。将用户的登录状态或其他会话数据存储在 Redis 中,使得不同节点之间可以共享会话状态,提高了系统的可伸缩性和容错性。

  4. 消息队列(Message Queue):Redis 的 Pub/Sub(发布/订阅)功能可以用作轻量级的消息队列系统。通过发布者将消息发送到指定的频道,订阅者可以实时获取到消息并进行处理。这种方式可用于实现异步消息传递、任务分发和事件驱动等应用。

  5. 计数器和统计信息(Counters & Statistics):Redis 提供了一些特殊的数据类型(如计数器和有序集合),可用于存储和操作计数器、计量数据和统计信息。它支持原子操作,可以快速地对计数器进行增减操作,并提供了方便的集合操作(如按范围获取数据、按权重排序)。

  6. 实时排行榜(Leaderboard):Redis 的有序集合数据类型可以用于创建实时排行榜。通过将用户的分数和标识存储在有序集合中,可以方便地进行排名、范围查询和 Top N 查询等操作,用于实现游戏排行榜、热门内容排名等功能。

除了以上场景,Redis 还可以用于实现分布式缓存、实时数据分析、时间序列数据存储等各种应用。由于 Redis 的高性能和丰富的功能,可以根据具体需求灵活地在各种场景下使用。

2.2 Redis的优缺点

优点:
a) 性能极高 – Redis 能支持超过 100K+ 每秒的读写频率。

b) 丰富的数据类型 – Redis 支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。

c) 原子 – Redis 的所有操作都是原子性的,同时 Redis 还支持对几个操作全并后的原子性执行。

attention 原子性定义:例如,A 想要从自己的帐户中转 1000 块钱到 B 的帐户里。那个从 A 开始转帐,到转帐结束的这一个过程,称之为一个事务。如果在 A 的帐户已经减去了 1000 块钱的时候,忽然发生了意外,比如停电什么的,导致转帐事务意外终止了,而此时 B 的帐户里还没有增加 1000 块钱。那么,我们称这个操作失败了,要进行回滚。回滚就是回到事务开始之前的状态,也就是回到 A 的帐户还没减 1000 块的状态,B 的帐户的原来的状态。此时A 的帐户仍然有 3000 块,B 的帐户仍然有 2000 块。我们把这种要么一起成功(A 帐户成功减少 1000,同时 B 帐户成功增加 1000),要么一起失败(A 帐户回到原来状态,B 帐户也回到原来状态)的操作叫原子性操作。如果把一个事务可看作是一个程序,它要么完整的被执行,要么完全不执行,这种特性就叫原子性。

d)丰富的特性 – Redis 还支持 publish/subscribe, 通知, key 过期等等特性。

缺点:
a)由于是内存数据库,所以,单台机器,存储的数据量,跟机器本身的内存大小。虽然 redis 本身有 key 过期策略,但是还是需要提前预估和节约内存。如果内存增长过快,需要定期删除数据。
b) 如果进行完整重同步,由于需要生成 rdb 文件,并进行传输,会占用主机的 CPU,并会消耗现网的带宽。不过 redis2.8 版本,已经有部分重同步的功能,但是还是有可能有完整重同步的。比如,新上线的备机。
c) 修改配置文件,进行重启,将硬盘中的数据加载进内存,时间比较久。在这个过程中,redis 不能
提供服务。

三、Redis常见的问题有哪些如何解决?

3.1 Redis 常见的性能问题都有哪些?如何解决?

(1)、Master 写内存快照,save 命令调度 rdbSave 函数,会阻塞主线程的工作,当快照比较大时对性能影响是非常大的,会间断性暂停服务,所以 Master 最好不要写内存快照。
(2)、Master AOF 持久化,如果不重写 AOF 文件,这个持久化方式对性能的影响是最小的,但是 AOF 文件会不断增大,AOF 文件过大会影响 Master 重启的恢复速度。Master 最好不要做任何持久化工作,包括内存快照和 AOF日志文件,特别是不要启用内存快照做持久化,如果数据比较关键,某个 Slave 开启 AOF 备份数据,策略为每秒同步一次。
(3)、Master 调用 BGREWRITEAOF 重写 AOF 文件,AOF 在重写的时候会占大量的 CPU 和内存资源,导致服务 load 过高,出现短暂服务暂停现象。
(4)、Redis 主从复制的性能问题,为了主从复制的速度和连接的稳定性,Slave 和 Master 最好在同一个局域网内。

3.2 Redis常见三大问题

在大多数互联网应用中,缓存的使用方式如下:
在这里插入图片描述
我们的查询操作在缓存上完成,而对数据的增删改则在数据库完成。

3.2.1 缓存穿透

业务系统要查询的数据根本就存在!当业务系统发起查询时,按照上述流程,首先会前往缓存中查询,由于缓存中不存在,然后再前往数据库中查询。由于该数据压根就不存在,因此数据库也返回空。这就是缓存穿透。
综上所述:业务系统访问压根就不存在的数据,就称为缓存穿透。

但是在如果大量查询数据库当中不存在的数据会怎么样呢?当然会导致数据库的崩溃。
解决方法:
它需要在缓存之前再加一道屏障,里面存储目前数据库中存在的所有key,如下图所示:

在这里插入图片描述
当业务系统有查询请求的时候,首先去BloomFilter中查询该key是否存在。若不存在,则说明数据库中也不存在该数据,因此缓存都不要查了,直接返回null。若存在,则继续执行后续的流程,先前往缓存中查询,缓存中没有的话再前往数据库中的查询。

这种方法适用于数据命中不高,数据相对固定实时性低(通常是数据集较大)的应用场景,代码维护较为复杂,但是缓存空间占用少。

3.2.2 缓存雪崩

缓存其实扮演了一个保护数据库的角色。它帮数据库抵挡大量的查询请求,从而避免脆弱的数据库受到伤害。

如果缓存因某种原因发生了宕机,那么原本被缓存抵挡的海量查询请求就会像疯狗一样涌向数据库。此时数据库如果抵挡不了这巨大的压力,它就会崩溃。

这就是缓存雪崩。缓存雪崩在实际当中不只会对数据库造成伤害,严重的话可能还会导致整个服务宕机,因为在具体的应用中服务可能是分布式的其中一台机器宕机可能会导致请求无法继续进行,进而导致整个服务宕机。

在这里插入图片描述
解决方法:
Hystrix是一款开源的“防雪崩工具”,它通过 熔断、降级、限流三个手段来降低雪崩发生后的损失。

Hystrix就是一个Java类库,它采用命令模式,每一项服务处理请求都有各自的处理器。所有的请求都要经过各自的处理器。处理器会记录当前服务的请求失败率。一旦发现当前服务的请求失败率达到预设的值,Hystrix将会拒绝随后该服务的所有请求,直接返回一个预设的结果。这就是所谓的“熔断”。当经过一段时间后,Hystrix会放行该服务的一部分请求,再次统计它的请求失败率。如果此时请求失败率符合预设值,则完全打开限流开关;如果请求失败率仍然很高,那么继续拒绝该服务的所有请求。这就是所谓的“限流”。而Hystrix向那些被拒绝的请求直接返回一个预设结果,被称为“降级”。

Hystrix是由Netflix开发的一款用于处理分布式系统之间的故障和延迟的开源库。它主要解决服务之间的依赖关系和网络调用的不可靠性,通过提供容错机制和断路器模式来提高系统的弹性和稳定性。

Hystrix的核心概念包括:

  1. 断路器(Circuit Breaker):Hystrix通过监控对远程服务的调用,当调用失败率超过事先设定的阈值时,会打开断路器,阻止对服务的请求,并返回预设的 fallback(回退)响应,避免继续对故障的服务进行调用,从而减少对故障服务的压力。

  2. 回退(Fallback):当断路器打开或远程服务调用失败时,Hystrix可以提供一个备选的回退响应,即返回一个默认值、缓存数据或执行一段备用逻辑,以保证系统的可用性,并进行适当的降级处理。

  3. 隔离策略(Isolation):为了提高系统的弹性和稳定性,Hystrix将每个远程服务的调用封装在独立的线程池中,以实现请求的隔离。这样可以避免一个故障服务的请求阻塞或影响其他服务。

  4. 超时控制(Timeout):Hystrix能够根据服务的响应时间设定超时时间,如果服务的响应时间超过设定的时间,则认为服务调用超时,触发回退逻辑。

  5. 实时监控和度量(Metrics):Hystrix提供了实时监控系统的功能,可以通过该功能收集和展示每个服务的调用指标、错误率、请求量、延迟等,以便于运维人员实时监控和调整服务的配置。

总结来说,Hystrix通过断路器、回退、隔离策略、超时控制和实时监控等机制,帮助开发人员构建弹性和可靠的分布式系统,使得系统能够更加优雅地处理分布式系统之间的故障和延迟。它与Spring Cloud等微服务框架结合使用,可以提供更完善的分布式系统解决方案。

3.2.3 缓存击穿

我们一般都会给缓存设定一个失效时间,过了失效时间后,该数据库会被缓存直接删除,从而一定程度上保证数据的实时性。

但是,对于一些请求量极高的热点数据而言,一旦过了有效时间,此刻将会有大量请求落在数据库上,从而可能会导致数据库崩溃。其过程如下图所示:
在这里插入图片描述
如果某一个热点数据失效,那么当再次有该数据的查询请求[req-1]时就会前往数据库查询。但是,从请求发往数据库,到该数据更新到缓存中的这段时间中,由于缓存中仍然没有该数据,因此这段时间内到达的查询请求都会落到数据库上,这将会对数据库造成巨大的压力。此外,当这些请求查询完成后,都会重复更新缓存。
解决方法:
加锁。
此方法只允许一个线程重建缓存,其他线程等待重建缓存的线程执行完,重新从缓存获取数据即可。

当第一个数据库查询请求发起后,就将缓存中该数据上锁;此时到达缓存的其他查询请求将无法查询该字段,从而被阻塞等待;当第一个请求完成数据库查询,并将数据更新值缓存后,释放锁;此时其他被阻塞的查询请求将可以直接从缓存中查到该数据。

当某一个热点数据失效后,只有第一个数据库查询请求发往数据库,其余所有的查询请求均被阻塞,从而保护了数据库。但是,由于采用了互斥锁,其他请求将会阻塞等待,此时系统的吞吐量将会下降。这需要结合实际的业务考虑是否允许这么做。

互斥锁可以避免某一个热点数据失效导致数据库崩溃的问题,而在实际业务中,往往会存在一批热点数据同时失效的场景。那么,对于这种场景该如何防止数据库过载呢?

设置不同的失效时间

当我们向缓存中存储这些数据的时候,可以将他们的缓存失效时间错开。这样能够避免同时失效。如:在一个基础时间上加/减一个随机数,从而将这些缓存的失效时间错开

关于缓存的三大问题参考自 缓存三大问题及解决方案大家可以去看原文,原文作者讲的更加细致。

3.3 数据库缓存数据同步问题

在这里插入图片描述

当我们使用缓存的时候,无可避免的会遇到这个问题。当我们在多线程的场景下遇到这个问题无论我们是先操作数据库还是操作缓存都会出现线程安全问题。
这个时候我们如何在保证CAP(一致性、效率、分区安全性)的前提下对缓存进行同步呢?

延时双删

在这里插入图片描述
延时指的是在数据库更改操作完成之后要等待一会,因为我们的数据库可能是主从模式或者是集群模式,读取数据的操作是在从数据库上完成的。所以我们要保证数据库的一致。

双删指的是两次删除缓存,第一次删除缓存是为了让线程直接去数据库查找,第二次删除则是为了保证数据的一致性;当我对数据库的修改并为未完成的时候数据被读回到缓存了怎么办呢?二次删除防止的就是这种情况。

当然这种方法只是保证了数据的最终一致性,如果对数据安全要求比较高的情况下,则需要通过加锁的方法,或者添加事务来解决数据一致性的问题了。也就是对CAP的取舍。

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

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

相关文章

华为流程体系:流程架构「OES方法」

目录 内容简介 OES方法 端到端的流程 专栏列表 CSDN学院 作者简介 内容简介 今天继续来谈谈华为流程体系中的流程架构。 在前期的内容已经介绍过 POS 流程架构的方法。 这里就先回顾一下 POS 方法的相关内容: 关于 POS,大家可以参看上面的这张图…

软件测试员的非技术必备技能

成为软件测试人员所需的技能 非技术技能 以下技能对于成为优秀的软件测试人员至关重要。 将您的技能组合与以下清单进行比较,以确定软件测试是否适合您 - 分析技能:优秀的软件测试人员应具备敏锐的分析能力。 分析技能将有助于将复杂的软件系统分解为…

Keepalived 在CentOS 7安装并配置监听MySQL双主

keepalived安装 MySQL双主配置请看这里:https://tongyao.blog.csdn.net/article/details/132016200?spm1001.2014.3001.5502 128、129两台服务器安装步骤相同,配置文件不同,下面有介绍。 1.安装相关依赖包,并下载keepalived安…

css 利用模糊属性 制作水滴

<style>.box {background-color: #111;height: 100vh;display: flex;justify-content: center;align-items: center;/* 对比度*/filter: contrast(20);}.drop {width: 150px;height: 159px;border-radius: 50%;background-color: #fff;position: absolute;/* 模糊 */filt…

如何用12306的积分买火车票

积分买的票是不允许退票的&#xff0c;所以最好自己买票的时候用。 积分获取 是根据价格*5&#xff0c;比如我买的是100元的票就可以获得500积分。

前端学习——Vue (Day8)

Vue3 create-vue搭建Vue3项目 注意要使用nodejs16.0版本以上&#xff0c;windows升级node可以西安使用where node查看本地node位置&#xff0c;然后到官网下载msi文件&#xff0c;在本地路径下安装即可 安装完可以使用node -v检查版本信息 项目目录和关键文件 组合式API - s…

Bean的加载方式

目录 1. 基于XML配置文件 2. 基于XML注解方式声明bean 自定义bean 第三方bean 3.注解方式声明配置类 扩展1&#xff0c;FactoryBean 扩展2,加载配置类并加载配置文件&#xff08;系统迁移) 扩展3&#xff0c;proxyBeanMethodstrue的使用 4. 使用Import注解导入要注入的bean…

【Liux下6818开发板(ARM)】触摸屏

(꒪ꇴ꒪ ),hello我是祐言博客主页&#xff1a;C语言基础,Linux基础,软件配置领域博主&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff01;送给读者的一句鸡汤&#x1f914;&#xff1a;集中起来的意志可以击穿顽石!作者水平很有限&#xff0c;如果发现错误&#x…

怎么通过通过 p 名称空间配置 bean以及怎么去引用/注入其它 bean 对象--ref和怎么去引用/注入内部 bean 对象-内部 bean 对象

&#x1f600;前言 本章是spring基于XML 配置bean系类中第2篇讲解怎么通过通过 p 名称空间配置 bean以及怎么去引用/注入其它 bean 对象–ref和怎么去引用/注入内部 bean 对象 &#x1f3e0;个人主页&#xff1a;尘觉主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0…

小白三步即可设置企业在线帮助中心?

设置企业在线帮助中心是提升客户服务质量和用户体验的重要举措。以下将介绍三个简单的步骤&#xff0c;帮助企业建立一个高效的在线帮助中心。 第一步&#xff1a;规划与设计 在设置企业在线帮助中心之前&#xff0c;需要进行一定的规划和设计工作&#xff0c;确保帮助中心能够…

MPAndroidChart学习及问题处理

1.添加依赖 项目目录->app->build.gradle dependencies {implementation com.github.PhilJay:MPAndroidChart:v3.0.3 }项目目录->app->setting.gradle dependencyResolutionManagement {repositories {maven { url https://jitpack.io }} }高版本的gradle添加依…

解决路由缓存问题

产生原因 路由只有参数发生变化时 会复用组件实例 解决 1.选择key 简单粗暴 2.选择beforeRouteUpdate钩子函数

【javaSE】 面向对象程序三大特性之继承

目录 为什么需要继承 继承的概念 继承的语法 注意事项 父类成员访问 子类中访问父类的成员变量 子类和父类不存在同名成员变量 子类和父类成员变量同名 访问原则 子类中访问父类的成员方法 成员方法名字不同 总结&#xff1a; 成员方法名字相同 总结&#xff1a; …

spider-flow可视化爬虫界面从入门到放弃

目录 下载编译部署官网地址编译部署启动 简单使用输出文件方式可以正常执行的任务 自定义任务获取小说名 总结 下载编译部署 官网地址 修改端口、数据库、存放地址、执行文件等配置&#xff08;前后端不分离&#xff0c;配置文件端口即页面登录端口&#xff09; spider-flow-w…

Vite+Vue3 开发UI组件库并发布到npm

一直对开源UI组件库比较感兴趣&#xff0c;摸索着开发了一套&#xff0c;虽然还只是开始&#xff0c;但是从搭建到发布这套流程基本弄明白了&#xff0c;现在分享给大家&#xff0c;希望对同样感兴趣的同学有所帮助。 目前我的这套名为hasaki-ui的组件库仅有两个组件&#xff0…

Meta AI研究团队新AI模型: Llama 2 大语言模型

Llama是Facebook Research团队开发的基础语言模型集&#xff0c;旨在提供广泛的语言理解能力。它基于转换器架构&#xff0c;参数范围从7B到65B。通过使用Llama模型&#xff0c;研究人员和开发人员可以构建更先进的自然语言处理系统。您可以在GitHub上找到相关的代码和资源&…

JIT 与 C#热更

JIT与AOT 一般程序运行有两种方式&#xff0c;静态编译与动态编译。 AOT: Ahead Of Time,预先&#xff08;静态&#xff09;编译 静态编译的程序&#xff0c;需要在执行之前全部翻译为机器码&#xff0c;运行前会使得程序安装时间相对较长&#xff0c;但程序运行的时候&#…

TDengine时区设置

一般来说&#xff0c;时序数据就是带有时间序列属性的数据。在处理时序数据时&#xff0c;TDengine有着自己独特的方式。但是如果没有正确理解TDengine在写入和查询上的行为&#xff0c;极可能会因为配置了错误的时区&#xff08;timezone&#xff09;&#xff0c;而导致写入和…

《怎样顺利通过答辩:论文答辩的策略与技巧》

最近在阅读《怎样顺利通过答辩这本书》&#xff0c;记录一下阅读获取的关键信息和心得。 目录 第一章 答辩是什么 在答辩前你需要做到以下几件事情&#xff0c;核查清单如下&#xff1a; 答辩根据考生及其研究的质量&#xff0c;服务于不同的目的&#xff1a; 通常意义上的…