1. 程式人生 > >redis 單機鎖 和 分散式鎖

redis 單機鎖 和 分散式鎖

單機鎖

程式碼偷自:https://www.cnblogs.com/iforever/p/5796902.html

<?php
require "vendor/autoload.php";

$client = new Predis\Client([
   'scheme' => 'tcp',
   'host'   => '127.0.0.1',
   'port'   => 6379,
]);

class RedisLock
{
   public $objRedis = null;
   public $timeout = 3;
   /**
    * @desc 設定redis例項
    *
    * @param obj object | redis例項
    */
public function __construct($obj) { $this->objRedis = $obj; } /** * @desc 獲取鎖鍵名 */ public function getLockCacheKey($key) { return "lock_{$key}"; } /** * @desc 獲取鎖 * * @param key string | 要上鎖的鍵名 * @param timeout int | 上鎖時間 */ public
function getLock($key, $timeout = NULL) { $timeout = $timeout ? $timeout : $this->timeout; $lockCacheKey = $this->getLockCacheKey($key); $expireAt = time() + $timeout; $isGet = (bool)$this->objRedis->setnx($lockCacheKey, $expireAt); if ($isGet) { return
$expireAt; } while (1) { usleep(10); $time = time(); $oldExpire = $this->objRedis->get($lockCacheKey); if ($oldExpire >= $time) { continue; } $newExpire = $time + $timeout; $expireAt = $this->objRedis->getset($lockCacheKey, $newExpire); if ($oldExpire != $expireAt) { continue; } $isGet = $newExpire; break; } return $isGet; } /** * @desc 釋放鎖 * * @param key string | 加鎖的欄位 * @param newExpire int | 加鎖的截止時間 * * @return bool | 是否釋放成功 */ public function releaseLock($key, $newExpire) { $lockCacheKey = $this->getLockCacheKey($key); if ($newExpire >= time()) { return $this->objRedis->del($lockCacheKey); } return true; } } $start_time = microtime(true); $lock = new RedisLock($client); $key = "name"; for ($i = 0; $i < 10000; $i++) { $newExpire = $lock->getLock($key); $num = $client->get($key); $num++; $client->set($key, $num); $lock->releaseLock($key, $newExpire); } $end_time = microtime(true); echo "花費時間 : ". ($end_time - $start_time) . "\n";

分散式鎖

官方原文: https://redis.io/topics/distlock
翻譯:http://ifeve.com/redis-lock/

注意下,按照上面的官方文件,setnx 的正確寫法是

SET resource_name my_random_value NX PX 30000