独立功能
发布订阅
订阅指令:
subscribe 频道名
发布指令
publish 频道名 消息
支持模式,即*通配符
订阅模式
psubscribe 频道名.*
事务
- 输入MULTI,标志事务的开始
- 命令队列,输入的命令入队列,如果命令是EXEC,DISCARD,WATCH,MULTI其中之一,那么立刻执行命令;其余的入队列
- 输入EXEC提交事务并且执行命令队列
WATCH
可以监视某个键,如果输入EXEC时,键对应的值被其他客户端修改了,那么EXEC执行失败
ACID
- 原子性,事务队列中的命令要么全部都执行,要么一个都不执行;redis不支持回滚
- 一致性,如果数据库在执行事务之前是一致的,那么在事务执行后,无论事务是否执行成功,数据库也应该仍然是一致的
- 入队错误,服务器会拒绝执行入队过程中出现的错误的事务
- 执行错误,即使在事务执行中发生了错误,服务器也不会中断事务的执行,它会继续执行事务中余下的其他命令,并且已执行的命令不会被出错的命令影响
- 服务器停机,如果是未采用持久化策略,那空白数据库必然是一致的;如果是RDB模型,备份过的是一致的,没备份的是空白的,那也是一致的;如果是AOF模式下,状态总是一致的
- 隔离性,redis使用单线程来执行事务,并且保证不会对事务中断,所以总是具有隔离性
- 持久性,特定条件下才有持久性
redis中使用lua
在redis里面使用lua脚本主要用三个命令
- eval
- evalsha
- script load
eval
EVAL script numkeys key [key ...] arg [arg ...]
> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
1) "key1"
2) "key2"
3) "first"
4) "second"
key代表要操作的rediskey
arg可以传自定义的参数
numkeys用来确定key有几个
script就是你写的lua脚本
lua脚本里面使用KEYS[1]和ARGV[1]来获取传递的key和arg
script load和evalsha
在用eval命令的时候,可以注意到每次都要把执行的脚本发送过去,这样势必会有一定的网络开销,所以redis对lua脚本做了缓存,通过script load 和 evalsha实现
script load命令会在redis服务器缓存你的lua脚本,并且返回脚本内容的SHA1校验和,然后通过evalsha 传递SHA1校验和来找到服务器缓存的脚本进行调用,这两个命令的格式以及使用方式如下
SCRIPT LOAD script
EVALSHA sha1 numkeys key [key ...] arg [arg ...]
lua内置函数
redis.call和redis.pcall
两者非常相似,区别在于:
若 Redis 命令执行错误,redis.call() 将错误抛出(即 EVAL & EVALSHA 执行出错);
redis.pcall() 将错误内容返回。
通过文件执行脚本
通常情况下我们都是把lua script放到一个lua文件中,然后执行这个lua脚本,这种模式,key和value用一个逗号隔开就好了,
redis-cli --eval script key1 key2 , arg1 age2
伪客户端
因为执行redis命令必须有相应的客户端状态,为了执行lua脚本中的redis命令,redis服务器专门为lua环境创建了一个伪客户端,并且用这个伪客户端负责处理lua脚本中的包含的所有redis命令
- lua环境将redis.call或者redis。pcall函数想要执行的命令传给伪客户端
- 伪客户端将想要执行的命令传给命令执行器
- 命令执行器执行伪客户端传给它的命令,并返回结果
- 伪客户端接受结果,并且返回给lua环境
- lua环境将结果返回给call或者pcall函数
- 函数返回值信息
eval的执行
- 根据客户端给定的lua脚本,在lua环境中定义一个lua函数
- 将客户端给定的脚本保存到lua_scripts字典
- 执行刚刚定义的函数