Redis --- 第三讲 --- 通用命令

一、get和set命令

Redis中最核心的两个命令

get 根据key来取value

set 把key和value存储进去

redis是按照键值对的方式存储数据的。必须要先进入到redis客户端。

语法 set key value  : key和value都是字符串。

对于上述这里的key value 不需要加上引号,就是表示字符串,加上引号也无伤大雅。redis中的命令不区分大小写。

使用get得到key对应的value值。

get命令直接输入key就能得到value。如果当前key不存在,返回nil,和null/NULL就是一个意思。

redis使用简单,学习成本很低。

二、全局命令

Redis全局命令

Redis是支持很多种数据结构的,整体上来说,Redis是键值对结构,key固定都是字符串,value实际上会有多种类型。比如字符串,哈希表,列表,集合,有序集合等等。每种数据结构都会对应着不同的命令,而全局命令就是能够搭配任意一个数据结构来使用的命令。

1)keys命令 用来查询当前服务器上匹配的key

通过一些特殊符号来描述key的模样,匹配上述模样的key就能被查询出来。 

语法:keys pattern 

pattern 包含特殊符号的字符串,有的地方翻译成样式或者模式。重点去认识这个英文术语。存在的意义,是去描述另外的字符串长啥样。

pattern具体咋写,支持哪些通配符呢

?匹配任意一个字符

*匹配0个任意多个字符

[ae] 只能匹配到ae,别的不行,相当于给出固定选项了

[^e] 排除e,只有e匹配不了,其他的都能匹配。

[a - e] 匹配a - e这个范围内的字符,包含两侧边界。

设置这样的key,通过上述的匹配方法进行查询

上述的匹配规则不需要去背。要查询文档。

keys命令的时间复杂度是O(N)。所以在生产环境上,一般都会禁止使用keys命令,尤其是大杀器keys * 。查询redis中所有的key!生产环境上的key可能会非常多!而redis是一个单线程的服务器,执行keys * 的时间非常长,就是redis服务器被阻塞了。无法给其他客户端提供服务。这样的后果可能是灾难性的。redis经常会用于做缓存,挡在mysql前面。替mysql负重前行。万一redis被一个keys * 阻塞住了,此时其他的查询redis操作就超时了。此时这些请求就会直接查数据库。突然一大波请求到来,mysql措手不及,会把它给搞挂了。这个操作非常危险,容易把工作给搞丢。那你就得让你的媳妇吃土或者喝西北风了,很可能你的媳妇就跟别人跑了。(开个小玩笑)。

穿插一个概念,叫做生产环境(线上环境):

未来的工作中会涉及到几个环境:

1、办公环境(入职之后,公司给你发个电脑)

笔记本电脑/台式机。

2、开发环境:有的时候,开发环境和办公环境是一个,有的时候,开发环境是单独的服务器,做前端/客户端,一般来说开发环境就是办公环境了。后端来说,很可能是单独的服务器,有的后端程序,会比较复杂。

1)一次时间特别久。

2)有的程序,启动要消耗很多的cpu和内存资源。办公电脑难以支撑。

3)有的程序比较依赖linux,在windows环境搭不起来。

3、测试环境(测试工程师用的)

4、线上环境/生产环境

(办公环境,开发环境,测试环境,统称为线下环境,外界用户无法访问到的)。线上环境则是外界用户能够访问到的。一旦生产环境出问题,一定会对于用户的使用产生影响!直接的影响到公司营收。

未来咱们去操作线上环境的任何一个设备/程序都要怀着12分的谨慎。

2)exists命令

exists判定key是否存在

语法:

返回值:key存在的个数。键值对存储的体系中(类似于哈希表)key得是唯一的呀。

这里的个数对于多个key来说是非常有用的 。他的查询复杂度为O(1),redis组织这些key就是按照哈希表的方式来组织的。

redis支持很多数据结构 =》指的是一个value可以是一些复杂的数据结构,redis自身的这些键值对,是通过哈希表的方式来组织的。redis具体的某个值,又可以是一些数据结构。

分开查询和一起查询会有什么区别吗。

我们要知道,redis是一个客户端,服务器结构的程序。客户端和服务器之间通过网络来进行通信!我们所敲的命令都会构建一个请求发送给服务器,服务器返回回复报文。要进行网络通信,它是相对于内存来说,效率比较低,成本比较高。

