1. 事务

1.1 概述
Redis 中的事务是一组命令的集合。一个事务中的命令要么全部都执行,要么全部都不执行。事务的原理是先将属于一个事务的命令发送给redis,然后再让Redis依次执行这些命令

# 告诉redis,后面输入的命令先不要执行,把它们暂时存起来
127.0.0.1:6379> multi
OK
# 输入的命令存入事务队列中,返回queued表示已存入事务队列中
127.0.0.1:6379> sadd user:1:following 2
QUEUED
127.0.0.1:6379> sadd user:2:followers 1
QUEUED
# 告诉redis将等待执行的事务队列中的所有命令按照发送顺序依次执行,返回值就是这些命令的返回值组成
127.0.0.1:6379> exec
1) (integer) 1
2) (integer) 1

Redis 保证一个事务中所有的命令要么都执行,要么都不执行,如果在发送exec命令前客户端断线了,redis会清空事务队列,redis 的事务还能保证一个事务内的命令依次执行而不被其他命令插入。

1.2 错误处理
(1)语法错误:命令不存在或者命令参数的个数不对

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set name jack
QUEUED
127.0.0.1:6379> set age
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379> ersf age
(error) ERR unknown command 'ersf'
# 只要有一个命令语法错误,执行exec会直接返回错误,正确的语法也不会执行
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.

(2)运行错误:在命令执行时出现的错误

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set ass 1
QUEUED
# 使用散列类型的命令操作集合类型的键,执行之前无法发现错误
127.0.0.1:6379> sadd ass 2
QUEUED
127.0.0.1:6379> set ass 3
QUEUED
# 如果事务里的一条命令出现运行错误,其他的命令依然会执行
127.0.0.1:6379> exec
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
3) OK
127.0.0.1:6379> get ass
"3"

1.3 watch命令介绍
watch 命令可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行,监控一直持续到exec命令执行完。

127.0.0.1:6379> set aaaa 1
OK
127.0.0.1:6379> watch aaaa
OK
127.0.0.1:6379> set aaaa 2
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set aaaa 3
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get aaaa
"2"
127.0.0.1:6379> set aaaa 4
OK
127.0.0.1:6379> get aaaa
"4"

执行exec命令后会取消对所有键的监控,我们也可以用unwatch 命令来取消监控。

2. 过期时间

# 给键设置过期时间
expire key seconds 

127.0.0.1:6379> set expirekey djkfj
OK
# 设置15分钟的过期时间,返回0表示键不存在或者设置失败,1表示成功
127.0.0.1:6379> expire expirekey 900
(integer) 1
# 查看还有多久时间过期
127.0.0.1:6379> ttl expirekey
(integer) 785
# 如果键的过期时间是永久的,返回-1
127.0.0.1:6379> ttl aaaa
(integer) -1
127.0.0.1:6379> expire aaaa 2
(integer) 1
# 如果键的过期时间已到,键被删除,ttl命令会返回-2
127.0.0.1:6379> ttl aaaa
(integer) -2

127.0.0.1:6379> set aaaa 11
OK
127.0.0.1:6379> expire aaaa 300
(integer) 1
# 清除键的过期时间
127.0.0.1:6379> persist aaaa
(integer) 1
127.0.0.1:6379> ttl aaaa
(integer) -1
# 重新设值之后也会清除过期时间
127.0.0.1:6379> expire aaaa 20
(integer) 1
127.0.0.1:6379> set aaaa 4
OK
127.0.0.1:6379> ttl aaaa
(integer) -1
# 重新设置时间后,过期时间会重新设置
127.0.0.1:6379> expire aaaa 20
(integer) 1
127.0.0.1:6379> ttl aaaa
(integer) 12
127.0.0.1:6379> expire aaaa 20
(integer) 1
127.0.0.1:6379> ttl aaaa
(integer) 16

expire命令的seconds 参数必须是整数,最小单位是1秒,如果想要更精确的过期时间可以使用pexpire,时间单位是毫秒,pttl 可以查看剩余过期时间。
注意:如果使用watch命令监控了一个拥有过期时间的键,该键时间到期自动删除并不会被watch命令认为该键被改变

小技巧:使用redis作为缓存服务器时,有些时候,会发现给一个键设置合理的过期时间很难,其实我们可以让redis按照一定的规则淘汰不需要的缓存键,这种方式在只将redis用作缓存系统时非常使用。
具体的设置方法:修改配置文件的maxmemory参数,限制Redis最大可用内存大小(单位是字节),当超出了这个限制时redis会依据maxmemory-policy参数指定的策略来删除不需要的键直到redis占用的内存小于指定内存
allkeys-lru规则:超过指定内存,会删除数据库中最近最少使用的键,其他规则查看P78页

3. 排序

3.1 sort 命令

127.0.0.1:6379> sadd setDD 1 3 6 2 5 9
(integer) 6
127.0.0.1:6379> sort setDD
1) "1"
2) "2"
3) "3"
4) "5"
5) "6"
6) "9"
127.0.0.1:6379> lpush mtlisht 2 4 1 3 7
(integer) 5
127.0.0.1:6379> sort mtlisht
1) "1"
2) "2"
3) "3"
4) "4"
5) "7"
# 有序集合排序会忽略分数,按值排序
127.0.0.1:6379> zadd myzet 30 1 40 4 10 5 20 2
(integer) 4
127.0.0.1:6379> sort myzet
1) "1"
2) "2"
3) "4"
4) "5"

除了可以排列数字外,还可以按照字典排列非数字元素

127.0.0.1:6379> lpush listA a c r d f b
(integer) 6
# 如果没有加alpha,sort命令会尝试将所有元素转换成双精度浮点数来比较,如果无法转换则提示错误
127.0.0.1:6379> sort listA
(error) ERR One or more scores can't be converted into double
127.0.0.1:6379> sort listA alpha
1) "a"
2) "b"
3) "c"
4) "d"
5) "f"
6) "r"

sort 命令默认从小到大顺序排列,也可以倒序排列,desc 参数

127.0.0.1:6379> sort listA alpha
1) "a"
2) "b"
3) "c"
4) "d"
5) "f"
6) "r"
127.0.0.1:6379> sort listA alpha desc
1) "r"
2) "f"
3) "d"
4) "c"
5) "b"
6) "a"

sort 命令还支持分页,limit offset count参数,表示跳过前offset 个元素,获得之后的count 元素

127.0.0.1:6379> sort listA alpha
1) "a"
2) "b"
3) "c"
4) "d"
5) "f"
6) "r"
127.0.0.1:6379> sort listA alpha limit 1 2
1) "b"
2) "c"