php redis实现统一登录,PHP Redis实现同步锁

接上文同步锁(用文件实现)

用文件的形式实现同步锁,需要对应目录有读写权限,有IO性能消耗,而且会生成残留文件, 其实也可以借助redis达到同样的效果

Redis是线程安全的,可以把Redis看成单线程的模型.

首先来看Redis的set命令

原生命令如下

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

9d779f5cc23c

image.png

PHP实现

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

我用的是Predis

namespace lock;

require_once 'lib/vendor/autoload.php';

use \Predis\Client;

class RedisLock

{

private $client;

private $key;

/**

* RedisLock constructor.

*

* @param $key

*/

public function __construct ($key) {

\Predis\Autoloader::register();

$client = new Client([

'scheme' => '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);

}

}

测试

use lock\RedisLock;

require_once 'RedisLock.php';

if (!isset($argv[1])){

echo '输入cacheKey';

return;

}

//获取输入的cacheKey

$cacheKey = $argv[1];

$redisLock = new RedisLock($cacheKey);

if($redisLock->getLock())

{

echo "读库-$cacheKey".PHP_EOL;

sleep(60);

//TODO 设置缓存

$redisLock->clearLock();

}else{

echo "获取锁失败$cacheKey";

}

效果

9d779f5cc23c

image.png

9d779f5cc23c

image.png

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值