REDIS执行LUA脚本整理

在处理高并发业务数据的时候,经常把使用REDIS作为数据载体,以提高接口响应速度。在复杂业务场景下,一次请求可能会涉及大量的redis操作,为了保证数据一致性,再使用MULTI/EXEC命令就不太合适了。2.6版本后,REDIS开始支持LUA脚本(将客户端的LUA脚本存入REDIS服务端,然后再执行)在REDIS内部保证脚本操作数据时的一致性。

redis执行 lua命令

redis主要通过eval和evalsha两个命令执行lua脚本:

eval命令格式如下

EVAL script numkeys key [key ...] arg [arg ...] 

script是一段LUA脚本的字符串;

evalsha命令要配合script load命令先将脚本上报到REDIS服务端后,才能正常使用,其参数格式类似eval命令

EVALSHA sha1 numkeys key [key ...] arg [arg ...]

其中sha1是script load命令返回的脚本sha1值,可以惟一指向服务端的一段脚本;执行evalsha命令前最好通过SCRIPT EXISTS先判断对应的脚本是否存在

譬如springboot中redistemplate如下

DefaultRedisScript<List> redisScript = new DefaultRedisScript<>();
redisScript.setResultType(List.class);
redisScript.setScriptText("return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}");

List<String> keys = Arrays.asList("hello", "world");
List result = (List) redisTemplate.execute(redisScript, keys, "li lei", "han mei mei");
return result;

redistemplate会重复利用脚本的sha1值,避免每次执行时重新提交脚本到服务器,参见DefaultScriptExecutor

protected <T> T eval(RedisConnection connection, RedisScript<T> script, ReturnType returnType, int numKeys, byte[][] keysAndArgs, RedisSerializer<T> resultSerializer) {
	Object result;
	try {
		result = connection.evalSha(script.getSha1(), returnType, numKeys, keysAndArgs);
	} catch (Exception var9) {
		if (!ScriptUtils.exceptionContainsNoScriptError(var9)) {
			throw var9 instanceof RuntimeException ? (RuntimeException)var9 : new RedisSystemException(var9.getMessage(), var9);
		}

		result = connection.eval(this.scriptBytes(script), returnType, numKeys, keysAndArgs);
	}

	return script.getResultType() == null ? null : this.deserializeResult(resultSerializer, result);
}

redis lua脚本说明

1. 使用KEYS[] ARGV[]代表传入的keys和args,下标从1开始;脚本中使用redis.call关键字执行redis命令,譬如redis.call('set', KEY[1], ARGV[1])

1. lua脚本将多个reids操作作为一个整体,并能执行一些简单的计算比较逻辑,跟单个redis命令一样,都是原子操作

2.对已经开始执行的lua脚本无法被中断

3. redis分片时,lua脚本会在某些分片上执行,所以执行前要确认所有的key值对应的数据是否都在一个分片上

4. lua脚本会存在redis服务端,可以通过SCRIPT FLUSH命令清除

 

参考 redis 脚本

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值