/*** 1、实现关于新闻列表缓存 、收藏 、点赞 、视频点击等功能使用redis缓存技术* * 2、列表新闻数据缓存模式 , 采用sorted set + hash *        使用zadd 缓存文章id , hset 缓存文章标题等详情信息** 3、视屏点赞存储在hash 中** 4、用户对单个视频的收藏和点赞使用hash ** 5、视频点击统计使用hash ,一小时同步数据** 6、后台抓取回来的数据缓存问题*    $videoId = $redis->ZREVRANGE('mi_new_video_id_' , 0 ,0)[0]; // 获取最新视频id$maxValue = $redis->ZSCORE('mi_new_video_id_' , $videoId);  // 获取视屏对应的score# 存入视屏id$redis->ZADD('mi_new_video_id_' , time()+1 ,$video_id );*/namespace app\api\controller;
use think\Controller;
use think\Cache;
use think\Error;
use think\Exception;
use think\Log;
use think\Request;
use app\api\common\RedisKeyConts;
use app\api\common\OutJson;
use app\api\common\Hint;
use app\api\common\Helper;
use app\api\model\VideoModel;
use app\api\model\SlideModel;
use app\api\model\UserPraiseModel;
use app\api\model\UserCollectionModel;class Homepage extends Common
{public function __construct(){parent::__construct();$this->videoDao = new VideoModel();}/*** [getNewList 获取新闻列表]* @param  Request $request [description]* @return [type]           [description]*/public function getNewList(Request $request){$wr_applet  = $request->post('wr_applet' , 0);        // 系统请求规则$page       = $request->post('page' , 1);             // 默认第一页$limit      =  10;                                    // 每页显示$uid        = $request->post('uid' , 0);               //  用户idif (empty($wr_applet) ||  empty($page) || $wr_applet != Hint::WR_APPLET)OutJson::outJsonNoData(Hint::PARAM_ERROR); // 返回错误码$videoIdtablePrefix = RedisKeyConts::$sortSetKey['mi_new_video_id_']; //  视屏id$videoInfoTablePrefix =  RedisKeyConts::$hastKey['mi_new_video_info_']; // 视屏详情$sortCluser = self::$redis->ZREVRANGE($videoIdtablePrefix ,  ($page - 1)*$limit , ($page - 1)*$limit+$limit-1); // 获取最新的分页集合 //$sortCluser ='';if (!empty($sortCluser)) {// 格式化列表$resultVideoList = $this->formatVideoListData($sortCluser ,$videoInfoTablePrefix ,$page ,$limit , $videoIdtablePrefix ,$uid);OutJson::outJsonResult(Hint::SUCCESS , $resultVideoList);}else{//获取mysql 当前页数据$this->getMysqlVideoList($page ,$limit , $videoIdtablePrefix ,$videoInfoTablePrefix);}}/*** @param $sortCluser sort set 存放的视频id* @param $videoInfoTablePrefix 视频详情表前缀* @param $page                当前页* @param $limit               每页显示条数* @param $videoIdtablePrefix  当前页获取到sort set 中的video_id 集合* @return array*/public function formatVideoListData($sortCluser ,$videoInfoTablePrefix ,$page ,$limit , $videoIdtablePrefix ,$uid ){$videoPraiseNumTablePrefix  = RedisKeyConts::$hastKey['mi_new_video_praise_num_']; // 视屏点赞前缀$videoPlayNumTablePrefix  = RedisKeyConts::$hastKey['mi_new_video_play_num_'];     // 视屏点击前缀$pieTablePrefix  = RedisKeyConts::$hastKey['mi_new_user_video_praise_history_'];   // 获取用户对当前视频赞历史$cloTablePrefix  = RedisKeyConts::$hastKey['mi_new_user_video_collect_history_'];  // 获取用户对当前视频收藏历史$resultVideoList = []; // 输出集合foreach ($sortCluser as $key => $value) { // $value => $video_id$setTable = Helper::getSplitTable($videoInfoTablePrefix , $value , 10); // 获取视屏存储的表$resultVideoList[$key] = unserialize(self::$redis->hget($setTable,$value));$resultVideoList[$key]['video_praise_num'] = $this->getSingleVideoFieldInfo($value ,$videoPraiseNumTablePrefix ,'video_praise_num'); // 获取点赞$resultVideoList[$key]['video_play_num']   = $this->getSingleVideoFieldInfo($value ,$videoPlayNumTablePrefix ,'video_play_num'); // 获取播放$resultVideoList[$key]['check_praise'] = 0; // 标记当前用户对当前视屏是否点过赞$resultVideoList[$key]['check_collect'] = 0; // 标记当前用户对当前视屏是否点收藏if(!empty($uid)){ //检测用户是否收藏 和点赞 当前$resultVideoList[$key]['check_praise']  =  $this->getUserAtPresentVideoCheck( $pieTablePrefix, $value , $uid);$resultVideoList[$key]['check_collect'] =  $this->getUserAtPresentVideoCheck($cloTablePrefix , $value , $uid); // 标记用户是否收藏}$resultVideoList[$key]['ls_time']           =   date('Y-m-d',$value['ls_time']);                                                                // 格式化时间}if (empty($resultVideoList)) {// 异常Log::write( date('Y-m-d H:i:s').'get sort set article_id exist , hset article_id null' ,  implode(',',$sortCluser) );// 删除sort set 中的article_id$this->unsetSortSetArticleId($sortCluser);// 重写生成缓存$this->getMysqlVideoList($page ,$limit , $videoIdtablePrefix ,$videoInfoTablePrefix);}return $resultVideoList;}/*** @desc  移除sorted set 中的文章id* @param $sortCluser article_ids 集合*/public function unsetSortSetArticleId($sortCluser){$articleColTable = RedisKeyConts::$hastKey['mi_new_video_id_'];foreach ($sortCluser as $k=>$v){self::$redis->zrem($articleColTable , $v);}}/*** @desc 从表中获取视屏列表* @param $page* @param $limit* @param $videoIdtablePrefix* @param $videoInfoTablePrefix*/public function getMysqlVideoList($page ,$limit , $videoIdtablePrefix ,$videoInfoTablePrefix ){$where =  ['status'=>1,  'is_index'=>0 // 显示首页];$offset =  ($page-1) * $limit;$order_by = ['sort'=>'asc' , 'ls_time'=>'desc'];// 获取首页列表$videoList =  $this->videoDao->getPageVideoList( $where , $order_by ,$offset , $limit);if (!empty($videoList)) {foreach($videoList as $key=>$value){// 缓存sort set video idself::$redis->zadd($videoIdtablePrefix , time()+$key  ,   $value['id']); // name score value// 缓存video info 分表存储$setTable = Helper::getSplitTable($videoInfoTablePrefix , $value['id'] , 10); // 分成10 张表self::$redis->hset($setTable , $value['id'] , serialize($value));  }OutJson::outJsonResult(Hint::SUCCESS , $videoList);} else {OutJson::outJsonNoData(Hint::HOMEPAGE_VIDEO_LIST_NULL);}}/*** @desc 获取单个视频的点赞数* @param $id 视频id*/public function getSingleVideoFieldInfo($id , $videoFieldTablePrefix , $field){$videoFieldTablePrefix = Helper::getSplitTable($videoFieldTablePrefix , $id , 10);$rdsVideoFieldNum  = self::$redis->hget($videoFieldTablePrefix , $id); // redis 视屏赞数量//$rdsVideoPraiseNum ='';if (empty($rdsVideoFieldNum)){$rdsVideoFieldNum  = $this->videoDao->getVideoInfo($id)[$field];$rdsVideoFieldNum =  $rdsVideoFieldNum == 0 ? rand(1 , 1000) : $rdsVideoFieldNum ;self::$redis->hsetnx( $videoFieldTablePrefix, $id , $rdsVideoFieldNum);}return $rdsVideoFieldNum;}/*** @param $checkTablePrefix 表前缀* @param $video_id* @param $uid* @return int*/public function getUserAtPresentVideoCheck( $checkTablePrefix , $video_id , $uid){//单用户对首页单个视频 的收藏只缓存30天// 对用户进行分表$tablePrefix =  RedisKeyConts::$hastKey[$checkTablePrefix];$setTable = Helper::getSplitTable($tablePrefix , $uid , 10); // 分成10 张表$hisResult= self::$redis->hget($setTable , $uid.'_video_'.$video_id);return $hisResult = $hisResult == '' || 0  ?  0 : $hisResult;}/*** @desc 增加视频点击  定时脚本统计入库*/public function addVideoClick(Request $request){$wr_applet  = $request->post('wr_applet' , 0);$video_id  = $request->post('video_id' , 0); // 视频id$uid  = $request->post('uid' , 0);             //  用户idif (empty($wr_applet) || empty($video_id) || empty($uid) || $wr_applet != Hint::WR_APPLET)OutJson::outJsonNoData(Hint::PARAM_ERROR);$videoTablePrefix = RedisKeyConts::$hastKey['mi_new_video_play_num_']; // 视屏点击前缀$videoTable  = Helper::getSplitTable($videoTablePrefix , $video_id , 10);if (self::$redis->HEXISTS($videoTable , $video_id)) {self::$redis->HINCRBY($videoTable , $video_id , 1);}else{self::$redis->hset( $videoTable, $video_id , 1); // 第一次点击}// 统计有更新的视频 ,用于同步mysql$videoClickTablePrefix  = RedisKeyConts::$hastKey['mi_new_video_click_update'];self::$redis->Hsetnx($videoClickTablePrefix , $video_id , $video_id); if(!self::$redis->EXISTS($videoClickTablePrefix)){self::$redis->expire($videoClickTablePrefix , RedisKeyConts::$expireTime[$videoClickTablePrefix]);}OutJson::outJsonResult(Hint::SUCCESS); //}/*** @desc 增加视频点赞 , +1 -1 定时脚本统计入库*/public function addMinusVideoPraise(Request $request){$wr_applet  = $request->post('wr_applet' , 0);$video_id  = $request->post('video_id' , 0); // 视频id$uid  = $request->post('uid' , 0);             //  用户id$is_type  = intval($request->post('is_type' , 1));             // is_type 点赞类型  默认为[1 +赞   0 - 赞 ]if (empty($wr_applet) || empty($video_id) || empty($uid)  || $wr_applet != Hint::WR_APPLET)OutJson::outJsonNoData(Hint::PARAM_ERROR);$videoPraiseNumTablePrefix  = RedisKeyConts::$hastKey['mi_new_video_praise_num_']; // 视屏点赞前缀$videoPraise = Helper::getSplitTable($videoPraiseNumTablePrefix , $video_id , 10);$userVideoPraiseHistoryPrefix = RedisKeyConts::$hastKey['mi_new_user_video_praise_history_'];$userVideoPraiseHistoryTable = Helper::getSplitTable($userVideoPraiseHistoryPrefix , $uid , 10); // 分成10 张表// +1if($is_type == 1){if (self::$redis->HEXISTS($videoPraise , $video_id)) {self::$redis->HINCRBY($videoPraise , $video_id , 1);}else{self::$redis->hset( $videoPraise, $video_id , 1); // 第一次点赞self::$redis->expire($videoPraise , RedisKeyConts::$expireTime[$videoPraiseNumTablePrefix]); // 设置单张表的缓存时间}// 增加用户赞历史self::$redis->hset($userVideoPraiseHistoryTable , $uid.'_video_'.$video_id  ,1);}else{if (self::$redis->HEXISTS($videoPraise , $video_id)) {// 视频总赞-1self::$redis->HINCRBY($videoPraise , $video_id , -1);// 移除当前用户 当前赞历史self::$redis->Hdel($userVideoPraiseHistoryTable , $uid.'_video_'.$video_id);// 更新数据表 , 用户取消赞//$userPraise = new UserPraiseModel();//$userPraise -> updateUserVideoPraise( $uid ,$video_id ,  $is_type);}}$videoClickUpdateTablePrefix  = RedisKeyConts::$hastKey['mi_new_video_praise_update']; // 一个小时视屏点赞前缀self::$redis->Hsetnx($videoPraiseNumTablePrefix , $video_id , $video_id); // 缓存一个小时内,有点击的视频 , 定时脚本同步mysql video_praise_numif(!self::$redis->EXISTS($videoClickUpdateTablePrefix)){self::$redis->expire($videoClickUpdateTablePrefix , RedisKeyConts::$expireTime[$videoClickUpdateTablePrefix]);}OutJson::outJsonResult(Hint::SUCCESS); //}/*** @desc 用户点击收藏*/public function userClickVideoCollect(Request $request){$wr_applet  = $request->post('wr_applet' , 0);$video_id  = $request->post('video_id' , 0); // 视频id$uid  = $request->post('uid' , 0);             //  用户id$is_type = $request->post('is_type' , 1); // 默认收藏 , [1 收藏 , 0 取消收藏]if (empty($wr_applet) || empty($video_id) || empty($uid) || $wr_applet != Hint::WR_APPLET)OutJson::outJsonNoData(Hint::PARAM_ERROR);$userVideoCollectHistoryPrefix = RedisKeyConts::$hastKey['mi_new_user_video_collect_history_'];$userVideoPraiseHistoryTable = Helper::getSplitTable($userVideoCollectHistoryPrefix , $uid , 10); // 分成10 张表try{if($is_type == 1){// 设置收藏self::$redis->Hsetnx($userVideoPraiseHistoryTable , $uid.'_video_'.$video_id , 1);}else{// 取消收藏self::$redis->hdel($userVideoPraiseHistoryTable ,  $uid.'_video_'.$video_id);// 更新用户收藏表$userCollectionModel = new UserCollectionModel();$userCollectionModel->updateUserVideoCollect( $uid ,$video_id ,  $is_type);}OutJson::outJsonNoData(Hint::SUCCESS);}catch (\Exception $e){Log::write('userClickVideoCollect Exception' , array('uid'=>$uid , 'video'=>$video_id , 'is_type'=>$is_type));}}}

redis 缓存新闻列表相关推荐

  1. redis存储新闻列表_每日一面 - Redis程序设计中,上百万的新闻,如何实时展示最热点的top10条呢...

    假设可以使用 MySQL,redis,本地缓存以及MQ. 用户量级千万,新闻数据百万,用户数比新闻数还多.用户的操作包括:关注某个新闻 获取某个新闻的关注数量 获取 top10 热点新闻 查询自己关注 ...

  2. redis存储新闻列表_AWS上的Redis 数据存储服务_Redis云数据存储-AWS云服务

    缓存 Redis 是实施高可用性内存中缓存的极佳选择,它可以降低数据访问延迟.提高吞吐量,并可以减轻关系数据库和应用程序或 NoSQL 数据库和应用程序的负载.Redis 能够以亚毫秒级的响应时间为频 ...

  3. redis存储新闻列表_Redis对象——集合(Set)

    集合类型 (Set) 是一个无序并唯一的键值集合.它的存储顺序不会按照插入的先后顺序进行存储. 集合类型和列表类型的区别如下: 列表可以存储重复元素,集合只能存储非重复元素: 列表是按照元素的先后顺序 ...

  4. ABP从入门到精通(3):aspnet-zero-core 使用Redis缓存

    一.Redis是什么? redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset ...

  5. Redis缓存面试题重点汇总

    概述 什么是Redis Redis(Remote Dictionary Server) 是一个使用 C 语言编写的,开源的(BSD许 可)高性能非关系型(NoSQL)的键值对数据库. Redis 可以 ...

  6. Redis缓存策略设计及常见问题

    Redis缓存设计及常见问题 缓存能够有效地加速应用的读写速度,同时也可以降低后端负载,对日常应用的开发至关重要.下面会介绍缓存使用技巧和设计方案,包含如下内容:缓存的收益和成本分析.缓存更新策略的选 ...

  7. 点赞模块设计:Redis缓存 + 定时写入数据库实现高性能点赞功能

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:solocoder juejin.im/post/5bdc2 ...

  8. 深入剖析Redis系列(七) - Redis数据结构之列表

    前言 列表(list)类型是用来存储多个 有序 的 字符串.在 Redis 中,可以对列表的 两端 进行 插入(push)和 弹出(pop)操作,还可以获取 指定范围 的 元素列表.获取 指定索引下标 ...

  9. 高并发下redis缓存穿透问题解决方案

    一.使用场景 我们在日常的开发中,经常会遇到查询数据列表的问题,有些数据是不经常变化的,如果想做一下优化,在提高查询的速度的同时减轻数据库的压力,那么redis缓存绝对是一个好的解决方案. 二.需求 ...

最新文章

  1. mysql64如何配置_win7 64位下如何安装配置mysql-winx64(安装记录)
  2. 科研助力|计算机科学方向一对一科研项目
  3. No module named ‘prompt_toolkit.enums‘
  4. 如何下载和离线安装Chrome的CRX扩展文件包
  5. [导入]给家人补补钙!双莲炖腔骨
  6. LwIP 之四 超时处理/定时器(timeouts.c/h)
  7. 这4部有生之年必看的“教材级”纪录片,免费领取!
  8. 爬虫必须学会的正则表达式
  9. Navicat for MySQL连接MySQL数据库时各种错误解决
  10. 一步一步搭建客服系统 (7) 多人共享的电子白板、画板
  11. 39. 恢复旋转排序数组
  12. 360服务器安全加固系统,360政企安全
  13. eclipse 版本 发行版本
  14. 电脑连手机热点找不到服务器的ip地址,电脑开热点手机连不上怎么连接
  15. Matlab信道容量的迭代计算实验
  16. 微信测试公众号如何进行支付测试
  17. 成都生物研究所高性能计算服务器,专家人才库数据----中科院成都生物所资源库...
  18. filter(matlab2C)
  19. 移动应用ui设计模式pdf_移动ui了解应用ui设计的13种基本模式
  20. 大江东去浪涛尽,千古风流人物故垒西边。

热门文章

  1. 我的Logo设计简史
  2. 关闭Win10的微软拼音(符号表情面板)快捷键(Ctrl+Shift+B)
  3. 拍照之外, 游戏手机会成为手机新品类吗?
  4. ios6和ios7区别
  5. 在word中像Latex一样键入公式
  6. 计算机不能读手机内存不足,电脑和手机的内存不足怎么办
  7. 解决WindowsForm窗体假死的状态
  8. 蜂鸣器+按键+led灯组合使用
  9. 小程序Promise用法
  10. 申宝公司-A股短期难改震荡走势