进行网络通信的时候,发送方发送一个数据,这个数据就要从应用层,到物理层,层层封装。势必会导致传输速度慢。所以我们要尽量少发请求。能用一个命令不用两个命令。

3)del(delete)删除指定的key

语法,返回值:删除掉的key的个数。

redis主要的应用场景,就是作为缓存,此时redis里存的只是一个热点数据,全量数据是在mysql数据库中。此时如果把redis中的key删除了几个,一般来说,问题不大。但是如果把所有的数据或者一大半数据一下都干没了,这种影响会很大。相比之下,如果是mysql这样的数据,哪怕误删了一个数据,都可能影响很大的。如果把redis作为数据库,此时误删数据的影响就大了。如果把redis作为消息队列,这种情况误删数据就得按情况来具体分析了。所以我们不能乱删数据。自己挖坑自己跳,得不偿失。

4)expire命令

作用是给指定的key设置过期时间,key存活时间超出这个指定的值,就会被自动删除。设置的时间单位是秒。基于redis实现分布式锁,为了避免出现不能正确解锁的情况,通常都会在加锁的时候设置一下过期时间(所谓的使用redis作为分布式锁,就是给redis里写一个特殊的key value)。

语法:

pexpire key mseconds 毫秒级

返回值:1成功,0失败

此处的设定的过期时间,必须是针对已经存在的key设置,设置成功返回1,设置失败返回0。时间复杂度也是O(1)。

过期后get不到value。

5)ttl命令

ttl time to live 存活时间。网络原理IP协议报头中,有一个字段TTL。IP中的TTL不是用时间衡量过期的,而是用次数。

ttl是一个时间。查看当前key的过期时间还剩多少

pttl查询毫秒级的key的过期时间。

时间复杂度也是O(1)。

redis的key的过期策略 【经典面试题】

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

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

如果直接遍历所有的key,显然是行不通的,效率非常低。

redis整体的策略是:

1、定期删除:此处也需要结合定期删除的操作,每次抽出一部分验证过期时间,保证这个抽取检查的过程足够快。对于定期删除的时间,有明确的要求:因为redis是单线程的程序。主要的任务(处理每个命令的任务,刚才扫描过期的key)如果扫描过期key消耗的时间太多了,就可能导致正常处理请求命令就被阻塞了,产生了类似key *这样的效果。

2、惰性删除:假设这个key已经到过期时间了,但是暂时还没删它,key还存在,紧接着,后面有一次访问,正好用到了这个key,于是这次访问就会让redis服务器触发删除key的操作,同时在返回一个nil。

虽然有了上述两种策略结合,整体的效果一般,仍然可能会有很多过期的key被残留了,没有及时删除掉,redis为了对上述进行补充,还提供了一系列的内存淘汰机制。

1)redis中并没有采取定时器的方式来实现过期key删除

2)如果有多个key过期,也可以通过一个定时器来高效/节省cpu的前提下来处理多个key。

为啥redis没有采取这种定时器的方式呢?

很难考证为啥,个人的猜测:基于定时器实现,势必就要引入多线程了。redis早期版本就是奠定了单线程的基调,引入多线程打破了作者的初衷。

定时器的实现原理:

定时器:在某个时间到达之后,执行指定的任务

1、基于优先级队列/堆

正常的队列是先进先出。而优先级队列则是按照指定的优先级,先出。啥叫优先级高?自定义的。在redis过期key的场景中,就可以通过“过期时间越早,就是优先级越高”。现在假定有很多key设置了过期时间,就可以把这些key加入到优先级队列中,指定优先级规则是过期时间早的先出队列。队首元素就是最早要过期的key!此时定时器中只要分配分配一个线程,让这个线程取检查队首元素,看是否过期即可!如果队首元素没有过期,后续元素一定没过期。此时扫描线程不需要遍历所有key只盯住这一个队首元素即可!另外在扫描线程检查队首元素过期时间的时候,也不能检查太频繁。此时做法就是可以根据当前时刻和队首元素的过期时间设置一个等待。当时间差不多到了,系统再唤醒这个线程。此时扫描线程,不需要高频扫描队首元素,把CPU的开销也节省下来了。

万一在线程休眠的时候,来了一个新的任务是11:30要执行。可以在新任务添加的时候,唤醒一下刚才的线程,重新检查一下队首元素,再根据时间差距重新调整阻塞时间即可。

