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

【Redis】安装Redis,通用命令

目录

一.在Ubuntu系统安装Redis

二. redis客户端介绍

 三. 通用命令

3.1.GET和SET命令

3.2.KEYS(生产环境禁止使用)

3.3.EXISTS

3.4.DEL

3.5.EXPIRE

3.6.TTL

3.6.1.Redis的过期策略

3.6.2.基于优先级队列/堆的实现去实现定时器

3.6.3.定时器:基于时间轮的实现 

3.7.TYPE  


一.在Ubuntu系统安装Redis

首先我们可以看看

apt search redis

我们找到下面这个来 

apt install redis

netstat -anp | grep redis

 Redis默认端口是6379。这里还是有一点问题。

大家注意到了吗?127.0.0.1可是本地回环IP啊,Redis绑定的IP地址可是本地回环IP啊,这怎么可以。

我们需要去修改一下Redis的配置文件,把这个绑定的IP地址修改为

cd /etc/redis

这个redis.conf就是redis的配置文件。

vim /etc/redis/redis.conf

我们往里面找到下面这一行

把上面那个给我修改成下面这个

除了上面这个绑定IP地址需要改之外,我们还需要修改下面这个

我们把yes给修改成no

有人就好奇,我们的redis有必要配置密码吗?

没有必要,虽然我们的Redis没有密码,但是因为我们的数据不值钱,就可以说是非常安全的,所以我们不配置密码的。

接下来我们需要重启redis服务器

service redis-server restart

 

接下来我们可以redis自带的客户端redis-cil登陆一下我们的redis。

redis-cli

到这一步,我们的redis就算是安装完成了。

那我们怎么退出呢?

直接ctl+d就能退出

二. redis客户端介绍

Redis 的核心架构:客户端-服务器模型

与 MySQL 等主流数据库系统类似,Redis 也严格遵循客户端-服务器 (Client-Server, C/S) 架构模型。这是其设计的基础,理解这一点至关重要:

  1. 服务端 (redis-server)

    • 这是 Redis 的核心,一个常驻运行的后台进程

    • 它负责数据存储、管理、执行命令、处理持久化、维护数据结构等核心功能。

    • 服务端通常运行在指定的服务器或主机上,监听配置的 TCP 端口(默认是著名的 6379 端口),等待客户端的连接请求。

    • 值得注意的是,Redis 服务端在处理命令时是单线程的(核心网络模型是 Reactor 模式),这使其命令执行具有原子性,但也意味着单个耗时操作会阻塞后续请求。

  2. 客户端

    • 任何需要与 Redis 服务进行交互的程序或工具都属于客户端范畴。

    • 客户端通过网络协议(RESP - REdis Serialization Protocol)与服务端建立连接、发送命令并接收结果。

    • 客户端的形态多样,如前所述,包括:

      • 命令行客户端 (redis-cli)

      • 图形用户界面 (GUI) 客户端

      • 各种编程语言的客户端库 (如 redis-py, Jedis, Lettuce, ioredisgo-redis 等),这些库被集成到应用程序代码中,是生产环境最主要的交互方式。

  3. 交互过程

    • 应用程序(客户端)发起连接请求到 redis-server

    • 连接建立后,客户端向服务端发送符合 RESP 格式的命令(例如 SET key valueGET keyLPUSH list item)。

    • 服务端接收命令,在其内存数据库中执行相应的操作。

    • 服务端将执行结果(数据、状态信息或错误)序列化为 RESP 格式,通过网络返回给客户端。

    • 客户端接收并解析结果,供应用程序使用。

Redis 客户端形态概览

