Redis常见数据结构上

发布于:2024-03-12 ⋅ 阅读:(46) ⋅ 点赞:(0)

目录

前言

基本全局命令

KEYS 

EXISTS

DEL 

EXPIRE 

 TTL 

TYPE

 数据结构和内部编码

单线程架构  

引出单线程模型 

 为什么单线程还这么快?

String字符串

字符串数据类型

常见命令 

SET 

GET

MGET

MSET  

SETNX 

计数命令

INCR 

INCRBY 

 INCRBYFLOAT

其他命令

APPEND 

 GETRANGE 

SETRANGE 

STRLEN  

 内部编码


前言

 Redis提供了5种数据结构,理解每种数据结构的特点对于Redis开发运维⾮常重要

  • 预备知识:几个全局命令,数据结构,内部编码,单线程模式机制分析
  • 5种数据结构的特点、命令使用、应用场景示例
  • 键遍历、数据库管理

基本全局命令

Redis有5种数据结构,但它们都是键值对种的值,对于键来说有⼀些通⽤的命令。

KEYS 

  • h?llo 匹配 hello , hallo和hxllo等
  • h*llo 匹配 hllo,heeeello
  • h[ae]llo 只匹配hallo,hello
  • h[^e]llo 匹配hallo,hbllo...不匹配hello
  • h[a-b]llo 匹配hallo到hbllo

语法:

KEYS pattern

返回值:

匹配pattern的所有key

从上面可以看出

? 只能匹配单个字符,且不能为空

*   可以匹配0到多个字符

[xyz] 可以单独匹配x与y与z,能够匹配[]中的单个字符

^ 就代表非的意思

[a-b] 中间有 ' - '就是a到b的意思即字符在a-b之间的都能匹配   

EXISTS

判断某个key是否存在

语法:

EXISTS key [key ...]

返回值:key存在的个数 

示例:

DEL 

 删除指定的key

语法:

DEL key [key ...]

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

EXPIRE 

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

语法:

EXPIRE key seconds

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

 TTL 

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

语法:

TTL key

 返回值:

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

TYPE

返回key对应的数据类型

语法:

TYPE key

 返回值:none、string、list、set、zset、hash、stream

示例:

 数据结构和内部编码

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

 

 内部编码:

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

这样设计有两个好处:

  • 可以改进内部编码的同时,对外的数据结构和命令使用毫无影响,对用户来说基本无感知
  • 多种编码可以实现在不同场景发挥各自的优势,例如ziplist节省内存,但是在列表元素比较多的情况下性能会下降,这时候Redis就会根据配置选项将列表类型的内部转化成linkedlist,整个过程用户感受不到 

单线程架构  

Redis使⽤了单线程架构来实现⾼性能的内存数据库服务

引出单线程模型 

现在开启三个redis-cli客户端同时在一个redis-server下同时执行命令

客户端1:set hello world

客户端2:incr counter

客户端3:incr counter

虽然这三个命令时同时发送的,但是从微观上看,这些命令还是线性的方式执行的,只是原则上的执行顺序不定,但是一定不会有两条命令同时执行,这就可以想象redis内部只有一个服务窗口,多个客户端按照 他们达到的先后顺序排队在串口前,依次接受Redis的服务,所以客户端2和客户端3同时对counter自增,并不会产生并发问题。 

 为什么单线程还这么快?

通常来讲,单线程处理能⼒要⽐多线程差,那为什么Redis使用单线程模型会达到万级的处理能力呢?

可以归结为一下三点

  • 1.纯内存访问。内存响应时间大约为100纳秒
  • 2.非阻塞IO。Redis使用epoll作为I/O多路复用技术的实现,不在网络I/O上浪费过多时间
  • 3.单线程避免了线程切换和线程竞争产生的小号,简化了模型。

虽然单线程给Redis带来很多好处,但还是有⼀个致命的问题:对于单个命令的执⾏时间都是有
要求的。如果某个命令执⾏过⻓,会导致其他命令全部处于等待队列中,迟迟等不到响应,造成⼾
端的阻塞,对于Redis这种⾼性能的服务来说是⾮常严重的,所以Redis是⾯向快速执⾏场景的数据库。

