redis脚本
Redis脚本是一段使用Lua编写的程序,用于在Redis服务端执行一系列的redis指令。
什么是Lua脚本
Lua是一种轻量级的脚本语言,被广泛用于嵌入式系统和应用程序的扩展性开发。在Redis中,Lua脚本通常被用来执行一些复杂的、需要原子性操作
的任务。
用通俗易懂的语言来说,可以把redis脚本看成一种特殊的命令组合
,可以在redis服务器上面执行多个操作。脚本可以包含判断、循环、变量等基本编程元素,让我们以一种更高级、更复杂的方式与redis进行交互,而redis通过EVAL
和EVALHA
命令执行lua脚本保证执行过程时不被其他命令插入,避免多客户端命令之间可能发生的并发问题。
总的来说,Redis脚本就是一种在服务端执行的、用于完成一系列Redis操作的小程序,它使得我们可以更灵活、高效地与Redis进行交互。
具体了解Lua可以点击右方链接:Lua教程-菜鸟教程
Redis脚本如何使用
在Redis中,Lua被用作脚本语言,通过EVAL或EVALSHA命令执行。以下是一些通俗易懂的Redis Lua脚本的用法和例子:
首先看一下java中通过redis使用脚本的例子:
java
Jedis jedis = new Jedis("localhost"); // 连接到本地的Redis服务器
String script = "local key = KEYS[1]\n" +
"local value = ARGV[1]\n" +
"redis.call('SET', key, value)\n" +
"return redis.call('GET', key)";
String result = jedis.eval(script, Collections.singletonList("myKey"), Collections.singletonList("myValue")); // 执行Lua脚本
System.out.println(result); // 输出执行结果
下面介绍一下lua的简单使用:
简单计算
lua
-- 将两个数字相加
local a = tonumber(redis.call('GET', KEYS[1]))
local b = tonumber(redis.call('GET', KEYS[2]))
return a + b
这个脚本从两个键中获取数字并返回它们的和。
条件更新
lua
local currentValue = tonumber(redis.call('GET',KEYS[1]))
if currentValue < 10 then
redis.call('SET',KEYS[1],currentValue + 1)
return 'Counter incremented!'
else
return 'Counter already at max value.'
end
循环
lua
-- for循环
for i = 1, 5 do
print("Iteration " .. i)
end
-- while循环
local count = 0
while count < 3 do
print("Count: " .. count)
count = count + 1
end
函数定义与调用
lua
---定义函数
function greet(name)
return "Hello," .. name .. "!"
end
---调用函数
local message = greet("Bob")
print(message)
表(Table)
lua
--- 创建表
local person = {
name = "John",
age = 40,
city = "China"
}
--- 访问表中的元素
print("name:" .. person.name)
print("age:" .. person.age)
print("city:" .. person.city)
闭包
lua
function createCounter()
local count = 0
return function()
count = count + 1
return count
end
end
local counter = createCounter()
print(counter())
print(counter())
字符串操作
lua
---字符串操作
local message = "lua is awesome"
---字符串长度
print("Length:" .. #message)
---字符串分割
local words = {}
for word in string.upper(message):gmatch("%S+") do
table.insert(words,word)
end
print("Words:" .. table.concat(words,", "))
这些例子涵盖lua中一些基础语法和常见用法,详细见[lua-教程](www.runoob.com/lua/)。Lua的间...
jedis中eval
和evalsha
的用法
eval
和evalsha
都是Redis中用于执行lua脚本的命令,他们之间的区别在于:
eval
:每次都将完整的lua脚本传输给redis并执行。这意味着脚本在每次执行时都会被发送到服务器,可能会导致比较大的网络开销。通常,这种方式适用于只执行一次或少量次数的脚本。举个简单例子
java
String luScript = "return 'Hello, world!";
Object result = jedis.eval(luaScript,0);
evalsha
:执行已经在Redis中缓存的lua脚本。在调用scriptLoad
预加载脚本之后,可以使用evalsha
来多次执行相同的脚本,以提升性能,因为脚本不需要每次都传输给Redis。示例如下
java
String luaScript = "return 'Hello, world!";
String scriptSha1 = jedis.scriptLoad(luaScript);
Object result = jedis.evalsha(scriptSha1,0);
总的来说,如果有经常要执行的脚本,就把它预加载,可以使用evalsha
执行脚本提升性能,如果执行次数少,就使用eval
。
引申
将脚本script添加到脚本缓存中,但并不立即执行这个脚本
命令: SCRIPT LOAD <script>
从脚本缓存中移除所有脚本
命令: SCRIPT FLUSH
杀死当前正在运行的lua脚本
命令:
SCRIPT KILL
生效条件:
脚本没有执行过任何写操作,这个命令才有效
作用:
一般用于杀死运行时间过长的脚本,比如一个因为bug产生的无线循环脚本,执行之后,当前运行的脚本会被杀死,执行这个脚本的客户端会从EVAL命令的阻塞当中退出,并收到一个错误作为返回值。
查看指定脚本是否已经保存在缓存当中
命令: SCRIPT EXISTS <script>
[script...]
下面是一个使用的例子:
json
127.0.0.1:6379> SCRIPT LOAD "return 'Hello world!'"
"9a3fdf49135ad384c54e462ac90fc0395600638c"
127.0.0.1:6379> SCRIPT EXISTS 9a3fdf49135ad384c54e462ac90fc0395600638c
1) (integer) 1
127.0.0.1:6379> SCRIPT FLUSH
OK
127.0.0.1:6379> SCRIPT EXISTS 9a3fdf49135ad384c54e462ac90fc0395600638c
1) (integer) 0