【Redis】全局命令/内部编码/浅谈单线程模型

news2024/11/20 17:38:23

目录

前言

两个核心命令

GET和SET

全局命令

KEYS

EXISTS 

DEL

EXPIRE

TTL

TYPE 

数据结构的内部编码

Redis的5中数据类型

Redis数据结构和内部编码

单线程架构


前言

Redis 提供了 5 种数据结构,理解每种数据结构的特点对于 Redis 开发运维⾮常重要,同时掌握每
种数据结构的常见命令,会在使用Redis 的时候做到游刃有余。在正式介绍 5 种数据结构之前,了解⼀下 Redis 的⼀些全局命令。单线程命令处理机制是⼗分必要的,它们能为后⾯内容的学习打下⼀个良好的基础。

注意:

  • Redis 的命令有上百个,如果纯靠死记硬背⽐较困难,但是如果理解 Redis 的⼀些机制,会发现这些命令有很强的通⽤性。
  • Redis 不是万⾦油,有些数据结构和命令必须在特定场景下使⽤,⼀旦使⽤不当可能对 Redis 本⾝或者应⽤本⾝造成致命伤害。

两个核心命令

GET和SET

这两个命令是Redis中最核心的两个命令,因为Redis是按照键值对的方式存储数据的;GET命令是根据KEY来取对应的value的,而SET是把一对key-value存储进去;

说明:

  • 使用SET存储一对KV值时,在命令行上敲的是字符串,但是对于value可能是不同的数据结构;
  • KV值可以加上单引号,双引号,也可以不加;

示例:

说明:

  • GET命令直接输入key就可以得到value;
  • 如果当前key不存在,回返回 nil;
  • Redis中的命令不区分大小写; 

全局命令

Redis支持很多种数据结构,包括:字符串、哈希表、列表、集合、有序集合等;对于key固定的就是字符串,但是value实际上会有很多种类型,操作不同的数据结构就会有不同的命令;因此我们在学习Redis中的数据结构之前,先了解一些全局命令:就是能够搭配任意一个数据结构来使用的命令;

KEYS

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

语法:

KEYS pattern
  • h?llo 匹配 hello , hallo 和 hxllo
  • h*llo 匹配 hllo 和 heeeello
  • h[ae]llo 匹配 hello 和 hallo 但不匹配 hillo
  • h[^e]llo 匹配 hallo , hbllo , ... 但不匹配 hello
  • h[a-b]llo 匹配 hallo 和 hbllo

时间复杂度:O(N)

返回值:匹配pattern的所有key

示例:

keys * 一个大“杀器”,查询Redis中所有的key;

注意:由于keys命令的时间复杂度是O(N),所有在真实的生产环境上,一般都会禁止使用keys*;因为生产环境上的key可能会非常的多,而redis是一个单线程的服务器,执行keys*的时间就会非常的长,就可能会使Redis的服务器被阻塞了,无法给客户端提供服务了;由于Redis经常会用于做缓存,挡在MySQL前面,而万一Redis被keys*阻塞了,此时其他查询Redis的操作就会超时,这些请求就会直接查询数据库;最终可能导致MySQL挂掉,整个服务器最后基本就瘫痪了。


EXISTS 

功能:判定某个key是否存在

语法:

EXISTS key [key ...]

时间复杂度:O(1)

返回值:key存在的个数

说明:

  • 这个命令针对查询多个key来说是非常有用的;
  • Redis组织这些key是按照哈希表的方式来组织的,所以时间复杂度是O(1)

示例:

上面两种执行命令的区别?

Redis只一个客户端服务器结构的程序,客户端和服务器之间通过网络来进行通信;分开写会产生多轮次的网络通信,而一起写只会有一次的网络通信,效率比较高,虽然结果是一样的;

DEL

功能:删除指定的key

语法:

DEL key [key ...]

时间复杂度:O(1)

返回值:删除掉的key的个数

示例:

说明:我们要联系Redis的定位用途,他是作为缓存来存放热点数据的,全量的数据是存放在MySQL中的;删除一个key一般来说问题不大;但是如果把所有的数据或者一大半数据删除了,这种影响会非常的大;因为这样容易把所有的请求打给MySQL,然后MySQL就会被搞挂;相比之下MySQL的全量数据哪怕误删一个数据影响都是很大的;


EXPIRE

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

语法:

EXPIRE key seconds

