一、Redis 常用类型的实战场景分析
5个最基础的类型:(数据类型拥有不同的命令)
- 1、String(字符串)用来做:1、缓存 set/get 2、分布式session(单点登录)
- 2、Hash(哈希) 用来做:1、用户信息存储(以key对应value进行存储) 2、哈希索引
- 3、List(列表)用来做:1、队列(秒杀、抢票)(先进先出特性,场景比较多)
- 4、Set(集合)用来做:1、共同关注了某个人,相同爱好,好友关系等。
- 5、Sorted Set(有序集合)用来做:1、排行榜
高级的:
1、pub/sub 发布订阅
2、geo 地理位置
3、布隆过滤器----->缓存穿透(防止大流量的请求中(有恶意请求)--->恶意请求--->进入缓存--->而攻击数据库)
二、Sorted Set数据类型来做排行榜的原理
以Sorted Set(有序集合)举例
一
1、榜名
2、榜中数据
3、榜中权重
二
1、选择排名
2、限制排行人
3。是否隐藏权重
三、排行榜在laravel中的应用redis存储
class Ranklist extends Controller {
// redis -----> sorted set // zSet/zAdd(榜名,权重,数据)
private $redis;
private $leaderboard;
public function __construct(){
$this->redis = new \Redis();
$this->redis->connect('127.0.0.1');
}
/**
* 添加
* @param [type] $leaderboard [榜名]
* @param [type] $node [数据]
* @param integer $count [权重]
*/
public function addLeaderboard($leaderboard=null,$node,$count=1){
if($leaderboard){
$this->leaderboard = 'leaderboard:' .$leaderboard;
}else{
$this->leaderboard = 'leaderboard:' .mt_rand(1,10000);
}
return $this->redis->zAdd($this->leaderboard,$count,$node);
}
/**
* 获取
* @param [type] $leaderboard [榜名]
* @param [type] $number [限制人数]
* @param boolean $asc [升降序]
* @param boolean $score [权重是否显示]
* @return [type]
*/
public function getLeaderboard($leaderboard=null,$number,$asc=true,$score=true){
$this->leaderboard = 'leaderboard:' .$leaderboard;
if($asc){
// redis 数据 升降序 也要用到redis命令
// 按照高分数进行一个顺序排序
$nowLeaderboard=$this->redis->zRevRange($this->leaderboard,0,$number-1,$score);
}else{
$nowLeaderboard=$this->redis->zRange($this->leaderboard,0,$number-1,$score);
}
return $nowLeaderboard;
}
}
路由
// 添加
Route::get('addLeaderboard/{leaderboard?}/{node}/{count?}','Ranklist@addLeaderboard ');
// 获取
Route::get('getLeaderboard/{leaderboard?}/{number}','Ranklist@getLeaderboard ');
四、List列表 用队列怎么预防解决超卖并发,流量消峰
请求 入队(push) 到 redis 然后 出队(rpop)
1、串行
如果A用户抢到手机队列只会终止其他的用户进行抢购,要等到A用户做出了相关的选择之后才会开启
相关的选择如下:
- 1)购买支付
- 2)舍弃订单
2、并行
如果有A-F用户抢购,就算有一个用户抢到了手机,但是不妨碍我们队列执行。就算有用户抢到了,数据库没有跟新过来,他会有更细记录
乐观锁和悲观锁
悲观锁 效率慢
A同学-----> 转你500
B同学-----> 转你500
首先A打开你的账号余额为0,------> 500+0 = 500 (数据库更新)
B要打开你的账户余额要给你转钱, A用户还在转钱中,这个时候 B无法给你转钱的,要等到A用户给你转完钱之后,并且数据库更新,才会给你机会转
A用户 ----> 余额为0 ----->0+500=500
B用户 ----> 余额为0 ----->0+500=500
最终你的钱只有500
不会锁带来的毛病
乐观锁
出现一个更新字段 0
A 转钱 ----> 余额为0 ----->0+500=500
B 转钱 ----> 余额为0 ----->0+500=500 +500 =1000
网友评论