1,redis加入了lua虚拟机,可以执行lua脚本。为复杂的redis操作提供了解决方案。性能方面也不错。
2,lua执行是原子性。
3,redis加入 lua是一件伟大的事情。
以前使用redis lua脚本。只是解决一些简单的事情。这次需要处理复杂的事情。遇到了很多问题。
1,方法的定义。
这次lua脚本需要多个操作。通过参数需要执行不同的操作。不想以 if else if 进行处理。需要定义方法。普通的方式定义方法是有问题的。
全局变量保护 为了防止不必要的数据泄漏进 Lua 环境, Redis 脚本不允许创建全局变量。如果一个脚本需要在多次执行之间维持某种状态,它应该使用 Redis key 来进行状态保存。 企图在脚本中访问一个全局变量(不论这个变量是否存在)将引起脚本停止, EVAL 命令会返回一个错误: redis 127.0.0.1:6379> eval 'a=10' 0 (error) ERR Error running script (call to f_933044db579a2f8fd45d8065f04a8d0249383e57): user_script:1: Script attempted to create global variable 'a' Lua 的 debug 工具,或者其他设施,比如打印(alter)用于实现全局保护的 meta table ,都可以用于实现全局变量保护。 实现全局变量保护并不难,不过有时候还是会不小心而为之。一旦用户在脚本中混入了 Lua 全局状态,那么 AOF 持久化和复制(replication)都会无法保证,所以,请不要使用全局变量。
解决方法,redis已经提供,
void scriptingEnableGlobalsProtection(lua_State *lua) { char *s[32]; sds code = sdsempty(); int j = 0; /* strict.lua from: http://metalua.luaforge.net/src/lib/strict.lua.html. * Modified to be adapted to Redis. */ s[j++]="local dbg=debug\n"; s[j++]="local mt = {}\n"; s[j++]="setmetatable(_G, mt)\n"; s[j++]="mt.__newindex = function (t, n, v)\n"; s[j++]=" if dbg.getinfo(2) then\n"; s[j++]=" local w = dbg.getinfo(2, \"S\").what\n"; s[j++]=" if w ~= \"main\" and w ~= \"C\" then\n"; s[j++]=" error(\"Script attempted to create global variable '\"..tostring(n)..\"'\", 2)\n"; s[j++]=" end\n"; s[j++]=" end\n"; s[j++]=" rawset(t, n, v)\n"; s[j++]="end\n"; s[j++]="mt.__index = function (t, n)\n"; s[j++]=" if dbg.getinfo(2) and dbg.getinfo(2, \"S\").what ~= \"C\" then\n"; s[j++]=" error(\"Script attempted to access unexisting global variable '\"..tostring(n)..\"'\", 2)\n"; s[j++]=" end\n"; s[j++]=" return rawget(t, n)\n"; s[j++]="end\n"; s[j++]="debug = nil\n"; s[j++]=NULL; for (j = 0; s[j] != NULL; j++) code = sdscatlen(code,s[j],strlen(s[j])); luaL_loadbuffer(lua,code,sdslen(code),"@enable_strict_lua"); lua_pcall(lua,0,0,0); sdsfree(code); }
定义一个table类型的局部变量。
然后通过setmeatable 把局部变量与_G进行版本。
可以局部变量,就可以绑定方法了。
2,返回
执行方法的返回,是无效的。需要在脚本末端,执行 return “data” ,返回数据。脚本末端没有return
3,命令属性。
因为需要要执行time 命令,结果报错
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的命令是分种类的。
#define CMD_WRITE 1 /* "w" flag */ #define CMD_READONLY 2 /* "r" flag */ #define CMD_DENYOOM 4 /* "m" flag */ #define CMD_NOT_USED_1 8 /* no longer used flag */ #define CMD_ADMIN 16 /* "a" flag */ #define CMD_PUBSUB 32 /* "p" flag */ #define CMD_NOSCRIPT 64 /* "s" flag */ #define CMD_RANDOM 128 /* "R" flag */ #define CMD_SORT_FOR_SCRIPT 256 /* "S" flag */ #define CMD_LOADING 512 /* "l" flag */ #define CMD_STALE 1024 /* "t" flag */ #define CMD_SKIP_MONITOR 2048 /* "M" flag */ #define CMD_ASKING 4096 /* "k" flag */ #define CMD_FAST 8192 /* "F" flag */
详细分类请看,server.h 或
http://blog.csdn.net/wtyvhreal/article/details/43193591
REDIS_CMD_NOSCRIPT 类型的命令,是无法执行的。
REDIS_CMD_RANDOM 类型的命令,执行会后无法执行 REDIS_CMD_WRITE命令,这也是一致报错的原因。最后删除了time命令,client传递时间戳。
4,KEYS, ARGV, 都是table类型,是可以迭代的。
相关推荐
lua链接redis的工具驱动代码
SpringBoot+Redis 执行 Lua 脚本的方法步骤 以下是 SpringBoot+Redis 执行 Lua 脚本的方法步骤的知识点总结: 1. 背景:在开发中,我们需要一次性操作多个 Redis 命令,但是这些操作不具备原子性,而 Redis 的事务...
“基于Redis和Lua脚本的分布式锁的实现” 基于Redis和Lua脚本的分布式锁的实现是使用Redis和Lua脚本来实现分布式锁的技术。分布式锁是指在分布式系统中,多个节点之间需要协调和同步的机制,以避免同时访问共享资源...
- Redis支持在服务器端执行Lua脚本,这可以减少网络通信次数,提高性能和原子性。 - 在这个项目中,可能会有一个Lua脚本,用于在Redis中执行锁定和解锁操作,确保整个过程的原子性。例如,脚本可能会检查key是否...
结合Redis使用Lua脚本可以提升应用的性能和可靠性,特别是在处理高并发、复杂业务逻辑以及事务处理时。以下是对这个主题的详细阐述: 首先,让我们深入了解一下使用Lua脚本在高并发场景中的价值。在并发环境中,...
Redis+LUA脚本实现限流测试视频
该源码对应个人博客【Spring Boot通过自定义注解和Redis+Lua脚本实现接口限流】教程的相关源码,小伙伴可以自行下载学习!不需要积分!不需要积分!不需要积分! 如果相关资源对您有所帮助,希望一键三连给博主一...
例如,如果需要执行一系列连续的Redis命令,如设置、获取和计算,这些命令可以通过一个Lua脚本一次性发送到服务器,减少了网络延迟和多次请求的开销。 2. **原子操作**: Redis将整个Lua脚本视为一个原子操作,这...
1. **Lua脚本优点**: Lua脚本在Redis中执行是原子性的,能确保在并发环境下数据的一致性。此外,通过减少网络往返,提高了数据操作的效率。 2. **`EVAL`命令**: Redis提供了`EVAL`命令来执行Lua脚本。Lua脚本作为...
rld 是一个非交互的调试工具,用于调试 Redis 的 Lua 脚本,这里有篇详细介绍的文章。 rld 特性包括: 易于安装,只有 6kB 可打印输出到本地和远端 跟踪执行的代码行 先进的数值变化的自动监控机制报告 报告...
例如,使用LUA脚本可以确保在增加用户积分时不会因并发问题而重复计分。 通过理解和掌握这些知识点,你将能够在面试中自信地讨论Redis中的LUA脚本,并在实际项目中有效地利用这一功能。在面试准备时,除了理论知识...
秒杀系统,高并发,Redis,Lua脚本,Golang,Gin.zip
1. **Lua 脚本执行**: Redis 支持使用 Lua 脚本来执行一系列操作,保证原子性。这在需要复杂逻辑且保证一致性的场景中非常有用,如计数、操作多个键等。 2. **优化性能**: 由于 Lua 脚本在服务器端执行,减少了网络...
使用Lua脚本可以解决很多传统Redis命令无法直接处理的问题,例如: - 实现复杂的事务操作。 - 创建自定义的命令。 - 减少客户端与服务器之间的通信次数,从而减少延迟。 - 使用Lua脚本的原子性保证来保证数据的一致...
Golang与Redis结合使用Lua脚本,能够有效地实现原子操作,从而提高系统的稳定性和效率。 首先,Redis是一个开源的键值存储系统,它广泛用于数据缓存、消息队列以及复杂的数据结构存储。Lua是一种轻量级的脚本语言,...
LUA脚本在Redis中的使用是为了实现原子操作,确保数据一致性,尤其是在处理多个操作时。本篇文章主要探讨如何通过phpredis执行LUA脚本来实现特定的Redis操作。 首先,我们需要了解LUA脚本的基本结构。在示例代码中...
lua reis nginx 配制 及 redis.lua 脚本 redis.lua 脚本 支持 get, post redis 的hash, 及 集合 命令 开启redis的密码认证auth nginxlua.conf 配制 lua地址: 示列: redis_lib.php 为PHP类包 redis_lua 类
在这个“nginx+lua+redis集群”解决方案中,提供的连接插件可能是指Nginx与Redis之间的通信模块,例如lua-redis-pconnector,这个插件允许Nginx通过Lua脚本直接与Redis进行交互。而脚本部分可能包括了处理业务逻辑、...
【Redis开发】lua脚本开发nginx 与 redis 模块 (Lua script development nginx and Redis modules) 文件列表: lua_files (0, 2017-05-21) lua_files\access_control.lua (1813, 2017-05-21) lua_files\app_redis_...
1. 减少网络开销:本来多次网络请求的操作,可以用一个请求完成,原先多次请求的逻辑放在redis服务器上完成 2. 原子操作:Redis会将整个脚本作为一个整体