Redis分布式锁(并发竞争)

Redis的并发竞争问题如何解决?

Redis为单进程单线程模式,采用队列模式将并发访问变为串行访问。Redis自己没有锁的概念,Redis对于多个客户端链接并不存在竞争,可是在Jedis客户端对Redis进行并发访问时会发生链接超时、数据转换错误、阻塞、客户端关闭链接等问题,这些问题均是因为客户端链接混乱形成。对此有2种解决方法:html

 1.客户端角度,为保证每一个客户端间正常有序与Redis进行通讯,对链接进行池化,同时对客户端读写Redis操做采用内部锁synchronized。  redis

    2.服务器角度,利用setnx实现锁。服务器

 注:对于第一种,须要应用程序本身处理资源的同步,可使用的方法比较通俗,可使用synchronized也可使用lock;第二种须要用到Redis的setnx命令,可是须要注意一些问题。并发



关于redis锁的可靠性:

1.互斥性。在任意时刻,只有一个客户端能持有锁。分布式

2.不会发生死锁。即便有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其余客户端能加锁。post

3.具备容错性。只要大部分的Redis节点正常运行,客户端就能够加锁和解锁。spa

4.解铃还须系铃人。加锁和解锁必须是同一个客户端,客户端本身不能把别人加的锁给解了。线程

setnx key value key不存在就设置code

public class RedisTool {
 
    private static final String LOCK_SUCCESS = "OK";
    private static final String SET_IF_NOT_EXIST = "NX";
    private static final String SET_WITH_EXPIRE_TIME = "PX";
 
    /**
     * 尝试获取分布式锁
     * @param jedis Redis客户端
     * @param lockKey 锁
     * @param requestId 请求标识
     * @param expireTime 超期时间
     * @return 是否获取成功
     */
    public static boolean tryGetDistributedLock(Jedis jedis, String lockKey, String requestId, int expireTime) {
 
        String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
 
        if (LOCK_SUCCESS.equals(result)) {
            return true;
        }
        return false;
 
    }
 
}

http://www.javashuo.com/article/p-xmztjgny-kx.htmlhtm

主要就是要设置过时时间,防止崩溃了能够本身解锁

value要设置为惟一标识,以方便同一个客户端来解锁,因此value通常不能设置为过时时间

http://www.javashuo.com/article/p-ejxnzdni-ht.html

相关文章
相关标签/搜索