Redis 完整

news2025/3/17 7:27:58

Redis

什么是 redis ?

是一种基于键值对的 NoSql 型数据库。与 hashMap 不同的是,Redis 中的 value 支持 string(字符串)、hash(哈希)、 list(列表)、set(集合)、zset(有序集合)、Bitmaps(位图)、GEO(地理信息定位)等多种数据结构。而 HashMap 只是 redis 中的 hash ,他们俩结构是相同的。

Redis 数据结构

Redis 有什么用

三分恶面渣逆袭:Redis的作用

缓存

redis 最常用的就是作为缓存。而之所以用 redis 作为缓存,是因为 redis 中的数据保存在内存之中,非常快,所以用 Redis 缓存可以极大地提高应用的响应速度和吞吐量。

排行榜/计数器

redis 中的数据结构 zset 适合去做排行榜的功能,同时原子递增可以实现计数器。

分布式锁

img

写文章-CSDN创作中心

Redis中的数据类型

String

可以用来存储任何类型的数据比如字符串、整数、浮点数、图片(图片的 base64 编码或者解码或者图片的路径)、序列化后的对象。

redis 自己构建的一种动态字符串。

有什么用:

字符串主要有以下几个典型的使用场景:

  • 缓存功能

  • 计数

  • 共享 Session

哈希

键值对集合,key 是字符串,value 是一个 Map 集合,比如说 value = {name: '沉默王二', age: 18},name 和 age 属于字段 field,沉默王二 和 18 属于值 value。

哈希类似于JDK 1.8之前的 HashMap ,底层实现都是数组加链表。

主要用于缓存对象和用户信息。

list

list 就是链表数据结构的实现,双向链表。

列表主要有以下两个使用场景:

  • 消息队列

  • 文章列表

Set

Set 像 Java 中的 hashSet。是无序集合,集合中的元素是唯一的,不允许重复。

基于 Set 轻易实现交集、并集、差集的操作,所以就可以实现一些共同关注,共同点赞的事。

sorted set

Zset,有序集合,比 set 多了一个排序属性 score(分值)。也就是说可以排序。

可以做排行榜。

Redis 线程模型

Redis为什么这么快//Redis的单线程模型

  1. 基于内存的数据存储。

    redis 中的数据都存储在内存之中,所以数据的读取更快。

  2. 单线程模型

    Redis 由于单线程模型,所以减少了锁竞争和线程切换带来的消耗。

  3. IO 复路

    IO 复路就是内核会一直监听socket的请求,谁有请求,就会将谁交给 redis 处理。

  4. 高效数据结构

    Redis 中的数据结构种类多,而且都经过优化。

IO 复路?

引用知乎上一个高赞的回答来解释什么是 I/O 多路复用。假设你是一个老师,让 30 个学生解答一道题目,然后检查学生做的是否正确,你有下面几个选择:

  • 第一种选择:按顺序逐个检查,先检查 A,然后是 B,之后是 C、D。。。这中间如果有一个学生卡住,全班都会被耽误。这种模式就好比,你用循环挨个处理 socket,根本不具有并发能力。

  • 第二种选择:你创建 30 个分身,每个分身检查一个学生的答案是否正确。 这种类似于为每一个用户创建一个进程或者- 线程处理连接。

  • 第三种选择,你站在讲台上等,谁解答完谁举手。这时 C、D 举手,表示他们解答问题完毕,你下去依次检查 C、D 的答案,然后继续回到讲台上等。此时 E、A 又举手,然后去处理 E 和 A。

第一种就是阻塞 IO 模型,第三种就是 I/O 复用模型。du

Linux 系统有三种方式实现 IO 多路复用:select、poll 和 epoll。

epoll 方式就是将用户的 socket 对应的 fd 注册进 epoll ,这样epoll 就可以监测用户信息是否到达,从而避免大量无效的无用操作。

为什么早期不用多线程||后面为什么又多线程

早期单线程

因为 Redis 是基于内存的,而多线程的目的是,让CPU资源得到充分利用。所以说没必要去利用多线程,本身就已经是基于内存的了。redis 的瓶颈最有可能是内存的大小或者网络限制。

后期多线程

后期多线程是为了提高网络 IO 能力,也就是提高了数据的读写能力,redis 的命令的执行仍然是单线程。/

这样做的⽬的是因为 Redis 的性能瓶颈在于⽹络 IO ⽽⾮ CPU,使⽤多线程能提升 IO 读写的效率,从⽽整体提⾼ Redis 的性能。

Redis 内存管理

