如何在redis存放日志和热门文章?针对这个问题,今天小编总结这篇有关Redis存放日志和热门文章的文章,希望帮助更多想学习Redis的同学找到更加简单易行的办法。
在成都做网站、成都网站设计过程中,需要针对客户的行业特点、产品特性、目标受众和市场情况进行定位分析,以确定网站的风格、色彩、版式、交互等方面的设计方向。成都创新互联还需要根据客户的需求进行功能模块的开发和设计,包括内容管理、前台展示、用户权限管理、数据统计和安全保护等功能。
使用Redis的列表数据类型可以实现多种数据结构,可以将它看做php中的索引数组。它可以实现栈、队列、消息队列的多种数据结构。
存放日志
大家知道,nginx日志默认不会自动切割,它会一直存放一个文件中,一直追加写入,需要我们自己做切割日志的操作。除了nginx外,很多地方都有用到日志。出了问题后,日志是我们是我们查找线索的主要途径之一。
我们现在打算将系统的日志写入到redis中,每天的日志都记录到一个list列表中,可以防止单个日志文件过大。
基本思路是,每天的日志信息都写入到单独的list列表中,然后做定时任务,定时任务的功能是取出1个月前的日志列表,将其持久化到文本文件中,然后删除redis中1个月前的日志列表,防止redis占用过多内存。
可以使用压缩函数将日志信息压缩,减少内存占用。另外,再维护一个列表存日志列表的键名,方便取出日志列表键名。存放日志的伪代码如下:
$log = ... // 日志信息 // 日志列表键名 $key = 'log:'.strtotime(date('Y-m-d')); // 维护一个键名列表 if (!$redis->exists($key)) { $listlogkey = 'log:key'; $redis->rpush($listlogkey, $key); } // 日志信息存放到redis中 $redis->rpush($key, $log);
定时任务代码如下:
$lastMonth = strtotime("-30 day"); while ($logkey = $redis->lpop('log:key')) { $logTime = explode(':', $logkey)[1]; if ($logTime < $lastMonth) { // 从日志列表里去日志信息,一次取50条 for ($start = 0, $end = 49;true;$start +=50, $end+=50) { $logs = $redis->lrange($logkey, $start, $end); if (!$logs) break; // 将日志信息解压缩,然后追加写入文本文件中 …… // 删除该日志列表 $redis->del($logkey); } } else { // 一个月之内的,重新push到左侧 $redis->lpush('log:key', $logkey); exit; } }
这里有几点需要注意,如果持久化日志失败后,或者是近一个月内的日志,需要重新将日志列表键名从左侧push。另外,从日志列表里取日志时,不要一次性全部取出,这样容易导致redis阻塞。每次,取一定数量(如50条),循环取出。
存放热门新闻ID
这里,就不贴代码了,主要讲讲思路。以前我弄个一个系统,有一个版单功能,有今日最热、一周最热、一月最热。当时,我们的网站流量还挺大的,过不了几天,网站就挂了。原因是,MySQL的慢查询问题。因为,这块的sql有分组、COUNT()、条件判断等。
和大家说说我们的解决方案:写一个mysql的存储过程,定时调用存储过程。该存储过程的作用是,筛选出今日、一周、一月最热文章,分别取100条文章id,将其文章id存放到redis的队列中。最热文章,我们只展示前100条。这样,我们的系统就没有了慢查询了。
关于Redis存放日志和热门文章的方法就分享到这里了,解决问题并不止文章中和大家分析的办法,不过本文分析的方法准确性是不容置疑的。如果喜欢本篇文章,不妨把它分享出去让更多的人看到。