redis基本指令

redis中最核心的两个命令

set

1
2
3
4
5
6
7
8
9
user@Ubuntu:~$ SET key value [expiration EX seconds | PX milliseconds] [NX|XX]

SET key value expiration EX seconds:设置key并设置过期时间(单位是秒)

SET key value expiration PX seconds:设置key并设置过期时间(单位是毫秒)

[NX|XX]:
如果key存在,更新key和value
如果key不存在,创建新的键值对,原来的ttl会失效

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

  • []相当于一个独立的单元,表示可选项(可有可无的)其中 | 表示 “或者” 的意思,多个只能出现一个。[][]之间,是可以同时存在的。
1
2
3
4
5
6
7
8
127.0.0.1:6379> set key1 123 ex 10
OK
127.0.0.1:6379> ttl key1
(integer) 6
127.0.0.1:6379> ttl key1
(integer) 5
127.0.0.1:6379> ttl key1
(integer) 4
1
2
3
4
127.0.0.1:6379> set key2 123 NX
OK
127.0.0.1:6379> set key1 123 NX
(nil)
1
2
3
4
5
6
127.0.0.1:6379> set key1 12
OK
127.0.0.1:6379> set key1 789 XX
OK
127.0.0.1:6379> get key1
"789"
1
2
3
4
5
6
7
8
9
10
127.0.0.1:6379> setnx key1 222
(integer) 0
127.0.0.1:6379> get key1
"111"
127.0.0.1:6379> setex key2 10 222 设置秒级别的过期时间
OK
127.0.0.1:6379> ttl key2
(integer) 6
127.0.0.1:6379> ttl key2
(integer) 5

这里的key value,不需要加上引号,就可以表示字符串类型。整体来说,Redis是键值对结构,key固定就是字符串,value实际上会有很多类型。(字符串,哈希表,集合,列表,有序集合)

MSET

时间复杂度:$O(N)$,N是我们插入键值对的数量。我们平时使用可以视为$O(1)$

1
MSET key value [key value...]
1
2
127.0.0.1:6379> mset key1 111 key2 222 key3 333
OK

get

1
2
GET key
对于GET来说,GET只是支持查询字符串类型的value,如果value是其他类型,使用GET就会报错!
1
2
3
4
127.0.0.1:6379> lpush key3 11 22 33
(integer) 3
127.0.0.1:6379> get key3
(error) WRONGTYPE Operation against a key holding the wrong kind of value

MGET

时间复杂度:$O(N)$,N是我们查询键值对的数量。我们平时使用可以视为$O(1)$

1
MGET key [key...]
1
2
3
4
5
6
127.0.0.1:6379> mset key1 111 key2 222 key3 333
OK
127.0.0.1:6379> mget key1 key2 key3
1) "111"
2) "222"
3) "333"

alt text{: height=75%, width=75%}
alt text{: height=75%, width=75%}

FLUSHALL

功能:清除redis上所有的数据

1
2
3
4
127.0.0.1:6379> FLUSHALL
OK
127.0.0.1:6379> keys *
(empty list or set)

全局命令

全局命令:能够搭配任意一个数据结构来使用的命令!

keys

功能:用来查询当前服务器上匹配的key。通过一些特殊符号(通配符)来描述key的模样,匹配上述模样的key就能查询出来。

1
user@Ubuntu:~$ keys [pattern]

pattern:包含特殊符号的字符串,有的地方成样式或者模式。

支持如下统配样式:

  • ? 匹配任意一个字符
    • h?llo 匹配 hellohallohxllo
  • * 匹配 0 个或者多个任意字符
    • h*llo 匹配 hlloheeeello
  • []只能匹配到[]中的字符。给出固定选项。
    • h[ae]llo 匹配hellohallo 但不匹配 hillo
  • [^e]排除e,只有e匹配不了,其他的都能匹配
    • h[^e]llo 匹配hallo , hbllo , … 但不匹配 hello
  • [a-b]只能匹配到a-b中的字符。给出固定范围
    • h[a-b]llo 匹配hallohbllo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
127.0.0.1:6379> keys h?llo
1) "hello"
2) "hallo"
3) "hbllo"
127.0.0.1:6379> keys h*llo
1) "heeeeeeeello"
2) "hello"
3) "hallo"
127.0.0.1:6379> keys h[abe]llo
1) "hello"
2) "hallo"
3) "hbllo"
127.0.0.1:6379> keys h[^ae]llo
1) "hbllo"

注意事项:

keys命令的时间复杂度是$O(N)$,所以在生产过程中,会禁用keys指令。尤其是key *(查询整个redis中所有的key)因为生产环境上的key可能会非常多,而redis是一个单线程的服务器,执行keys *的时间非常长,就使redis服务器被阻塞了。无法给其他客户端提供服务。突然一大波请求过来了,mysql措手不及,就容易挂了,整个系统就基本上瘫痪了。