关于过期时间

为什么要设置过期时间?

防止内存超出范围。

那怎么看出来一个键值对过没过过期?

利用的 hash 表,键保存的就是键值对的键值,value 是 longlong 类型的过期时间。

Redis 的过期数据回收策略有哪些?

  1. 惰性删除:访问 key 的时候,如果发现已过期,那么删除。如果一直不访问,可能一直不删除。对 CPU 友好,但是浪费内存资源

  2. 定期删除:定期的随机测试一些建,如果发现过期,那么删除过期的键。

  3. 延迟队列:将键都放进队列中,谁过期了,谁出去。这样能保证每个过期的键都能被删除,但是维护队列本身就很麻烦。

  4. 定时删除:为每个键都加一个定时器,如果时间到了就删除对应的键,但是这样对CPU 压力是最大的,因为要为每个键设置一个定时器。

Redis 中采用的是定期删除 + 惰性删除。

Redis 的内存淘汰策略

Redis 的内存是会发生不足的。那我们应该怎么解决?

Redis 内存不足的解决办法
  1. 修改配置文件,redis.conf 中的 maxmemory

  2. 也可以通过命令 set maxmemory 动态设置内存上限

  3. 修改内存淘汰策略

  4. Redis 集群

内存淘汰策略

当 Redis 所用内存达到 maxmemory 上限时,会触发相应的溢出控制策略。

Redis 提供了 6 种内存淘汰策略:

  1. volatile-lru(least recently used):从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰。

  2. volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰。

  3. volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰。

  4. allkeys-lru(least recently used):从数据集(server.db[i].dict)中移除最近最少使用的数据淘汰。

  5. allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰。

  6. no-eviction(默认内存淘汰策略):禁止驱逐数据,当内存不足以容纳新写入数据时,新写入操作会报错。

4.0 版本后增加以下两种:

  1. volatile-lfu(least frequently used):从已设置过期时间的数据集(server.db[i].expires)中挑选最不经常使用的数据淘汰。

  2. allkeys-lfu(least frequently used):从数据集(server.db[i].dict)中移除最不经常使用的数据淘汰。

Redis 持久化

RDB

RDB 是创建快照,每隔指定的一段时间创建快照然后保存到磁盘中的 RDB 文件中。

可以通过两种方式手动创建

  • save

  • bgsave、

以下场景会自动触发 RDB 持久化:

①、在 Redis 配置文件(通常是 redis.conf)中,可以通过save指令配置自动触发 RDB 持久化的条件。这个指令可以设置多次,每个设置定义了一个时间间隔(秒)和该时间内发生的变更次数阈值。

save 900 1
save 300 10
save 60 10000

这意味着:

  • 如果至少有 1 个键被修改,900 秒后自动触发一次 RDB 持久化。

  • 如果至少有 10 个键被修改,300 秒后自动触发一次 RDB 持久化。

  • 如果至少有 10000 个键被修改,60 秒后自动触发一次 RDB 持久化。

满足以上任一条件,RDB 持久化就会被自动触发。

②、当 Redis 服务器通过 SHUTDOWN 命令正常关闭时,如果没有禁用 RDB 持久化,Redis 会自动执行一次 RDB 持久化,以确保数据在下次启动时能够恢复。

③、在 Redis 复制场景中,当一个 Redis 实例被配置为从节点并且与主节点建立连接时,它可能会根据配置接收主节点的 RDB 文件来初始化数据集。这个过程中,主节点会在后台自动触发 RDB 持久化,然后将生成的 RDB 文件发送给从节点。

save

会同步的将数据集的快照存入磁盘中的 RDB 文件中。这个操作会阻塞所有客户端请求直到 RDB 文件被完全写入磁盘,会阻塞主线程。

bgsave

会异步的将数据集的快照存入磁盘中的 RDB 文件中。这个命令会立即返回,所以不会耽误Redis 的主线程。会 fork 出一个子线程去创建快照,子线程执行,不会阻塞主线程。

AOF

AOF 是通过将操作数据集的命令,追加到 AOF 文件后,如果需要持久化,在重新执行一遍 AOF 的命令。

