目录
事务就是原子性。
先multi指令,让redis进入事务过程,然后接下来的指令都是事务范围的,事务的指令被一条条发送到服务端,服务端将指令以队列的形式顺序存储,等到客户端发来 exec 指令后,服务端一次性执行完刚才所有的指令。
1、事务过程中的错误处理。
1、语法错误
只要事务指令中有一条指令有语法错误,在输入 exec 命令之后,所有的指令都不会执行。
2、运行错误。
检查不出错误,只有在运行的时候才会出错,比如数据类型的不恰当运行。
redis不提供回滚机制,所以会将正确的指令执行了,运行错误的指令就报错。
3、为什么 redis 不提供事务回滚
事务中的语句只有存在运行错误时才会导致事务执行出现问题,但是这主要是开发者写的程序有问题,所以 redis 没必要背这个锅;其次,redis 是单工作线程的数据库,目的是快,因此,没有必要提供事务回滚,使得 redis 自身简单快捷。
discard 指令
discard 指令的在 exec 之前执行的,作用是取消当前事务的所有指令。
watch指令——乐观锁
WATCH命令可以监控一个或多个键,监控持续到事务的exec命令为止,watch指令监控了键之后,只要在multi指令(下一个事务)之前有修改键值或者删除键值的行为,那么multi到exec之间的所有事务指令不执行。exec指令之后watch就失效了。
即便 watch 监视的键过期了,事务仍然正常执行。
2、键的过期时间
给一个键设置过期时间,时间一到redis会自动删除它(具体怎么删除,什么时候删除,这决定于 redis 对过期键的删除策略,是惰性删除,还是定期删除)。
expire key seconds;时间为秒,成功返回1,键不存在或设置失败返回0.
TTL key;可以查看键的还有多长时间过期。键不存在返回-2,如果键是永久的(即默认, 没有设置过期时间),则返回-1.
persist key;删除键的过期时间。set指令重新赋值也会删除键的过期时间,重置过期时间。
实现访问控制频率
一般情况下。比如一分钟之内,用户访问不能超过100次。
为用户设置一个键,这个键是自增的,访问一次就加1,同时设置这个键的过期时间为60秒,而且这两个设置指令要是事务,不然出问题的话就功能不一样了。
另一种情况。比如第一分钟的最后一秒访问了99次,第二分钟的第一秒访问99次,这样没有超过限制,但是两秒之内就访问了198次,这样的话,访问强度很大的,所以还可以另一种思想:使用列表类型的一个键来存储用户最近100次访问的时刻,当访问次数超过了100,就计算判断一次,用最新一次访问的时间与最旧一次的访问时间间隔,如果小于1分钟,那么说明访问频率超了,要限制一下,如果大于1分钟,那么没有超,将最旧的那次访问删除,同时存储下最新的访问。
3、排序
sort key;进行排序,可以是集合类型,有序集合类型和列表类型。
如果是要进行先后顺序排序的话,建议直接使用列表。
如果是要按照某种权值来进行排序的话,建议直接使用有序集合。
4、消息通知
4.1、任务队列
可以用列表来实现队列,按照消息的先后入队的顺序来消费消息。
另外,可以用多个列表来实现优先级队列,比如 BRPOP key1 key2 .... , 会按照 key 的顺序从左向右返回第一个不为空的列表的最右端元素。
4.2、发布-订阅模式
subscribe channel channel2 ... // 订阅若干个频道,如果频道已经存在,则订阅它,如果不存在,则创建该频道,并订阅它。
unsubscribe channel channel2 ... // 退订若干个频道,如果没有指定任何频道,则会退订此客户端订阅的所有频道。
psubscribe pattern pattern2 .. // 订阅能够匹配上所指模式的所有的频道。
punsubscribe pattern pattern2 .. // 退订能够匹配上所指模式的所有的频道。
publish channel message // 发布消息到频道 channel 上,返回值是订阅此频道的用户数。
pubsub channels [pattern] // 返回所有(如果有 pattern 的话,就要符合匹配模式的)订阅者数量不为0的频道。
pubsub numsub channel channel2 ... // 返回这些频道的订阅者数量。
pubsub numpat // 返回所有客户端订阅的匹配模式的数量和,比如 sys1*, sys2*,这些等等。
使用通配符匹配规则订阅
如果使用通配符订阅的话,可以允许一个用户重复订阅一个频道。订阅完之后,服务端也会显示出多个用户订阅,而不是一个用户。
4.3、发布-订阅的工作原理
在服务端会保存着所有频道的信息,每个频道都连接着一个链表,这个链表里存储的就是订阅了这个频道的客户端。客户端订阅了频道后,如果频道已经存在,则服务端会将客户端加入到该频道的链表中,如果频道不存在,则创建该频道,并将客户端添加到链表中,一旦有人往某个频道发布消息,服务端会遍历该频道的链表,将消息发送给所有订阅者。
退订频道就是将客户端信息从某个频道的链表中删除即可。