Redis 提供了多种客户端连接方式,以适应不同的使用场景和需求:

  1. 命令行客户端 (redis-cli)

    • Redis 自带的标准命令行工具,功能强大且轻量。

    • 直接在终端启动即可连接本地默认端口的 Redis 服务:redis-cli

    • 支持指定连接远程或特定端口的 Redis 服务:redis-cli -h <hostname> -p <port>

    • 这是学习和基础管理最常用的方式,尤其在服务器环境或需要通过 SSH 连接时非常方便。

  2. 图形化界面客户端 (GUI)

    • 提供可视化的桌面程序或 Web 应用界面,操作更直观,方便查看数据结构和监控状态。

    • 市面上有多种选择(如 Another Redis Desktop Manager, RedisInsight, Redis Desktop Manager, web-redis 等)。

    • 重要提示: 在企业生产环境中,图形化客户端的使用可能受限:

      • 办公 Windows 电脑可能无法直接连接到部署在隔离网络(如生产服务器、内网)中的 Redis 实例。

      • 连接路径通常涉及复杂的网络架构,如跳板机、堡垒机,并需要严格的权限审批。

      • 其可用性不如命令行工具 (redis-cli) 或程序化 API 稳定可靠。

  3. 基于 Redis API 的程序化客户端

    • 这是实际开发工作中最主要的集成方式。非常类似于mysql的c语言api

    • 开发者使用 Redis 官方或社区提供的各种编程语言客户端库(如 Python 的 redis-py, Java 的 Jedis/Lettuce, Node.js 的 ioredis, Go 的 go-redis 等),在自己的应用程序代码中直接与 Redis 进行交互。

    • 这种方式提供了最大的灵活性,允许应用程序执行所有 Redis 命令、管理连接池、处理序列化/反序列化,并实现缓存、会话存储、消息队列等核心功能。

    • 其原理和重要性类似于关系型数据库中的 JDBC (Java) 或 ODBC/Python DB-API 等驱动接口,是实现应用与 Redis 深度集成的关键。

Redis 性能的辩证认知与应用场景分析

Redis 性能快不快,得看和谁比:MYSQL<Redis<内存变量

  • 相较于 MySQL 等磁盘存储的关系型数据库,Redis 基于内存操作,速度优势显著。

  • 但若与应用程序进程内直接操作内存变量(如 HashMap) 相比,Redis 需经过网络通信才能访问数据,反而会引入额外开销,性能可能更低


单机系统下的选择困境
在单应用服务器场景中,是否引入 Redis 需具体问题具体分析

  • 进程内变量 (如 HashMap) 的优势

    • 极致速度:直接内存操作,无网络延迟。

  • 引入 Redis 的代价与收益

    • 代价 (可能更慢)网络 I/O 成为瓶颈。

    • 核心收益

      • 数据持久化与隔离:Redis 作为独立进程存储数据,应用服务器重启不会丢失数据

      • 为分布式演进铺路:未来扩展为多节点分布式系统时,Redis 可充当共享、中心化的数据存储,天然支持多应用服务器访问同一数据源。而进程内变量无法跨进程共享。


实例剖析:用户点赞数存储
以存储 <视频ID, 点赞数> 键值对为例:

  • 方案 A:进程内 HashMap

    • 优势:操作极快(纳秒级内存访问)。

    • 致命缺点:数据与应用生命周期绑定;服务器重启数据清零;无法支持分布式扩展。

  • 方案 B:Redis

    • 代价:每次读写需网络通信(毫秒级),速度慢于 HashMap。

    • 核心优势:数据独立持久化;天然支持多服务器节点访问同一数据集;便于后续扩展。

  1. 技术选型原则:理性决策,避免“锤子思维”

    • 深入分析需求:明确当前痛点(速度?持久性?)与未来规划(是否分布式?)。

    • 权衡利弊:清晰认知引入任何技术(如 Redis)解决什么问题,同时引入什么问题(如网络延迟、运维复杂度)。

    • 切忌“无脑”跟风:不能因为 Redis “快” 或 “流行” 就不加思考地使用。技术是工具,对症下药才是关键

 

 三. 全局命令

通过 redis-cli 客户端和 redis 服务器交互,涉及到很多的 redis 的命令

redis 的命令非常非常多!!!

  1. 掌握常用命令(多练多练习)

  2. 学会使用 redis 的文档

阅读文档,是程序域的基础!!

任何一个工具软件,去找相关资料,一定是官方网站!!!

虽然 redis 这种知名软件,都是有中文文档的。但是老温仍然建议大家看英文的。(英语这一关,必须要过,也一定能过!!)

后面工作中可能会用到一些不太知名的软件/库,很可能没有中文文档,但是一定有英文文档。


我们看看Redis的官方文档在哪里?

首先我们来到Redis官网:Redis - The Real-time Data Platform

例如说我们需要查询一下ping命令,我们可以像下面这样 

 

后续我们查询文档的时候,就是按照上面这样子去操作。