流程
  • 命令追加:所有命令 append 到 AOF 缓冲区,这个缓存区在内存中,暂时存放命令。

  • 文件写入( write ):系统会将AOF缓冲区中的内容写入到AOF文件中。这个写入操作并不是立即完成的,而是先写入到操作系统的系统内核缓存中。此刻 write 方法被调用。

  • 文件同步:为了保证数据的安全性,需要将文件系统缓存中的数据真正地写入到磁盘上。可以通过修改配置中的 appendfsync 来决定同步策略:

    • always:每次写命令执行后都立即同步数据到磁盘。

    • everysec:每秒同步一次数据到磁盘。

    • no:由操作系统决定何时同步数据到磁盘。

  • 文件重写:随着 AOF 文件越来越大,文件是需要被重写的。AOF 重新会创建一个新的 AOF 文件,并且会遍历整个数据集,这个文件会包含重建数据库的最小数据集。在重写的过程中,命令还是会添加到旧的 AOF 文件中,但同时也会记录到缓冲区中,一旦重写完成,将被写入新的 AOF 文件。

    AOF 重写操作由 BGREWRITEAOF 命令触发,它会创建一个子进程来执行重写操作,因此不会阻塞主进程。

两种方式优缺点

AOF 相当于 RDB 来说,更灵活,实时性更好,可以设置不同的 fsync 策略,如每秒同步一次,每次写入命令就同步,或者完全由操作系统来决定何时同步。

RDB 更适合做备份数据。使用 RDB 文件恢复数据,直接解析还原数据即可,不需要一条一条地执行命令,速度非常快。而 AOF 则需要依次执行每个写命令,速度非常慢。也就是说,与 AOF 相比,恢复大数据集的时候,RDB 速度更快,但是可能会丢失最后一次快照之后的数据。

一般来说,要保证数据的安全性,两种方式应该结合使用。

如果发生故障,怎么恢复?

发生故障,可以RDB 或 AOF 恢复,将 RDB 或 AOF 文件拷贝到 Redis 数据目录下。如果使用 AOF 恢复,配置文件开启 AOF,然后启动 redis-server 即可。

具体:

如果都存在优先加载 AOF。

Redis 启动时加载数据的流程:

  1. AOF 持久化开启且存在 AOF 文件时,优先加载 AOF 文件。

  2. AOF 关闭或者 AOF 文件不存在时,加载 RDB 文件。

  3. 加载 AOF/RDB 文件成功后,Redis 启动成功。

  4. AOF/RDB 文件存在错误时,Redis 启动失败并打印错误信息

Redis4.0后的混合持久化

混合持久化是RDB在AOF 重写的时候生成一份快照,在持久化的时候,或者恢复数据时,先加载 RDB快照,然后再执行 AOF 文件中的命令,这样又快又不会丢失数据。

Redis 缓存设计

Redis 作为缓存的时候,会发生缓存击穿,缓存穿透,缓存雪崩三种问题。

缓存击穿

概念

某个热点数据,在某时刻过期,那么大量请求在缓存中找不到这个数据,那么请求就会直达数据库,数据库压力瞬间增大。

解决办法
  1. 互斥锁:给这个 key 加锁,使只能有一个线程访问 key,加载数据到缓存,其他请求等到缓存有之后,再去访问缓存。

  2. 使用异步的方式,不断刷新 key 的过期时间,或者干脆不设置过期时间。

缓存穿透

缓存穿透指的是一直查询一个数据库中不存在的数据,导致每次在缓存中都找不到,请求总是直达数据库。

解决办法
  1. 布隆过滤器:查询缓存前,利用布隆过滤器判断数据是否存在,如果不存在,直接返回,不进行查询。

  2. 空值缓存:当我们查询数据的时候,如果没在数据库内,那么我们在缓存中添加一个 key ,null 的键值对,并且设置一个较短的过期时间,来避免占用资源。

缓存雪崩

缓存雪崩是指在某一个时间点,由于大量的缓存数据同时过期或缓存服务器突然宕机了,导致所有的请求都落到了数据库上(比如 MySQL),从而对数据库造成巨大压力,甚至导致数据库崩溃的现象。

总之就是,崩了,崩的非常严重,就叫雪崩了(电影电视里应该看到过,非常夸张)。

解决办法
  1. 集群 Redis

  2. 备份缓存

  3. 设置不同的过期时间 (在原有的过期时间基础上 添加一个随机值)

  4. 限流与降级

    1. 可以用一些限流策略,例如令牌桶,从而限制访问流量。

    2. 可以降级,例如去关闭一些核心业务

如何保证缓存与数据库一致性

正常逻辑,如果只是读的话并不涉及一致性问题,但是如果写的话,需要考虑一致性问题。

在用 Redis 当缓存的时候,我们去更新数据库,总会造成缓存与数据库不一致的问题。

有两种处理方法:先处理缓存还是先操作数据库。

