Redis分布式锁的最佳实践

1 篇文章 0 订阅

原文链接:https://www.jianshu.com/p/8cc44d008177

使用redis的SET resource-name anystring NX EX max-lock-time 方式,用于分布式锁

实现原理

命令 SET resource-name anystring NX EX max-lock-time 是一种在 Redis 中实现锁的简单方法。

客户端执行以上的命令:

  1. 如果服务器返回 OK ,那么这个客户端获得锁。
  2. 如果服务器返回 NIL ,那么客户端获取锁失败,可以在稍后再重试。
  3. 设置的过期时间到达之后,锁将自动释放。

实现优化

可以通过以下修改,让这个锁实现更健壮:

  1. 不使用固定的字符串作为键的值,而是设置一个不可猜测(non-guessable)的长随机字符串,作为口令串(token)。
  2. 不使用 DEL 命令来释放锁,而是发送一个 Lua 脚本,这个脚本只在客户端传入的值和键的口令串相匹配时,才对键进行删除。

这两个改动可以防止持有过期锁的客户端误删现有锁的情况出现。

使用评价

参考实现的代码功能已经实现了,详见https://www.jianshu.com/p/8cc44d008177

但没有实现java的java.util.concurrent.locks.Lock接口,不方便以后更改实现或者进行扩展。

如果要集成到系统中使用,建议使用代理模式进行优化,将参考的RedisLock类作为RedisLockAdapter,实际的RedisLock实现代码如下:

public class RedisLock implements Lock {

	private RedisLockAdapter redisLockAdapter;

	/**
	 * @param redisLockAdapter
	 */
	public RedisLock(RedisLockAdapter redisLockAdapter) {
		super();
		this.redisLockAdapter = redisLockAdapter;
	}

	@Override
	public void lock() {
		redisLockAdapter.lock();

	}

	@Override
	public void lockInterruptibly() throws InterruptedException {
		// TODO method lockInterruptibly() is not implemented
	}

	@Override
	public boolean tryLock() {
		return redisLockAdapter.tryLock();
	}

	@Override
	public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
		// TODO method tryLock(time, unit) is not implemented
		return false;
	}

	@Override
	public void unlock() {
		redisLockAdapter.unlock();
	}

	@Override
	public Condition newCondition() {
		// TODO method newCondition() is not implemented
		return null;
	}

}

扩展阅读

另外,也研究了下Redis官方推荐的Redisson框架

官方网站:https://redisson.org/

整合参考资料:https://yq.aliyun.com/articles/554753

功能的确很强大:

  1. 支持Redis部署的各种模式
  2. 提供了很多jdk标准接口的实现

但Redisson的配置不兼容spring-data-redis,侵入性太强,非常不优雅。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值