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

Redis 详解

简介

Redis 的全称是 Remote Dictionary Server,它是一个基于内存的 NoSQL(非关系型)数据库,数据以 键值对 存储,支持各种复杂的数据结构

为什么会出现 Redis?

Redis 的出现是为了弥补传统数据库在高性能要求下的不足传统的关系型数据库在读写速度、并发处理和扩展性上有时不能满足某些高并发场景的需求。尤其是在互联网应用中,对于海量数据的处理、低延迟和高吞吐量的要求越来越高,Redis 提供了一种高效且灵活的解决方案

Redis的作用

大量在以下方面使用:
缓存系统: Redis 经常被用作缓存数据库,减轻传统关系型数据库的压力,提升访问速度。例如,在 Web 应用中,Redis 可以缓存数据库查询结果,当用户请求相同的数据时,可以直接从 Redis 获取,而不需要每次都访问数据库。这样可以大幅提高响应速度和降低数据库负载

高性能的数据存储: Redis 是一个内存数据库,它将数据存储在内存中,因而读取和写入速度非常快。它也支持持久化功能,可以定期将数据存储到硬盘上,避免丢失数据。

消息队列Redis 支持发布/订阅模式以及基于列表的数据结构,可以用作消息队列系统处理高并发的消息传递。例如,生产者将消息写入 Redis 队列,消费者从队列中获取消息进行处理,支持高效的异步任务处理。

分布式锁: Redis 提供了分布式锁的实现,可以解决多个进程或服务对同一资源的并发控制问题确保在分布式环境下只有一个线程能够执行特定的操作

实时分析和计数: Redis 可以处理实时的数据分析和计数,比如网站访问量统计、实时数据处理等。它的高性能使得它能够在大规模、高并发的环境下工作。

Redis的特点:

高性能:Redis 是内存存储,数据操作速度极快,读写性能远高于传统的磁盘数据库。
持久化:虽然 Redis 是内存数据库,但它提供了数据持久化的机制,可以将内存中的数据异步地保存到硬盘,防止数据丢失。
丰富的数据类型:Redis 支持多种复杂的数据结构,如字符串、哈希、列表、集合、排序集合等。
原子操作:支持原子操作,可以通过管道(Pipelining)方式批量执行多个命令。
发布/订阅模式:支持消息队列模式,可以实现不同服务之间的异步通信。
高可用与分布式:通过 Redis 的主从复制、哨兵模式以及集群模式,可以实现高可用性和水平扩展

Redis的常用数据类型:

常用类型有String,list,hash,set,zset
高级类型Bitmap(位图)、HyperLogLog、Geospatial(地理位置)、Streams(流)

String(字符串):

最简单的类型,一个字符串最多可以是 512MB。

使用场景
缓存:比如缓存用户的会话信息、网页、API 响应等。
计数器:通过 INCR 或 DECR 命令可以很方便地实现简单的计数器(例如访问量、点赞数等)。
限流:通过字符串类型和 INCR 命令,可以实现请求次数的计数,用于实现 API 的限流。

List(列表):

按插入顺序存储多个字符串。

使用场景:
消息队列:利用 Redis 列表,可以实现一个高效的消息队列。比如生产者将消息推送到列表的一端,消费者从另一端弹出并处理消息。
任务调度:可以将待处理的任务以列表形式存储,消费者通过从队列中弹出任务来进行处理。

Set(集合):

存储不重复的字符串元素。

使用场景
去重:适用于需要去重的场景,比如存储用户的浏览记录或点赞信息。
标签或兴趣管理:比如管理用户兴趣标签,用户可以关注不同的兴趣,而集合确保每个兴趣标签只会出现一次。
推荐系统:通过集合的交集、并集等操作,可以实现推荐系统的功能,例如找出共同兴趣的用户。

Sorted Set(有序集合):

和 Set 类似,但每个元素都有一个分数,可以根据分数对元素进行排序。

