【Redis】常用命令

在学习命令之前,我们一定要参考Redis的官网,能够看英文官方文档,是每个程序员的"基操".

🐼Redis最核心的命令

我们说过,Redis是按照键值对的方式来存储数据的。

GET

cpp 复制代码
GET key

通过key获取value, 如果 key 不存在,返回 nil。如果 value 的数据类型不是 string,会报错。时间复杂度O(1)

SET

cpp 复制代码
SET key value 

设置键值对[key, value], 将 string 类型的 value 设置到 key 中。如果 key 之前存在,则覆盖,⽆论原来的数据类型是什么。之前关于此 key 的 TTL 也全部失效。时间复杂度O(1)

不管是set还是get,其中key和value都是字符串

Redis不区分大小写,和MySQL一样。

为什么他俩是最核心的两个命令吗,不就是一个读,一个写,与Redis通过网络进行IO,通过这两个O(1)时间复杂度的操作,我们就能完成绝大部分操作了。


🐼Redis全局命令

我们说了,Redis是键值对结构,其中key是固定字符串,其中value表示很多数据结构类型,Redis 有 5 种数据结构,不过对于键来说有⼀些通用的命令,而value对于不同的容器我们到时候再去看。

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

✅KEYS

返回所有满足样式(pattern)的 key,该命令可以看到的是每一个key的模样,同时也可以允许存在通配符等,当我们不确定我们的redis中有哪些key时,可以试着来查找

cpp 复制代码
KEYS pattern

来看一下官网给的pattern的介绍,主要是一些通配符的匹配规则,忘记了去官网查即可。

cpp 复制代码
h?llo matches hello, hallo and hxllo  # ?表示匹配任意一个字符。
h*llo matches hllo and heeeello # *表示可以匹配一个或者多个任意个字符。
h[ae]llo matches hello and hallo, but not hillo # [....]表示可以从中匹配这些字符,不再[]中的字符不行。
h[^e]llo matches hallo, hbllo, ... but not hello # 表示除e的字符其他都行
h[a-b]llo matches hallo and hbllo # 表示匹配 [a, b]之间的字符,包括边界

注意事项:

keys的时间复杂度为O(N),因此,不建议使用keys,在生产环境上,明确禁止使用keys,尤其是像keys * 这样的导致Redis挂掉的命令

🚩为啥嘞,首先生产环境就是线上环境,就是和用户交互的环境,你在线上环境搞个这,因为Redis是基于网络的,是客户端服务器的模式,而且Redis是单线程的,又不单单是服务你一个客户端,如果你这个客户端发一个key*,导致Redis只为你一个人服务了,导致其他用户的访问都去MySQL那里了,MySQL它又很"娇气",一不小心就挂了,所以,强烈禁止,不要让站在MySQL背后的哪个男人-Redis阻塞住!它在为MySQL负重前行嘞!

**✅**EXISTS

判断KEY是否存在

cpp 复制代码
EXISTS key [key ...]

返回值为Key存在的个数,也就是我们可以一次性判断多个key是否存在,存在几个就返回几!

时间复杂度为O(1),官网写的是O(N)其中这个N就是key的个数,这个N是多少,不好说,但你一次性要判断的KEY不能特别多对吧,所以就是O(1).

注意下面这两种写法的区别:

🚩第一种写法和第二种分两次写,有啥区别吗?

其实,有本质的区别,我们知道我们的redis是客户端服务器通信的,我们每操控的一条命令,都是基于网络发给redis-server的,然后redis-server处理完再发给我们。相比于操控在内存,是很慢的,走网络就有开销,比如os什么时候刷新网卡?网卡IO效率还慢,还得封装分用。那么你说一次命令完成的事情,走两次,哪个好?

redis也意识到了这一点,所以redis支持一次性一个命令来操作多个key完成多种操作。

✅DEL

删除指定的 key

cpp 复制代码
DEL key [key ...]

返回值依旧是成功删除掉key的个数。时间复杂度为O(1)

🚩这里需要注意一下,就是之前学的MySQL,是很忌讳你去删除东西的,这里Redis呢?在Redis中删除东西,要看你Redis是缓存还是被当做数据库使用了,如果你仅仅是一个热点数据,全量数据在MySQL中,那么删除几个key,问题不大,不过删多了,可能导致热点数据命中率不高,进而导致MySQL挂掉。但是如果Redis被当做数据库使用,那么此时就不敢随意删除了,一旦删除,可能不能进行回滚操作,导致数据丢失了~归根结底,还是不要乱删数据!

