搜狐技术:未读消息数系统设计

在互联网海量信息传播的背景下,大数据量、高频率更新场景中的未读消息数计算与提醒,成为考验系统性能与用户体验的关键问题。

作者:赵勇
来源:搜狐技术产品
原文:https://mp.weixin.qq.com/s/hVM0sBB8L5IET_uctULiMA

01 设计背景

搜狐技术:未读消息数系统设计

互联网技术的飞速发展使得信息传播的速度与规模呈指数级增长,各类互联网平台均需向用户实时推送关注对象产生的新消息,并通过未读消息数提醒引导用户获取信息。在海量用户、用户关注对象繁多且关注对象粉丝数量庞大的场景下,未读消息数的高效、准确计算成为平台技术实现的核心需求。

现有未读消息提醒多采用推拉结合模式:新内容产生时,任务脚本遍历所有粉丝,逐个更新其未读计数缓存;用户访问时再主动拉取展示。在大数据量、高更新场景下,该模式存在明显缺陷:

1. 粉丝量或关注对象过多时,遍历用户量呈几何级增长,任务耗时久、计算资源消耗大;

2. 频繁更新用户未读计数,导致缓存压力大、存储成本高;

3. 推拉存在时间差,消息提醒延时明显;

4. 受展示与数据同步规则影响,未读计数易出现偏差,准确性不足。

针对现有方案的不足,亟需设计一套全新的未读消息数计算系统,在保证未读消息数精准、实时的前提下,有效降低系统的计算成本与存储成本,适配大数据量、快速更新的业务场景,提升用户体验与系统性能。

02 核心设计思想

搜狐技术:未读消息数系统设计

本系统的核心设计思想围绕分治思想与用户状态差异化处理展开,同时结合模拟在线用户实时请求与缓存高效管理机制,从根本上解决传统方案的痛点。

1.分治思想的落地:将全量用户按照在线状态划分为在线用户池与离线用户池,对不同用户池采用差异化的计算策略,避免对全量用户进行无差别的遍历与计算,减少系统不必要的计算量。同时,对在线用户池通过哈希算法进行均匀分桶处理,将大规模在线用户分散至多个子池,实现在线用户的精细化管理,方便系统快速遍历与计算,提升处理效率。

2.用户状态差异化处理:针对在线用户与离线用户的行为特征设计不同的计算逻辑。在线用户对消息实时性要求高,系统采用实时遍历、实时计算、按需推送的方式,保证未读消息数的无延时更新;离线用户无实时消息获取需求,系统不进行持续计算,仅在用户冷启动(重新上线)时触发实时计算,实现计算资源的按需分配。

3.模拟在线用户实时请求:摒弃传统方案中 “新内容产生即遍历用户更新计数” 的被动推送模式,模拟在线用户的实时请求行为,由计数系统主动遍历在线用户,根据用户的关注对象与访问时间计算未读消息数,实现从 “推数据” 到 “算数据” 的转变,减少无效的数据推送与更新。

4.缓存高效管理:采用哈希结构的缓存存储用户未读消息相关数据,对缓存数据进行按需更新而非全量更新。在线用户未读消息数无变化时,仅更新缓存中的用户访问时间,不进行消息提醒与多余数据操作;仅当未读消息数发生变化时,才向客户端推送通知并更新缓存计数。同时,针对无缓存数据的用户设置默认规则,保证计算逻辑的完整性,提升缓存的使用效率,降低存储消耗。

03 系统整体架构设计

搜狐技术:未读消息数系统设计

本系统围绕 “数字气泡更新” 核心流程,划分为五大功能模块,各模块协同完成未读消息数的计算、存储与展示:

1.消息中心实时拉取:负责客户端主动拉取气泡数据,优先展示缓存结果,提升用户体验。

2.气泡计算服务(bubble-core):核心计算单元,负责根据用户关注列表和时间戳,计算最新未读消息数。

3.计算调度中心(bubble-server):负责在线用户池的管理、任务分片与分布式调度,确保计算任务高效执行。

4.云端:作为数据与事件的枢纽,处理用户在线 / 下线事件,维护用户气泡数和最新 feed 时间戳。

5.客户端轮询:触发气泡更新检查,根据用户在线状态决定数据来源。

04 核心流程

详解1. 消息中心实时拉取(客户端主动拉取)

当用户进入消息中心页面时,客户端触发主动拉取流程:

1. 从气泡数字 redis中获取当前用户的气泡数和上次气泡计算时间。

2. 比较用户上次刷新时间与气泡计算时间:

