Redis 服务器拥有两种不同的脚本复制模式,第一种是从 Redis 2.6 版本开始支持的脚本传播模式,而另一种则是从 Redis 3.2 版本开始支持的命令传播模式
脚本传播模式
就是主服务器会把将要被执行的脚本及参数(就是EVAL命令)复制到AOF文件以及从服务器里面。但是会为了保证脚本的纯函数性质,Redis会对脚本进行限制:
- 脚本不能访问Lua的时间模块、内部状态又或者除给定参数之外的其他外部信息
- 不能使用带有随机性质的redis命令,例:SPOP
- 在调用会产生随机顺序的命令时,Lua环境会在返回结果之前进行排序,也就是返回的结果元素总是有序的,例:KEYS
- Redis 会确保每个被执行的脚本都拥有相同的随机数生成器种子,这意味着如果用户不主动修改这一种子,那么所有脚本在默认情况下产生的伪随机数列都将是相同的。
脚本传播模式为Redis脚本复制的默认模式
命令传播模式
就是主服务器会把执行脚本的写命令用事务包裹起来,然后复制到AOF文件以及从服务器里面。因为复制的只是写命令而不是脚本本身,所以对于脚本传播模式会有以下放松:
- 可以执行带有随机性质的命令
- 脚本的伪随机数生成器在每次调用之前,都会随机地设置种子。换句话说,被执行的每个脚本在默认情况下产生的伪随机数列都是不一样的。
选择性的命令传播
Redis允许用户在脚本里面选择性的打开或关闭命令传播功能。函数:redis.set_repl(),参数如下:
redis.REPL_ALL—— 默认值,将写命令传播至 AOF 文件以及所有从服务器。redis.REPL_AOF—— 只将写命令传播至 AOF 文件。redis.REPL_SLAVE—— 只将写命令传播至所有从服务器。redis.REPL_NONE—— 不传播写命令。
总结
-
如果脚本需要大量计算产生结果,就使用
命令传播模式,因为它只会把计算完之后的结果的写命令复制给从服务器,不需要从服务器再计算一遍而节省资源 -
如果脚本含有大量的写命令,就使用
脚本传播模式,因为它会把整个脚本当做整体复制给从服务器,只传送一次,所以可以节省网络资源的消耗。