2、基于时间轮实现的定时器

把时间划分成很多小段(划分的粒度,看实际需求)。

每一个小段上都挂着一个链表,每个链表都代表一个要执行的任务,(相当于一个函数指针,以及对应的参数。有点像jiava中也可以通过对象来实现类似的效果)。 

假设需要添加一个key,这个key在300ms之后过期。添加到第三个格子,每个格子是100毫秒所以是第三个格子,此时这个指针,就会每隔固定的间隔每次走到一个格子,就会把这个格子上链表的任务尝试执行一下。对于时间轮来说,每个各自是多长时间,一共多少个格子都是需要根据实际的场景,灵活调配的。

此处大家注意,Redis并没有采取上述的方案。但是要了解这两种方案,都是属于高效的定时器的实现方式,很多场景可能都会用得到。

6)type命令

返回key对应的value的类型。此处redis所有的key都是string,key对应的value可能会存在多种类型。

stream是redis作为消息队列的时候,使用这个类型的value。

在redis中上述类型操作方式差别很大,使用的命令,都是完全不同的。时间复杂度也是O(1)

小结

当前已经学习了redis中几个基本的全局命令

set:设置一个kv值

get:通过key得到value

keys:用来查看匹配规则的key。

exists:用来判定指定key是否存在。

del:删除指定的key

expire:给key设置过期时间

ttl:查询key的过期时间

type:查询key对应的value的类型。

接下来就是围绕每个数据结构来介绍相关命令了。

当前版本的redis支持10个数据类型。

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

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

相关文章

【基础算法总结】链表篇

目录 一, 链表常用技巧和操作总结二,算法原理和代码实现2.两数相加24.两两交换链表中的节点143.重排链表23.合并k个升序链表25.k个一组翻转链表 三,算法总结 一, 链表常用技巧和操作总结 有关链表的算法题也是一类常见并且经典的题…

Linux命令大全及小例子

撰写一份关于Linux命令大全的详尽报道和分析是一项重要的任务,旨在让读者全面了解Linux命令的用途和应用场景。Linux系统因其强大的命令行工具而闻名,无论是系统管理、文件操作还是网络配置,Linux命令行都提供了灵活且强大的解决方案。以下是…

保险丝基础知识

一、简介 保险丝(fuse)也被称为电流保险丝,它能够在电流异常升高到一定的高度和热度时,自动熔断切断电流,从而保护电路安全运行。 IEC127标准将它定义为“熔断体(fuse-link)”。熔断体是由电阻率比较大而熔…

初识Linux · 文件(1)

目录 前言: 回顾语言层面的文件 理解文件的预备知识 文件和磁盘 使用和认识系统调用函数 前言: 本文以及下篇文章,揭露的都是Linux中文件的奥秘,对于文件来说,初学Linux第一节课接触的就是文件,对于C…

在树莓派上部署开源监控系统 ZoneMinder

原文:https://blog.iyatt.com/?p17425 前言 自己搭建,可以用手里已有的设备,不需要额外买。这套系统的源码是公开的,录像数据也掌握在自己手里,不经过不可控的三方。 支持设置访问账号 可以保存录像,启…

《深入理解java虚拟机》——java内存区域与内存溢出异常

我是很喜欢用java语言编写代码的。从开始学习到现在其实也是在一步步体会java语言的各方面,开始看深入理解java虚拟机这本书觉得java虚拟机的内部感觉就像是一个操作系统,也可以说是个计算机。想要深入的理解我觉得需要先从整体去看。为什么需要java虚拟…

ProtoBuf快速上手

文章目录 创建 .proto文件编译 .proto文件编译后生成的文件序列化与反序列化的使用 此篇文章实现内容: 对一个通讯录的联系人信息,使用PB进行序列化,并将结果输出对序列化的内容使用PB进行反序列化,解析联系人信息并输出联系人信…

redis-数据类型

十大数据类型 学习 redis 操作手册 英文 Commands 中文 Redis命令中心(Redis commands) – Redis中国用户组(CRUG) 学习方法 举出一个数据结构的应用场景(理解数据结构特点),并操作&…

【Java的SPI机制】Java SPI机制:实现灵活的服务扩展

