【译】看 Reddit 如何统计每篇帖子的浏览量

原文链接

我们想要更好的向用户展示 Reddit 的规模。为了这一点,投票和评论数是一个帖子最重要的指标。然而,在 Reddit 上有相当多的用户只浏览内容,既不投票也不评论。所以我们想要建立一个能够计算一个帖子浏览数的系统。这一数字会被展示给帖子的创作者和版主,以便他们更好的了解某个帖子的活跃程度。

在这篇文章中,我们将讨论如何实施计数。

计数方法

对于计数我们主要有四种需求:

  • 计数必须是实时的或接近实时的,而不是每天或每小时汇总。

  • 每个用户在短时间内多次访问,只能计算一次

  • 显示的浏览量与真实浏览量间的误差允许在几个百分点内

  • 系统要能在生产环境的规模上正常运行,在几秒钟内处理发生的事件

满足所有这四个要求比听起来更棘手。为了保持实时精确计数,我们需要知道特定用户是否曾访问过该帖子。要了解这些信息,我们需要存储先前访问过每个帖子的用户集合,然后在每次查看帖子时检查该集合。一个天真的实现方式就是将唯一的用户集作为散列表存储在内存中,以帖子 ID 为 key。

这种实现方式对于访问量低的帖子是可行的,但一旦一个帖子变得流行,访问量剧增时就很难控制了。有的帖子甚至有超过 100 万的独立访客! 对于这样的帖子,存储独立访客的 ID 并且频繁查询某个用户是否之前曾访问过会给内存和 CPU 造成很大的负担。

由于我们无法提供确切的数据,我们研究了几种不同的基数估计算法。有两个符合我们需求的选项:

  • 线性概率计数方法是非常准确的,但是随着被计数的集合的增加,所需内存会线性变大。

  • 基于 HyperLogLog(简称 HLL)的计数方法。HLLs 随着设置大小而呈线性增长,但是精确度不如线性计数。

了解 HLLs 会节省多少内存。如果我们不得不存储 100 万个唯一的用户 ID,并且每个用户 ID 是一个8字节的长度,那么我们将需要 8M 的内存来计算单个帖子的唯一用户数!相比之下,使用 HLL 进行计数将占用较少的内存。不同的 HLL 实现方式消耗的内存不同。但是在这种实现的情况下,存储超过 100 万个 ID 仅需 12 KB,是原来的 0.15%!

Big Data Counting: How to count a billion distinct objects using only 1.5KB of Memory 这篇文章对上述两种算法都有很好的概述。

许多 HLL 的实现都是结合了上面两种算法。在集合小的时候采用线性计数,当集合大小到达一定的阈值后切换到 HLL。前者通常被称为 ”稀疏“(sparse) HLL,后者被称为”稠密“(dense) HLL。这种结合了两种算法的实现有很大的好处,因为它对于小集合和大集合都能够保证精确度,同时保证了适度的内存增长。这种方法更详细地描述参看 Google 论文

现在我们已经确定要采用 HLL 算法了,不过在选择具体的实现时,我们考虑了以下三种不同的实现。因为我们的数据工程团队使用 Java 和 Scala,所以我们只考虑 Java 和 Scala 的实现。

  1. Twitter’s Algebird library, implemented in Scala。Algebird 有很好的文档,但对于 sparse 和 dense HLL 的实现细节不是很容易理解。

  2. An implementation of HyperLogLog++ located in stream-lib, implemented in Java。stream-lib 中的代码有很好的文档,但是很难理解如何正确使用库并根据需要进行调整。

  3. Redis’s HLL implementation (which we chose)。我们认为 Redis HLLs 的实施文档很好、容易配置,提供的相关 API 也很容易整合。作为一个额外的好处,使用 Redis 可以将计数应用程序的 CPU 和内存密集型部分(HLL计算)移动到专用服务器上,从而缓解了许多性能问题。

Reddit 的数据管道依赖于 Apache Kafka。当用户查看帖子时,事件将被触发并发送到事件收集服务器,该服务器将事件分批并将其持久化在 Kafka 中。

之后,计数系统会按顺序依次运行两个组件。我们的计数架构的第一部分是一个称之为 Nazar 的 Kafka 的消费者。Nazar 将从 Kafka 中读取每个事件,并通过一系列配置规则来判断该事件是否需要被计数。Nazar 使用 Redis 维持状态,并跟踪不应该被计数的潜在原因。其中一个我们不将一个事件计数在内的原因就是同一个用户在很短时间内重复访问。在将事件发送回 Kafka 之前,Nazar 会更改事件,并添加一个布尔标志,表示是否应该计数。

下面就是系统的第二部分。我们将第二个 Kafka 的消费者称为 Abacus,用来进行真正的计数,并将计算结果显示在网站或客户端。Abacus 从 Kafka 中读取经过 Nazar 处理过的事件,并根据 Nazar 的处理结果决定是跳过这个事件还是将其加入计数。如果事件被标记为计数,则 Abacus 首先检查 Redis 中是否存在与事件相对应的帖子的 HLL 计数器。如果已经存在,Abacus 会给 Redis 发送一个 PFADD 请求。如果不存在,那么 Abacus 会给 Cassandra 集群(用来持久化 HLL 计数器和计数值)发送一个请求,然后再向 Redis 发送请求。这通常发生在人们访问较老帖子的时候,这时该帖子的计数器很可能已经在 Redis 中过期了。

为了维护 Redis 中计数器过期的老帖子的计数,Abacus 会定期向 Redis 发出完整的 HLL 计数器以及每个帖子的计数到 Cassandra 集群。为了避免集群过载,我们以 10 秒为周期批量写入。

事件流程图:


总结

我们希望浏览量可以让发帖者了解帖子全部的访问量,也帮助版主快速定位自己社区中高访问量的帖子。在未来,我们计划利用数据管道在实时方面的潜力来为 Reddit 的用户提供更多的有用的反馈。

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

推荐阅读更多精彩内容