• Redis实战之商品相关缓存(php代码实现)


    电商商品缓存

    主要解决问题

    1. 登录cookie数量过多的更新问题
    2. 购物车cookie
    3. 缓存生成的网页
    4. 缓存商品信息
    5. 分析网页访问记录

    具体代码

    <?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();
    
    想生活,不想谋生
  • 相关阅读:
    JavaScript 中正则匹配时结果不一致的问题
    /dev/null
    Xcode 中通过 target 运行多个 c 程序
    Xcode 调试时打印变量值
    Recoil 请求的刷新之使用随机参数
    npm ci 与 install 的区别
    项目中私有 npm 源的设置
    Crontab 的使用
    Nest 在日志中打印对象
    配置 ESLint 自动格式化自闭合标签(Self closing tag)
  • 原文地址:https://www.cnblogs.com/Daneil/p/15229693.html
Copyright © 2020-2023  润新知