✅EXPIRE

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

返回1表示设置成功。0 表示设置失败。时间复杂度为O(1)

cpp 复制代码
EXPIRE key seconds

怎么理解这个过期时间,就是如果你的key超过这个过期时间,就会被自动删除~

✅TTL

全称为time to live

获取已经存在的指定 key 的过期时间,秒级

返回值:剩余过期时间。-1 表示没有关联过期时间,-2 表示key 不存在。时间复杂度为O(1)

cpp 复制代码
 TTL key

通长这个命令配合expire来使用,来查看过期时间的。

✅TYPE

返回 key 对应value的数据类型

时间复杂度为O(1)

cpp 复制代码
TYPE key

返回值包括: returned are: string, list, set, zset, hash, stream, and vectorset.

对于以上value的操作,操作差别很大, 命令是完全不同的,但是我们都可以使用type来看看对应的key的value到底是啥~


🐼扩展知识(面试题)

Redis中的key的过期时间是怎么实现的?Redis中的key那么多,你怎么知道哪些key要被删除,哪些key不被删除,哪些key还没过期?如果我们直接遍历所有的key,那么"杀伤力"不亚于key *

主要有两种方式:

✅定期删除

每次抽取一部分,进行验证过期时间,保证这个抽取过程是足够快的!为什么要保证足够快呢?或者说为什么要进行抽取呢?原因是Redis是单线程程序,主要任务是执行每个命令的任务,如果抽取过程占用的时间太久,导致其他客户端的连接是阻塞的,就类似与执行key*咯

✅惰性删除

假设这个key已经过期,但是暂时还没删它,key还存在,紧接着,redis-cli后面又再一次访问到了这个key,然后再将它删除,并返回给客户端nil。

虽然上述两种操作可以删除过期的key,但是效果一般,并不能保证所有key及时删除。不过redis进行了一写淘汰策略的机制。


这里有一个有意思的故事:

为什么没有使用定时器?

网上有人说,Redis的删除key的策略如果是根据定时器来完成的,那么不靠谱。真的是这样吗?

其实不然,Redis的作者并没有实现定时器,猜测因为Redis完全就是一个线程的基调,引入定时器,就意味着引入了多线程。为了不打破作者的初衷,这里并没有引入多线程。也没有引入定时器了!

定时器真的不靠谱吗?我们来看一下常用的两种定时器:

⌚️根据优先级队列实现的定时器

优先级队列就是按照指定的优先级进行先入先出的,啥叫优先级高,自定义的~

在redis删除key的场景中,就可以通过"过期时间越早,优先级越高的方式",那么队首元素,就是最早的key,最先过期的,所以我们只需要分配一个线程,取出队首元素,看看是不是需要删除即可,如果队首都没过期,那么所有key都没过期~此时,我们就不需要遍历key了

⌚️根据时间轮来实现定时器

把时间划分为一个个小段,就是一个小格子,小段的粒度,看具体的场景。比如,将时间段为每100ms一次,而每一个格子上挂接这一个个链表,这一个个链表的节点,可能是 一个任务,每隔100ms,小格子都移动一格,尝试把对应任务执行一下,如图:

如果删除key操作使用定时器看起来是高效的,而没有使用定时器也不是网上所说的,还是Redis的初衷就是单线程的基调~

相关推荐
松涛和鸣2 小时前
72、IMX6ULL驱动实战:设备树(DTS/DTB)+ GPIO子系统+Platform总线
linux·服务器·arm开发·数据库·单片机
likangbinlxa2 小时前
【Oracle11g SQL详解】UPDATE 和 DELETE 操作的正确使用
数据库·sql
r i c k3 小时前
数据库系统学习笔记
数据库·笔记·学习
野犬寒鸦3 小时前
从零起步学习JVM || 第一章:类加载器与双亲委派机制模型详解
java·jvm·数据库·后端·学习
IvorySQL4 小时前
PostgreSQL 分区表的 ALTER TABLE 语句执行机制解析
数据库·postgresql·开源
·云扬·4 小时前
MySQL 8.0 Redo Log 归档与禁用实战指南
android·数据库·mysql
IT邦德4 小时前
Oracle 26ai DataGuard 搭建(RAC到单机)
数据库·oracle
惊讶的猫4 小时前
redis分片集群
数据库·redis·缓存·分片集群·海量数据存储·高并发写
不爱缺氧i5 小时前
完全卸载MariaDB
数据库·mariadb
期待のcode5 小时前
Redis的主从复制与集群
运维·服务器·redis