基于redis实现分布式锁

Posted 成功的路上总是离不开贵人的帮助,名师的指点和小人的刺激。

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于redis实现分布式锁相关的知识,希望对你有一定的参考价值。

相对于利用数据库实现分布式锁,利用redis来实现分布式锁,有以下几个优点

   优点:

1.可以集群部署的,可以解决单点问题。

2.自带过期时间可以解决死锁问题。

 可靠性介绍

  1. 互斥性。在任意时刻,只有一个客户端能持有锁。
  2. 不会发生死锁。即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁。
  3. 具有容错性。只要大部分的Redis节点正常运行,客户端就可以加锁和解锁。
  4. 解铃还须系铃人。加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了。

 

利用redis语句加锁。

 set key value nx ex 2

解锁

delete key 

 

问题所在:

虽然可以加入失效时间,一旦到了时间会自动删除锁,但是失效时间我设置多长时间为好?如何设置的失效时间太短,方法没等执行完,锁就自动释放了,那么就会产生并发问题。如果设置的时间太长,其他获取锁的线程就可能要平白的多等一段时间。这个问题使用数据库实现分布式锁同样存在。

 

package com.test;

import redis.clients.jedis.Jedis;

import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by edison on 2019/2/4.
 */
public class RedisJava {
    public static void main(String[] args) {
        //连接本地的 Redis 服务
        Jedis jedis = new Jedis("192.168.43.150");
        System.out.println("连接成功");
        //查看服务是否运行
        System.out.println("服务正在运行: "+jedis.ping());

        ConcurrentHashMap cMap = new ConcurrentHashMap();
        cMap.put("key1", ""abc"");
        cMap.put("key2", ""def"");
        cMap.put("key3", ""ghk"");
        System.out.println(cMap.toString());

        StringBuffer sb = new StringBuffer();
        sb.append("local lockKeys = " + cMap.toString() + " ");
        sb.append("local flag = 1 ");
        sb.append("for i,v in pairs(lockKeys) do ");
        sb.append("  local result = redis.call("set",i, v,"nx","ex", 20) ");
        sb.append("if type(result) ~= "table" then" );
        sb.append("  flag = 0 ");
        sb.append(" break ");
        sb.append(" end ");
        sb.append(" end ");
        sb.append(" return flag ");
        System.out.println(sb.toString());
       Long eval = (Long) jedis.eval(sb.toString());
        System.out.println(eval);
        System.out.println("redis设置成功");


        StringBuffer sb2 = new StringBuffer();
        sb2.append("local lockKeys = " + cMap.toString() + " ");
        sb2.append("for i,v in pairs(lockKeys) do ");
        sb2.append("  redis.call("del",i) ");
        sb2.append(" end ");

        Object eval1 = jedis.eval(sb2.toString());
        System.out.println("redis请除成功");


    }
}

 

以上是关于基于redis实现分布式锁的主要内容,如果未能解决你的问题,请参考以下文章

Redis实现分布式锁(设计模式应用实战)

redis基于redis实现分布式并发锁

基于 Redis 分布式锁实现“秒杀”(含代码)

基于Redis实现分布式锁

基于redis和zookeeper的分布式锁实现方式

分布式锁的两种实现方式(基于redis和基于zookeeper)