需要注意的是无论是哪种方法,都推荐删除缓存替代修改缓存,修改缓存成本更高,删缓存业务逻辑更简单。

先处理缓存
数据不一致

并发线程会导致数据不一致。

首先线程 1 发布了一个修改数据库的请求,于是他先清除 redis 中的缓存,然后更新数据库,但是更新的过程是需要一定时间,并且有网络延迟的。此时线程2发起查数据的请求,先查 redis 中的数据,redis 中没有,就查数据库,此时数据库还没更新完,还是脏数据。查数据库之后就要返回缓存到redis中,那么redis中还是脏数据,白删了。

解决方法(延迟双删)

redis 中还会出现脏数据,会导致后面的请求如果想查数据,返回的一直是错误的数据。

所以我们可以在数据库更新之后,再删一次 redis 中的缓存。这样只有线程2 一个线程读的是脏数据,其他之后的线程都是正确的数据。(无法保证强一致性)。

又因为更新数据库需要一定的时间,所以要等一段时间再次删除缓存,解决办法叫延迟双删。

强一致性

如果要保证强一致性,一次都不能错,那就只能加锁了,但是加锁会影响吞吐量,用redis 的目的就是增加吞吐量,所以一般不推荐这么做。

先处理数据库
数据不一致

先更新数据库,此时并发线程2查询数据,查询缓存,读出来的是脏数据。等更新完数据库,就删除 redis 缓存,此时如果有数据再读,redis 如果为空,查询数据库,数据库返回缓存到 redis ,之后的线程查询的就都是正确的了。

所以只有线程 2 读的是脏数据。

处理缓存和处理数据库都有的问题

删除失败怎么办?

如果删除失败的话读的一直是老数据,所以引入删除重试的机制。

通过异步请求的方式,发送消息将需要删除的 key 放入至 mq 之中,然后系统监听 mq,重新删除。

但是这个方法仍然有问题,mq 是放在整个流程内的,代码耦合度高,我们单独将它拿出来,可以利用cannal.

cannal 是阿里研发的,用途是基于 MySQL 增量日志,提供增量数据订阅和消费。cannal 客户端可以是一个 springboot 应用。也就是说我们将删除重试的操作放在 springboot 应用中去解决,解决了代码耦合度问题

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

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

相关文章

Kafka(十三)监控与告警

目录 Kafka监控与告警1 解决方案1.2 基础知识JMX监控指标代理查看KafkaJMX远程端口 1.3 真实案例Kafka Exporter:PromethusPromethus Alert ManagerGrafana 1.3 实际操作部署监控和告警系统1.2.1 部署Kafka Exporter1.2.2 部署Prometheus1.2.3 部署AlertManger1.2.4 添加告警规…

3D透视图转的时候模型闪动怎么解决?---模大狮模型网

在3D建模与渲染的世界中,透视图是我们观察和操作模型的重要窗口。然而,有时候在旋转透视图时,模型会出现闪动的现象,这不仅影响了我们的工作效率,还可能对最终的渲染效果产生负面影响。本文将探讨这一问题的成因&#…

【Text2SQL 经典模型】HydraNet

论文:Hybrid Ranking Network for Text-to-SQL ⭐⭐⭐ arXiv:2008.04759 HydraNet 也是利用 PLM 来生成 question 和 table schema 的 representation 并用于生成 SQL,并在 SQLova 和 X-SQL 做了改进,提升了在 WikiSQL 上的表现。 一、Intro…

WGCAT工单系统如何配置通知

WGCAT工单系统可以配置邮件通知 只要配置了邮件通知,那么一旦我们账号有新的工单需要处理,就会接受到邮件通知 除了邮件之外,还可以配置其他方式的通知,比如微信钉钉短信等方式,参考如下 https://www.wgstart.com/wgc…

Docker常用软件安装

文章目录 1.安装Tomcat1.docker hub查找镜像并复制拉取镜像命令2.拉取镜像到本地1.执行官网命令2.查看是否拉取成功 3.启动tomcat4.退出和重启1.由于是以交互方式启动的,所以不方便,直接ctrl c退出2.查看当前的容器3.使用docker start 命令启动容器&…

内外网文件传输安全可控的方式有哪些?这几款软件值得参考

在信息化时代,随着企业对网络安全和数据保护需求的日益增强,内外网隔离已成为一种常见的网络安全策略。内外网隔离旨在防止未经授权的访问和数据泄露,确保企业网络的安全稳定。然而,在实施内外网隔离的同时,如何实现文…

读书笔记-Java并发编程的艺术-第1章 并发编程的挑战

