在 Redis 上执行 Lua 语言
首先
本次我們將學習關於 Redis 官方文件中的 Scripting with Lua。
※ 我经常搞混了,但这次我要讲述在 Redis 服务器上执行 Lua 的方法。(我不会提及如何从 Lua 程序中使用 Redis 客户端。)
关于 Redis 和 Lua
在Redis中,可以在服务器上执行Lua脚本。这些脚本可以通过程序控制,以使用命令访问数据库。
-
- スクリプトはサーバー内で実行されるため、スクリプトからのデータの読み書きは非常に効率的になる 。(PostgreSQL の PL/pgSQL に似ている)
- Redis ではスクリプトの実行にはアトミック性が保証される。スクリプトの実行中、サーバーのアクティビティはブロックされる(スクリプトがすべて作用しているか、すべて作用していないかの状態になる)
使用 Redis 和 Lua 可以实现的功能是什么
使用Lua可以在Redis内部执行应用程序逻辑的一部分。例如,可以做到以下这些事情。
-
- 複数のキーを条件付きで更新する
- 複数の異なるデータ型を組み合わせて操作する
※ 脚本由内置在 Redis 中的执行引擎执行。(仅支持 Lua 5.1)
※ 执行 EVAL 的脚本被视为客户端应用程序的一部分,而不是服务器端,并且不会被持久化。脚本可能会在服务器重新启动后无法找到,因此需要从应用程序中重新加载。从 Redis 7 开始,还可以使用 Redis 函数来扩展服务器本身以进行编程的附加逻辑。
例1. 像”你好,世界”的东西
> EVAL "return 'Hello, scripting!'" 0
"Hello, scripting!"
在这个例子中,EVAL 接受了两个参数。
-
- 第 1 引数: Lua のスクリプト(関数の定義ではなく、そのまま実行されるプログラムを書く)
- 第 2 引数: キーの数(今回はキーを与えていないので 0 を指定している)
例2. 给脚本传递参数
请用中文进行重述,只需要一种选项:
以下这段脚本。
redis> EVAL "return 'Hello'" 0
"Hello"
redis> EVAL "return 'Scripting!'" 0
"Scripting!"
可以使用参数如下所示
redis> EVAL "return ARGV[1]" 0 Hello
"Hello"
redis> EVAL "return ARGV[1]" 0 Parameterization!
"Parameterization!"
-
- 第 1 引数: Lua のスクリプト
-
- 第 2 引数: キーの数が 0
- 第 3 引数: ARGV に入る値の 1 つ目(Lua のインデックスは 1 から始まる)
请注意:
在应用程序中生成并执行多个微妙不同的脚本,就像上面的例子一样,被称为反模式。
EVAL で実行したスクリプトはサーバーの専用のキャッシュに保存されるので、さまざまなスクリプトの生成によりホストのメモリリソースを使い果たす可能性がある。
脚本需要具有通用性,可以通过参数来定制执行内容。
给脚本提供密钥
redis> EVAL "return { KEYS[1], KEYS[2], ARGV[1], ARGV[2], ARGV[3] }" 2 key1 key2 arg1 arg2 arg3
1) "key1"
2) "key2"
3) "arg1"
4) "arg2"
5) "arg3"
-
- 第 1 引数: Lua のスクリプト
-
- 第 2 引数: キーの数が 2
-
- 第 3、4 引数: キー(KEYS に入る値)
- 第 5、6、7 引数: 引数(ARGV に入る値)
在使用KEYS和ARGV时要注意区别:KEYS应该用于获取Redis中所有键的值(key-value对中的键)。而对于其他可以进行共通处理的参数,则应该使用ARGV。
用脚本与 Redis 进行交互的示例4。
可以使用 redis.call() 或 redis.pcall() 来执行 Redis 命令。
> EVAL "return redis.call('SET', KEYS[1], ARGV[1])" 1 foo bar
OK
运行此脚本会调用 SET 命令,并将值“bar”设置给键 foo。
重要事项:
为了正确执行脚本,需要将脚本访问的所有键的名称明确指定为输入键的参数。
不要通过程序生成的名称键或存储在数据库中的数据键来访问脚本。