2023.12.19 关于 Redis 通用全局命令

目录

 引言

Redis 全局命令

SET & GET

KEYS

EXISTS

DEL

EXPIRE

TTL

TYPE

redis 引入定时器高效处理过期 key

基于优先级队列方式

基于时间轮方式


引言

  • Redis 是根据键值对的方式存储数据的
  • 必须要进入 redis-cli 客户端程序 才能输入 redis 命令


Redis 全局命令

  • Redis 支持很多种数据结构
  • 整体上来说,Redis 是键值对结构
  • key 固定为字符串类型,但 value 有很多种类型
  • 如 字符串、哈希表、列表、集合、有序集合 等
  • 操作不同的数据结构,就会有不同的命令
  • 全局命令就是能够搭配任意一个数据结构来使用的命令

SET & GET

  • set 根据 key 和 value 来存数据
  • key 和 value 都是字符串类型

语法:

set key value 

实例理解

  • 对于上述的 key value 不加上引号,其表示的就是字符串类型
  • 当然也可以给 key 和 value 加上引号,单引号 或 双引号 都行!

注意:

  • redis 中的命名不区分大小写

  • get 根据 key 来取 value
  • get 命令直接输入 key 就能得到 value

语法:

get key

实例理解

​​​​​​

  • 如果当前 key 不存在就会直接返回 nil
  • 此处的 nil 和 null、NULL 表示同一个意思

KEYS

  • 用来查询当前服务器上能匹配的 key
  • 通过一些特殊符号(通配符)来描述 key 的模样,能匹配上述模样的 key 就能被查询出来

时间复杂度:

  • O(N)

语法:

​keys pattern
  • 此处的 pattern 为包含特殊符号的字符串,其存在的意义是去描述 另外的字符串长啥样的
匹配任意一个字符
*匹配 0 个或者多个任意字符
[ab]只能匹配到 a b ,别的都不行 相当于给出固定的选项
[^ae]只有 a、e 匹配不了 其他的都能匹配
[a-e]匹配 a - e 这个范围内的字符 包含两侧边界

实例理解

  • 此处我们随意添加几个 键值对

  • ?通配符

  • * 通配符

  • [ab] 通配符

  • [^ae] 通配符

  • [a-e] 通配符

注意:

  • 上述匹配规则不需要刻意去背

注意事项:

  • keys 命令的时间复杂度是 O(N)
  • 所以 在生产环境上 一般会禁止使用 keys 命令
  • 尤其是 keys * ,即查询 redis 中所有的 key

原因:

  • 生产环境上的 key 可能会非常多!
  • redis 是一个单线程的服务器
  • 如果执行 keys * 的时间过长,可能导致 redis 服务器被阻塞,从而无法给其他客户端提供服务

严重后果:

  • redis 经常被用作缓存 挡在 mysql 前面
  • 如果 redis 被 keys * 阻塞了,那么此时其他查询 redis 的操作便会超时
  • 从而这些请求就会 直接查询 mysql 数据库
  • 这么一大波 突然来临的请求会让 mysql 措手不及,进而导致 mysql 数据库挂掉
  • 最终导致整个系统瘫痪

EXISTS

  • 判定 key 是否存在

时间复杂度:

  • O(1)
  • redis 按照 哈希表 的方式组织这些 key

语法:

exists key [key...]

返回值:

  • 我们的 exists 是可以判断多个 key 是否存在的,所以其返回值为 key 存在的个数


实例理解


注意事项:

  • 此处红框写法 与 绿框写法 相差很大

原因:

  • redis 是一个 客户端 服务器 结构的程序
  • 客户端和服务器之间通过 网络 来进行通信
  • 绿框写法 相较于 红框写法 会产生更多轮次的网络通信

补充:

  • 网络通信 相较于 直接操作内存,效率更低、成本更高
  • 所以 redis 很多命令均支持一次能操作多个 key  或者 支持多种操作

DEL

  • 删除指定的 key
  • 可以一次删除 一个 或 多个

时间复杂度:

  • O(1)

语法:

del key [key ...]

返回值:

  • 删除掉的 key 的个数

实例理解


注意事项:

  • 学 mysql 的时候,像删除 类型的操作,如 drop database、drop table 等 都是非常危险的操作,一旦删除,数据就无了
  • redis 主要的应用场景为 用作缓存
  • 此时 redis 中存的只是 热点数据,全量数据均存在 mysql 数据库中
  • 如果把 redis 中的 key 删除几个,一般来说问题不会大
  • 但是如果把 所有的数据 或 一大半的数据 都删除,这种影响便会很大

