PHP Redis实现同步锁

接上文同步锁(用文件实现)
用文件的形式实现同步锁,需要对应目录有读写权限,有IO性能消耗,而且会生成残留文件, 其实也可以借助redis达到同样的效果
Redis是线程安全的,可以把Redis看成单线程的模型.

首先来看Redisset命令

原生命令如下
set key value [EX seconds] [PX milliseconds] [NX|XX]
参数说明
*key 
*value
*[EX seconds] 可选,过期时间 单位秒
*[PX milliseconds] 可选,过期时间 单位毫秒
*[NX|XX] 可选,NX表示key不存在时执行set命令
              XX表示key存在时执行set命令

来个例子实验一下

设置name->zhangsan
过期时间20秒,且内存中不存在名为name的key时,命令执行
127.0.0.1:6379> set name zhangsan EX 20 NX 

执行两遍相同命令,只有第一条返回OK

image.png

PHP实现

用composer 下载Redis三方包,不同的包操作可能会有些差异.
我用的是Predis

 'tcp',
            'host'   => '127.0.0.1',
            'port'   => 6379,
        ]);
        $this->client = $client;
        $this->key    = $key;
    }
    /**
     * 获取锁
     * 
     * @return mixed
     */
    function getLock(){
        return $this->client->set($this->key,1,'EX',10,'NX');
    }
    /**
     * 清除锁
     */
    function clearLock(){
        $this->client->del($this->key);
    }
}

测试

getLock())
{
    echo "读库-$cacheKey".PHP_EOL;
    sleep(60);
    //TODO 设置缓存
    $redisLock->clearLock();
}else{
    echo "获取锁失败$cacheKey";
}

效果
image.png

image.png

确保只有一个线程进入读取数据库的代码段.就能避免缓存击穿问题.

你可能感兴趣的:(PHP Redis实现同步锁)