在Java开发中,SPI(Service Provider Interface,服务提供者接口)机制是一种重要的设计模式,它允许在运行时动态地插入或更换组件实现,从而实现框架或库的扩展点。本文将深入浅出地介绍Java SPI机制&#xff…

JAVA开源项目 旅游管理系统 计算机毕业设计

本文项目编号 T 063 ,文末自助获取源码 \color{red}{T063,文末自助获取源码} T063,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析5.4 用例设计 六、核…

TypeScript 封装 Axios 1.7.7

随着Axios版本的不同,类型也在改变,以后怎么写类型? yarn add axios1. 封装Axios 将Axios封装成一个类,同时重新封装request方法 重新封装request有几个好处: 所有的请求将从我们定义的requet请求中发送&#xff…

Vue3实现动态菜单功能

文章目录 0.效果演示1.搭建Vue3项目1.1 vite 脚手架创建 Vue3 项目1.2 设置文件别名1.3 安装配置 element-plus1.4 安装配置路由2.登录页面3.后台管理页面3.1 搭建后台框架3.2 左侧菜单栏3.3 header 用户信息3.4 主要内容3.5 footer4.配置静态路由5.记录激活菜单5.1 el-menu 绑…

信号处理快速傅里叶变换(FFT)的学习

FFT是离散傅立叶变换的快速算法,可以将一个信号变换到频域。有些信号在时域上是很难看出什么特征的,但是如果变换到频域之后,就很容易看出特征了。这就是很多信号分析采用FFT变换的原因。另外,FFT可以将一个信号的频谱提取出来&am…

webpack信息泄露

先看看webpack中文网给出的解释 webpack 是一个模块打包器。它的主要目标是将 JavaScript 文件打包在一起,打包后的文件用于在浏览器中使用,但它也能够胜任转换、打包或包裹任何资源。 如果未正确配置,会生成一个.map文件,它包含了原始JavaScript代码的映…

课设实验-数据结构-线性表-手机销售

题目&#xff1a; 代码&#xff1a; #include<stdio.h> #include<string.h> #define MaxSize 10 //定义顺序表最大长度 //定义手机结构体类型 typedef struct {char PMod[10];//手机型号int PPri;//价格int PNum;//库存量 }PhoType; //手机类型 //记录手机的顺序…

【HTTP(3)】(状态码,https)

【认识状态码】 状态码最重要的目的&#xff0c;就是反馈给浏览器:这次请求是否成功&#xff0c;若失败&#xff0c;则出现失败原因 常见状态码: 200:OK&#xff0c;表示成功 404:Not Found&#xff0c;浏览器访问的资源在服务器上没有找到 403:Forbidden&#xff0c;访问被…

springboot系列--web相关知识探索三

一、前言 web相关知识探索二中研究了请求是如何映射到具体接口&#xff08;方法&#xff09;中的&#xff0c;本次文章主要研究请求中所带的参数是如何映射到接口参数中的&#xff0c;也即请求参数如何与接口参数绑定。主要有四种、分别是注解方式、Servlet API方式、复杂参数、…

【案例】距离限制模型透明

开发平台&#xff1a;Unity 2023 开发工具&#xff1a;Unity ShaderGraph   一、效果展示 二、路线图 三、案例分析 核心思路&#xff1a;计算算式&#xff1a;透明值 实际距离 / 最大距离 &#xff08;实际距离 ≤ 最大距离&#xff09;   3.1 说明 | 改变 Alpha 值 在 …

stm32f103调试,程序与定时器同步设置

在调试定时器相关代码时&#xff0c;注意到定时器的中断位总是置1&#xff0c;怀疑代码有问题&#xff0c;经过增大定时器的中断时间&#xff0c;发现定时器与代码调试并不同步&#xff0c;这一点对于调试涉及定时器的代码是非常不利的&#xff0c;这里给出keil调试stm32使定时…

自用Proteus(8.15)常用元器件图示和功能介绍(持续更新...)

文章目录 一、 前言二、新建工程&#xff08;以51单片机流水灯为例&#xff09;2.1 打开软件2.2 建立新工程2.3 创建原理图2.4 不创建PCB布版设计2.5 创建成功2.6 添加元器件2.7 原理图放置完成2.8 编写程序&#xff0c;进行仿真2.9 仿真 三、常用元器件图示和功能介绍3.1 元件…