如何让redis lua周期执行某一个lua脚本

看过本文的人也看了:
我要留言技术领域:
取消收藏确定要取消收藏吗?
删除图谱提示你保存在该图谱下的知识内容也会被删除,建议你先将内容移到其他图谱中。你确定要删除知识图谱及其内容吗?
删除节点提示无法删除该知识节点,因该节点下仍保存有相关知识内容!
删除节点提示你确定要删除该知识节点吗?为什么在 Redis 实现 Lua 脚本事务_百度知道
为什么在 Redis 实现 Lua 脚本事务
我有更好的答案
所以我决定改变这种情况,Redis 很像当初采用 InnoDB 前的 MySQL。而 Redis 采用了一种很合理的方式来保证数据完整性(复制,#4 都会导致数据异常(#2 与 #4)和&#47。3,它会一直执行直到以下任一种情况出现;或数据丢失(#3 和 #4)。如果你很重视数据.6 开始引入的 Lua 脚本在功能与易用性方面为 Redis 的成长提供了很大助力. 脚本运行时出错并中途退出,AOF 等),并且从 Redis2。但很遗憾目前的 Redis 也帮不了你多少。相对来说,Lua 脚本与其他数据库中的存储过程很相似,但脚本的执行有些许不同。在本文中最重要的一点就是一旦将脚本写入数据库,所有写操作处理完成后脚本会自动退出,所有以前执行的写操作都已发生,但不会再有其他写操作:1,你应该尽可能地阻止数据异常与丢失。这不是哲学,而是工作(This is not philosophy, this is doing your job). Redis 通过 SHUTDOWN NOSAVE 关闭时(不保存)。4. 你附加了调试器来“使”脚本完成 #1 与 #2 (或其他手段来保证不会丢失数据)。对于使用数据库开发软件的人,我想你也认同只有情景 #1 是最理想的。情景 #2,#3. 完成所有工作。2数据完整性从很多方面来看
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。匿名用户不能发表回复!|Redis中使用Lua脚本的开发思路-mysql教程-PHP中文网QQ群微信公众号还没有收藏Redis中使用Lua脚本的开发思路Redis提供了通过eval命令来执行Lua脚本。下面通过几个小例子来讲述如何在Redis服务端执行Lua脚本。
Redis提供了通过eval命令来执行Lua脚本。下面通过几个小例子来讲述如何在Redis服务端执行Lua脚本。
1. 执行Lua脚本的几个命令如下:
对应Jedis客户端Jedis对象的方法之一(有更多重载方法)
EVAL script numkeys key [key ...] arg [arg ...]
执行Lua脚本
public Object eval(String script, int keyCount, String... params)
EVALSHA sha1 numkeys key [key ...] arg [arg ...]
根据给定的 sha1 校验码,对缓存在服务器中的脚本进行求值
public Object evalsha(String sha1, int keyCount, String... params)
SCRIPT LOAD script
将给定的脚本缓存,不执行,并返回sha1校验值
public String scriptLoad(String script)
SCRIPT EXISTS sha1 [sha1 ...]
给定一个或多个脚本的 SHA1 校验和,返回一个包含 0 和 1 的列表,表示校验和所指定的脚本是否已经被保存在缓存当中
public List&Boolean& scriptExists(String... sha1)
SCRIPT FLUSH
清除所有 Lua 脚本缓存
SCRIPT KILL
杀死当前正在运行的 Lua 脚本,当且仅当这个脚本没有执行过任何写操作时,这个命令才生效(如果已经执行了写操作,则需要通过shutdown nosave命令来处理)
2.通过redis-cli客户端执行Lua脚本
redis-cli --eval myscript.lua key1 key2 , arg1 arg2 arg3
需要注意的是用逗号来分割key和参数,这里与在交互式模式下执行evel命令有所不同。
3.实际案例
场景一:对一个特定请求1秒钟只允许访问10次,当符合请求访问条件时,返回True,否则返回False。
Java客户端操作Redis服务,实现代码如下:
* 访问控制
* 1秒内最多可访问10次
* @param key
public boolean isAccess(String key) {
String rkey = "acc:" +
long value = jedis.incr(rkey);
if (value == 1) {
jedis.expire(rkey, 1);
boolean rs = value &= 10;
INCR命令作为计数器,如果rkey存在,则增加1返回最终值,否则初始化值为0,,然后加1。如上程序,如果访问rkey不存在,则表示第一次请求,这时对其rkey设置过期时间为1秒,否则比较其值是否超过制定请求数的阀值10. 用Lua脚本来完成这一操作:
--[[ Judge status
KEYS[1]:key ARGV[1]:request numbers ARGV[2]:expires times seconds --]]
local key, rqn, exp
= KEYS[1], ARGV[1], ARGV[2]; local value=redis.call("incr", key); redis.log(redis.LOG_NOTICE, "incr "..key); if(tonumber(value) == 1)then
redis.call("expire", key,
redis.log(redis.LOG_NOTICE, "expire "..key.." "..exp)
return tonumber(value) &= tonumber(rqn); end
通过Java客户端代码实现该功能存在一定缺陷,比如每1秒就需要操作1个incr和expire命令,并且该命令是由客户端通过网络发起的,而使用Lua脚本则既可以保证操作的原子性,又能使每次操作只需要一个key即可在服务器端完成相应的判断操作。可以通过SCRIPT LOAD的方式将脚本缓存到服务器,通过sha1校验值+参数(Key,ARG)来执行,减轻网络传输,也对该功能做到较好的封装。
场景二:指定模式key批量删除
redis目前提供的删除命令del仅支持删除指定数量的key,并不能通过指定模式key来进行删除,比如:del *user 删除以user结尾的key。
在redis中提供了keys命令,该命令可以通过指定模式key来获取key列表,下面通过keys和del命令组合实现一个指定模式key批量删除的命令。
--[[ Pattern delete key KEYS[1]:pattern --]]
redis.log(redis.LOG_NOTICE, "call keys "..KEYS[1]);
local keys=redis.call("keys", KEYS[1]); local count = 0; if(keys and (table.maxn(keys) & 0)) then
for index, key in ipairs(keys) do
redis.log(redis.LOG_NOTICE, "del "..key);
count = count +
redis.call("del", key);
需要注意的是场景二可以作为一种思路,通过Lua脚本组合redis内置命令来实现特定功能的命令。而这里的模式key批量删除并未一个好的命令,因为如果key的数量很大时,将会有比较严重的性能问题。redis默认限制Lua脚本执行时间最大为5秒,如果超过5秒将继续接受来自客户端的请求,并简单的返回BUSY结果。这时候则需要SCRIPT KILL或者SHUTDOWN NOSAVE命令做相应的处理。因此应该尽力保证脚本的执行速度极快。
场景三:生成随机数
对于Redis而且,脚本执行在相同数据集,相同参数下执行写命令具有一致性的。其不依赖与隐式的数据集,脚本执行过程中不同执行时期的状态变化,也不依赖外部I/O设备的输入。
要符合Redis服务执行的脚本条件,需要注意的地方比较多,可以参见:
下面是实现随机数列表的Lua脚本:共3篇276点赞收藏分享:.php.cn&猜你喜欢PHP中文网:独家原创,永久免费的在线,php技术学习阵地!
All Rights Reserved | 皖B2-QQ群:关注微信公众号

我要回帖

更多关于 lua redis 模块 的文章

 

随机推荐