Redis 使用键值对来存储数据。 即我们插入一个数据, 要指定对应的key和value。我们未来查数据, 也是利用key查数据。
对于redis里面的key, 默认是一个字符串类型。 value的类型可以多样, redis的有一个特性就是支持多种数据结构存储,value的类型可以是redis支持的任意一种数据结构, 比如string, hash, set, list等等。
对于key来说, 这些key我们可以把所有的key看作放在了一个空间里面, 这个空间叫做keyspace。因为key固定是字符串类型, 所以操作key的命令只有一套,就是通用命令。即: 通过通用命令来操作keyspace的key数据, 管理键值。
对于value来说, 这些value因为类型不同, 所以不同的类型有不同的操作方法, 就要有不同的命令,这些命令是属于对应数据结构的专属命令。
非通用命令get 和 set
本节内容主要学习通用命令, 这两个非通用命令用来辅助学习通用命令。
Set
- set是插入一个value类型为string的键值对
- 如下为示例:
vbnet
set key value
- 插入后, 返回一个ok则代表插入成功
Get
- get是获取一个value类型为string的键值对
- 如下为示例:
vbnet
get key
- 如果存在, 则返回对应的value, 如果不存在, 返回nil。
通用命令
Del
- del是删除某一个键值对
- 下面为示例:
vbnet
del key [key...] #这个key...代表可以指定多个key, 同时删除
- 返回成功删除的个数。
Exists
- exists返回某个键值对是否存在
- 下面为示例:
vbnet
exists key [key...] #这个key...代表可以指定多个key, 全部进行判断
- 返回存在的键值对个数
Type
- type返回某个键值对的value类型
- 下面为代码示例:
bash
type key
- 如果存在, 返回对应的value类型, 如果不存在, 返回none。
Expire
- expire是对一个键值对设定过期值
- 下面为代码示例:
sql
expire key second
- 设置成功返回1, 失败返回0, 同时被设置的key在过期后自动被删除
TTL
- TTL能够返回一个键值对的过期时间
- 下面为代码示例:
vbnet
ttl key
- 成功则返回一个键值对的过期时间, 失败则报错
Scan
- scan类似于一个迭代器, 遍历整个keyspace, 但是不会一次全部遍历, 每次只会遍历一段。
- 下面为代码示例:
arduino
scan cursor
- cursor是迭代的起始位置, 返回值为当前迭代到了哪里, 如果返回0,则代表全部迭代完成。
Keys
- keys命令, 先遍历整个keyspace , 然后返回要求的匹配结果。注意, 该命令会先遍历整个keyspace空间, 所以很容易造成系统阻塞。在分布式系统中, 一旦redis阻塞, 那么就不能为冷库分担压力,MySQL这种就会接收到大量请求, 很容易造成冷库崩溃,然后整个分布式系统就崩溃了。所以, keys命令很危险, 不能在线上环境使用keys命令,其他环境也尽量减少使用,防止形成习惯。
- 下面为代码示例:
ini
keys [*?] #*表示匹配任意多个字符, ?表示匹配一个任意字符
keyspace的过期策略
redis采用定期删除和惰性删除相结合的过期策略
定期删除
- redis不会遍历整个keyspace检查哪个key过期,哪个没有过期。 因为这样会阻塞redis,产生类似keys命令的效果。
- redis采用的是抽取一部分key,检查过期时间, 保证这个检查的时间足够快, 不影响redis的正常运行。比如十万个key, 一次抽取1/10, 一次抽取1/100等。
惰性删除
- 惰性删除就是当要用到某个key的时候, 如果这个key的过期时间到了, 那么就把这个key删除, 返回nil。
通过上面两种策略, 并不能完全解决过期key空间占用的问题, 还要进行一种内存淘汰机制。