分佈式鎖實現(mysql redis zk)

  • 1 mysql方式

1,利用insert 和 delete控制數據記錄來實現鎖
2,利用mysql自帶鎖

  • 2 redis

private static final String LOCK_SUCCESS = "OK";
    private static final String SET_IF_NOT_EXIST = "NX";
    private static final String SET_WITH_EXPIRE_TIME = "EX";
    private static final Long RELEASE_SUCCESS = 1L;
    /**
     * 嘗試獲取分佈式鎖
     * @param jedis Redis客戶端
     * @param lockKey 鎖
     * @param requestId 請求標識
     * @param expireTime 超期時間
     * @return 是否獲取成功
     */
    public static boolean tryGetDistributedLock(Jedis jedis, String lockKey, String requestId, int expireTime) {
    	try{
    		String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
    		if (LOCK_SUCCESS.equals(result)) {
                return true;
            }
    	}finally{
    		if(jedis != null){
    			jedis.close();
    		}
    	}
        return false;
    }
    
    /**
     * 釋放分佈式鎖
     * @param jedis Redis客戶端
     * @param lockKey 鎖
     * @param requestId 請求標識
     * @return 是否釋放成功
     */
    public static boolean releaseDistributedLock(Jedis jedis, String lockKey, String requestId) {
    	try{
		    String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
	        Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));

	        if (RELEASE_SUCCESS.equals(result)) {
	            return true;
	        }
    	}finally{
    		if(jedis != null){
    			jedis.close();
    		}
    	}
        return false;
    }
    /**
     * 判斷鎖是否存在
     * @param jedis Redis客戶端
     * @param lockKey 鎖
     * @param requestId 請求標識
     * @return 鎖是否存在
     */
    public static boolean checkDistributedLock(Jedis jedis, String lockKey) {
    	try{
    		String value = jedis.get(lockKey);
            if (StringUtils.isEmpty(value)) {
                return true;
            }
    	}finally{
    		jedis.close();
    	}
        return false;
    }

使用緩存實現分佈式鎖的優點

性能好。

使用緩存實現分佈式鎖的缺點

實現過於負責,需要考慮的因素太多。

  • 3 zk

創建臨時節點

可以解決單機,鎖無法釋放,非阻塞,不可衝入,非公平的問題

總結

從理解的難易程度角度(從低到高)

數據庫 > 緩存 > Zookeeper

從實現的複雜性角度(從低到高)

Zookeeper > 緩存 > 數據庫

從性能角度(從高到低)

緩存 > Zookeeper >= 數據庫

從可靠性角度(從高到低)

Zookeeper > 緩存 > 數據庫

參考:https://blog.csdn.net/u010963948/article/details/79006572

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章