原因:

  • 本来 redis 是帮 mysql 负重前行的
  • 此时 redis 中没数据了,mysql 便需要应对大量的请求,然后 mysql 便会很容易挂掉

补充:

  • 相比之下,如果是 mysql 数据库,哪怕误删了一个数据 都可能会造成很大的影响
  • 但是如果把 redis 也作为数据库,此时误删数据也会造成很大的影响
  • 因为此时 redis 中存储的是 全量数据
  • 如果把 redis 作为消息队列,这种情况误删数据影响大不大,需要具体问题具体分析

总结:

  • 不要乱删数据

EXPIRE

  • 给指定的 key 设置过期时间
  • 即 key 存活时间超出这个指定的值,就会被自动删除

语法:

  • 此处的时间单位为 秒
expire key seconds
  • 对于计算机来说,秒是一个非常长的时间
  • 此处的时间单位为 毫秒
pexpire key millisecond

返回值:

  • 此处设定过期时间 必须是针对已经存在的 key 设置,设置成功返回 1 设置失败 返回 0

实例理解


经典业务场景:

  • 很多业务场景,是有时间限制的
  • 比如手机验证码,点外卖的优惠券,在指定时间内有效、基于 redis 实现分布式锁

redis 实现分布式锁:

  • 为了不能避免出现不能正确解锁的情况,通常都会在加锁的时候设置一下过期时间
  • 所谓的 redis 作为分布式锁,就是给 redis 里写一个特殊的 key value

TTL

  • 查看当前 key 的过期时间
  • 时间单位为 秒

时间复杂度:

  • O(1)

语法:

ttl key

返回值:

  • 剩余过期时间 -1 表示没有关联过期时间 -2 表示 key 不存在

实例理解


redis 相关的经典面试题 :

  • redis 中 key 的过期策略是怎么实现的?

理解:

  • 一个 redis 中可能同时存在很多 key
  • 这些 key 中可能有很大一部分都有过期时间
  • 此时 redis 服务器咋知道哪些 key 已经过期要被删除,哪些 key还没过期?

回答:

  • redis 的整体策略有三种

1、定期删除

  • 此处需要结合定期删除的操作,即每次抽取一部分验证过期时间
  • 必须保证这个抽取检查的过程足够快!
  • 为啥这里对于定期删除的时间 有明确的要求呢?
  • 因为 redis 是单线程的程序,其主要的任务为 处理每个命令的任务
  • 如果扫描过期的 key 消耗时间太多,就可能导致正常处理请求命令被阻塞,即产生了类似于 keys * 这样的效果

2、惰性删除

  • 假设一个 key 已经到过期时间了,此时并不会将其直接删除,即 key 还会保存在 redis 中
  • 紧接着如果后面的访问中用到了这个 key 
  • 那么此次访问将会让 redis 服务器触发删除 key 的操作,与此同时再返回一个 nil 

3、内存淘汰策略


注意:

  • redis 中没有采取 定时器 的方式实现过期 key 的删除
  • 如果有多个 key 过期 也可以通过一个定时器
  • 在高效 且 节省 cpu 的前提下 来处理多个 key,如 基于优先级队列 或 基于时间轮 均可以实现比较高效的定时器

TYPE

  • 返回 key 对应 value 的数据类型

时间复杂度:

  • O(1)

语法:

type key

返回值:

  • none、string、list、set、zset、hash、stream 等
  • none 表示 key 不存在
  • stream 表示当 redis 作为消息队列的时候,value 将使用这个类型

实例理解

注意:

  • 在 redis 中,上述类型操作方式差别很大,使用的命令都是完全不同的

redis 引入定时器高效处理过期 key

  •  redis 引入定时器实现高效处理过期 key 有两种方式

基于优先级队列方式

  • 当然也可以通过 堆 的方式

基本概念

  • 正常队列为先进先出
  • 优先级队列则是 按照自定义指定的优先级 先出
  • 在 redis 处理过期 key 场景中,可以设置优先级为:过期时间越早  优先级越高

实例理解

  • 假设有很多 key 被设置了过期时间

  • 此时定时器中只要分配一个线程,让这个线程去检查队首元素 看其是否过期即可
  • 如果队首元素还没过期,在队首元素之后元素一定没过期

优势:

  • 此时 扫描线程 无需遍历所有 key ,仅需盯住 队首元素 即可

