目录
前言:
基本全局命令
KEYS
EXISTS
DEL
EXPIRE
TTL
TYPE
数据结构和内部编码
内部编码:
单线程架构
引出单线程模型:
为什么单线程还这么快?
String字符串
字符串数据类型:
常见命令:
SET
GET
MGET
MSET
SETNX
计数命令:
INCR
INCRBY
INCRBYFLOAT
其他命令:
APPEND
GETRANGE
SETRANGE
STRLEN
内部编码:
前言:
Redis提供了5种数据结构,理解每种数据结构的特点对于Redis开发运维⾮常重要
基本全局命令
语法:
KEYS pattern
返回值:
匹配pattern的所有key
从上面可以看出
? 只能匹配单个字符,且不能为空
* 可以匹配0到多个字符
[xyz] 可以单独匹配x与y与z,能够匹配[]中的单个字符
^ 就代表非的意思
[a-b] 中间有 ' - '就是a到b的意思即字符在a-b之间的都能匹配
判断某个key是否存在
语法:
EXISTS key [key ...]
返回值:key存在的个数
示例:
删除指定的key
语法:
DEL key [key ...]
返回值:删除掉的key的个数
为指定的key添加秒级的过期时间(Time To Live TTL)
语法:
EXPIRE key seconds
返回值:1表示设置成功,0表示设置失败
获取指定key的过期时间,秒级
语法:
TTL key
返回值:
剩余过期时间,-1表示没有关联过期时间,-2表示key不存在
返回key对应的数据类型
语法:
TYPE key
返回值:none、string、list、set、zset、hash、stream
示例:
数据结构和内部编码
type 命令实际返回的就是当前键的数据结构类型,它们分别是:string(字符串)、list(列表)、hash(哈希)、set(集合)、zset(有序集合),但这些只是Redis对外的数据结构
可以看到每种数据结构都有⾄少两种以上的内部编码实现,例如list数据结构包含了linkedlistziplist两种内部编码。同时有些内部编码,例如ziplist,可以作为多种数据结构的内部实现,可以通
过object encoding命令查询内部编码
这样设计有两个好处:
单线程架构
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是不处理字符集编码问题的,客⼾端传⼊的命令中使⽤的是什么字符集编码,就存储什么字符集编码
将string类型的value设置到key中。如果key之前存在,则覆盖,⽆论原来的数据类型是什么。之前关于此key的TTL也全部失效。
语法:
SET key value [expiration EX seconds|PX milliseconds] [NX|XX]
选项:
返回值:
获取key对应的value。如果不存在就返回nil,如果key的类型不是string就会报错
语法:
GET key
返回值:key对应的value,或者nil当key不存在
⼀次性获取多个key的值。如果对应的key不存在或者对应的数据类型不是string,返回nil。
语法:
MGET key [key ...]
返回值:对应value的列表
示例:
⼀次性设置多个key的值
语法:
MSET key value [key value ...]
返回值:永远是OK
示例:
设置key-value但只允许在key之前不存在的情况下
语法:
SETNX key value
返回值:1表示设置成功,0表示设置失败
示例:
SETXX也是同理~~
将key对应的string表⽰的数字加⼀。如果key不存在,则视为key对应的value是0。如果key对应的string不是⼀个整型或者范围超过了64位有符号整型,则报错。
语法:
INCR key
返回值:integer类型的加完后的值
示例:
DECR同理,但DECR是减一
将key对应的string表⽰的数字加上对应的值。如果key不存在,则视为key对应的value是0。如果key对应的string不是⼀个整型或者范围超过了64位有符号整型,则报错。
语法:
INCRBY key decrement
返回值:integer类型加完后的数值
示例:
DECRBY同理,不过是减去对应的值
将key对应的string表⽰的浮点数加上对应的值。如果对应的值是负数,则视为减去对应的值。如果
key不存在,则视为key对应的value是0。如果key对应的不是string,或者不是⼀个浮点数,则报
错。允许采⽤科学计数法表⽰浮点数。
语法:
INCRBYFLOAT key increment
返回值:加/减完之后的值
如果key已经存在并且是⼀个string,命令会将value追加到原有string的后边。如果key不存在,
则效果等同于SET命令。
语法:
APPEND key value
返回key对应的string的⼦串,由start和end确定(左闭右闭)(start,end)。可以使⽤负数表⽰倒数。-1代表
倒数第⼀个字符,-2代表倒数第⼆个,其他的与此类似。超过范围的偏移量会根据string的⻓度调整成正确的值
语法:
GETRANGE key start end
返回值:string类型的字符串
示例:
覆盖字符串的一部分,从指定的偏移开始
语法:
SETRANGE key offset value
返回值:替换后的string长度
示例:
获取key对应的string的⻓度。当key存放的类似不是string时,报错
语法:
STRLEN key
返回值:
string的长度,或当key不存在的时候,返回0
示例:
字符串的内部编码有三种:
Redis会根据当前值的类型和⻓度动态决定使⽤哪种内部编码实现。
示例: