Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【精选好文】Reddit如何统计每个帖子的浏览量

【精选好文】Reddit如何统计每个帖子的浏览量

作者头像
凯哥Java
发布于 2019-07-01 07:46:58
发布于 2019-07-01 07:46:58
1.5K0
举报
文章被收录于专栏:凯哥Java凯哥Java

之前没听过也没了解过 HyperLogLog,通过翻译这篇文章正好简单学习下。欢迎指正错误~

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

在这篇博客中,我们将讨论我们是如何实现超大数据量的计数。

计数机制

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

1、帖子浏览数必须是实时或者近实时的,而不是每天或者每小时汇总。

2、同一用户在短时间内多次访问帖子,只算一个浏览量。

3、显示的浏览量与真实浏览量间允许有小百分之几的误差。

4、Reddit 是全球访问量第八的网站,系统要能在生产环境的规模上正常运行,仅允许几秒的延迟。

要全部满足以上四个需求的困难远远比听上去大的多。为了实时精准计数,我们需要知道某个用户是否曾经访问过这篇帖子。想要知道这个信息,我们就要为每篇帖子维护一个访问用户的集合,然后在每次计算浏览量时检查集合。一个 naive 的实现方式就是将访问用户的集合存储在内存的 hashMap 中,以帖子 Id 为 key。

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

因为我们不能提供准确的计数,我们查看了几种不同的基数估计算法。有两个符合我们需求的选择:

一是线性概率计数法,很准确,但当计数集合变大时所需内存会线性变大。

二是基于 HyperLogLog (以下简称 HLL )的计数法。 HLL 空间复杂度较低,但是精确度不如线性计数。

下面看下 HLL 会节省多少内存。如果我们需要存储 100 万个独立访客的 ID, 每个用户 ID 8 字节长,那么为了存储一篇帖子的独立访客我们就需要 8 M的内存。反之,如果采用 HLL 会显著减少内存占用。不同的 HLL 实现方式消耗的内存不同。如果采用这篇文章的实现方法,那么存储 100 万个 ID 仅需 12 KB,是原来的 0.15%!!

Big Data Counting: How to count a billion distinct objects using only 1.5KB of Memory – High Scalability -这篇文章很好的总结了上面的算法。

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

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

1、Twitter 提供的 Algebird,采用 Scala 实现。Algebird 有很好的文档,但他们对于 sparse 和 dense HLL 的实现细节不是很容易理解。

2、stream-lib中提供的 HyperLogLog++, 采用 Java 实现。stream-lib 中的代码文档齐全,但有些难理解如何合适的使用并且改造的符合我们的需求。

3、Redis HLL 实现,这是我们最终选择的。我们认为 Redis 中 HLLs 的实现文档齐全、容易配置,提供的相关 API 也很容易集成。还有一个好处是,我们可以用一台专门的服务器部署,从而减轻性能上的压力。

Reddit 的数据管道依赖于 Kafka。当一个用户访问了一篇博客,会触发一个事件,事件会被发送到事件收集服务器,并被持久化在 Kafka 中。

之后,计数系统会依次顺序运行两个组件。在我们的计数系统架构中,第一部分是一个 Kafka 的消费者,我们称之为 Nazar。Nazar 会从 Kafka 中读取每个事件,并将它通过一系列配置的规则来判断该事件是否需要被计数。我们取这个名字仅仅是因为 Nazar 是一个眼睛形状的护身符,而 ”Nazar“ 系统就像眼睛一样使我们的计数系统远离不怀好意者的破坏。其中一个我们不将一个事件计算在内的原因就是同一个用户在很短时间内重复访问。Nazar 会修改事件,加上个标明是否应该被计数的布尔标识,并将事件重新放入 Kafka。

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

为了存储存在 Redis 中的计数器过期的老帖子的浏览量。Abacus 会周期性的将 Redis 中全部的 HLL 和 每篇帖子的浏览量写入到 Cassandra 集群中。为了避免集群过载,我们以 10 秒为周期批量写入。

下图是事件流的大致流程:

总  结

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

Java我最强,是专注Java技术的垂直社群,加入精品技术群请公众号后台留言“加群”。投稿合作请邮件至:javawozuiqiang@qq.com,注明“Java我最强投稿”。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-09-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
如何使用 Redis 实现大规模的帖子浏览计数
满足上面四个条件,其实比想象中要复杂。为了在实时统计的情况下保持精准度,我们需要知道某一个用户之前是否浏览过一篇文章,所以我们需要为每一篇文章存储浏览过它的用户的集合,并且在每次新增浏览时检查该集合进行去重复操作。
芋道源码
2018/12/29
2.2K0
如何使用 Redis 实现大规模的帖子浏览计数
90. 说一下使用 Redis 实现大规模的帖子浏览计数的思路
满足上面四个条件,其实比想象中要复杂。为了在实时统计的情况下保持精准度,我们需要知道某一个用户之前是否浏览过一篇文章,所以我们需要为每一篇文章存储浏览过它的用户的集合,并且在每次新增浏览时检查该集合进行去重复操作。
用户11332765
2024/11/01
1440
90. 说一下使用 Redis 实现大规模的帖子浏览计数的思路
Reddit 如何实现大规模的帖子浏览计数
本文介绍了Reddit如何实现大规模浏览计数系统,该系统使用基于HyperLogLog的算法来估计用户的浏览量。首先介绍了HyperLogLog算法,然后描述了Reddit是如何利用Redis和Cassandra来实现这个系统的。
企鹅号小编
2018/01/08
1.4K0
Reddit 如何实现大规模的帖子浏览计数
【Redis基础】Redis新数据类型(Bitmaps,HyperLoglog,Geospatial)命令简介与案例演示
Bitmaps 并不是实际的数据类型,而是定义在String类型上的一个面向字节操作的集合。因为字符串是二进制安全的块,他们的最大长度是512M,最适合设置成2^32个不同字节。 bitmaps的位操作分成两类:1.固定时间的单个位操作,比如把String的某个位设置为1或者0,或者获取某个位上的值 2.对于一组位的操作,对给定的bit范围内,统计设定值为1的数目(比如人口统计)。 bitmaps最大的优势是在存储数据时可以极大的节省空间,比如在一个项目中采用自增长的id来标识用户,就可以仅用512M的内存来记录40亿用户的信息(比如用户是否希望收到新的通知,用1和0标识)
小尘要自信
2023/10/10
3060
Redis6发布订阅及Redis新数据类型
Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息
大忽悠爱学习
2021/11/15
5410
2023-06-13:统计高并发网站每个网页每天的 UV 数据,结合Redis你会如何实现?
2023-06-13:统计高并发网站每个网页每天的 UV 数据,结合Redis你会如何实现?
福大大架构师每日一题
2023/06/21
4980
2023-06-13:统计高并发网站每个网页每天的 UV 数据,结合Redis你会如何实现?
浏览量的简单设计
    哈喽,又是一天早起的日子,今天就写写昨天实现了的浏览量逻辑设计,顺带一些其它的小知识总结,
时光潜流
2022/12/26
4040
从SpringBoot构建十万博文聊聊高并发文章浏览量设计
在经历了,缓存、限流、布隆穿透等等一系列加强功能,十万博客基本算是成型,网站上线以后也加入了百度统计来见证十万+ 的整个过程。
小柒2012
2019/12/05
1K0
网站访客总浏览量插件 PageViews
插件简介 这是一款用于在网站任何地方调用显示你的网站的访客总浏览量的Typecho插件,通过这个插件可以让别人知道你的网站已经有多少网友访问浏览过,TypechoWiki君查看了他是通过将统计数据存入数据库的方式来实现的,TypechoWiki君之前分享过一个PHP系统都可用的代码实现网站访客数统计的方式,如果你不想使用插件,并且对代码有些研究你可以查看文章Typecho 实现博客在线访问人数统计代码。当然Typecho关于访问量统计的实现方式特别多,不论是文章字数统计,文章内容统计,可以查看本文尾部的感兴
团团生活志
2022/08/16
1.1K0
如何实现亿级用户在线状态统计?
以 QQ 在线状态统计为例,其典型特征包括:数据量大、内存占用高、实时性要求高。传统的解决方案(如在数据库中为每个用户添加一个在线状态字段,上线设为 1,下线设为 0)在这种场景下显得力不从心。原因如下:
用户11397231
2025/01/24
1530
如何实现亿级用户在线状态统计?
HyperLogLog统计网站UV 太丝滑
网站的UV(Unique Visitor)是指独立访客的数量,用于衡量网站的访问量和流量。在网站统计中,通常使用UV来度量网站的独立访客数量。
柯柏技术笔记
2024/01/26
2881
Java统计网站PV、UV
当一个系统上线后,基本都需要统计用户活跃度,活跃度一般有两个指标,一个是PV(Page View)页面浏览量,一个是UV(Unique Visitor)唯一用户量,比如微信小程序后台中就有每小时UV的统计。
一杯茶Ja
2024/09/20
3380
Java统计网站PV、UV
见缝插针 —— 深入 Redis HyperLogLog 内部数据结构分析
HyperLogLog算法是一种非常巧妙的近似统计海量去重元素数量的算法。它内部维护了 16384 个桶(bucket)来记录各自桶的元素数量。当一个元素到来时,它会散列到其中一个桶,以一定的概率影响这个桶的计数值。因为是概率算法,所以单个桶的计数值并不准确,但是将所有的桶计数值进行调合均值累加起来,结果就会非常接近真实的计数值。
老钱
2018/09/29
3.2K1
见缝插针 —— 深入 Redis HyperLogLog 内部数据结构分析
Redis系列(十八)独立功能之hyperloglog
Redis 提供了很多精巧的独立功能,本文介绍 HyperLogLog, 它可以称作唯一性统计的利器了。
呼延十
2020/12/23
2.5K0
Redis系列(十八)独立功能之hyperloglog
概率数据结构:Hyperloglog算法
现在我们想要实时统计有多少用户访问我们的网站,这是一个相当简单的任务,一般的做法是存储用户ID,然后计算任意时刻集合中不同ID的个数即为网站实时访问量,这是一种可行的做法,但是慢慢就会发现随着用户的不断增长,存储集合数据所需要的空间越来越大,所需要的统计成本也越来越高,因此我们需要另外一种算法来解决这个问题,即本次我们要介绍的hyperloglog概率数据结构。
深度学习与Python
2019/08/02
5K0
高并发文章浏览量计数系统设计
https://juejin.im/post/5c3aa3c86fb9a04a0e2d6c9f
搜云库技术团队
2019/10/17
3.2K0
小厂后端十连问(附答案)
大家好,在此分享一份面试真题,我整理了一下答案给大家。如果有不正确的,欢迎指出哈,一起进步。
用户1263954
2022/05/23
4200
小厂后端十连问(附答案)
Reids(4)——神奇的HyperLoglog解决统计问题
HyperLogLog 是最早由 Flajolet 及其同事在 2007 年提出的一种 估算基数的近似最优算法。但跟原版论文不同的是,好像很多书包括 Redis 作者都把它称为一种 新的数据结构(new datastruct) (算法实现确实需要一种特定的数据结构来实现)。
乔戈里
2020/03/13
6100
6.Redis新数据类型
现代计算机用二进制(位) 作为信息的基础单位, 1个字节等于8位, 例如“abc”字符串是由3个字节组成, 但实际在计算机存储时将其用二进制表示, “abc”分别对应的ASCII码分别是97、 98、 99, 对应的二进制分别是01100001、 01100010和01100011,如下图
一个风轻云淡
2022/11/13
3070
6.Redis新数据类型
⑧【HyperLoglog】Redis数据类型:HyperLoglog [使用手册]
pfmerge destkey sourcekey [sourcekey ...]
.29.
2023/11/26
1850
⑧【HyperLoglog】Redis数据类型:HyperLoglog [使用手册]
推荐阅读
相关推荐
如何使用 Redis 实现大规模的帖子浏览计数
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档