Redis_配合Lua做Java分布式事务锁

Redis作Java分布式锁

 我们都知道redis现在成为越来越多人作为缓存工具的选择,redis在性能、操作等方面上有着独特的优势。

1. 检查reids版本
  因为redis是在2.6版本后才内置了Lua脚本解释器,所以也就是说要用redis执行lua脚本,最基本的要求就是redis版本必须是2.6.0以上
  查看redis版本命令:info
在启动redis客户端后,连接redis客户端,输入命令如下图:
查询redis版本号命令
 

2.编写lua脚本
  做分布式锁的lua语句如下,这边选的是最简单的语句:

local key = KEYS[1]
local value = KEYS[2]
local sec = KEYS[3]

local result = redis.call("SET",key, value, "NX", "EX", sec)
if(result) then
	return 1
else
	return 0;
end

 这个lua脚本的意思是传三个值,第一个值是键,第二个值是值,第三个值是过期时间,单位秒。

3.使用DOS窗口让redis客户端调用lua脚本
使用DOS命令调用

命令为:redis-cli.exe --eval E:\redis\redisLock.lua testKey testValue 300--前有个空格)

参数 解释
redis-cli.exe 调用该服务
–eval 告诉redis客户端进行执行lua脚本
E:\redis\redisLock.lua 这边是我自己的路径,换成你们lua脚本路径
testKey、testValue、300 这个lua脚本接受的数据,根据你自己编写的lua脚本而定

结果
 我们可以看到我们设置的redis的结果和我们预期的是一样的。

4.Java整合Redis

 先上Java上的代码:

package com.dahantc.iot.util;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.ScriptSource;
import org.springframework.scripting.support.ResourceScriptSource;
import org.springframework.stereotype.Service;

import com.dahantc.iot.core.util.LogUtil;

@Service
public class LuaRedisLockUtils{
	
	private final static Logger logger = LogUtil.get();
	
	@Autowired
	private RedisTemplate redisTemplate;
	
	public Boolean lock(String key, String value, String seconds){
		try{
			String path = "redis_lock.lua";
			ClassPathResource resource = new ClassPathResource(path);
			ScriptSource scriptSource = new ResourceScriptSource(resource);
			DefaultRedisScript defaultRedisScript = new DefaultRedisScript();
			defaultRedisScript.setScriptSource(scriptSource);
			//设置返回类型
			defaultRedisScript.setResultType(Long.class);
			
			//组装数据
			List<Object> keyList = new ArrayList<>();
			keyList.add(key);
			keyList.add(value);
			keyList.add(seconds);
			// 第三个参数是无用的,但不能为空,考虑到内存空间,遂作故用
			Long result = (Long)redisTemplate.execute(defaultRedisScript, keyList);
			return result == 1;
		}catch(Exception e){
			logger.error("redis分布式锁存在异常,请注意key:{},value:{}, seconds:{}", key, value, seconds);
			return false;
		}
	}

}

lua脚本位置
 该项目过测试,整合是成功。这边不再跑一遍作示范了。

总结:BASE理论面向的是大型高可用可扩展的分布式系统,和我们传统的ACID型事务是背道而驰的。传统ACID事务要求的是强一致性,而分布式系统则是通过牺牲强一致性来换取可用型,允许数据在某较短的时间内不一致,当然分布式系统也是要保证数据的最终一致性。

扫描二维码关注公众号,回复: 8812359 查看本文章
发布了204 篇原创文章 · 获赞 69 · 访问量 19万+

猜你喜欢

转载自blog.csdn.net/pseudonym_/article/details/95314650
今日推荐