热门列表的实现思路整理


title: 热门列表的实现思路整理
date: 2018-09-09
tags: [工作笔记]


热门的规则

对于热门文章的定义是:

单位时间内,活跃度(”分享“数 + ”点赞“数 + ”评论“数的总和)大于某特定值的文章,被视为热门文章。

热门文章的列表是由后台动态生成的,而且在每次生成的时候,产生的数据不一定是相同的。为了减轻系统的压力和提高api的响应速度,该计算任务使用celery 进行后台任务调度。

后台定时任务循环执行,任务执行时向缓存数据库中插入当前计算出的符合规则的热门文章的索引值,缓存数据库采用的是redis。

定时任务的实现

  • 将新增的热门文章索引写入缓存数据库中,插入的时候,score 值取当前时间戳。
  • 清除一定时间前的热门文章。

新增热门文章

计算热门文章sql 语句实现如下(暂时不考虑分享的数据):

SELECT result.user_publish_id FROM (
    SELECT a.user_publish_id, COUNT(*) AS count FROM
    (
        SELECT p.user_publish_id
        FROM user_publish AS p
        JOIN user_like AS l
        ON
            l.for_obj = p.user_publish_id AND l.like_type = 0 AND l.created_at > '{0}'
        WHERE p.status = 'VISIBLE'

        UNION ALL

        SELECT p.user_publish_id
        FROM user_publish AS p
        JOIN user_comments AS c
        ON
            p.user_publish_id = c.publish_id AND c.status = 'VISIBLE' AND c.created_at > '{0}'
        WHERE p.status = 'VISIBLE'

    ) AS a
    WHERE a.user_publish_id not in ("{2}")
    GROUP BY a.user_publish_id
) AS result
WHERE result.count >= {1}

(user_publish 用户发布文章信息表,user_like 用户点赞表,user_comments 用户评论表)
以上sql语句完成了对符合热门条件的文章的筛选,返回的结果集中将不包含应已经在缓存数据库的中索引。

将以上返回的文章索引插入redis:

pipeline.zadd(ALL_HOT_KEYS_CACHE, time.time(), item)

(ALL_HOT_KEYS_CACHE redis 中有序集合的键)

清除一定时间前的热门文章

热门文章进入缓存之后,需要在一定的时间内清除,这是因为被写入redis的之后,score不会被改动。定时任务需要将距离当前较远的缓存数据删除以减轻缓存的压力。

后端的实现

热门类别的分页没有上一页与下一页之说。客户端在请求的时候,有两种参数情况:

  • count:要多少条数据
  • publish_ids:客户端已经缓存的文章id列表

客户端如果仅传入count 参数,后端将返回最新的count条数据信息。
如果传入countpublish_ids,后端返回的count数据中,publish_ids中包含的文章信息将不会被缓存。

这样保证了客户端数据的不重复问题。但是随着客户端浏览的数据越来越多,把么客户端请求的publish_ids列表也越大,后端去重的时候复杂度较高。但是解决这个问题得力于redis的集合操作方法。


# redis_utils.py

def get_redis_sorted_set_diffs(uid, items, count):
    
    user_key = USER_HOT_KEYS_CACHE.format(uid)
    user_hot_key_cache(items, user_key)
    dest = USER_HOT_KEYS_DESTINATION_CACHE.format(uid)
    redis_store.zunionstore(dest, {ALL_HOT_KEYS_CACHE: 1, user_key: 0}, 'MIN')

    x = redis_store.zrevrangebyscore(dest, '+inf', 1)[:count]
    redis_store.delete(user_key)
    redis_store.delete(dest)
    return x

返回的数据排序按照redis返回的集合顺序。

客户端相关的任务

  • 用户首次进入列表界面时,请求不要携带publish_ids
  • 用户下拉刷新的操作同首次进入列表界面的操作。
  • 用户上拉浏览列表的时候,需要携带publish_ids,用于后端管理去重。

存在的问题

  • 客户端访问时需要携带大量的已经缓存的文章id
  • 后端获取数据时的去重,随着publish_ids越来越繁琐。
  • 客户端处理较为繁琐

社区排行榜和热门列表的实现思路对比

相同:

  • 顺序都是动态变化的
  • 都需要额外的资源来保证需求的实现
  • 客户端处理比较繁琐

不同:

  • 社区排行榜是有序的,热门列表是设置门槛的。
  • 社区排行榜是需要记录关注人数的,热门不需要记录活跃度点赞数和评论数均取实时的。
  • 社区有分页参数,热门列表是没有上一页下一页的概念的,仅需要声明count的大小
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容