时间复杂度:O(1)

返回值:1 表⽰设置成功。0 表⽰设置失败。

示例:

说明:

这个命令 有很多的时间限制的业务场景的,例如:手机验证码(该验证码5分钟内有效)、外卖优惠券(该优惠券在指定的时间内有效)等等;


TTL

功能:获取指定 key 的过期时间,秒级

语法:

TTL key

时间复杂度:O(1)

返回值:剩余过期时间。-1 表⽰没有关联过期时间,-2 表⽰ key 不存在。

示例:

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

Redis的key的过期策略是怎么实现的?(经典面试题)

Redis整体策略是定期删除和惰性删除

  • 定期删除:每次抽取一部分,进行验证过期时间;保证抽取检查的过程足够快;
  • 惰性删除:假设这个key已经到过期的时间了,但是暂时还没有处理它,key还存在;紧接着后面又一次访问,正号用到了这个key,于是这次访问就会让Redis触发机制删除key的操作,同时在返回一个nil;

虽然有了上述两种策略结合整体效果一般,仍然可能会有很多过期的key被残留没有被即使删除;Redis为了对上述进行了补充,还提供了一系列的内存淘汰策略,我会在后面的文章中提到;


TYPE 

功能:返回key对应的数据类型

语法:

TYPE key

时间复杂度:O(1)

返回值:none , string , list , set , zset , hash and stream .

示例:

本篇文章只是抛砖引⽟,给出⼏个通⽤的命令,为 5 种数据结构的使⽤做⼀个热⾝,后续章节将对
键管理做⼀个更为详细的介绍。 

数据结构的内部编码

type 命令实际返回的就是当前键的数据结构类型,它们分别是:string(字符串)、list(列
表)、hash(哈希)、set(集合)、zset(有序集合),但这些只是 Redis 对外的数据结构

Redis的5中数据类型

实际上 Redis 针对每种数据结构都有⾃⼰的底层内部编码实现,⽽且是多种实现,这样 Redis 会
在合适的场景选择合适的内部编码

Redis数据结构和内部编码

可以看到每种数据结构都有⾄少两种以上的内部编码实现,例如 list 数据结构包含了 linkedlist 和
ziplist 两种内部编码。同时有些内部编码,例如 ziplist,可以作为多种数据结构的内部实现,可以通过 object encoding 命令查询内部编码:

可以看到 hello 对应值的内部编码是 embstr,键 mylist 对应值的内部编码是 ziplist。
Redis 这样设计有两个好处:

  1. 可以改进内部编码,⽽对外的数据结构和命令没有任何影响,这样⼀旦开发出更优秀的内部编码,⽆需改动外部数据结构和命令,例如 Redis 3.2 提供了 quicklist,结合了 ziplist 和 linkedlist 两者的优势,为列表类型提供了⼀种更为优秀的内部编码实现,⽽对⽤⼾来说基本⽆感知。
  2. 多种内部编码实现可以在不同场景下发挥各⾃的优势,例如 ziplist ⽐较节省内存,但是在列表元素⽐较多的情况下,性能会下降,这时候 Redis 会根据配置选项将列表类型的内部实现转换为linkedlist,整个过程⽤⼾同样⽆感知。 

单线程架构

Redis只是用一个线程来处理所有的命令请求,不是说一个Redis服务器进程内部真的只有一个线程,其实也有多个线程,多个线程是在 处理网络IO;

当有很多的客户端同时并发的对Redis服务器发起了请求;此时的服务器并不会因此而产生线程安全问题,因为Redis服务器实际上是采用单线程模型的,保证当前收到的多个请求是串行执行的;

多个请求同时到达Redis服务器时,也是要在队列中排队;再等待Redis服务器一个一个的取出里面的命令再执行;

Redis能够使用单线程模型很好的工作,原因主要在于Redis的核心业务逻辑都是短平快的,不太消耗CPU资源;

因此它的单线程模型也是它的缺点:使用Redis必须特别小心,某个操作占用时间太长,就会阻塞其他命令的执行;如果某个命令执⾏过⻓,会导致其他命令全部处于等待队列中,迟迟等不到响应,造成客⼾端的阻塞,对于 Redis 这种⾼性能的服务来说是⾮常严重的,所以 Redis 是⾯向快速执⾏场景的数据库。