使用场景
排行榜:例如网站的用户积分排行榜,玩家的游戏得分排行榜,Redis 会自动根据分数排序并提供快速查询。
实时推荐:根据用户活跃度、评分等进行动态排序,并实时更新推荐结果。
限时优惠:可以存储和查询具有过期时间的优惠活动信息,例如商场的打折商品列表。

Hash(哈希):

存储键值对的集合,适合存储对象。

使用场景:
用户信息存储:可以存储一个用户的各种属性(例如用户的姓名、年龄、邮箱等)。每个属性对应哈希中的一个字段。
配置项:存储一些系统的配置信息,便于快速读取和修改。

持久化

redis是数据存储在内存中,那么如果服务器重启之后或者redis崩溃之后数据不就丢失了吗
所以redis为了防止这种情况支持多种持久化方式,以便在服务器重启后仍然能够恢复数据。Redis 主要有两种持久化方式:**RDB(快照持久化)**和 AOF(追加文件持久化)。这两种持久化方式可以单独使用,也可以结合使用。

RDB(快照持久化)

RDB 是 Redis 的默认持久化方式,它通过在指定时间点生成数据库的快照来实现持久化。快照是一个包含所有 Redis 数据的二进制文件,通常是 .rdb 文件

工作原理:
Redis 会根据配置定期执行“生成快照”的操作,将当前内存中的数据保存到硬盘上的 RDB 文件中。

默认情况下,可以配置触发快照的条件,如某个时间内有多少次写操作,或者某段时间内数据是否发生了变化等。
RDB 文件存储的是 Redis 的完整数据快照,而不是增量更新。

优点:
快照生成过程相对较快
数据文件较小,适合用于数据恢复。
不会影响 Redis 的读写操作,因为生成快照时 Redis 会通过 **fork(多进程)**创建子进程。

缺点
如果 Redis 在生成快照期间崩溃可能会丢失未写入磁盘的数据。
恢复速度可能较慢,特别是在数据量很大的时候

配置:在 redis.conf 配置文件中,常见的 RDB 配置项如下:

save 900 1      # 900秒内有1次写操作时生成快照
save 300 10     # 300秒内有10次写操作时生成快照
save 60 10000   # 60秒内有10000次写操作时生成快照

RDB 快照的生成和覆盖过程

假设你设置 Redis 每 1 分钟生成一个 RDB 快照:

第一分钟:假设数据库有 3 条记录,RDB 会生成包含这 3 条记录的快照文件。此时,dump.rdb 文件中包含了这 3 条记录。

第一到第二分钟之间新增了 5 条记录:在第二分钟到来时,Redis 会根据配置的策略生成新的 RDB 快照。新的快照会覆盖掉上一个快照,并且这次的快照会包含所有的记录,包括之前的 3 条和新增的 5 条记录。所以此时,新的 RDB 文件会包含 8 条记录。

第二到第三分钟之间新增了 7 条记录:如果 Redis 在此时崩溃或重启,RDB 文件会保留最后一次成功生成的快照,也就是第二分钟时的 8 条记录,而不会包含第三分钟内新增的 7 条记录。

总结:RDB 文件确实是每次生成快照时覆盖之前的文件。即使 Redis 崩溃后重启,它也只会恢复到最后一次成功保存的快照,这可能导致部分数据丢失,尤其是在上次快照之后发生的修改数据,这就是为什么RDB效率高,但是不安全

AOF(追加文件持久化)

AOF 通过记录所有的写操作(每次修改数据的命令)到一个日志文件中来实现数据持久化。这个文件通常是 appendonly.aof

工作原理:
Redis 会将每个写操作(如 SET、HSET 等)追加到 AOF 文件中,这些操作在 Redis 重启后会重新执行以恢复数据。

AOF 文件会包含所有的写操作,Redis 会按照命令顺序依次执行,从而恢复出原来的数据。

AOF 提供了三种不同的同步策略
always每次操作后都将命令写入 AOF 文件,性能最差,但数据安全性最好。
everysec每秒钟将 AOF 文件写入一次,是默认选项,兼顾性能和数据安全。
no完全不进行同步,性能最好,但可能丢失所有未同步的数据。