补充:

  • 在 扫描线程 检查队首元素过期时间时,根据 过期时间 与 当前时间 之差来设置一个等待时间
  • 当等待时间差不多到了,系统再唤醒该线程
  • 此时扫描线程便不需要高频扫描 队首元素,把 cpu 的开销也节省下来了

问题:

  • 在线程休眠的时候 插入了一个新 key,且该 key 的过期时间为 10:30

解决办法:

  • 在新任务添加的时候,唤醒一下正在休眠的线程
  • 即重新检查一下 队首元素,再根据时间差距重新调整阻塞时间

基于时间轮方式

  • 把时间划分成多个小段
  • 对于时间轮来说,每个格子是多少时间,一共多少个格子,都是需要根据实际场景灵活调配的

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# SQLite基础工具类

目录 1、安装System.Data.SQLite工具包 2、创建数据库 3、数据库的连接与断开 4、执行一条SQL语句 5、批量执行sql语句 6、返回首行首列值 7、执行sql语句返回datatable 1、安装System.Data.SQLite工具包 2、创建数据库 /// <summary> /// 数据库路径 …

C++的泛型编程—模板

目录 一.什么是泛型编程&#xff1f; ​编辑 ​编辑 二.函数模板 函数模板的实例化 当不同类型形参传参时的处理 使用多个模板参数 三.模板参数的匹配原则 四.类模板 1.定义对象时要显式实例化 2.类模板不支持声明与定义分离 3.非类型模板参数 4.模板的特化 函数模板…

事件和事件源

事件监听 在JS当中写事件监听是这个函数&#xff0c;写了这个函数&#xff0c;前面是DOM对象&#xff0c;当由DOM树和CSSOM树形成的渲染树也有这个监听&#xff0c;这个函数可以添加到DOM树&#xff0c;最后渲染树也有。渲染树会渲染标签当标签发生该事件就会执行这个函数。这个…

conda环境下执行conda命令提示无法识别解决方案

1 问题描述 win10环境命令行执行conda命令&#xff0c;报命令无法识别&#xff0c;错误信息如下&#xff1a; PS D:\code\cv> conda activate pt conda : 无法将“conda”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果包括路径&a…

Transformer引领AI领域:从模型到平台,全方位探索与实践

编辑推荐 在不到4 年的时间里&#xff0c;Transformer 模型以其强大的性能和创新的思想&#xff0c;迅速在NLP 社区崭露头角&#xff0c;打破了过去30 年的记录。BERT、T5 和GPT 等模型现在已成为计算机视觉、语音识别、翻译、蛋白质测序、编码等各个领域中新应用的基础构件。…

pnpm :无法加载文件 D:\nodejs\node_global\pnpm.ps1,因为在此系统上禁止运行脚本

目录 一、问题描述 二、原因分析 三、解决问题 一、问题描述 pnpm : 无法加载文件 D:\learningsoftware\nodejs\node_global\pnpm.ps1&#xff0c;因为在此系统上禁止运行脚本。有关详细信息&#xff0c;请参阅 https:/go.microsoft.com/fwlink/?LinkID1351 70 中的 a…

5G+云渲染技术:将如何快速推进XR和元宇宙?

XR&#xff08;扩展现实&#xff09;领域正在以惊人的速度增长。目前&#xff0c;到 2024 年&#xff0c;一些专家表示这个行业的价值将达到 3000 亿美元。 这个行业发展如此迅速的部分原因是 XR 将在商业环境中的带来巨大利益。近年来&#xff0c;很多企业遇到了将增强现实和…

spring MVC概述和土门案例(无配置文件开发)

SpringMVC 1&#xff0c;SpringMVC概述2&#xff0c;SpringMVC入门案例2.1 需求分析2.2 案例制作步骤1:创建Maven项目步骤2:补全目录结构步骤3:导入jar包步骤4:创建配置类步骤5:创建Controller类步骤6:使用配置类替换web.xml步骤7:配置Tomcat环境步骤8:启动运行项目步骤9:浏览器…

vue 简单实现购物车:商品基础信息最终的 html 文件 + 商品计数器的组件处理,实现了购物车;

购物车实现过程&#xff1a; Ⅰ、商品购物车作业需求&#xff1a;1、商品购物车页面示例&#xff1a;2、具体需求&#xff1a; Ⅱ、html 文件的构建&#xff1a;商品购物车.html Ⅲ、组件文件的构建&#xff1a;商品购物车1.js Ⅳ、小结&#xff1a; Ⅰ、商品购物车作业需求&am…

【HarmonyOS开发】ArkTs关系型和非关系型数据库的存储封装