为什么单线程还能这么块?(经典面试题)

  1. 就如上面所说Redis核心功能,比其他数据库的核心功能更简单
  2. 纯内存访问。Redis 将所有数据放在内存中,内存的响应时⻓⼤约为 100 纳秒,这是 Redis 达到每秒万级别访问的重要基础。其他数据库是访问硬盘。
  3. 单线程避免了线程切换和竞态产⽣的消耗。单线程可以简化数据结构和算法的实现,让程序模型更简单;其次多线程避免了在线程竞争同⼀份共享数据时带来的切换和等待消耗。
  4. ⾮阻塞 IO。Redis 使⽤ epoll 作为 I/O 多路复⽤技术的实现,再加上 Redis ⾃⾝的事件处理模型将 epoll 中的连接、读写、关闭都转换为事件,不在⽹络 I/O 上浪费过多的时间;也就是再处理网络IO的时候使用了IO多路复用机制

今天对Redis常用命令、内部编码、单线程模型的分享到这就结束了,希望大家读完后有很大的收获,也可以在评论区点评文章中的内容和分享自己的看法;个人主页还有很多精彩的内容。您三连的支持就是我前进的动力,感谢大家的支持!!! 

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

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

相关文章

easyrecovery和diskgenius哪个好 easyrecovery好用吗 diskgenius值得买吗

随着数据存储重要性的不断增加,数据丢失问题变得让人越来越担忧。当文件因为操作不慎、存储文件的介质损坏或其他原因导致数据丢失时,人们迫切需要一种强大的数据恢复工具来帮助他们找回丢失的文件。在这篇文章中,我们将比较两款知名的数据恢…

[Bugku] web-CTF靶场系列系列详解④!!!

平台为“山东安信安全技术有限公司”自研CTF/AWD一体化平台,部分赛题采用动态FLAG形式,避免直接抄袭答案。 平台有题库、赛事预告、工具库、Writeup库等模块。 --------------------------------- eval 开启环境: 进入页面发现是一道php题&…

axios请求响应拦截器

目录 axios-拦截器 拦截器的作用 请求拦截器-基本写法: axios请求拦截器-统一设置token 需求: 核心步骤: 关键代码: 响应拦截器-基本写法: axios响应拦截器-统一处理token失效 需求: 核心步骤: 关键代码: axios响应拦截器-数据剥离 需求: 核心步骤: 关键代码: ax…

试用AWS全新神器:Amazon Bedrock的「Open Artifacts」版Claude.ai Artifacts

Claude.ai的Artifacts真是太方便了。 GitHub上的AWS Samples仓库中有一个仿制Artifacts的应用程序。 Open Artifacts for Amazon Bedrock https://github.com/aws-samples/open_artifacts_for_bedrockhttps://github.com/aws-samples/open_artifacts_for_bedrock本文将介绍「…

【Java算法专场】前缀和(下)

目录 和为 K 的子数组 算法分析 算法步骤 算法代码 算法示例 和可被 K 整除的子数组 算法分析 同余定理 负数取余 算法步骤 算法代码 算法示例 连续数组 算法分析 算法步骤 算法代码 算法示例 矩阵区域和 算法分析 算法步骤 算法代码 算法示例 算法分析 …

1008 Elevator(Java)

题目 解释 输入数字N,数字N后面跟着N个数字代表着目的楼层,起始点是0层,每上升一层花费6秒,每下降一层花费4秒,每达到一个目的楼层,电梯会停5秒。问你一共花费多少秒? 解题思路 这道题不难&a…

【论文笔记】Matching Anything by Segmenting Anything

【引用格式】:Li S, Ke L, Danelljan M, et al. Matching Anything by Segmenting Anything[C]//Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition. 2024: 18963-18973. 【网址】:https://openaccess.thecvf.com/co…

【Python】把list转换成json文件(list中为字典,元素按行写入)

0.前言 数据需要处理成与大模型输入相同类型的数据,从csv文件读出后,想要转换成json文件,看了好多资料都是把整个list写入了json,并不是我想要的格式,这里记录一下最后的按行写入的格式。 1.list转json import json …

Camtasia怎么自动加字幕 Camtasia怎么设置字幕

为了防止观众听不清楚视频中的解说声音,在进行视频编辑时,往往需要添加字幕。但是,你是否觉得一个一个添加字幕有些麻烦?使用Camtasia时,有没有什么能够快速、方便添加字幕的方法呢?添加字幕后,…

