网站某个详情页 要做阅读数
讲一下 我实现的大概思路 //欢迎批评指正
假设网址为 www.xxx.com/article/id_1.html
1:用cache记录阅读数。
因为文章详情页被访问的量很大,直接链接数据库进行+1,是最low的做法。
- 用 cache (redis 或 memcached) 存储阅读数,每当被阅读一次 就自增(incr)一下
- 但是阅读数最终还是要写在db中, 所以需要脚本来辅助。脚本是连接cache把对应的值取出来存入数据库中。 脚本需要定时执行,用linux 的 crontab 即可。
2: 用cache + 消息队列(MQ)// gearman, rabbitmq 属于消息队列
因为 如果cache down了,那么最新的数据就没了,假设linux的crotab 每两个小时执行一次。那就可能丢掉 0~2小时之内的数据。 如果linux的crontab间隔比较短的话,丢的数据会少,链接数据库频繁,也是不应该的。最终还是可能会丢数据。
- 在请求页面的时候 阅读数不仅要存入cache中,还要添加到消息队列(消息生产者)。
- 然后就要处理消息队列(消息消费者), 消费者可以合并请求,就不用每一次都入库, 就可以每500次入库一次,等等。
- 这时就不需要定时任务了,假设每500次入库一次,并且还要修正cache, 以保证数据库和cache的数据一致性。
3:用 cache + 分析nginx log 保证数据一致性
通过分析nginx log 的url来得到确切的数值。
但是在实际的业务场景中你可能需要的阅读数并不是总数,而是最近一星期,最近一个月的阅读数。
并且还让你做统计,以图表的形式展现出阅读数每天的变化情况等等。
一、目前的数据库设计不支持
- 新建数据库 单独用存储阅读数等各种数的情况。
- 按照业务要求存储数据 确定区间大小 单位为天还是小时
仅供参考
+-------------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-----------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | |
| day | date | NO | PRI | NULL | |
| shownum | int(11) | NO | | 0 | //阅读数 |
| sharenum | int(11) | NO | | 0 | //分享数 |
| commentnum | int(11) | NO | | 0 | //评论数 |
| buynum | int(11) | NO | | 0 | //购买数 |
| update_time | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------------+-----------+------+-----+-------------------+-----------------------------+
id 与 day 共同做为主键
参考数据
+-----+------------+---------+----------+------------+--------+---------------------+
| id | day | shownum | sharenum | commentnum | buynum | update_time |
+-----+------------+---------+----------+------------+--------+---------------------+
| 454 | 2016-10-26 | 42599 | 599 | 183 | 23 | 2016-10-26 14:53:37 |
| 454 | 2016-10-25 | 78238 | 738 | 239 | 34 | 2016-10-25 23:43:12 |
| 454 | 2016-10-24 | 78898 | 738 | 239 | 34 | 2016-10-24 22:53:42 |
+-----+------------+---------+----------+------------+--------+---------------------+
二、我采用的是cache+消息队列
假设业务场景是取最近7天的阅读数 根据最近7天的阅读数进行排序 // 以天为单位
- 消息队列,消费者就要向这个统计库添加当天的数据,并且要修正cache(此时cache记录的是总数)
- 脚本定时执行 从统计库 获取最近7天的数据到主库 // 定时执行为linux的crontab 时间任务
- 主数据库的数据表结构 应该有两个字段 一个是记录的总数 另一个是最近7天的数据, 总数与cache中保持一致,最近7天的数据用于排序。当然阅读数总数的字段可以舍去,因为统计库中已经存在完成的数据。