在 Redis 中,操作不同数据结构(如 String, Hash, List, Set, Sorted Set 等)时,通常需要使用其对应的专属命令。例如,操作 List 会用到 LPUSH/RPOP,操作 Hash 会用到 HSET/HGET

而 全局命令 (Global Commands) 则是一类特殊的命令,它们的核心特点是:不依赖于键(Key)所关联的具体数据结构类型。这意味着:

  1. 跨数据结构通用性: 无论一个键关联的是 String、List、Hash 还是其他任何 Redis 数据结构,全局命令都可以作用于这个键。

  2. 操作对象是键本身: 这些命令通常关注的是键的元数据生命周期管理,而非其内部存储的具体数据结构值(虽然有些命令如 TYPE 会返回数据类型信息)。

  3. 提供统一的操作接口: 它们在 Redis 的键空间 (Key Space) 层面工作,为管理和操作所有键提供了一组基础且一致的指令。

我们整个第三大节讲述的都是全局命令。

3.1.GET和SET命令

这两个命令是Redis的核心命令,

注意redis是按照键值对的方式来存储数据的

  • get就是根据key来获取value
  • set则是把key和value存储进去

注意:key和value会被解析为字符串

接下来我们来演示一下

我们先进入redis客户端

redis-cli

接下来我们将使用set来存储一下键值对

set key1 value1
set key2 value2

接下来我们使用get命令,就能获取我们上面使用set存储的键值对

如果我们查询的是一个不存在的key呢?

这里的nil和C语言的NULL是一样的,都是表示空。

现在学到这里,我们就能使用redis解决大量的问题了。这就是redis的优势之一——学习成本低

3.2.KEYS(生产环境禁止使用)

Redis 支持很多种数据结构~~

整体上来说,Redis 是键值对结构。key 固定就是字符串。value 实际上会有多种类型,就像下面这些

  • 字符串
  • 哈希表
  • 列表
  • 集合
  • 有序集合

操作不同的数据结构,就会有不同的命令~

而全局命令,就是能够搭配任意一个数据结构来使用的命令~

而我们本文中讲解的所有命令都是属于全局命令。


现在我们先来讲解keys

KEYS用来查询当前服务器上符合条件的KEY

语法:

KEYS pattern
  • 命令有效版本:1.0.0 之后
  • 时间复杂度:O(N)
  • 返回值:匹配 pattern 的所有 key。

模式(Pattern)

指包含特殊通配符的字符串表达式(英文术语需重点掌握:pattern)。
其核心作用是 描述目标字符串的特征规则,实现高效匹配检索。

通配符语义详解

符号

名称

匹配规则

示例

?

单字符占位

匹配任意1个字符

h?llo → hello/hallo

*

多字符通配

匹配0个或多个字符

h*llo → hllo/heeeello

[ ]

字符集

匹配括号内任意1个字符

h[ae]llo → hello/hallo

[^ ]

排除字符集

匹配不在括号内的字符

h[^e]llo → hallo/hbllo

[a-b]

字符范围

匹配指定范围内的字符

h[a-c]llo → hallo/hbllo/hcllo

 我们来举一下例子

set hello 1
set hallo 1
set hbllo 1
set hllo 1
set heeeeeeeello 1

?表示匹配任意1个字符

*匹配0个或多个字符

[ ] 匹配括号内任意1个字符

[^ ]匹配不在括号内的字符

[a-b]匹配指定范围内的字符

注意事项:

生产环境必须禁止使用!

核心问题

  1. 性能杀手
    KEYS * 命令需要遍历所有键(时间复杂度 O(N))。当 Redis 存储海量数据时,此操作可能耗时数秒甚至分钟级。

  2. 单线程阻塞灾难
    Redis 单线程架构导致:

    • 执行 KEYS * 期间整个服务被冻结

    • 所有客户端请求超时失败

    • 缓存失效引发数据库雪崩(如 MySQL 被突发流量击垮)

    • 最终导致系统级联瘫痪

  3. 职业风险
    若因此引发线上事故:

    • 轻则年终奖受损

    • 重则面临失业危机

3.3.EXISTS

判断某个key是否存在。

语法:

EXISTS key [key ...]
  1. 命令有效版本:1.0.0之后
  2. 时间复杂度:O(1),这个是因为redis就是按照哈希表的方式来组织key的。
  3. 返回值:key存在的个数。