优点
提供更高的数据安全性,AOF 可以保证数据尽可能不丢失
可以配置同步策略,灵活调整性能和持久化的安全性。

缺点:
AOF 文件会随着写操作的增多而变得较大
由于每次写操作都需要记录到文件中,AOF 会对性能产生一定的影响。
Redis 重启时,恢复过程可能比 RDB 更慢,尤其是在写操作很多的情况下。

配置:在 redis.conf 配置文件中,常见的 AOF 配置项如下:

appendonly yes           # 启用 AOF 持久化
appendfsync everysec     # 每秒同步一次 AOF 文件
no-appendfsync-on-rewrite yes # 重写期间不进行同步

RDB + AOF 混合持久化

Redis 允许同时开启 RDB 和 AOF 持久化,这样可以利用两者的优点,避免单独使用时的缺点。

自redis4之后对更改了RDB + AOF 混合持久化的流程

混合持久化的基本流程
  1. 判断是否开启 AOF 持久化:如果 Redis 配置中开启了 AOF 持久化,Redis 会继续执行混合持久化的后续流程;如果未开启 AOF,Redis 会直接加载 RDB 文件进行恢复。
  2. 检查 appendonly.aof 文件是否存在
    如果 AOF 文件存在,Redis 会继续执行混合持久化恢复流程。
    如果 AOF 文件不存在,Redis 会直接加载 RDB 文件进行恢复。
  3. 判断 AOF 文件是否包含 RDB 格式数据
    Redis 会检查 AOF 文件的开头是否是 RDB 格式的数据头。这个特性是混合持久化的关键。
    如果 AOF 文件的开头包含 RDB 格式的数据,Redis 会首先加载这些 RDB 数据,然后继续加载 AOF 文件中剩余的操作日志。
    如果 AOF 文件的开头没有 RDB 格式数据,Redis 会直接加载整个 AOF 文件。
混合持久化的文件结构

在 Redis 4.0 之后,混合持久化将 RDB 数据和 AOF 日志存放在同一个文件中。这意味着 Redis 在生成持久化文件时,会先生成一个 RDB 快照(通常是某个时间点的全量快照),然后将自上次持久化以来的增量写操作(AOF)追加到这个文件中。这个文件是一个混合文件,它包含了两部分内容:

RDB 格式数据:在混合持久化文件的开头部分,包含了当前数据库的 RDB 快照内容。这个部分的数据格式与普通的 RDB 文件相同。

AOF 格式的增量操作:在 RDB 数据之后,紧跟着是自上次 RDB 持久化之后发生的增量操作,这部分是 AOF 格式的,记录了每个写操作(如 SET、DEL 等)。

具体的存储方式

假设你设置了每 1 分钟生成一个 RDB 快照,而每分钟新增 5 条数据。混合持久化在生成文件时的存储内容大致如下:

假设场景:
每 1 分钟生成一个 RDB 快照。
每分钟新增 5 条数据,假设这些数据的操作是 SET key:value(这里以 5 条为例)。
混合持久化文件的结构:
第 1 分钟的 RDB 快照:在文件的开头会有一个完整的 RDB 格式的快照,包含你数据库的所有数据(比如 10 条记录)。

这部分数据是全量快照,比如:

RDB header
数据条目 1 (key1: value1)
数据条目 2 (key2: value2)
...
数据条目 N (keyN: valueN)

自上次 RDB 快照之后的增量 AOF 操作:在 RDB 快照之后,会有一段 AOF 格式的增量操作,这部分操作会记录每一个写操作。

假设在第 1 分钟到第 2 分钟之间新增了 5 条数据(SET key1 value1, SET key2 value2, …),那么在混合持久化文件中会紧跟 RDB 数据之后记录这些操作:

AOF操作 1 (SET key1 value1)
AOF操作 2 (SET key2 value2)
AOF操作 3 (SET key3 value3)
AOF操作 4 (SET key4 value4)
AOF操作 5 (SET key5 value5)

然后里面的格式大致如下

RDB快照:
key1: "value1"
key2: "value2"
key3: "value3"

