一文搞懂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
相关推荐
九圣残炎5 分钟前
【从零开始的LeetCode-算法】1456. 定长子串中元音的最大数目
java·算法·leetcode
wclass-zhengge7 分钟前
Netty篇(入门编程)
java·linux·服务器
LunarCod13 分钟前
WorkFlow源码剖析——Communicator之TCPServer(中)
后端·workflow·c/c++·网络框架·源码剖析·高性能高并发
Re.不晚34 分钟前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
雷神乐乐40 分钟前
Maven学习——创建Maven的Java和Web工程,并运行在Tomcat上
java·maven
sszmvb123441 分钟前
测试开发 | 电商业务性能测试: Jmeter 参数化功能实现注册登录的数据驱动
jmeter·面试·职场和发展
码农派大星。44 分钟前
Spring Boot 配置文件
java·spring boot·后端
测试杂货铺1 小时前
外包干了2年,快要废了。。
自动化测试·软件测试·python·功能测试·测试工具·面试·职场和发展
王佑辉1 小时前
【redis】redis缓存和数据库保证一致性的方案
redis·面试
顾北川_野1 小时前
Android 手机设备的OEM-unlock解锁 和 adb push文件
android·java