关键特性

  1. 键唯一性原则
    Redis 采用键值对存储模型(类哈希表结构),所有键必须是全局唯一的标识符。

  2. 底层高效实现

    • 时间复杂度:O(1)(恒定时间操作)

    • 实现原理:Redis 使用哈希表组织所有键,实现瞬时查找

  3. 数据结构分层理解

    层级组织结构示例说明
    键存储层全局哈希表所有键的存储容器
    值存储层多数据结构值可以是字符串/列表等

我们看一下例子 

 

3.4.DEL

删除指定的key。可以一次删除一个或者多个,

语法: 

DEL key [key ...]
  •  命令有效版本:1.0.0之后
  • 时间复杂度:O(1),这个是因为redis就是按照哈希表的方式来组织key的。
  • 返回值:删除掉的key的个数。

我们来看看

核心认知:数据删除的破坏力完全取决于 Redis 在系统中的角色定位

之前我们在学习mysql的时候,总是强调删除数据的操作是十分危险的操作,因为一删除数据就没有了,那么现在redis呢?

这个其实需要分情况讨论

  1. Redis作为缓存(最常见)
  2. Redis作为主数据库
  3. Redis作为消息队列

一、Redis作为缓存场景下的相对可控性

作为 MySQL 的前置缓存(主流应用模式),Redis 存储的仅是热点数据副本。此时删除部分键值如同撤下商场的展示样品——虽然会导致短暂缓存击穿,但源数据仍安全存储在 MySQL 中。通过自动重建机制,通常能在秒级恢复服务。真正的风险在于大规模批量删除:当大量热数据突然消失,所有请求将如洪水般直冲后端数据库。某电商曾因误删 80% 缓存键,致使 12 万 QPS 的流量瞬间压垮 MySQL,引发 47 分钟服务瘫痪,直接损失 180 万美元。这种 "缓存雪崩→数据库崩溃→业务停摆" 的连锁反应,正是运维人员最警惕的噩梦。

二、Redis作为主数据库的毁灭性风险

当 Redis 承担唯一数据源角色时,任何删除操作都等同于焚毁仓库库存。不同于缓存场景的数据重建可能,此时误删将导致业务核心数据永久丢失。某社交平台曾因 FLUSHDB 命令清空用户关系库,致使 3000 万用户连接图谱消失,最终需花费 17 小时从冷备中恢复——期间市值蒸发 9%。这种场景下,即便删除单个键(如用户支付凭证)也可能引发资金对账灾难。

三、Redis作为消息队列角色的复杂影响

Redis 用作消息队列时,风险呈现灰度特征:

  • 低风险场景:删除非关键消息(如用户行为日志),最多影响数据分析完整性

  • 高风险场景:清除待处理任务(如支付订单),将直接导致资金损失。某金融系统曾误删 10 万条支付指令,引发 300 万美元资金流水断裂,整个技术团队季度奖金归零
    判断标准取决于消息的不可再生性——如同销毁物流清单,普通商品可补发,而限时药品缺货将酿成事故。

3.5.EXPIRE

为指定的 key 添加秒级的过期时间(Time To Live TTL)  

语法:  

EXPIRE key seconds  
  • 注意单位是秒!!!
  • 命令有效版本:1.0.0 之后  
  • 时间复杂度:O(1)  ,
  • 返回值:1 表示设置成功。0 表示设置失败。  

示例:  

3.6.TTL

获取指定 key 的过期时间,秒级。

语法:

TTL key
  • 命令有效版本:1.0.0 之后
  • 时间复杂度:O(1)
  • 返回值:剩余过期时间。-1 表示没有关联过期时间,-2 表示 key 不存在。

示例:

EXPIRE 和 TTL 命令都有对应的支持毫秒为单位的版本:PEXPIRE 和 PTTL,详细用法就不再介绍了。

3.6.1.Redis的过期策略

 redis里面有很多key,这些key里面势必有很多key有过期时间,那么这个时候redis服务器是怎么知道当前有哪些key过期了需要去删除,哪一些key还没有过期呢?

