zoukankan      html  css  js  c++  java
  • 基于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请除成功");
    
    
        }
    }
  • 相关阅读:
    Confluence 6 使用 WebDAV 客户端来对页面进行操作
    Confluence 6 的 WebDAV 客户端整合介绍
    Confluence 6 MySQL 3.x 字符集编码问题
    Confluence 6 € 欧元字符集不能正常显示
    Confluence 6 字符集编码的问题解决
    Confluence 6 数据库字符集编码和问题
    Confluence 6 配置字符集编码
    Confluence 6 邮件队列
    pyDay6
    c++第十六天
  • 原文地址:https://www.cnblogs.com/edison20161121/p/10295291.html
Copyright © 2011-2022 走看看