Redis - API
通用命令
keys:遍历所有的key,支持模糊匹配(注:这个命令比较heavy,在prod谨慎适用)
> keys *
1) "key1"
2) "key2"
> keys key1*
1) "key1"
dbsize:计算所有key的数量
> dbsize
(integer) 2
exists [key]:判断key是否存在(1-存在;0-不存在)
> exists key1
(integer) 1
> exists key3
(integer) 0
del [key]:删除key(1-成功;0-不成功)
> del key2
(integer) 1
> del key2
(integer) 0
expire [key] [seconds]:设置key在多少秒后过期
ttl [key]:查看key剩余的过期时间(-1代表永不过期,-2代表已经过期了)
persist [key]:设置key不过期
> set hello world
OK
> expire hello 10
(integer) 1
> ttl hello
(integer) 5
> ttl hello
(integer) -2
type [key]:返回key的类型
- string
- hash
- list
- set
- zset
- none
> set hello world
OK
> type hello
string
时间复杂度

数据结构和内部编码
redis中的对象,一个数据类型,可以有多种实现(编码方式)。

比如一个数据结构List,对应的内部编码方式有Linklist或者Ziplist。

单线程
Redis(大部分场景)是单线程的。
单线程为什么快?
- 纯内存(主要)
- 非阻塞IO
- 避免线程切换和竞态消耗

注意点:
- 一次只运行一条命令
- 拒绝长慢命令(keys, flushall, flushdb, slow lua script, mutil/exec, etc.)
String
重点理解:Reids的基本数据格式是key-value。而数据类型,是针对value而言的。
- 比如
String,是指value是一个广义的String - 再比如
Hash,是指value是一个近似的’hashmap’ - 再比如
List,是指value是一个近似的’linklist’
键值类型
以下的类型,最终都可以转换成字符串存储
- String
- int
- bits (二进制0/1)
- jason格式
注:最大可以存放512MB的内容
使用场景
- 缓存
- 计数器
- 分布式锁
命令
get, set
get [key]
// 不管key存不存在都设置,相当于-add or override
set [key] [value]
// key不存在才设置,相当于-add only
setnx [key] [value]
// key存在才设置,相当于-update only
set [key] [value] xx
append [key] [value]
// 返回value的长度
strlen [key]
incr, decr, incrby, decrby 自增,自减
incr [key]
decr [key]
incrby [key] [k]
decrby [key] [k]
mget, mset 批量操作
mget [key1] [key2] [key3]
mset [key1] [value1] [key2] [value2] [key3] [value3]
注:对于获取n个key,可以调用一次mget,或者n次调用get,redis处理的速度是一样的,但是前者省去了(n-1次)网络传输时间。
时间复杂度
基本上都是O(1)

实战
用Redis缓存视频的基本信息,数据源是MySQL

分布式Id生成器

Hash
redis中hash的组成和传统的键值对略微有所不同,它有三个组成部分:
- key (e.g. users:1)
- field (e.g. email, etc)
- value (e.g. john@domain.com, etc)
其实,相当于一个key对应一个obj,然后通过obj.field得到value。
注:field不能相同,value可以相同。
命令
hget, hset, hdel:对一个key的一个field进行操作,时间复杂度都是O(1)
hset user:1:info age 23
-> (integer)1
hset user:1:info name alex
-> (integer)1
hget user:1:info age
-> "23"
hgetall user:1:info
-> 1) "age"
2) "23"
3) "name"
4) "alex"
hdel user:1:info age
-> (integer)1
hexists, hlen:时间复杂度都是O(1)
hexists user:1:info age
-> (integer)1
// 注:hlen返回的是field的个数
hexists user:1:info
-> (integer)2
hmget, hmset:批量操作一个key的多个field,时间复杂度都是O(n)
hmset user:2:info age 30 name bob
-> OK
hmget user:2:info age name
-> 1) "30"
2) "bob"
hgetall, hvals, hkeys:时间复杂度都是O(n)
hkeys user:2:info
-> 1) "age"
2) "name"
hvals user:2:info
-> 1) "30"
2) "bob"
实战
使用redis缓存视频的基本信息,数据源在mysql中,下面演示的是读取数据的过程
List
命令
增 rpush O(1-n), lpush O(1-n), linsert O(n)
rpush listkey a b c
-> a-b-c
lpush listkey a b c
-> c-b-a
linsert listkey before b X
a-b-c -> a-X-b-c
linsert listkey after b Y
a-b-c -> a-b-Y-c
删 lpop O(1), rpop O(1), lrem O(n), ltrim O(n)
lpop listkey
a-b-c -> b-c
rpop listkey
a-b-c -> a-b
lrem [key] [count] [value]
//count=0, delete all matches values
//count>0, start from left, delete matching values up to count
//count<0, start from right, delete ...
ltrim [key] [start] [end]
// trim the list and save from start position to end position, inclusive
查 lrange O(n), lrange O(n), llen O(1)
lrange listkey 1 3
a-b-c-d-e -> b-c-d
lrange listkey 1 -1
a-b-c-d-e -> b-c-d-e
lindex listkey 2
a-b-c-d-e -> c
llen listkey
a-b-c-d-e -> 5
改 lset O(n)
lset listkey 2 X
a-b-c-d-e -> a-b-X-d-e
组合功能
- LPUSH + LPOP = Stack
- LPUSH + RPOP = Queue
- LPUSH + LTRIM = Capped Collection
- LPUSH + BRPOP = Message Queue
Set
sadd:添加 O(1)
srem:删除 O(1)
scard:计算集合大小
sismember:判断是否在集合中
srandmember:从集合中随机挑选几个元素展示
spop:从集合中随机”弹出”一个元素
smembers:获取集合所有元素
sdiff:差集
sinter:交集
sunion:并集
组合功能
- SADD = Tagging
- SPOP/SRANDMEMBER = Random item
- SADD + SINTER = Social Graph
实战
- 抽奖
- 点赞
- 关注
Zset
有序集合
命令
zadd O(logN)
zadd user:1:ranking 255 tom
zrem O(1)
zrem user:1:ranking 255 tom
zscore O(1) 返回元素的分数
zscore user:1:ranking tom
zincrby O(1) 增加或减少元素的分数
zincrby user:1:ranking 9 mike
zcard O(1) 返回元素的总数
zcard user:1:ranking
zrange O(log(n)+m) 返回index position范围内的升序元素
zrange user:1:ranking 1 3 withscores
zrangebyscore O(log(n)+m) 返回score范围内的升序元素
zrangebyscore user:1:ranking 90 200 withscores
zcount O(log(n)+m) 返回score范围内的元素个数
zcount user:1:ranking 90 200
实战
排行榜