想象一个超级忙碌的便利店,只有一个老板(Redis的单线程):

  1. 定期抽查(定期删除):

    • 老板很忙: 老板大部分时间都在收银台(处理顾客请求),不能一直去检查货架上的商品过期没。

    • 抽空检查: 每隔一小会儿(比如100毫秒),老板就快速离开收银台,去货架上随机抽查一小部分商品(比如20件)。

    • 限时检查: 这个检查动作有严格的时间限制(比如25毫秒)!不管查到多少,时间一到必须立刻回收银台。为啥?因为不能让顾客(请求)等太久,否则队伍排老长,店就瘫痪了(阻塞)。

    • 发现过期: 抽查时发现过期的商品(键),就当场扔掉(删除)。

    • 为啥不全查? 货太多(海量键),全查一遍太花时间,顾客等不起!

  2. 顾客结账时检查(惰性删除):

    • 即时发现: 当顾客(客户端)想买(访问)某个商品(键)时,老板在收银台拿到这个商品会先看一眼保质期。

    • 当场处理: 如果发现过期了,老板立刻说:“这个过期了,不能卖”,然后顺手把它扔进垃圾桶(删除),告诉顾客没有这个货了(返回空值)。

    • 你的方便面经历: 这就像小时候你去小卖部买方便面,老板拿出来才看到过期了,然后说“这个坏了,我给你换一个/没货了”。过期的东西不会自己消失,只有被人拿起来看的时候才会被发现并处理掉。

问题:总有“漏网之鱼”

  • 有些商品(键)可能一直没被老板抽检到,也一直没人来买(访问)。它们就默默地待在货架(内存)的角落里过期了,成了“幽灵商品”(幽灵数据),占着地方(内存)。

终极清仓大甩卖(内存淘汰机制):

  • 货架满了咋办? 当便利店的货架(内存)快被塞满时,光靠抽查和结账检查不够用了。这时老板会启动紧急清仓策略(内存淘汰机制)。

  • 按规则扔: 老板会根据定好的规则(比如“把最近最没人买的商品扔掉” - LRU策略),主动清理掉一批商品(键),腾出空间给新货,即使有些商品可能还没过期。这是防止内存彻底用光的最后防线。

灵魂拷问:为啥不用“定时炸弹”自动炸毁过期商品?

很多工程师想过:给每个商品装个小定时器(时间轮/优先级队列),到点就“砰”自动消失,多省事?

但老板(Redis作者)有顾虑:

  • 太复杂: 管理成千上万个定时器本身就很麻烦,需要额外的人手(多线程),违背了便利店“只雇一个老板”(单线程简单)的原则。

  • 干扰营业: 想象一下,每隔五分钟,店里就“砰”、“砰”、“砰”地自动炸毁过期商品。且不说吓跑顾客,爆炸声(定时器触发)本身就会打断老板收银(处理请求),让结账速度变慢(服务抖动)。老板宁愿自己抽空去检查,也不想被定时炸弹干扰。

血泪教训:

  • 有个大超市(电商平台)曾经就是“抽检”动作慢了一点点(超时7毫秒),结果在打折日顾客爆满时,收银台(主线程)被拖住了,顾客请求堵成长龙,最后整个系统都崩溃了(数据库雪崩)。这证明了那个“25毫秒必须回收银台”的红线是多么重要!

3.6.2.基于优先级队列/堆的实现去实现定时器

定时器:基于优先级队列/堆的实现

定时器的核心功能是在指定时间点到达后,执行预设的任务。

1. 优先级队列基础

  • 普通队列遵循“先进先出”(FIFO)原则。

  • 优先级队列则根据自定义的优先级决定元素的出队顺序优先级高的元素先出队。

  • 优先级定义示例: 在Redis处理过期Key的场景中,可以将“过期时间越早”定义为优先级越高。

2. 过期Key管理的应用
假设有大量Key设置了过期时间:

  • 将这些Key放入一个优先级队列,并指定排序规则:过期时间最早的Key优先级最高,位于队首

  • 队首元素的意义: 它始终是最早要过期的Key!

    • 示例:

      • key1: 过期时间 12:00

      • key2: 过期时间 13:00

      • key3: 过期时间 14:00

      • 此时队首元素是 key1 (12:00)。

3. 高效的扫描机制

  • 定时器只需分配一个专用扫描线程

  • 该线程的核心工作是:持续检查队首元素是否已过期

  • 关键原理: 如果队首元素尚未过期,那么队列中所有后续元素必然也未过期!因此,扫描线程无需遍历整个队列,只需聚焦于队首元素即可,大大减少检查开销。