刷新时间 ≤ 计算时间:说明缓存数据是最新的,直接展示气泡数字,随后清空 redis 中的气泡数据,避免重复展示。

刷新时间 > 计算时间:说明缓存数据已过期,需要触发气泡计算服务进行重新计算。2. 气泡计算服务(bubble-core)执行流程

当缓存数据过期或不存在时,气泡计算服务启动:

1.服务自启动与数据预热:服务启动后,先进行数据预热,为后续计算做准备。

2.获取任务分片:通过分布式锁从节点 redis中获取当前节点需要处理的用户池分片序号,避免任务重复执行。

3.拉取用户数据:根据分片序号,拉取对应用户池中的用户关注人话题列表。

4.获取计算基准时间:从 redis 中获取用户上次气泡计算时间,若不存在(如新用户或 7 天未登录),则默认使用 7 天前的时间作为基准。

5.核心计算(compute):基于用户关注列表和基准时间,计算从基准时间到当前时间内,所有关注对象产生的新消息 /feed 数量,得到最新气泡数字,并更新最新 feed 时间。

6.结果输出:将计算得到的气泡数字和最新 feed 时间戳同步至云端存储。3. 计算调度中心(bubble-server)调度逻辑

计算调度中心是系统的 “大脑”,负责管理和分配计算任务:

1.在线用户池管理:实时接收云端推送的用户在线 / 下线事件,动态维护多个在线用户池,确保只对在线用户进行实时计算。

2.节点调度:通过节点调度接口,结合节点 redis 中的分片信息,将在线用户池的计算任务均匀分配给各个 bubble-core 节点,实现负载均衡。

3.任务触发:定时或按需触发 bubble-core 服务,遍历在线用户池,确保在线用户的气泡数始终保持最新。

4. 客户端轮询(被动更新)

客户端会定期或在特定时机触发轮询,检查气泡数是否需要更新:

1. 客户端触发轮询请求。

2. 系统检查用户是否处于在线用户池中:

 是(在线):直接从云端获取最新的气泡数和时间戳,实时更新客户端展示。

否(离线):触发一次气泡计算服务,计算最新气泡数后同步至云端和客户端。

05 关键技术与优化点

1.分布式锁与分片:通过分布式锁保证任务不重复,通过用户池分片实现计算任务的水平扩展,避免单点瓶颈。

2.缓存策略:利用 redis 缓存气泡数和计算时间,优先展示缓存数据,减少计算压力;设置 7 天有效期,避免无效缓存占用。

3.状态差异化处理:对在线用户进行实时遍历计算,对离线用户采用 “触发才计算” 的策略,大幅节省计算资源。

4.事件驱动:基于用户在线 / 下线事件动态维护用户池,确保计算资源只投入到有实时需求的用户身上。

06 流程闭环总结

整个系统形成了一个高效的闭环:

· 客户端拉取触发数据检查。

· 调度中心根据用户状态分配计算任务。

· 计算服务精准计算未读消息数。

· 云端存储最新状态并支持实时推送。

· 最终通过客户端轮询或主动拉取,将最新气泡数展示给用户。这套流程在保证用户体验的同时,最大化地优化了系统资源的使用效率。

07 系统核心技术细节

7.1 哈希算法的应用

本系统在两处核心环节采用了哈希算法,分别为在线用户的分桶管理与缓存数据的存储,哈希算法的高效性与均匀性为系统性能提供了保障:

1.在线用户分桶:采用一致性哈希或普通哈希算法,将用户 ID 作为哈希因子,将在线用户均匀分配至 100 个子池,保证每个子池的用户数量均衡,避免单池子过载,同时哈希算法的单向性保证了用户分桶的稳定性,便于系统快速定位与遍历。

2.缓存数据存储:采用哈希结构(如 Redis Hash)存储用户未读消息数据,以用户 ID 为大 Key,以未读消息数(key1)和访问时间(key2)为小 Key,实现单用户数据的快速读取、修改与删除,哈希结构的时间复杂度为 O (1),可满足大数据量下的高速缓存操作需求。

7.2 长连接通信机制

系统与客户端之间采用长连接方式进行未读消息数更新通知的推送,摒弃了短连接的轮询方式,减少了服务器与客户端的连接建立与释放开销,同时保证了通知推送的无延时性。当客户端上线时,与服务器建立长连接并保持,仅当未读消息数更新时,服务器才通过该连接发送通知,实现 “按需推送”,大幅降低了通信资源消耗。

7.3 计数系统的高可用设计

计数系统作为系统的核心,采用分布式部署方式,100 个在线用户子池对应分配至不同的计数系统节点,实现计算任务的分布式处理,避免单节点故障导致的系统瘫痪。同时,计数系统采用定时遍历与批量计算相结合的方式,控制单批次处理的用户数量,避免服务器 CPU 与内存过载,保证系统的高可用与稳定性。

08 系统技术优势与性能提升

相较于传统的未读消息数计算方案,本系统基于分治思想与状态差异化处理设计,在计算效率、存储消耗、计数准确性、实时性等方面实现了全方位的提升,其核心技术优势体现在以下几个方面:

8.1 大幅降低系统计算成本

系统通过将全量用户划分为在线与离线用户池,仅对在线用户进行实时遍历与计算,对离线用户采用 “冷启动才计算” 的策略,避免了对全量用户的无差别计算,减少了大量不必要的计算任务。同时,对在线用户进行哈希分桶处理,实现计算任务的分布式拆分,提升了遍历与计算效率,解决了传统方案中 “新内容产生即遍历所有粉丝” 导致的计算量过大、任务耗时过长的问题,经实际应用验证,系统的计算资源消耗较传统方案降低 80% 以上。

8.2 减少缓存存储空间消耗

本系统采用哈希结构的缓存存储方式,仅存储用户未读消息数与访问时间两个核心数据,数据量精简;同时,采用 “按需更新” 的缓存策略,在线用户未读消息数无变化时仅更新访问时间,不进行多余的数据操作,避免了传统方案中 “每个新内容都更新所有粉丝缓存计数” 导致的缓存频繁写入。此外,对离线用户不进行持续的缓存更新,仅在冷启动时更新一次,进一步降低了缓存的存储压力与写入开销,缓存存储空间消耗较传统方案降低 70% 以上。

8.3 实现未读消息数的精准无延时

系统摒弃了传统推拉结合模式的被动推送,采用计数系统主动遍历在线用户、实时计算未读消息数的方式,结合长连接的即时推送机制,保证在线用户的未读消息数更新无延时,客户端可实时展示最新的未读消息数字。同时,未读消息数的计算以用户最新的访问时间为起始点,基于关注对象的实际发布内容进行计数,避免了传统方案中因展示规则、数据同步导致的计数偏差,保证了未读消息数的准确性,计数误差率降至 0。

8.4 适配大数据量快速更新场景

系统的分布式分桶设计、分布式计数系统部署,使得系统可支撑海量在线用户的同时处理,即使在用户量千万级、关注对象新内容发布频率秒级的快速更新场景下,仍能保证计算效率与实时性。同时,系统的弹性扩展能力强,可根据在线用户数量灵活增加计数系统节点与在线用户子池数量,适配业务规模的持续增长。

8.5 实现用户状态切换的无缝衔接

系统设计了完善的用户在线 / 离线状态切换处理逻辑,以及冷启动处理流程,保证用户在离线、在线状态切换过程中,未读消息数的计算不中断、不重复、不遗漏。用户冷启动时可快速获取最新的未读消息数,在线时实时更新,实现了不同状态下未读消息数计算的无缝衔接,提升了用户的整体使用体验。

09 应用场景与实践效果

本系统适用于各类存在关注关系、需要向用户推送未读消息提醒的互联网平台,尤其适配大数据量、高频率更新的业务场景,包括但不限于:社交平台的关注消息提醒、内容资讯平台的关注作者作品更新提醒、短视频平台的关注博主视频更新提醒、电商平台的店铺消息提醒等。

实践证明,本系统在大数据量快速更新场景下,能够有效平衡系统性能与用户体验,为平台的未读消息数提醒功能提供了高效、稳定的技术支撑。

10 总结与展望

本文设计的大数据量未读消息数系统,以分治思想为核心,通过用户状态差异化处理、在线用户哈希分桶、缓存高效管理与实时推送等技术,解决了传统方案中计算量大、存储成本高、提醒延时、计数不准等问题,实现了精准无延时计算,大幅降低了系统开销,可适配海量用户与高频更新场景。

该系统的状态差异化、按需计算与更新思想,为互联网平台未读消息数处理提供了新思路,也可迁移至其他大数据量计数场景。未来可从三方面优化:

1. 引入 AI 算法,按用户活跃度分层,采用差异化遍历频率,提升资源利用率;

2. 结合边缘计算,将部分计算任务下沉,降低中心服务器压力,提升异地用户体验;

3. 引入缓存预热机制,对高活跃用户数据提前预热,加快冷启动计算速度。

随着互联网技术发展与用户体验要求提升,未读消息数系统将向更高效、精准、轻量化方向演进,本方案为后续技术创新奠定了基础。

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