一文搞懂redis的脚本使用

redis脚本

Redis脚本是一段使用Lua编写的程序,用于在Redis服务端执行一系列的redis指令。

什么是Lua脚本

Lua是一种轻量级的脚本语言,被广泛用于嵌入式系统和应用程序的扩展性开发。在Redis中,Lua脚本通常被用来执行一些复杂的、需要原子性操作的任务。

用通俗易懂的语言来说,可以把redis脚本看成一种特殊的命令组合,可以在redis服务器上面执行多个操作。脚本可以包含判断、循环、变量等基本编程元素,让我们以一种更高级、更复杂的方式与redis进行交互,而redis通过EVALEVALHA命令执行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中evalevalsha的用法

evalevalsha都是Redis中用于执行lua脚本的命令,他们之间的区别在于:

  1. eval:每次都将完整的lua脚本传输给redis并执行。这意味着脚本在每次执行时都会被发送到服务器,可能会导致比较大的网络开销。通常,这种方式适用于只执行一次或少量次数的脚本。举个简单例子
java 复制代码
String luScript = "return 'Hello, world!";
Object result = jedis.eval(luaScript,0);
  1. 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
相关推荐
monkey_meng11 分钟前
【遵守孤儿规则的External trait pattern】
开发语言·后端·rust
草莓base24 分钟前
【手写一个spring】spring源码的简单实现--bean对象的创建
java·spring·rpc
Estar.Lee26 分钟前
时间操作[计算时间差]免费API接口教程
android·网络·后端·网络协议·tcp/ip
drebander1 小时前
使用 Java Stream 优雅实现List 转化为Map<key,Map<key,value>>
java·python·list
乌啼霜满天2491 小时前
Spring 与 Spring MVC 与 Spring Boot三者之间的区别与联系
java·spring boot·spring·mvc
tangliang_cn1 小时前
java入门 自定义springboot starter
java·开发语言·spring boot
程序猿阿伟1 小时前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
Grey_fantasy1 小时前
高级编程之结构化代码
java·spring boot·spring cloud
新知图书1 小时前
Rust编程与项目实战-模块std::thread(之一)
开发语言·后端·rust
弗锐土豆1 小时前
工业生产安全-安全帽第二篇-用java语言看看opencv实现的目标检测使用过程
java·opencv·安全·检测·面部