Redis-PHP实战篇——常用的使用场景

Redis-PHP实战篇——常用的使用场景

redis-php实战

1
2
3
4
5
6
7
8
9
public function getRedis()
{
$redis = new \Redis();
$redis->connect(env("REDIS_MASTER",'127.0.0.1'),6379);
$redis->auth(env('REDIS_AUTH','123456'));
return $redis;
}

$redis = $this->getRedis();

String 简单字符串缓存实战

1
2
3
4
5
6
7
$key  = 'str:name';

// 字符串缓存实战
$redis->set($key, 'WXiangQian');
$name = $redis->get($key);
echo $name; // WXiangQian
$redis->expire($strCacheKey, 30); # 设置30秒后过期

HSET 简单哈希缓存实战

1
2
3
4
5
6
$key = 'hset:name'

$uid = 1;
$redis->hSet($key, $uid, 'WXiangQian');
$data = $redis->hGet($key, 1);
print_r($data); //输出数据

排行榜实战

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$strKey = 'zset:ranking_list';

//存储数据
$redis->zadd($strKey, '50', json_encode(['name' => 'Tom']));
$redis->zadd($strKey, '70', json_encode(['name' => 'John']));
$redis->zadd($strKey, '90', json_encode(['name' => 'Jerry']));
$redis->zadd($strKey, '30', json_encode(['name' => 'Job']));
$redis->zadd($strKey, '100', json_encode(['name' => 'LiMing']));

$dataOne = $redis->ZREVRANGE($strKey, 0, -1, true);
echo "---- {$strKey}由大到小的排序 ---- <br /><br />";
print_r($dataOne);

$dataTwo = $redis->ZRANGE($strKey, 0, -1, true);
echo "<br /><br />---- {$strKey}由小到大的排序 ---- <br /><br />";
print_r($dataTwo);

list分页实战

1
2
3
4
5
6
7
$strKey = 'list:data';
$page = $request->input('page',1);
$pageSize = $request->input('limit',50);
$limit_s = ($page-1) * $pageSize;
$limit_e = ($limit_s + $pageSize) - 1;
$data = $tools->redis->lRange($strKey,$limit_s,$limit_e);
print_r($data);

简单字符串悲观锁实战

解释:悲观锁(Pessimistic Lock), 顾名思义,就是很悲观。

每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁。

场景:如果项目中使用了缓存且对缓存设置了超时时间。

当并发量比较大的时候,如果没有锁机制,那么缓存过期的瞬间,

大量并发请求会穿透缓存直接查询数据库,造成雪崩效应。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**
* 获取锁
* @param String $key 锁标识
* @param Int $expire 锁过期时间
* @return Boolean
*/
public function lock($key = '', $expire = 5) {
$is_lock = $this->_redis->setnx($key, time()+$expire);
//不能获取锁
if(!$is_lock){
//判断锁是否过期
$lock_time = $this->_redis->get($key);
//锁已过期,删除锁,重新获取
if (time() > $lock_time) {
unlock($key);
$is_lock = $this->_redis->setnx($key, time() + $expire);
}
}

return $is_lock? true : false;
}

/**
* 释放锁
* @param String $key 锁标识
* @return Boolean
*/
public function unlock($key = ''){
return $this->_redis->del($key);
}

// 定义锁标识
$key = 'str:lock';

// 获取锁
$is_lock = lock($key, 10);
if ($is_lock) {
echo 'get lock success<br>';
echo 'do sth..<br>';
sleep(5);
echo 'success<br>';
unlock($key);
} else { //获取锁失败
echo 'request too frequently<br>';
}

简单事务的乐观锁实战

解释:乐观锁(Optimistic Lock), 顾名思义,就是很乐观。

每次去拿数据的时候都认为别人不会修改,所以不会上锁。

watch命令会监视给定的key,当exec时候如果监视的key从调用watch后发生过变化,则整个事务会失败。

也可以调用watch多次监视多个key。这样就可以对指定的key加乐观锁了。

注意watch的key是对整个连接有效的,事务也一样。

如果连接断开,监视和事务都会被自动清除。

当然了exec,discard,unwatch命令都会清除连接中的所有监视。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
$strKey = 'str:age';

$redis->set($strKey,10);

$age = $redis->get($strKey);

echo "---- Current Age:{$age} ---- <br/><br/>"; // 10

$redis->watch($strKey);

// 开启事务
$redis->multi();

//-------------------------------
/**
* 在这个时候新开了一个新会话执行
*
* redis-cli 执行 $redis->set($strKey,30); //新会话 模拟其他终端
* 这时候$age=30; //30
*/
//-------------------------------



$redis->set($strKey,20);

$redis->exec();

$age = $redis->get($strKey);

echo "---- Current Age:{$age} ---- <br/><br/>"; //30

//当exec时候如果监视的key从调用watch后发生过变化,则整个事务会失败

悲观锁与乐观锁的适用场景:

悲观锁:比较适合写入操作比较频繁的场景,如果出现大量的读取操作,每次读取的时候都会进行加锁,这样会增加大量的锁的开销,降低了系统的吞吐量。

乐观锁:比较适合读取操作比较频繁的场景,如果出现大量的写入操作,数据发生冲突的可能性就会增大,为了保证数据的一致性,应用层需要不断的重新获取数据,这样会增加大量的查询操作,降低了系统的吞吐量。

总结:两种所各有优缺点,读取频繁使用乐观锁,写入频繁使用悲观锁。

像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行retry,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适,之所以用悲观锁就是因为两个用户更新同一条数据的概率高,也就是冲突比较严重的情况下,所以才用悲观锁.

悲观锁比较适合强一致性的场景,但效率比较低,特别是读的并发低。乐观锁则适用于读多写少,并发冲突少的场景

redis篇集合

Redis基础篇——Redis安装

Redis基础篇——介绍以及了解

Redis基础篇——基本用法

Redis进阶篇——PHP连接redis

Redis-PHP实战篇——常用的使用场景

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. redis-php实战
    1. 1.1. String 简单字符串缓存实战
    2. 1.2. HSET 简单哈希缓存实战
    3. 1.3. 排行榜实战
    4. 1.4. list分页实战
    5. 1.5. 简单字符串悲观锁实战
    6. 1.6. 简单事务的乐观锁实战
    7. 1.7. 悲观锁与乐观锁的适用场景:
  2. 2. redis篇集合