我正在参与掘金创作者训练营第4期(带链接:juejin.cn/post/706419…
科普
REmote DIctionary Server(Redis) 是一个由 Salvatore Sanfilippo 写的 key-value 存储系统,是跨平台的非关系型数据库。
Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API。
Redis 通常被称为数据结构服务器,因为值(value)可以是字符串(String)、哈希(Hash)、列表(list)、集合(sets)和有序集合(sorted sets)等类型。
起因
最近接到个新需求,其中有个小功能是将需要将2个值存REDIS中,一开始想分2次往REDIS中存入。 后来分析需求发现这俩值需要同时写入REDIS 并且需要做好防并发,看了上面所有的redis命令之后发现好像并没有直接的命令,绝望之时发现了一道光!
点进去看看
EVAL script numkeys key [key ...] arg [arg ...]
从 Redis 2.6.0 版本开始,通过内置的 Lua 解释器,可以使用 EVAL 命令对 Lua 脚本进行求值。
script 参数是一段 Lua 5.1 脚本程序,它会被运行在 Redis 服务器上下文中,这段脚本不必(也不应该)定义为一个 Lua 函数。
numkeys 参数用于指定键名参数的个数。
键名参数 key [key ...] 从 EVAL 的第三个参数开始算起,表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,用 1 为基址的形式访问( KEYS[1] , KEYS[2] ,以此类推)。
在命令的最后,那些不是键名参数的附加参数 arg [arg ...] ,可以在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似( ARGV[1] 、 ARGV[2] ,诸如此类)。
感觉还是不太明白,那就按照例子来一遍
> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
key1
key2
first
second
引号内为一段Lua脚本。KEYS ,ARGV都为 Lua脚本中的全局变量
继续执行
> eval "return {KEYS[1],ARGV[1],ARGV[2]}" 2 key1 key2 first second
key1
first
second
> eval "return {KEYS[1],ARGV[1],ARGV[2]}" 2 key1 key2 first
key1
first
> eval "return {KEYS[1],ARGV[1],ARGV[2]}" 3 key1 key2 key3
key1
说明 script 后面的参数 是有严格的位置控制的
2后面就为2个key 2个value;
3 后面则需要对应3个key 3个value
脚本编写
简单了解了redis 执行Lua脚本的格式后,我们需要用Lua调用Redis的API
在 Lua 脚本中,可以使用两个不同函数来执行 Redis 命令,它们分别是:
redis.call()
redis.pcall()
这两个函数的唯一区别在于它们使用不同的方式处理执行命令所产生的错误
想详细了解的可以点击文稿
通过REDIS LUA + SETEX 命令设置1个数据
redis.call('SETEX', KEYS[1], ARGV[2],ARGV[1]); return 1;
通过REDIS LUA + SETEX 命令设置2个数据
redis.call('SETEX', KEYS[1], ARGV[3],ARGV[1]); redis.call('SETEX', KEYS[2], ARGV[3],ARGV[2]); return 1;
执行语句
> eval "redis.call('SETEX', KEYS[1], ARGV[3],ARGV[1]); redis.call('SETEX', KEYS[2], ARGV[3],ARGV[2]); return 1;" 2 key1 key2 v1 v2 999
1
执行成功 返回1; 2代表有2个键名参数,后面的3个参数 v1,v2,999为附加参数分别对应ARGV[1]、ARGV[2]、ARGV[3] LUA中数组下标的起始位置为1
以上我们就为开始的小功能写好了对应的LUA脚本了。
感谢您的查看 我们下回见。