AOF增量操作:
SET key4 "value4"
SET key5 "value5"
SET key6 "value6"
SET key7 "value7"
SET key8 "value8"

下一个 RDB 快照:在第 2 分钟时,Redis 会生成一个新的 RDB 快照,这时会记录整个数据库的当前状态(例如,除了第 1 分钟的 10 条记录外,再新增了 5 条)。这个快照会覆盖前一个 RDB 快照。

自第 2 分钟以来的增量 AOF 操作:在第 2 分钟到第 3 分钟之间新增的 5 条数据,也会记录在增量 AOF 部分。

总结

混合持久化将 RDB 快照 和 增量 AOF 操作 存放在同一个文件中。
RDB 文件存储的是一个完整的数据库快照,而AOF 文件存储的是自上次 RDB 快照后的增量操作(如每个 SET、DEL 等命令)。
在 Redis 重启时,Redis 会先加载 RDB 快照文件,恢复大部分数据,然后根据增量 AOF 操作补充那些在 RDB 快照之后的修改操作,从而恢复到最后的数据库状态。

问题

为什么 RDB 生成效率更快?

RDB 是通过生成一个数据库的“快照”来实现数据持久化的。具体来说,Redis 会将当前内存中的数据存储到一个二进制的 .rdb 文件中。这个过程是由 Redis 的子进程(通过 fork 创建)来执行的主进程继续处理客户端的请求。快照生成时,子进程会复制当前的内存数据并保存到磁盘。

RDB 更高效的原因

RDB 是通过一次性保存所有数据的快照来实现持久化的,整个过程是比较简单且高效的,尤其是在数据量比较小或保存间隔较长时。
生成快照的过程不会影响 Redis 主进程的性能,因为它是通过 fork 创建子进程的,主进程不需要等待子进程的写入操作,从而可以继续响应客户端请求。
但是,需要注意的是,RDB 生成快照的过程在数据量比较大的时候可能会变得较慢,因为它需要将所有数据(无论是大还是小)都写入硬盘。

AOF 为什么更安全?

AOF 是通过将每个写操作(如 SET、HSET 等)追加到日志文件中来记录数据。每次写操作发生时,Redis 会将相应的命令记录到 AOF 文件中,从而确保可以在 Redis 重启时通过重新执行这些命令恢复数据。

AOF 更安全的原因:

AOF 提供了三种不同的同步策略,可以精确控制数据持久化的安全性。特别是 appendfsync always(每次写操作都同步到磁盘)能够最大程度地保证数据不会丢失。
即便 Redis 崩溃,AOF 文件也能记录所有的写操作,因此通过重放 AOF 文件中的命令可以恢复所有的操作。
AOF 的安全性来源于它记录了每一个写操作,在 Redis 重启时,只需要按顺序执行这些操作,就可以精确地恢复数据。

重写AOF
为什么要重写AOF

首先,AOF 文件记录了所有的写操作,包括 SET、HSET、DEL 等命令。这意味着每个写操作(无论是插入、修改还是删除)都会被记录下来。而因为 Redis 是一个高性能的内存数据库,通常对数据进行频繁的修改,比如 SET 命令可能会多次修改相同的键值

这样,随着时间的推移,AOF 文件会记录下大量的“修改操作”,这些操作的执行结果有可能是“覆盖之前的数据”,但是它并不意味着那些修改操作本身是必要的。实际上,我们可以通过重写 AOF 文件来去掉这些不必要的操作,保留最新的数据状态

因此为什么需要 AOF 重写?
AOF 重写的目的是: 缩小文件的大小,同时去除不必要的历史修改操作(例如,某个键的多个 SET 操作),确保 AOF 文件只记录当前数据的最终状态,而不需要记录每一步修改。通过这种方式,AOF 文件的大小可以被有效控制。

举个例子:
假设有以下操作序列:

SET key “hello”
SET key “world”
DEL key
假设你的 key 原始值是 “hello”,然后它被 SET 改为 “world”,最后被删除。如果不进行重写,AOF 文件会记录三条命令:

SET key "hello"
SET key "world"
DEL key

但是在 Redis 重新启动时,这三条命令会依次执行,导致 “world” 变成了 nil(因为最后是删除操作)。实际上,你只需要在 AOF 文件中保留一个DEL key 操作,而不需要再保留之前的 SET 操作。

AOF 重写过程:
重写过程中,Redis 会重新扫描当前的数据库状态,并生成一个新的 AOF 文件,其中仅记录恢复当前数据所必需的最少命令。
比如,AOF 重写后,新的文件可能只包含 DEL key,因为这是恢复当前状态的唯一必要命令。
通过 AOF 重写,Redis 会减少不必要的历史修改操作,从而减少文件大小。

缓存问题

咱们使用redis的时候经常作为缓存,因为是内存数据库具有高性能,但是作为缓存会有以下问题,所以设计的时候需要考虑到以下场景的情况

缓存穿透、缓存击穿、缓存雪崩

缓存穿透

定义:
缓存穿透是指请求的数据在缓存中没有命中,并且请求的数据在数据库中也不存在。也就是说,缓存没有这个数据,数据库查询也没有这个数据。由于没有缓存,可以直接访问数据库,导致大量无效请求打到数据库,造成数据库压力,无法利用缓存的优势。

为什么会有缓存穿透:
不存在的数据:有些请求可能查询的是根本不存在的数据(例如恶意请求、非法请求等)。
缓存未命中:缓存中的数据不存在或已过期,因此会查询数据库。

解决方案:

缓存空数据:

对于查询结果为空的数据(即数据库没有这个数据),可以在缓存中也存一个空值,设置一个较短的过期时间。这样,下次如果再有相同的请求,就能从缓存中直接返回空值,避免再次访问数据库。

前端防护:

通过接口层或前端校验来过滤非法请求,确保不向缓存或数据库发送无效请求。

缓存击穿(Cache Breakdown)

定义:
缓存击穿是指某一时刻,大量请求访问一个过期的缓存数据,也叫热点数据,而缓存数据已经过期或失效。此时,所有的请求都会直接访问数据库,导致数据库瞬间压力增大,性能下降

解决方案:

互斥锁机制:

在缓存过期时,只允许一个请求去查询数据库并更新缓存,其它请求需要等待。

代码

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class CacheBreakdownSolution {

    private RedisClient redisClient;
    private DatabaseClient databaseClient;
    private Lock lock = new ReentrantLock();

    public String getData(String key) {
        // 先尝试从缓存中获取数据
        String cacheValue = redisClient.get(key);
        
        if (cacheValue == null) {  // 如果缓存中没有数据
            lock.lock();  // 获取锁,防止多个线程同时查询数据库
            try {
                // 再次检查缓存是否已经被其他线程填充
                cacheValue = redisClient.get(key);
                if (cacheValue == null) {
                    // 查询数据库
                    String dbValue = databaseClient.query(key);
                    if (dbValue == null) {
                        redisClient.set(key, "empty", 60);  // 缓存空数据
                        return null;
                    }
                    redisClient.set(key, dbValue, 3600);  // 缓存数据
                    return dbValue;
                }
            } finally {
                lock.unlock();  // 释放锁
            }
        }
        return cacheValue;  // 如果缓存中有数据,直接返回
    }
}

延长过期时间

通过延长热点数据过期时间,减少发生的概率

缓存雪崩

定义
缓存雪崩是指在同一时刻,大量缓存数据集中失效(比如缓存批量过期),这时大量请求直接访问数据库,导致数据库承受巨大压力,甚至崩溃。
可能情况:
缓存同时过期:如果大量缓存设置了相同的过期时间,缓存一旦失效,就会在同一时刻大量过期,从而导致大量请求直接访问数据库。

解决方案

设置不同的过期时间:

避免所有缓存设置相同的过期时间,可以给不同的数据设置不同的过期时间,降低缓存同时过期的概率。

使用永不过期的缓存:

对于某些数据,可以通过将缓存设置为永不过期,避免频繁失效,但需要定期通过后台线程或任务来清理过期的数据。

