Redis下Lua脚本的复制模式
假设我们的Redis选择了主从架构, 和AOF持久化方式.
当我们执行一条写命令时, 该条命令会被发送到从服务器, 和追加到AOF文件中.
当我们执行的不是一条命令, 而是Lua脚本时, 默认情况下, 整个Lua脚本的内容会进行复制, 但是存在一些特殊情况, 我们来看一个例子, Lua脚本内容如下:
-- 当前时间 local now_time = redis.call('TIME'); -- 设置OPERATE_TIME值为当前秒数 redis.call('SET','OPERATE_TIME',now_time[1]);
默认执行的时候, 会报错如下:
Write commands not allowed after non deterministic commands. Call redis.replicate_commands() at the start of your script in order to switch to single commands replication mode.
翻译过来就是说, 写命令不被允许出现在‘非确定性命令’的后面, 请在脚本开始时调用redis.replicate_commands()来切换到命令复制模式.
修改之后的Lua脚本内容如下:
-- 开启单命令复制模式 redis.replicate_commands(); -- 当前时间 local now_time = redis.call('TIME'); -- 设置OPERATE_TIME值为当前秒数 redis.call('SET','OPERATE_TIME',now_time[1]);
再执行就不会报错, 然后我们到AOF文件下去查看一下, 我们发现追加的不是脚本内容, 而是MULTI...EXEC命令:
$1 0 *1 $5 MULTI *3 $3 SET $12 OPERATE_TIME $10 1572855544 *1 $4 EXEC
回到脚本上来, 我们的脚本包含了TIME命令来获取系统时间, 这个命令在不同时间去执行返回的值肯定不一样, 如果在主从复制和AOF追加时, 直接复制整个脚本的内容, 那么肯定会造成执行时数据的不一致性.
所以, 在执行Lua时Redis默认不允许动态的不确定性的变量存在. 如果存在, 则需要开启命令复制模式, 即只复制Lua脚本里包含的写命令, 所有的写命令会被包装在MULTI ... EXEC里.
Redis官方, 把默认的复制整个脚本内容的模式定义为whole scripts replication, 把只复制脚本里写命令的模式定义为 script effects replication.
在命令复制模式下, 还可以选择是否对某个命令进行目标复制, 即是否需要复制到‘从服务器’和‘AOF文件’ , 如下:
redis.set_repl(redis.REPL_ALL) -- Replicate to AOF and slaves. redis.set_repl(redis.REPL_AOF) -- Replicate only to AOF. redis.set_repl(redis.REPL_SLAVE) -- Replicate only to slaves. redis.set_repl(redis.REPL_NONE) -- Don't replicate at all.
举个例子:
redis.replicate_commands() -- 开启命令复制模式 redis.call('set','A','1') redis.set_repl(redis.REPL_NONE) -- 不进行复制 redis.call('set','B','2') redis.set_repl(redis.REPL_ALL) -- 复制到所有,即从服务器和AOF文件 redis.call('set','C','3')
在执行完脚本之后, 只有A和C的写操作会进行复制. 这种选择性复制的功能, 在需要过滤掉一些没必要的临时变量时有点用途, 但是提升不了太多性能, 而且操作有风险, 所以可以忽略掉此功能.
当然, 在执行Lua时, 并不是只有出现像TIME这样的非确定性命令时才可以开启命令复制模式, 如果你的脚本内容太多, 而写操作就只有几条, 那么为了提高效率也可以选择开启.
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
GitLab,是谁给了你歧视中国程序员的勇气?
编者注:Gitlab 安全漏洞不断(详情),收集用户行为数据(详情),今天又找到新的作死方法了。 由谷歌投资的全球第二大开源代码托管平台 GitLab 在其官网上发布了一项声明,称他们决定为有权访问客户数据的团队成员启用“工作家庭国家/地区封锁”令,并表示在当前的地缘政治环境下,这是最为人道的解决方案。 而这一“封锁令”针对的两个国家是:中国和俄罗斯。 更新的招聘流程里明确规定: GitLab 不会给中国/俄罗斯公民提供 offer 那些有权限访问客户数据的员工,现在也不能移居到中国或俄罗斯 该公告原文如下: 在 2019 年 10 月 15 日星期一的电子小组讨论中,我们决定为有权访问客户数据的团队成员启用“工作国家/地区封锁”。这是一些企业客户的关注点所在,也是当前地缘政治气候下我们行业中的一种普遍做法。 涉及的国家包括: 中国 俄罗斯 这个issue是为了跟踪向支持手册中添加流程的过程,以及需要更新的任何招聘流程,以确保: 我们不向居住在这些国家/地区的个人提供 offer 当前的团队成员被阻止前往这些国家,并保持担任这一被禁止的角色 如今我们没有一种技术方法可以用来处理这种权限...
- 下一篇
Proxy-Go v8.5 发布,全能代理服务工具,专业加速!
Proxy 是 golang 实现的高性能 http、https、websocket、tcp、udp、socks5 代理服务器,支持正向代理、反向代理、透明代理、内网穿透、TCP/UDP 端口映射、SSH 中转、TLS 加密传输、协议转换、DNS 防污染智能代理、前置 CDN/Nginx 反代、代理连接重定向、API动态调用上级代理、限速限连接数。同时提供全平台的功能强大的命令行版本和友好易用的 web 控制面板版本。 更新内容 1.tcp代理转发增加了指定出口IP功能。 2.修复了智能模式某些情况不能准确工作的问题。 3.socks/http(s)/sps监听支持多端口和端口范围了。 参数-p现在可以这样写了: ```text -p ":8081" 监听8081 -p ":8081,:8082" 监听8081和8082 -p ":8081,:8082,:9000-9999" 监听8081和8082以及9000,9001至9999,共1002个端口 ``` 4.增加了freebsd平台。 特色功能 链式代理,程序本身可以作为一级代理,如果设置了上级代理那么可以作为二级代理,乃至N...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS8编译安装MySQL8.0.19
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Hadoop3单机部署,实现最简伪集群
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果