前提
有一堆帖子(大概 100w 条数据左右),有一个点赞的字段。
需求
实现本周和上周热门帖子排行榜,排序的根据是该帖子在本周或上周被点赞的数量来进行排行的。
同理,上月热门也是根据上月被点赞的数量来进行排行。
实现?
-
新的统计表
既然根据的是上周 /上月的数据来进行排序,那么可不可以新建一个表,专门记录每个帖子每周被点赞的数量?但是每月该怎么实现呢?而且这么做,好像数据量有点太大了。。。小肉鸡怕扛不住。
-
缓存
用 redis 去存?合理吗?
大佬们的见解?
不知道各位大佬们,有没有比较好的解决方法分享一下?
后端小白一枚,还请各位多多指教。
服务器环境
操作系统: ubuntu16.04 后台语言:nodejs v8.11.1 数据库:mongodb v2.6.10 服务器配置: 2c4g.
Mongo的话每个帖子新建两个字段 stars_by_month stars_by_week 存储本月和本周的点赞量,每月初和每周初清零,排序的时候 order_by(stars_by_week)就行? total_stars, 90d_stars, 30d_stars, 7d_stars
理论上大多数历史帖子不会被翻出来点赞,所以估计10%的帖子会多出3个int字段,并且随着时间推移帖子数增多这个比例会下降,维持在特定数量(数量跟用户数和用户活跃度有关)。这三个字段还可以侧面反映社区活跃度。
没有实践经验,以上随便说的。
@loongmxbt 谢谢思路,有想过这种方法,但是上月和上周的怎么办?
@JZLeung 分为stars_this_month, stars_last_month,月末自动将stars_this_month的值给stars_last_month,然后stars_this_month在下月初清零。不知道这样可以么?
@loongmxbt 一百多万条数据,估计要跑很久吧,这配置。
搞个持久化的redis服务 有序集合足矣
来自酷炫的 CNodeMD
用redis有序集合,集合数量设为固定100,只排前100名。 用4个有序集合来实现,本周,上周,本月,上月
- 当帖子赞数量变化时,更新前两个集合,
- 周初或月初时把前两个集合的数据复制到另外两个集合,然后清空。
优点:
相比于在mongodb中给每个帖子增加字段并排序来说更高效,每次直接从redis中取出列表就行
看在我打了那么多字,你也回答下我的问题吧:
来自酷炫的 CNodeMD
@lovegnep 缺点是断电没,除非持久化。
但是如何知道该帖子的数量需要入库呢?
- redis本身就支持持久化
- 用户对帖子点赞 ------》 在mongodb中更新并查询帖子点赞数量findAndModify -----》在redis中将帖子ID做为member,点赞数量做为score存入周榜和月榜zadd month score member(如果member已经存在集合中则redis会自动更新对应的score)
redis.zadd redis.zrevrangebyscore redis.expire 完美解决
难道不是直接按周和月份分组就行吗?
@aojiaotage 大佬能说下大概流程吗?
redis.zadd(`monthly_rank:${YYYY_MM}`, score, member ) //更新月记录YYYY_MM为某年某月
redis.zadd(`monthly_rank:${YYYY_MM_WW}`, score, member ) //更新周记录,YYYY_MM_WW为某年某月某周,可以用 moment 处理
redis.zrevrangebyscore(`monthly_rank:${YYYY_MM_WW}`, 0, 100) //取当周记录
到周/月切换的时候就自动换排行的key了,所以相当于到期清零
@aojiaotage score 一定要 int 型吗?
redis吧 不用担心断电,redis本身就支持持久化