预热缓存
降级机制:

当缓存失效并且访问量较大时,可以设计降级机制,对于一些不重要的数据返回默认值或者静态页面,减少数据库的负载。

部署模式

常见的部署模式包括 单机模式、主从模式、哨兵模式 和 集群模式。每种模式适用于不同的场景

单机模式

特点:单机模式是 Redis 最简单的部署方式,所有数据都存储在一个 Redis 实例中,只有一个 Redis 进程在运行。
用途:适用于数据量较小,或者对高可用性和扩展性要求不高的场景。通常用于开发和测试环境,或者一些简单的小型应用。

主从复制

特点:主从模式下,存在一个主节点(Master)和多个从节点(Slave)。主节点负责写操作和数据更新,而从节点负责读取数据,且从节点会从主节点同步数据。主从模式提高了读取性能,但主节点的故障会导致整个系统不可用。
用途:适用于读取压力较大的场景,通过从节点分担读取压力,提高读取性能。数据的高可用性较低,因为如果主节点宕机,从节点只能继续提供读服务,无法进行写操作。
使用场景:适用于读多写少的应用场景,例如缓存、日志存储、排行榜等。

配置方法:从节点通过 slaveof 指令指定主节点。 在从节点的 redis.conf 配置文件中,加入以下配置:

slaveof <master-ip> <master-port>

也可以运行直接使用命令

redis-server --slaveof <master-ip> <master-port>

哨兵模式

特点:哨兵模式是 Redis 为了实现高可用性而提供的解决方案。哨兵(Sentinel)是一个独立的进程,它监控 Redis 实例的状态。如果主节点宕机,哨兵会自动选举一个从节点提升为主节点,并通知客户端新的主节点地址。哨兵还可以提供自动故障转移和配置更新。
用途:适用于要求高可用性的场景,通过自动故障转移来保证系统的稳定性。在主节点发生故障时,不会影响系统的正常运行。
使用场景:适用于生产环境中需要高可用的应用,尤其是对数据写入要求较高的场景,如分布式系统、实时数据处理等。

配置方法:每个哨兵需要独立的配置文件。配置文件名通常为 sentinel.conf,并在文件中指定监控的主节点。

创建一个哨兵配置文件 sentinel.conf,并在文件中配置要监控的主节点信息:

sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1

解释:
mymaster 是要监控的主节点名称。
127.0.0.1 和 6379 是主节点的 IP 地址和端口。
2 是最少的哨兵数(需要多少个哨兵同意才能执行故障转移)。
down-after-milliseconds 是判定主节点宕机的时间。
failover-timeout 和 parallel-syncs 分别设置故障转移的超时和同步数量。

其中为什么不配置从节点,因为哨兵模式是基于主从模式的,我们知道主节点之后就知道从节点了

启动多个哨兵来提供冗余和容错能力:

redis-server /path/to/sentinel1.conf --sentinel
redis-server /path/to/sentinel2.conf --sentinel

集群模式(Cluster)

**主从和哨兵都没有解决一个问题:单个节点的存储能力和访问能力是有限的。**集群模式把数据进行分片存储。集群的键空间被分割成16384个slots(即hash卡槽),通过hash的方式将数据分到不同的分片上。某个主节点宕机,那这个主节点下的从节点会通过选举产生一个主节点,替换原来的故障节点

特点:集群模式是 Redis 为了解决水平扩展(sharding)问题而设计的。它将数据分布到多个 Redis 节点上,通过哈希槽(Hash Slot)将数据分散到不同的节点。集群模式支持自动分片、自动故障转移等特性,支持多个主节点和从节点,具有较高的扩展性和可用性。
用途:适用于数据量大、需要水平扩展的场景,能够提供更高的性能和可用性。集群模式通过分片来提高存储容量和处理能力。
使用场景:适用于需要大规模数据存储、高并发访问的应用,如社交网络、大数据分析、推荐系统等。

为什么Redis处理速度快

主要是Redis有一些4个特征

  1. 内存存储
  2. 单线程
  3. 多路i/o复用
  4. 数据结构

