Redis 学习笔记

发布于:2025-09-08 ⋅ 阅读:(28) ⋅ 点赞:(0)

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

redis 是一个客户端-服务器结构的程序,客户端和服务器之间通过网络来进行通信。

在启动redis客户端的时候,加上一个 --raw 这样的选项,就可以使 redis 客户端尝试把二进制数据进行翻译。

加上 --raw 之前:image-20250906160734241

加上后:image-20250906160938093

redis 命令

redis 命令官方文档:Commands | Docs

redis 文档给出的语法格式说明:

[] 相当于一个独立的单元,表示可选项。

| 表示“或者”的意思。

[] 和 [] 之间,是可以同时存在的。

redis 命令不区分大小写

进入redis

redis-cli

存数据

设置一个键值对

set key value
  • key 是字符串
  • 这个命令后面可以跟很多参数,去看看官方文档

设置多个键值对

mset key value [key value...]
  • 时间复杂度O(N),这里的N指的是你输入key、value 的数量

image-20250906145834308

因为 redis 的客户端和服务器之间是靠网络来进行交互的,而网络的传输速度又比较慢,当需要设置多个 key 时,更推荐使用 mset 来进行设置。

当key不存在时,则设置成功,key不存在时,设置失败

setnx key value

设置key的过期时间

单位: 秒

setex key 秒 value

单位:毫秒

psetex key 毫秒 value

拿数据

获取一个value

get key
  • 如果当前 key 不存在,则返回 nil
  • get命令只能拿字符串类型的value

获取多个value

mget key [key...]
  • 时间复杂度O(N),这里的N指的是你输入 key 的数量

image-20250906145834308

因为 redis 的客户端和服务器之间是靠网络来进行交互的,而网络的传输速度又比较慢,当需要获取多个 value 时,更推荐使用 mget 来进行设置。


用来查询当前服务器上匹配的key

keys pattern
  • pattern:正则表达式
  • keys 命令的时间复杂度是 O(N)

判断 key 是否存在

exists key
  • exists 会返回 key 存在的个数
  • exist 命令的时间复杂度是 O(1)

删除 数据

del key [key ...]
  • del 可以一次性删除多个 key
  • del 会返回删除 key 的个数
  • del 命令的时间复杂度为O(1)

添加过期时间(秒)

expire key 秒数
  • 时间复杂度 O(1)

  • 返回值:1 表示设置成功;0表示设置失败

添加过期时间 (毫秒)

pexpire key 毫秒数
  • 时间复杂度 O(1)
  • 返回值:1 表示设置成功;0表示设置失败

查询过期时间(秒)

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

查询过期时间(毫秒)

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

type 查看key所对应的value的类型

type key
  • redis 中的key的类型为string

  • redis 中的value的类型可以为 none,list,zset,set,string,hash,stream。

  • 时间复杂度 O(1)

    image-20250904165618451

    stream:在redis作为消息队列时,使用这个类型的value


查看key所对应value的编码类型

object encoding key

image-20250906105724123


字符串类型

image-20250907120632395

让key所对应的value + 1

incr key

让key所对应的value + n

incrby key 数字

让key所对应的value - 1

decr key

让key所对应的value - n

decrby key 数字
  • 以上命令操作的 value 必须为整数,否则报错。若操作的 value 大于8个字节,则报错。

  • 若以上命令操作的 key 不存在,则就会把这个 key 的 value 当作 0 来使用。

  • 以上命令的返回值都为 value 加/减 操作完成后的值。例如:

让key所对应的 value +/- n

incrbyfloat key 小数
  • value 必须为数字,否则报错。

  • 若命令操作的 key 不存在,则就会把这个 key 的 value 当作 0 来使用。

  • 返回值为 value 加/减 操作完成后的值

当多个客户端同时针对key进行加减操作时,不会出现“线程安全”问题。因为 redis 采用了单线程模型


让 key 所对应的 value 的后面加上 指定的字符串

append key 字符串
  • key 对应的 value 必须为字符串类型。
  • 如果 key 不存在,则该命令等价于 set 命令
  • 返回值:字符串的长度,单位:字节

截取 字符串

getrange key start end
  • key 对应的 value 必须为字符串类型。
  • 截取范围是 [start,end],闭区间
  • 如果截取汉字,得到的结果很可能不是你想要的
  • 范围可以为负数,比如 -1 表示倒数第一个元素,下标为 len - 1 的元素
  • 返回值:截取后的字符串