1
2
3
4
5
6
7
8
127.0.0.1:6379> keys *
1) "key2"
2) "key1"
3) "heeeeeeeello"
4) "hello"
5) "hallo"
6) "hbllo"
7) "key3"

exists

功能:判定key是否存在,返回key存在的个数。redis组织这些key就是按照哈希表的方式来组织的。

时间复杂度:$O(1)$

1
2
3
4
5
6
127.0.0.1:6379> EXISTS key [key...] 

127.0.0.1:6379> exists hello
(integer) 1
127.0.0.1:6379> exists hello hallo
(integer) 2

del

功能:可以删除一个或者多个key,返回删掉key的个数
时间复杂度:$O(1)$
注意:redis不怕误删数据,删掉的数据可以再从Mysql当中读回来。但是误删了MySQL数据,影响就大了。

1
2
3
4
5
6
127.0.0.1:6379> DEL key [key...]

127.0.0.1:6379> del hllo
(integer) 0
127.0.0.1:6379> del hello
(integer) 1

基于redis实现的分布式锁,为了避免出现不能正确的解锁情况,通常都会在加锁的时候设置一下过期时间(所谓的使用redis作为分布式锁,就是给redis里写一个特殊的key value

expire

功能:指定的key设置过期时间。key存活时间超出这个值,就会被自动删除。设置的时间单位是秒。

1
2
3
4
5
6
7
8
9
10
127.0.0.1:6379> EXPIRE key seconds

127.0.0.1:6379> expire key1 3
(integer) 1
127.0.0.1:6379> keys *
1) "key2"
2) "key3"
3) "hbllo"
4) "hallo"
5) "heeeeeeeello"

ttl

功能:查看key的过期时间
时间复杂度:$O(1)$

1
2
3
4
5
6
7
8
9
10
127.0.0.1:6379> TTL key

127.0.0.1:6379> expire key2 10
(integer) 1
127.0.0.1:6379> ttl key2
(integer) 6
127.0.0.1:6379> ttl key2
(integer) 5
127.0.0.1:6379> ttl key2
(integer) 4

type

功能:查看key对应的value的数据类型。
时间复杂度:$O(1)$

1
2
3
4
5
6
7
8
127.0.0.1:6379> TYPE key

127.0.0.1:6379> type key
none
127.0.0.1:6379> type key1
string
127.0.0.1:6379> type key2
list

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

redis的整体策略是:定期删除和惰性删除相结合的方式

  • 定期删除
    每次抽取一部分,进行验证过期时间,保证这个抽取检查的过程足够快!因为redis是单线程程序,

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

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

注意:redis中并没有采用定时器的方式来实现过期key删除。

计数指令

所有计数指令操作的时间复杂度均为$O(1)$

INCR

1
INCR key:返回value+1之后的值。

注意:key对应的value必须要是整数,浮点数也是不允许的!

  • value只支持64位的整数也就是long long
  • incr操作的key如果不存在,就会把这个keyvalue当做0来使用。
1
2
3
4
5
6
7
8
9
10
127.0.0.1:6379> set key 10
OK
127.0.0.1:6379> incr key
(integer) 11
127.0.0.1:6379> get key
"11"
127.0.0.1:6379> set key2 hello
OK
127.0.0.1:6379> incr key2
(error) ERR value is not an integer or out of range

INCRBY

1
INCR key n:返回value+n之后的值。n可以为负数
1
2
3
4
127.0.0.1:6379> incrpy key 10
(integer) 21
127.0.0.1:6379> incrpy key2 10
(error) ERR value is not an integer or out of range

DECR

1
DECR key:返回value-1之后的值

注意:key对应的value必须要是整数,浮点数也是不允许的!

  • value只支持64位的整数也就是long long
  • incr操作的key如果不存在,就会把这个keyvalue当做0来使用。
1
2
3
4
5
6
7
8
9
10
127.0.0.1:6379> incrby key 10
(integer) 21
127.0.0.1:6379> incrby key2 10
(error) ERR value is not an integer or out of range
127.0.0.1:6379> decr key
(integer) 20
127.0.0.1:6379> decr key2
(error) ERR value is not an integer or out of range
127.0.0.1:6379> decr key3
(integer) -1

DECRBY

1
DECRBY key n:返回value-n之后的值,n可以为负数
1
2
3
4
127.0.0.1:6379> decrpy key 10
(integer) 21
127.0.0.1:6379> decrpy key2 10
(error) ERR value is not an integer or out of range

incrbyfloat

1
INCRBYFLOAT key n:value为浮点数,返回value-n之后的值,n可以为负数
1
2
3
4
127.0.0.1:6379> set key3 10.5
OK
127.0.0.1:6379> incrbyfloat key3 2.3
"12.8"

其他命令

OBJECT ENCODING

功能:查看keyredis内部实际的编码方式

1
2
3
4
127.0.0.1:6379> OBJECT ENCODING key

127.0.0.1:6379> object encoding key1
"int"