Redis系列 | 阿里云 Redis 版数据库Lua脚本支持与限制
官方工单支持:
您好,
您的实例版本是16G集群版(8节点),
集群实例的命令限制您参考:
https://help.aliyun.com/document_detail/145968.html?spm=5176.11065259.1996646101.searchclickresult.30071fcfYM8QY7
Lua使用限制
为了保证脚本里面的所有操作都在相同slot进行,云数据库Redis集群版本会对Lua脚本做如下限制:
1、所有key都应该由KEYS数组来传递,redis.call/pcall中调用的redis命令,key的位置必须是KEYS array(不能使用Lua变量替换KEYS),否则直接返回错误信息:
1 | -ERR bad lua script for redis cluster, all the keys that the script uses should be passed using the KEYS array\r\n |
2、所有key必须在1个slot上,否则返回错误信息,"-ERR eval/evalsha command keys must be in same slot\r\n
"。
3、调用必须要带有key,否则直接返回错误信息, "-ERR for redis cluster, eval/evalsha number of keys can't be negative or zero\r\n
"。
4、不支持发布订阅命令,包括:PSUBSCRIBE、PUBSUB、PUBLISH、PUNSUBSCRIBE、SUBSCRIBE、UNSUBSCRIBE。
原生的Lua脚本案例(不支持)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | $script = <<<luascript local rate_key = KEYS[1] local limit = tonumber(ARGV[1]) -- 最大限制 local expire_time = ARGV[2] -- 过期时间 local result = redis.call( 'SETNX' ,rate_key,1); -- SETNX 只有不存在的时候才设置,返回1。否则返回0 if result == 1 then redis.call( 'expire' ,rate_key,expire_time) return 1 else if tonumber(redis.call( "GET" , rate_key)) >= limit then return 0 else redis.call( "INCR" , rate_key) return 1 end end luascript; $scriptSha = $redis->script( 'load' , $script); |
以上脚本在原生的Redis是可以运行的,但是在阿里云Redis则不行,直接返回false
解释一下官方的限制:
key的位置必须是KEYS array(不能使用Lua变量替换KEYS),而上面的脚本则是把KEYS[1] 赋值给了Lua变量 rate_key ,从而导致不能使用
最终修改兼容版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | local limit = tonumber(ARGV[1]) -- 最大限制 local expire_time = ARGV[2] -- 过期时间 local result = redis.call( 'SETNX' ,KEYS[1],1); -- SETNX 只有不存在的时候才设置,返回1。否则返回0 if result == 1 then redis.call( 'expire' ,KEYS[1],expire_time) return 1 else if tonumber(redis.call( "GET" , KEYS[1])) >= limit then return 0 else redis.call( "INCR" , KEYS[1]) return 1 end end luascript; $scriptSha = $redis ->script( 'load' , $script ); |
负载信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | " # Server redis_version:4.0.11 tcp_port:6379 uptime_in_seconds:5198246 uptime_in_days:60 hz:10 lru_clock:16284991 # Clients connected_clients:0 client_longest_output_list:0 client_biggest_input_buf:14 blocked_clients:0 # Memory used_memory:1569209784 used_memory_human:1.46G used_memory_rss:1856352256 used_memory_rss_human:1.73G used_memory_peak:1672249240 used_memory_peak_human:1.56G used_memory_overhead:954746082 used_memory_overhead_human:910.52M used_memory_startup:161978704 used_memory_startup_human:154.47M used_memory_dataset:614463702 used_memory_dataset_human:586.00M used_memory_lua:345088 used_memory_lua_human:337.00K maxmemory:17179869184 maxmemory_human:16.00G maxmemory_policy:volatile-lru mem_fragmentation_ratio:1.45 mem_allocator:jemalloc-5.1.0 active_defrag_running:0 lazyfree_pending_objects:0 # Stats total_connections_received:160659957 total_commands_processed:777588709 instantaneous_ops_per_sec:2763 total_net_input_bytes:81642748753 total_net_output_bytes:305788723191 instantaneous_input_kbps:327 instantaneous_output_kbps:1346 rejected_connections:0 sync_full:8 sync_partial_ok:0 sync_partial_err:0 expired_keys:38333350 evicted_keys:0 keyspace_hits:181375543 keyspace_misses:74435657 pubsub_channels:0 pubsub_patterns:0 latest_fork_usec:9565 migrate_cached_sockets:0 # Replication connected_slaves:1 master_repl_offset:10266296484 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:33554432 repl_backlog_first_byte_offset:10232742053 repl_backlog_histlen:33554432 # CPU used_cpu_sys:39038.91 used_cpu_user:45386.70 used_cpu_sys_children:9.07 used_cpu_user_children:100.86 # Cluster cluster_enabled:0 databases:256 nodecount:8 # Keyspace db0: keys =5856727,expires=5856723,avg_ttl=14963354 db10: keys =1,expires=0,avg_ttl=0 " |
1 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构