String字符串

⾸先Redis中所有的键的类型都是字符串类型,⽽且其他⼏种数据结构也都是在字符串类似基础上构建的,例如列表和集合的元素类型是字符串类型,所以字符串类型能为其他4种数据结构的学习奠定基础

TIPS:由于Redis内部存储字符串完全是按照⼆进制流的形式保存的,所以Redis是不处理字符集编码问题的,客⼾端传⼊的命令中使⽤的是什么字符集编码,就存储什么字符集编码

字符串数据类型

 

常见命令 

SET 

将string类型的value设置到key中。如果key之前存在,则覆盖,⽆论原来的数据类型是什么。之前关于此key的TTL也全部失效。

语法:

SET key value [expiration EX seconds|PX milliseconds] [NX|XX]

选项:

  • EX seconds : 使用秒级作为单位设置key的过期时间
  • PX milliseconds : 使用毫秒作为单位设置key的过期时间
  • NX : 只在key不存在时才进行设置,如果之前key已经存在就不设置了
  • XX : 只在key存在的时候再进行设置,如果之前key不存在,就不设置 

返回值:

  • 成功返回OK
  • 如果由于SET指定NX或者XX不满足条件,SET不会执行并返回nil
GET

获取key对应的value。如果不存在就返回nil,如果key的类型不是string就会报错

语法

GET key

 返回值:key对应的value,或者nil当key不存在 

MGET

⼀次性获取多个key的值。如果对应的key不存在或者对应的数据类型不是string,返回nil。

语法:

MGET key [key ...]

 返回值:对应value的列表 

示例:

MSET  

⼀次性设置多个key的值

 语法:

MSET key value [key value ...]

 返回值:永远是OK 

 示例:

SETNX 

 设置key-value但只允许在key之前不存在的情况下

语法:

SETNX key value

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

示例:

 SETXX 只允许在key之前存在的情况下

计数命令

INCR 

将key对应的string表⽰的数字加⼀。如果key不存在,则视为key对应的value是0。如果key对应的string不是⼀个整型或者范围超过了64位有符号整型,则报错。
语法:

INCR key

返回值:integer类型的加完后的值

示例:

DECR同理,但DECR是减一 

INCRBY 

将key对应的string表⽰的数字加上对应的值。如果key不存在,则视为key对应的value是0。如果key对应的string不是⼀个整型或者范围超过了64位有符号整型,则报错。

语法: 

INCRBY key decrement

返回值:integer类型加完后的数值

示例:

 

DECRBY同理,不过是减去对应的值 

 INCRBYFLOAT

将key对应的string表⽰的浮点数加上对应的值。如果对应的值是负数,则视为减去对应的值。如果
key不存在,则视为key对应的value是0。如果key对应的不是string,或者不是⼀个浮点数,则报
错。允许采⽤科学计数法表⽰浮点数。

语法:

INCRBYFLOAT key increment

 返回值:加/减完之后的值 

其他命令

APPEND 

如果key已经存在并且是⼀个string,命令会将value追加到原有string的后边。如果key不存在,
则效果等同于SET命令。

语法:

APPEND key value
 GETRANGE 

返回key对应的string的⼦串,由start和end确定(左闭右闭)(start,end)。可以使⽤负数表⽰倒数。-1代表
倒数第⼀个字符,-2代表倒数第⼆个,其他的与此类似。超过范围的偏移量会根据string的⻓度调整成正确的值

语法:

GETRANGE key start end

 返回值:string类型的字符串

 示例:

SETRANGE 

覆盖字符串的一部分,从指定的偏移开始

语法:

SETRANGE key offset value

 返回值:替换后的string长度

示例:

STRLEN  

获取key对应的string的⻓度。当key存放的类似不是string时,报错

语法:

STRLEN key

返回值:

string的长度,或当key不存在的时候,返回0

示例:

 内部编码

 字符串的内部编码有三种:

  • int:8个字节长整型
  • embstr:小于等于39个字节的字符串
  • raw:大于39个字节的字符串 

 Redis会根据当前值的类型和⻓度动态决定使⽤哪种内部编码实现。

示例:

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

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