内存存储:

内存访问速度:内存是计算机中 最快的存储介质,其读取速度和写入速度非常高,通常在纳秒级别(ns)。内存是直接由 CPU 控制的,数据可以直接被读取到 CPU 中进行处理,不需要额外的操作。
磁盘访问速度:与内存相比,传统的硬盘(特别是机械硬盘)访问速度慢得多。机械硬盘的读写速度通常在毫秒级(ms)或微秒级(µs),远远慢于内存。即使是 固态硬盘(SSD),它的访问速度也只能达到内存的一个较低级别,大约是纳秒级的数千倍到万倍,虽然 SSD 要比传统硬盘快,但还是不及内存。

单线程

Redis在设计过程中使用的是单线程,为什么不使用多线程?
首先,Redis 使用的是 单线程模型。所有的客户端请求都通过一个线程进行处理,看似这是一个限制,但实际上,这反而是 Redis 性能高的关键之一。

没有严重的上下文切换锁的性能开销,以及实现的复杂度,Redis单线程已经够用

i/o多路复用

这里虽然Redis是单线程,但是使用i/o多路复用,以及利用事件驱动

事件驱动:Redis 使用事件循环的方式处理请求,所有的请求(无论是读还是写操作)都通过一个事件循环队列进行排队,Redis 会按照事件的顺序依次处理请求。这个事件循环是非阻塞的,意味着当 Redis 正在处理某个请求时,它不会因等待某个 I/O 操作(如网络读取或磁盘操作)而阻塞其他操作。

通过这种方式,Redis 不会在处理请求的过程中空闲等待,而是会一直保持高效地执行其他任务

I/O 多路复用:I/O 多路复用技术(如 epoll,select等)允许 Redis 在同一线程中同时监听多个网络连接的状态。Redis 可以在一个线程中同时处理多个客户端的请求,而不是每次都为每个客户端请求创建一个新的线程。这是通过 I/O 多路复用机制来完成的。

具体来说,Redis 通过 I/O 多路复用机制,能够在网络层同时 监听多个客户端的连接,并且在数据准备好时,迅速响应。这与传统的阻塞 I/O 有本质的不同。传统的阻塞 I/O 会让线程阻塞在等待数据准备的状态,直到数据准备好才能继续执行,而 Redis 通过 I/O 多路复用,能够在同一线程中 高效地轮询多个客户端的连接,确保在等待数据的过程中不浪费任何 CPU 时间。


http://www.kler.cn/a/519121.html

相关文章:

  • Spring集成Redis|通用Redis工具类
  • c语言中的数组(上)
  • 《探秘:人工智能如何为鸿蒙Next元宇宙网络传输与延迟问题破局》
  • [极客大挑战 2019]BuyFlag1
  • StarRocks BE源码编译、CLion高亮跳转方法
  • docker部署jenkins
  • 开源智慧园区管理系统对比五款主流产品探索智能运营新模式
  • PCB布线注意事项(1)
  • 深度学习 | 表示学习 | 卷积神经网络|翻转卷积核是干啥呢|09
  • 搭建Spring Boot开发环境
  • hot100_141. 环形链表
  • 125周六复盘 (167)帧数优化
  • Blazor-选择循环语句
  • 奇怪的单词(快速扩张200个单词)
  • 基于Matlab实现雷达目标特性相关仿真
  • 数据结构:二叉树—面试题(一)
  • 股指期货交割日是哪一天?股指期货什么时候交割?
  • C语言常用字符串处理函数
  • 神经网络|(二)sigmoid神经元函数
  • 07 区块链安全技术
  • 汽车表面划痕刮伤检测数据集VOC+YOLO格式1221张1类别
  • Spring FatJar写文件到RCE分析
  • Vue2下篇
  • 快递代取项目Uniapp+若依后端管理
  • 消息队列篇--通信协议篇--AMOP(交换机,队列绑定,消息确认,AMOP实现实例,AMOP报文,帧,AMOP消息传递模式等)
  • Tailwind CSS—骨架屏生成器