一文搞懂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
相关推荐
Freak嵌入式10 分钟前
全网最适合入门的面向对象编程教程:50 Python函数方法与接口-接口和抽象基类
java·开发语言·数据结构·python·接口·抽象基类
前端小马20 分钟前
解决IDEA出现:java: 程序包javax.servlet不存在的问题
java·servlet·intellij-idea
白总Server30 分钟前
MongoDB解说
开发语言·数据库·后端·mongodb·golang·rust·php
计算机学姐42 分钟前
基于python+django+vue的家居全屋定制系统
开发语言·vue.js·后端·python·django·numpy·web3.py
IH_LZH1 小时前
Broadcast:Android中实现组件及进程间通信
android·java·android studio·broadcast
去看全世界的云1 小时前
【Android】Handler用法及原理解析
android·java
.Net Core 爱好者1 小时前
Redis实践之缓存:设置缓存过期策略
java·redis·缓存·c#·.net
晚睡早起₍˄·͈༝·͈˄*₎◞ ̑̑1 小时前
苍穹外卖学习笔记(五)
java·笔记·学习
码上一元1 小时前
【百日算法计划】:每日一题,见证成长(017)
java·算法
用生命在耍帅ㅤ1 小时前
java spring boot 动态添加 cron(表达式)任务、动态添加停止单个cron任务
java·开发语言·spring boot