前面使用了首选项的存储方式&#xff0c;因此将其他的两种存储方式&#xff08;键值型数据库和关系型数据库&#xff09;也学习一下&#xff0c;简单记录一下&#xff0c;并进行封装&#xff0c;方便后续使用。 1、效果预览 2、使用条件 2.1 键值型数据库 键值型数据库实现数据…

Modbus-TCP数据帧

Modbus-TCP基于4种报文类型 MODBUS 请求是客户机在网络上发送用来启动事务处理的报文MODBUS 指示是服务端接收的请求报文MODBUS 响应是服务器发送的响应信息MODBUS 证实是在客户端接收的响应信息 Modbus-TCP报文: 报文头MBAP MBAP为报文头&#xff0c;长度为7字节&#xff0c…

CentOS操作学习(二)

上一篇学习了CentOS的常用指令CentOS指令学习-CSDN博客 现在我们接着学习 一、Vi编辑器 这是CentOS中自带的编辑器 三种模式 进入编辑模式后 i&#xff1a;在光标所在字符前开始插入a&#xff1a;在光标所在字符串后开始插入o&#xff1a;在光标所在行的下面另起一新行插入…

【排序算法】C语言实现选择排序与冒泡排序

文章目录 &#x1f680;前言&#x1f680;冒泡排序✈️冒泡排序的逻辑✈️冒泡排序coding &#x1f680;选择排序✈️选择排序的逻辑✈️选择排序coding &#x1f680;前言 这里是阿辉算法与数据结构专栏的第一篇文章&#xff0c;咱们就从排序算法开始讲起&#xff0c;排序算法…

freeswitch on debian docker

概述 freeswitch是一款简单好用的VOIP开源软交换平台。 因为centos系统期限的原因&#xff0c;尝试在debian的docker上使用fs。 环境 docker engine&#xff1a;Version 24.0.6 debian docker&#xff1a;bullseye 11.8 freeswitch&#xff1a;v1.10.7 Debian准备 目前…

C语言之初识C语言

文章目录 前言一、什么是C语言二、第一个C语言程序三、数据类型四、变量&#xff0c;常量1、变量1.1 变量的命名1.2 变量的分类1.3 变量的使用1.4 变量的作用域和生命周期2、变量 五、字符串1. 概念2. 求解字符串的长度【strlen】3. 转义字符【含笔试题】 六、注释七、选择语句…

Docker 文件和卷 权限拒绝

一 创作背景 再复制Docker影像文件或访问Docker容器内已安装卷上的文件时我们常常会遇到&#xff1a;“权限被拒绝”的错误&#xff0c;在此&#xff0c;您将了解到为什么会出现“权限被拒绝”的错误以及如何解决这个问题。 二 目的 在深入探讨 Docker 容器中的 Permission De…

互操作性(Interoperability)如何影响着机器学习的发展?

互操作性&#xff08;Interoperability&#xff09;&#xff0c;也称为互用性&#xff0c;即两个系统之间有效沟通的能力&#xff0c;是机器学习未来发展中的关键因素。对于银行业、医疗和其他生活服务行业&#xff0c;我们期望那些用于信息交换的平台可以在我们需要时无缝沟通…

springboot+vue前后端分离的社区养老服务管理管理系统(有文档)

springbootvue前后端分离的社区养老服务管理管理系统。系统功能齐全&#xff0c;配置完成可运行&#xff0c;有文档&#xff0c;演示视频&#xff0c;配置说明&#xff0c;数据库文件&#xff0c;虚拟产品下单不退不换&#xff01; 技术&#xff1a;springbootmybatisplusmysql…

STM32的以太网外设+PHY(LAN8720)使用详解(6):以太网数据接收及发送

0 工具准备 1.野火 stm32f407霸天虎开发板 2.LAN8720数据手册 3.STM32F4xx中文参考手册1 以太网数据接收及发送 1.1 以太网数据接收&#xff08;轮询&#xff09; 1.1.1 检查是否接收到一帧完整报文 使用轮询的方式接收以太网数据是一种简单但是效率低下的方法&#xff0c;…

【Seata源码学习 】 篇二 TM与RM初始化过程

【Seata源码学习 】 篇二 TM与RM初始化过程 1.GlobalTransactionScanner 初始化 GlobalTransactionScanner 实现了InitializingBean 接口&#xff0c;在初始化后将执行自定义的初始化方法 io.seata.spring.annotation.GlobalTransactionScanner#afterPropertiesSet Override…