文章目录 1.1 上下文切换1.1.1 多线程一定快吗1.1.2 如何减少上下文切换 1.2 死锁1.3 资源限制的挑战 1.1 上下文切换 即时是单核处理器也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制。时间片是CPU分配给多个线程的时间,因为时间…

H3CNE-6-ICMP数据包分析

ICMP:Internet Control Message Protocol ICMP用来传递差错、控制、查询等信息 Wireshark抓包 Wireshark下载国内镜像 ICMP数据包格式 Type:表示ICMP消息类型 Code:表示同一消息类型中的不同信息 ICMP消息类型和编码类型 ICMP应用 &…

idea中显示git的Local Changes

1. 第一打开idea中的Settings文件 2. 找到Version Contro中的commint 3. 取消勾选应用即可 4. 本地提交就会显示出来

Python高级进阶--dict字典

dict字典⭐⭐ 1. 字典简介 dictionary(字典) 是 除列表以外 Python 之中 最灵活 的数据类型,类型为dict 字典同样可以用来存储多个数据字典使用键值对存储数据 2. 字典的定义 字典用{}定义键值对之间使用,分隔键和值之间使用:分隔 d {中…

【Linux网络编程】传输层中的TCP和UDP(TCP篇)

【Linux网络编程】传输层中的TCP和UDP(TCP篇) 目录 【Linux网络编程】传输层中的TCP和UDP(TCP篇)TCP协议TCP协议段格式确认应答(ACK)机制(保证可靠性)超时重传机制连接管理机制理解T…

“等保测评与安全运维的协同:保障企业网络安宁

"等保测评与安全运维的协同:保障企业网络安宁"是一个涉及信息安全领域的重要话题。这里,我们可以从几个方面来探讨这个主题。 1. 等保测评(等级保护测评) 等保测评,即信息安全等级保护测评,是依…

社交媒体数据恢复:连信

在使用连信的过程中,如果我们误删了重要的照片或者文件,可以通过以下步骤进行数据恢复: 一、有备份恢复 若你在删除之前已经备份了相关照片或文件,那么恢复起来就相对容易一些。以下是具体的恢复步骤: 登录连信账号&…

vue data中的return

vue 的data return 是干啥的呢,vue中页面中绑定的变量都要放在data的return中,可以赋值,值可在script中改,修改引用就用this了 如果不使用return包裹的数据会在项目的全局中可见,会造成变量污染; 使用retu…

虚拟机启动Operating System not found找不到操作系统

错误信息 PEX-E51 No SHCP or proxyDHCP offers were received. PXE-M0F: Exiting Intel PXE ROM. Operating System not found解决方法1 到服务里面检查跟vmware相关的服务是否已经全部启动 如果服务怎么都无法启动,最简单的办法还是重装vmware 解决方法2 &#…

音视频开发5 补充 - Nginx搭建rtmp流媒体服务器,目的是让ffmpeg 可以直播推流

直播推流 ffmpeg -re -i out.mp4 -c copy flv rtmp://server/live/streamName -re, 表示按时间戳读取文件 参考: Nginx 搭建 rtmp 流媒体服务器 (Ubuntu 16.04) https://www.jianshu.com/p/16741e363a77 第一步 准备工作 安装nginx需要的依赖包 打开 ubutun 终端…

2024年5月26日 十二生肖 今日运势

小运播报:2024年5月26日,星期日,农历四月十九 (甲辰年己巳月庚寅日),法定节假日。 红榜生肖:马、猪、狗 需要注意:牛、蛇、猴 喜神方位:西北方 财神方位:…

【2024最新华为OD-C卷试题汇总】传递悄悄话的最长时间(100分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 文章目录 前…

3.Redis之Redis的环境搭建redis客户端介绍

1.版本的选取 安装 Redis:Redis 5 系列~~ 在 Linux 中进行安装~~ Redis 官方是不支持 Windows 版本的~~ 微软维护了一个 Windows 版本的 Redis 分支 Centos和Ubuntu.Docker 2.如何进行安装??? 1.ubuntu 2.centos yum instal…

欧拉函数、快速幂、扩展欧几里得算法、中国剩余定理和高斯消元

欧拉函数 给定 n 个正整数 ai,请你求出每个数的欧拉函数。 欧拉函数的定义1∼N 中与 N 互质的数的个数被称为欧拉函数,记为 ϕ(N)。 若在算数基本定理中,Np1a11p2a2…pmm,则:ϕ(N) Np1−1/p1p2−1/p2…pm−1/pm 输…