1. Redis的其他功能
redis 除了简单对对象的增删改查的功能之外,其实还有其他高级功能,了解这些内容有利于我们更灵活的使用 redis 完成我们的业务功能。
2. 发布与订阅
2.1. 基本概念
很多中间件都有发布与订阅功能,但是,作为一个数据库,redis 是如何实现发布与订阅功能呢,在 java (具体语言)里如何使用呢?
- 订阅频道:SUBSCRIBE "news.it"
- 发送消息: PUBLISH "news.it" "hello"
- 订阅模式消息:PSUBSCRIBE news.[ie]t ,通过匹配符匹配对应的频道。相当于对频道匹配的扩展。
pattern:一个或多个模式,可以包含特殊字符 *(匹配任意数量的字符)、?(匹配单个字符)、[abc](匹配括号内的任意一个字符)等。
2.2. 数据结构
- 频道:
在字典 pubsub_channels 中保存力扣所有频道,key 是频道名,value 是订阅的客户端列表。
订阅频道订阅或者退订的过程就是在字典里塞值或者删除值。
- 模式:
每增加一个模式订阅,都会添加一个pubsubPattern 数据结构在链表中,因为这个一般不会太大,通常也不需要和并处理。
退订和频道退订思路一致。
发消息的时候会首先发送频道里的单个订阅者,然后再遍历所有模式订阅者,查看是否匹配当前模式。
通常模式不能太多,因为这种遍历并不高效。
3. 事务
3.1. 基本概念
事务就是提供了一层性顺序执行多条命令的功能,由于 redis 是单线程应用,所以,事务实现非常简单。
3.2 实现思路
单线程嘛,只要通知redis现在进入事务状态,这时候阻塞其他请求,执行一条条事务命令,end后再退出事务状态。
不过 redis 做了一些优化,没有在输入命令的时候就阻塞所有请求,而是在完全提交后再阻塞请求。不过大致思路和上面单线程阻塞思路一致。
3.3 watch 的监视乐观锁
watched_keys 字典里保存监视信息,key 是被监视的键,value 是监视该键的客户端。
redis 修改键值有个修改标识的动作,可以给被修改的监视键打上标识。 如果在exec的时候,发现 监视的键的标识被修改了,返回执行错误。
Redis 事务具有,原子性(一起执行或者不执行),隔离性(单线程阻塞),持久性(rdb,aof),一致性。
redis 没有回滚机制,一旦开始执行事务,执行失败也不会影响后续命令的执行。
4. Lua 脚本
Redis 从 2.6版本开始引人对Lua脚本的支持,通过在服务器中嵌入 Lua 环境,Redis 客户端可以使用
Lua脚本,直接在服务器端原子地执行多个Redis 命令。
如果你认为 redis 提供的默认的乐观锁无法正确满足你灵活的需求,可以通过 Lua 脚本实现你的原子操作。
LUA 脚本不太会,不做过多阐述(dog)