替换 字符串

setrange key offset 字符串
  • key 对应的 value 必须为字符串类型。offset 表示替换开始的位置
  • 如果截取汉字,得到的结果很可能不是你想要的
  • 返回值为替换后的字符串长度
  • 当 key 不存在时:image-20250906170515165

查看字符串长度

strlen key
  • key 对应的 value 必须为字符串类型。
  • 返回值:字符串长度,单位 字节

字符串的使用场景

redis 常用数据结构

redis 做了一个承诺,承诺插入、查询、删除操作的时间复杂度为 O(1)

在redis中使用string等数据类型时,redis对这些类型做了特殊优化,它的内部编码方式可能不是string等数据类型,而是其他类型,但是依然保证承诺有效。

image-20250904172452044

string 类型:

  • raw 可以存储较长的字符串,各种类型的字符串
  • int 存储数字类型的字符串
  • embstr 存储比较短的字符串

hash 类型:

  • hashtable:最基本的哈希表
  • ziplist:压缩列表,当哈希表中的数据较少时,做的特殊优化,可以节省空间

list 类型:

  • linkedlist:基本的链表
  • ziplist:压缩列表

从 redis 3.2 版本开始,list 的内部编码使用的是 quicklist(将linkedlist与ziplist的优点相结合)

set 类型:

  • hashtable:最基本的哈希表
  • intset:存储整数的set

zset 类型:

  • skiplist:跳表,每个节点上有多个指针域。从调表上查询元素的时间复杂度为 O(log N)
  • ziplist:压缩列表

redis 的应用场景

作为缓存

redis 可以用来作为缓存,存储热点数据。

image-20250907130332227

当服务器接收到查询请求时,请求会先去redis中查找,如果查到了,直接返回响应。如果没查到,则去 mysql 中查询,查询到数据后,将数据写入到 redis 中,之后返回响应。

问题:redis 每次没查到数据,之后会将数据写入 redis 中,那么 redis 使用的内存会不会一直增加?

答:每次将查询到的数据写入 redis 中时,可以给数据添加一个超时时间。其次,redis 也提供了内存淘汰机制。


redis 小知识

redis 删除策略

  • 定期删除,每过一段时间,redis会随机抽查一些设置过 过期时间的key,把过期的key删除

  • 惰性删除相结合,当一个key过期时,redis并不会立即删除这个key,而是等到下次用到时,再进行删除操作。

经过上面两个删除策略后,仍然会残留很多过期的key。为了解决这个问题,redis又引入了内存淘汰机制。


redis 是单线程模型,它只用一个线程来处理命令请求。也不是说redis服务器内部真的只有一个线程,其实也有多线程,只不过多线程是用来处理网络IO的。

因为redis是单线程模型,所以当两个自增请求同时到达并且还是操作同一个对象时,redis 不会出现只自增了一次的情况,因为虽然这两个请求都是同时到达的,但是实际上它们是串行执行的(因为只有一个线程在处理请求)。

单线程模型的优点:

  • 不需要加锁解锁,减少了性能开销

  • 不会出现线程安全问题

  • 代码简单易懂,维护起来方便

单线程模型的缺点:

  • 当一条命令耗费时间过长时,会阻塞其他命令的执行。

redis为什么就可以使用单线程模型呢?

因为 redis 的核心业务逻辑都是短平快的,不太消耗 cpu,也就不太吃多核了。


redis 是单线程模型,为啥效率还这么高、速度这么快呢?

因为 redis 操作数据都是在内存中完成的,而在内存中处理数据本来就很快。redis的核心功能也比较简单,就是对数据简单的处理一下。redis 的瓶颈不在于 cpu,而在于 网络 IO 的读写速度,redis 采取了 epoll 这样的 IO 多路复用机制。再一个,redis 的数据结构都经过优化,对数据操作的时间复杂度都在 O(1)或 O(logN)之内。还有,单线程模型它不需要加锁解锁等操作,不需要额外消耗 cpu。

IO多路复用:IO多路复用——深入浅出理解select、poll、epoll的实现 - 知乎

简单来说就是一个线程处理多个 socket


redis 不会将存储的数据进行编码转换,这也就意味着出现乱码的概率降低。redis中存储的都是二进制数据。



网站公告

今日签到

点亮在社区的每一天
去签到