附
以下模块的使用场景,有些典型场景未考虑进去的情况,欢迎有经验的读者前来补充。
前言
假定使用者,已经在业务中熟练掌握了连接,SET,GET,SETEX。Redis还有一些其它的非常好的模块可以用在业务里。
1. 原子增减incr
客户端命令加一,减一。该命令为原子操作,可以在多客户端调用并发安全。
set index 0
incr index
decr index
使用场景: 在线用户,接口调用次数,商品抢购数量
2. 对已有的key,增加/修改过期约束,并查看过期时间
过期单位为秒
set index 0
expire index 120
ttl index
使用场景: 查看商品还有多少时间下架,活动多少时间结束
3. 操作队列list
左进,右进, 取子list(含头含尾), 队列元素必须同类型,取长度,左弹出,右弹出
RPUSH friends "Alice"
RPUSH friends "Bob"
LPUSH friends "Sam"
LRANGE friends 0 -1 => 1) "Sam", 2) "Alice", 3) "Bob"
LRANGE friends 0 1 => 1) "Sam", 2) "Alice"
LRANGE friends 1 2 => 1) "Alice", 2) "Bob"
LLEN friends => 3
LPOP friends => "Sam"
RPOP friends => "Bob"
使用场景: 不易变的数组队列的缓存,比如app内小图标的排序。
4. 无序唯一集set
增加,列表,删除, 是否包含, 合并多个set为一个set(依旧保持去重无序)
sadd users "Kimi"
sadd users "Uky"
smember users
srem users "Kimi"
sismember users "Uky"
sunion users key2 key3 // 合并多个set为一个set
5. 有序唯一集zset
增加,列表,删除,包含,合并
ZADD hackers 1940 "Alan Kay"
ZADD hackers 1906 "Grace Hopper"
ZADD hackers 1953 "Richard Stallman"
ZADD hackers 1965 "Yukihiro Matsumoto"
ZADD hackers 1916 "Claude Shannon"
ZADD hackers 1969 "Linus Torvalds"
ZADD hackers 1957 "Sophie Wilson"
ZADD hackers 1912 "Alan Turing"
ZRANGE hackers 2 4 => 1) "Claude Shannon", 2) "Alan Kay", 3) "Richard Stallman"
6. 开启事务
以multi开头,exec结尾,事务之间的命令会被压入执行队列,事务结束时,提交所有操作,具备原子性。
返回值是对应暂存的命令返回结果
multi
set name "ft"
set name "ft2"
exec
// 回滚 discard
关于回滚,有一个地方要特别注意。不显式调用discard,子命令行出错时,已执行的命令不会回滚。举例:
set key1 1
multi
set key1 2
set key1 3
set key1 3 kk kj jj
exec
如上所示,第三个事务子语句,很显然语法错误,输出key1的值,为3,因为前两句话正确得执行了。
乐观锁
这里重点讲一下,很有用。
以前面提到的INCR为例,为某一个数字自增1是一个原子操作。那么问题来了,在业务中,我们对key值的修改,可能也需要做到原子性,其修改操作不能简单地被形容成自增1.这种情况应该怎么做呢?
使用乐观锁。
乐观锁使用模式是固定的: (需要保证原子性的操作,写在multi和exec之间,并发不安全的key,写到watch后)
watch key1 key2
multi
...
exec
它做到了这样的逻辑:
在 multi和exec之间的任何命令,一旦[出错]/[被监控的key发生了变化,比如被其他客户端修改了值],则事务回滚。
那么,要达到成功执行的结果,便需要,不断提交该次事务,直到成功。
SETNX
SET usernamet 5 EX 20 NX