4. 优化:避免忙等待与节省CPU

  • 频繁检查队首元素(例如循环空转)会浪费CPU资源。

  • 优化策略:

    1. 扫描线程计算当前时间队首元素过期时间的差值。

    2. 根据这个时间差,让线程主动休眠(阻塞) 相应时长。

    3. 当休眠时间结束(或接近队首元素过期时间)时,系统自动唤醒线程进行检查。

  • 效果: 线程在等待期间不占用CPU,显著节省资源。

5. 处理新增的高优先级任务

  • 场景: 当扫描线程处于休眠状态时,如果添加了一个新的任务,其过期时间(例如 11:30)早于当前队首元素(例如 12:00)

  • 解决方案:

    1. 在添加新任务的逻辑中,立即唤醒处于休眠状态的扫描线程。

    2. 被唤醒的线程重新检查新的队首元素(此时是刚加入的11:30任务)。

    3. 根据新的队首元素的过期时间重新计算并调整休眠时间

  • 意义: 确保了即使在高优先级新任务插入时,定时器也能及时响应并调整调度计划,保证准确性。

总结: 这种基于优先级队列(通常使用最小堆实现)的定时器方案,通过聚焦队首元素和智能休眠机制,实现了对大量定时任务的高效、低开销管理,特别适用于像Redis过期Key处理这类需要精确管理最早到期事件的场景。其效率高度依赖于优先级队列(堆)操作的性能(O(log n) 的插入和删除)。

3.6.3.定时器:基于时间轮的实现 

时间轮(Timing Wheel)是一种将时间离散化处理的高效定时器设计方案,尤其适合管理大量短周期定时任务。

1. 核心结构:离散化时间片

  • 将连续的时间流划分为固定长度的小时间单元,称为 “槽”(Slot) 或 “格子”

  • 时间粒度(Tick Duration): 每个槽代表的时间长度(例如:100ms)。该粒度是核心参数,需根据实际应用场景(如对精度的要求、任务密度)进行配置。

  • 时间轮结构: 一个环形数组(或循环队列),数组的每个元素对应一个时间槽。

2. 任务组织:槽与链表

  • 每个时间槽上关联一个链表

  • 每个链表节点代表一个需要在该槽对应的时间点(或之后) 执行的定时任务

  • 任务表示: 包含任务执行所需的逻辑。在底层实现中,这通常是一个函数指针(或回调函数) 及其参数。在面向对象语言(如 Java)中,也可以通过实现特定接口(如 Runnable)的任务对象来封装执行逻辑。

3. 运作机制:指针扫描

  • 时间轮由一个指针(Current Pointer) 驱动,该指针按照固定的时间间隔(等于时间粒度,如每 100ms)向前移动一个槽位。

  • 指针移动: 通常由一个独立的时钟线程或集成在事件循环中的计时器驱动。

  • 任务触发: 每当指针移动到一个新的槽位时:

    1. 取出该槽位上链表中的所有任务节点。

    2. 执行这些任务节点关联的任务逻辑。

  • 关键点: 指针移动到某个槽位,意味着该槽位所代表的“到期时间窗口”(例如第 N 个槽代表 [N * tick_duration, (N+1) * tick_duration))已到达或刚过,挂在该槽上的任务应被触发。

4. 添加定时任务

  • 场景: 添加一个需要在 delay 毫秒后执行的任务(例如:delay = 300ms)。

  • 计算槽位:

    1. 确定任务需要经过多少个完整的时间片(槽):slots = delay / tick_duration (取整或向上取整,取决于具体实现策略)。

    2. 计算任务应放入的目标槽索引target_slot_index = (current_pointer_index + slots) % total_slots

  • 挂载任务: 将代表该任务的新节点插入到 target_slot_index 对应槽的链表中。

