1. 程式人生 > >Redis實現分散式鎖機制

Redis實現分散式鎖機制

Redis實現分散式鎖思路
  常用的是redis函式是setnx(),這個應該是實現分散式鎖最主要的函式。首先是將某一業務標識名作為鍵存到redis裡,併為其設個過期時間,如果是還有加鎖請求過來,先是通過setnx()看看是否能將鎖的標識插入到redis裡,可以的話就返回true,不可以就返回false。
  
  此處使用Lua指令碼簡單的實現Redis鎖的實現 :

package com.tencent.sxwx.wechat.util;


import redis.clients.jedis.Jedis;

public class DistributeLocker {

    private
Jedis jedis; private Lock lock; /** * 加鎖成功標識 */ private static final String LOCK_SUCCESS = "1"; /** * 指令碼入參個數 */ private static final int KEY_COUNT = 1; /** * 加鎖指令碼 */ private static String LOCK_SCRIPT; /** * 解鎖指令碼 */ private static String RELEASE_SCRIPT; /** * 初始化指令碼 */
static { LOCK_SCRIPT = "local key = redis.call('get',KEYS[1]) if ('1' == key) then return 0 " + "else redis.call('set',KEYS[1],'1') redis.call('expire',KEYS[1],ARGV[1]) return 1 end"; RELEASE_SCRIPT = "if (redis.call('exists',KEYS[1])) then redis.call('del',KEYS[1]) end"
; } /** * 定義帶參建構函式 */ public DistributeLocker (Lock lock) { } public void lock (final String key, final int exprieTime) { if (isLocked(key, exprieTime)) { lock.success(); } else { lock.failure(); } } /** * 加鎖邏輯 */ private boolean isLocked(final String key, final int exprieTime) { Object obj = jedis.eval(LOCK_SCRIPT, KEY_COUNT, key, String.valueOf(exprieTime)); if (LOCK_SUCCESS.equals(obj)) { return true; } return false; } /** * 解鎖邏輯 */ public void releaseLock (String key) { jedis.eval(RELEASE_SCRIPT, KEY_COUNT, key); } }
package com.tencent.sxwx.wechat.util;

public interface Lock {

    void success();

    void failure();
}
package com.tencent.sxwx.wechat.util;

public class Test {

    void purchase(String key, int secondTime){
        DistributeLocker locker = new DistributeLocker(new Lock() {
            @Override
            public void success() {
                // do something
            }

            @Override
            public void failure() {
                // do something
            }
        });
        try {
            locker.lock(key,secondTime);
        } finally {
            locker.releaseLock(key);
        }
    }
}

注:Redis分散式鎖的實現方式有很多種,各有利弊,加鎖的時候主要注意檢查鎖與加鎖操作要有原子性,防止重複加鎖成功。過期時間主要是為了防止未釋放鎖導致鎖的一直存在,從而無法獲取鎖操作。