Docker 环境下使用 Traefik 3 的最佳实践:快速上手

Traefik 最近终于发布了大版本升级后的第一个修正版本,或许是时候正式迁移程序到新版本了。 写在前面 最近 Traefik 发布了 3.1 版本。作为从 Traefik 1.x 开始使用的用户,Traefik 每个大版本升级都会出现一些配置不兼容的情况,这次 3.x 的正…

DC-DC芯片:MT2492说明

文章目录 一. MT2492介绍1. 特点2. 应用3. 额定值4. 电气特性5. 引脚说明6. 典型应用电路 二. 功能说明内部调节器过电流保护和打嗝模式误差放大器启动和关闭内部软启动设置输出电压电感器的选择输入电容器的选择输入电容器的选择PCB布局建议 一. MT2492介绍 MT2492是一款完全…

LaneATT推理详解及部署实现(下)

目录 前言一、LaneATT推理(Python)1. LaneATT预测2. LaneATT预处理3. LaneATT后处理4. LaneATT推理 二、LaneATT推理(C)1. ONNX导出2. LaneATT预处理3. LaneATT后处理4. LaneATT推理 三、LaneATT部署1. 源码下载2. 环境配置2.1 配置CMakeLists.txt2.2 配置Makefile 3. ONNX导出…

平衡二叉树 - 力扣(LeetCode) C语言

110. 平衡二叉树 - 力扣(LeetCode)(点击前面链接即可查看题目) 一、题目 给定一个二叉树,判断它是否是 平衡二叉树 是指该树所有节点的左右子树的深度相差不超过 1。 示例 1: 输入:root […

计量经济学(十六)--一文读懂和学会医学统计学中的四种检验方法

1. 统计学是什么? 统计学是应用数学的一个分支,主要通过利用概率论建立数学模型,收集所观察系统的数据,进行量化的分析、总结,并进而进行推断和预测,为相关决策提供依据和参考。它被广泛的应用在各门学科之上,从物理和社会科学到人文科学,甚至被用来工商业及政府的情报…

原神自定义倒计时

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><title>原神倒计时</title><style>* {margin: 0;padding: 0;box-sizing: border-box;user-select: none;body {background: #0b1b2c;}}header {…

C++ ---- vector的底层原理剖析及其实现

vector 一、定义二、常用接口及模拟实现三、vector迭代器失效问题四、使用memcpy拷贝会出现的问题五、二维数组vector<vector< T >> vv 一、定义 vector 是 C 标准模板库&#xff08;Standard Template Library, STL&#xff09;中的一个非常有用的容器。它是一个…

SD卡受损数据会消失吗 内存卡坏了数据还能恢复吗 SD卡受损里面的数据怎么办 sd卡受损最简单的修复方法

SD卡里的数据有时候也容易出现消失或者遭到破坏等情况&#xff0c;针对此类情况&#xff0c;给大家详细讲解&#xff0c;SD卡受损数据会消失吗&#xff0c;以及SD卡受损了里面的数据怎么办。 一、SD卡受损数据会消失吗 SD卡本身比较小巧&#xff0c;里面的小芯片比较密集&…

04 RabbitMQ:控制界面详解

04 RabbitMQ&#xff1a;控制界面详解 1. 控制台界面2. 控制界面详解2.1. Overview&#xff08;概览&#xff09;2.1.1. Totals&#xff08;总数&#xff09;2.1.1.1. Queued messages2.1.1.2. Message rates2.1.1.3. Global counts 2.1.2. Nodes&#xff08;节点消息&#xff…

SpringBoot多数据源事务处理

多数据源时,一般会配置多个事务管理器 Spring编程式 第二种方式 不可能去同一个方法上写两个事务注解 不允许 SpringBoot 2.6.0之后禁止自己注入自己 本来可以自己注入自己去调用 (为什么要自己注入自己调用,AOP代理,类不是自己写的类) 最简单方式 引入 <dependency&…

DPDK基础入门(一):认识和理解DPDK

Linux的网络瓶颈 以Linux为例&#xff0c;传统网络设备驱动包处理的动作可以概括如下&#xff1a; 数据包到达网卡设备。网卡设备依据配置进行DMA操作。网卡发送中断&#xff0c;唤醒处理器。驱动软件填充读写缓冲区数据结构。数据报文达到内核协议栈&#xff0c;进行高层处理…