5. 处理长周期任务

  • 挑战: 如果任务的延迟时间(例如 3000ms)远大于时间轮的总跨度total_span = tick_duration * total_slots),直接按上述方法计算 target_slot_index 会失效(因为 slots 可能远大于 total_slots)。

  • 解决方案:多级时间轮 (Hierarchical Timing Wheels)

    • 构建多个层级的时间轮,每一层覆盖更大的时间范围。

    • 例如:第一级时间轮(细轮):粒度 100ms,共 10 个槽 -> 覆盖 1000ms。

    • 第二级时间轮(粗轮):粒度 1000ms (1s),共 10 个槽 -> 覆盖 10000ms (10s)。

    • 当一个任务在细轮上到期时间超过其覆盖范围时,会被“降级”添加到粗轮中更远的槽位。

    • 粗轮指针移动更慢(每 1s 移动一次)。当粗轮上的任务即将进入细轮覆盖范围时,会被“升级”重新分配到细轮的合适槽位。

    • 通过层级结构,可以用有限的空间(槽数)高效管理极长延时的任务。

6. 配置要点

  • 时间粒度 (tick_duration): 决定了定时器的最小精度和扫描频率。粒度越小,精度越高,但指针移动和任务检查开销也越大。

  • 槽数量 (total_slots): 决定了时间轮单层的最大覆盖时间 (tick_duration * total_slots)。

  • 权衡与优化: 需要根据应用的典型任务延时分布、任务数量、精度要求、CPU 负载容忍度等因素,灵活调整粒度和槽数,或在需要时采用多级时间轮。

总结: 时间轮通过将时间离散化为槽并使用指针周期性扫描,实现了对大量定时任务的批量触发,其时间复杂度(添加任务 O(1),触发任务 O(n) 其中 n 是槽上任务数)在任务密集时通常优于基于堆的方案。结合多级时间轮,它能有效处理各种时间跨度的定时任务,是高性能网络框架(如 Netty)、消息队列(如 Kafka)、操作系统内核中管理定时器的常用高效机制。 

注意事项

此处大家一定要注意!Redis 并没有采取上述的方案!

但是要了解这两种方案,都是属于高效的定时器的实现方式。很多场景可能都会用到。

在 Redis 源码中,有一个比较核心的机制,是 事件循环。

3.7.TYPE  

返回 key 对应的数据类型。  

语法:  

TYPE key  
  • 命令有效版本:1.0.0 之后  
  • 时间复杂度:O(1)  
  • 返回值:none, string, list, set, zset, hash and stream...  

示例:

DEL key1
DEL key2
DEL key3 
SET key1 "value"  
LPUSH key2 "value"  
SADD key3 "value"  
TYPE key1  
TYPE key2 
TYPE key3  

http://www.lryc.cn/news/609980.html

相关文章:

  • Redis键值对中值的数据结构
  • 05 基于sklearn的机械学习-梯度下降(下)
  • 解决 “crypto.hash is not a function”:Vite 从 6.x 升级至 7.x 后 `pnpm run dev` 报错问题
  • vue3+vue-flow制作简单可拖拽可增删改流程图
  • JMeter的基本使用教程
  • OpenLayers 详细开发指南 - 第八部分 - GeoJSON 转换与处理工具
  • 《Java Agent与Instrumentation:运行时增强的魔法武器》
  • 为什么ping和dig(nslookup)返回地址不一样,两者的区别
  • 基于C语言实现(控制台 )小区物业管理系统
  • Java常用数据结构入门
  • 推荐广告搜索三种业务的区别
  • 车载通信架构 ---车内通信的汽车网络安全
  • 人工智能之数学基础:条件概率及其应用
  • 跟着顶刊学写论文-摘要1
  • 深入浅出 RabbitMQ:工作队列实战(轮训策略VS公平策略)
  • SpringCloud之Nacos基础认识-服务注册中心
  • 13.Home-面板组件封装
  • Mac桌面仿制项目--让ai一句话生成的
  • mac 技巧
  • 【AI 加持下的 Python 编程实战 2_13】第九章:繁琐任务的自动化(中)——自动批量合并 PDF 文档
  • 大模型×垂直领域:预算、时间、空间三重夹击下的生存法则
  • 2.2 vue2子组件注册使用
  • 西门子PLC S7-1200单轴步进控制电动机
  • Axure设计Web端新增表单页面模板案例
  • 【LeetCode 热题 100】215. 数组中的第K个最大元素——(解法一)快速选择
  • 安卓逆向(基础①-Google Pixel-Root)
  • Visual Studio 2022安装与快捷键全攻略
  • 模型蒸馏(Distillation):原理、算法、应用
  • 【达梦MPP(带主备)集群搭建】
  • Selenium教程(Python 网页自动化测试脚本)