Redis实战之商品相关缓存(php代码实现)
电商商品缓存
主要解决问题
- 登录cookie数量过多的更新问题
- 购物车cookie
- 缓存生成的网页
- 缓存商品信息
- 分析网页访问记录
具体代码
<?php
/**
* Created by PhpStorm.
* User: daneil
* Date: 21-8-24
* Time: 下午11:21
*/
class Token
{
private $redis = null;
private $login_key = 'login:';
private $recent_key = 'recent:';
private $view_key = 'view:';
private $cart_key = 'cart:';
// 测试方法,可忽略
public function test() {
$this->redis->zAdd('test_score',1,'a');
}
public function __construct()
{
$this->redis = new \Redis();
$this->redis->connect('172.17.0.3','6379','5');
$this->redis->select(7);
}
// 检查token返回user_id
public function checkToken($token) {
$user_id = $this->redis->hGet($this->login_key, $token);
if (empty($user_id)) {
echo 'token验证失败!';
exit();
}
return $user_id;
}
// 更新token
public function updateToken($token, $user_id, $item_id='') {
$time = time();
// 更新hash中的token
$this->redis->hSet($this->login_key,$token,$user_id);
// 加入到最近登录
$this->redis->zAdd($this->recent_key,$time,$token);
//商品ID不为空
if ($item_id) {
// 加入到浏览记录中
$this->redis->zAdd($this->view_key.$token, $time, $item_id);
// 只保留最新的2条
$this->redis->zRemRangeByRank($this->view_key.$token, 0, -3);
// 将浏览过的数据商品 view:item_id 分值 -1
$this->redis->zIncrBy($this->view_key, $item_id, -1);
}
echo 'token 更新成功!';
exit();
}
// 清除session
public function cleanSessions() {
$flag = false;
$limit = 1000000;
while (!$flag) {
// 计算recent:的数量
$count = $this->redis->zCard($this->recent_key);
if ($count <= $limit) {
sleep(1);
continue;
} else {
//$flag = true;
$end_index = min($count-$limit,100);
$tokens = $this->redis->zRange(0,$end_index-1);
foreach ($tokens as $token) {
//$session_key[] = 'viewed:'.$token; //给被删除的令牌构建键名
$this->redis->delete($this->view_key.$token);
// 增加一个删除用户的购物车
$this->redis->delete($this->cart_key.$token);
// 删除token
$this->redis->del($this->login_key.$token);
// 从最近登录中移除
$this->redis->zRem($this->recent_key, $token);
}
}
}
}
// 加入购物车
public function addCart($token, $item_id, $count) {
// 商品真实性
if ($count <= 0) {
// 从购物车清除
$this->redis->hDel($this->cart_key.$token, $item_id);
} else {
// 加入购物车,书上说的是覆盖,我个人觉得自增应该是比较合理,除非是输入的指定数量
$this->redis->hSet($this->cart_key.$token, $item_id, $count);
}
return true;
}
// 移除非热门商品缓存
public function rescalViewed() {
$quit = false;
while (!$quit) {
// 删除排名在20000名之后的商品缓存
$this->redis->zRemRangeByRank($this->view_key,0, -20001);
// 将浏览次数降低为原来的一半(这里不懂为何要降低一半)
$this->redis->zInterstore($this->view_key,[$this->view_key],[0.5],'SUM');
}
}
}
// zset特性分值越高,排名越后
$token = new Token();
//$token->updateToken('abc1',1,'good_1');
//$token->updateToken('abc1',1,'good_5');
$token->test();
想生活,不想谋生