案例:百度的评论系统是怎么设计的?你想象不到

百度评论中台为百度系产品提供便利接入、持续稳定的评论能力,是百度社区氛围体系内最重要的基础能力之一,日均流量达到百亿规模,在业务不断发展过程中,百度评论中台实现了功能快速迭代、性能稳步提升,本文将从整体介绍百度评论中台的架构设计,同时结合具体案例讲述如何构建高可用、高性能的分布式服务。

 1 

背景

评论作为用户主动表达提供情绪/态度/观点的重要方式之一, 其产品形态是以资讯作为载体,建设生产-分发-浏览的用户内容生态,最终促进内容与用户,用户与用户,用户与作者之间的价值交互氛围。

在阅读过一条资讯后,用户往往会浏览到评论区,或是抒发内心情感,或是寻找一些共鸣,也可能只是满足吃瓜群众的好奇心,有吸引力的评论区板块可以满足用户的互动诉求,同时也可以增加用户的产品粘性,促进业务发展;那么如何构建一套评论系统,在业务上能够支撑产品形态的多样化以及持续的迭代,在性能上能够提供稳定的能力输出,下面我们将会详细介绍百度评论中台的架构设计思路以及在业务发展过程中的一些挑战与探索。

7a49e45763b0a9e963ce04e2686c93be.png

 2 

概念介绍

评论从生产到读取历经多个环节,下图是评论生命周期中各个环节的简易模型:

e6b5bfc43d75b4591c44b0e0d328c73b.png

评论数据的生产由用户触发,评论系统维护了与资源关联的主题数据,通过主题信息来检索归属的评论内容,评论数据本身维护了发表人,层级关系,是否展现状态,内容,点赞数,回复数,时间等等,每个数据维度用于特定的展现场景以及数据分析。

在用户生产内容过程中,系统识别恶意请求,针对用户、资源、内容等维度进行层层过滤,完成数据落盘,数据采用分布式数据库存储,同时根据查询维度进行垂直/水平拆库拆表,以解决业务持续增长带来的数据读写性能瓶颈,数据层面的变更最终落入大数据中心,用来分析业务现状以及未来的发展发向。

 3 

服务设计

上文铺垫了评论业务的相关概念,接下来我们侧重于介绍整体的服务设计,评论服务最初立足于百度App业务,为Feed等内容体系提供稳定便捷的评论能力,随着公司在中台方向上的战略转型,评论服务重新定位为评论中台,面向百度系的各个产品线,角色的转变,引发了架构设计方面的巨大改变,同时也带来了新的技术挑战:

15c6d90ca3eeb8205b30bb723a7d778b.png

从业务接入角度来看,接入业务方多,需求量大,定制化要求高,需要中台侧对外能够给予业务侧友好的快速接入,对于此部分需求,我们作为首个中台方完成了服务托管移动开发者中心(百度移动开发管理平台)的接入,借助该平台管理接口权限、技术文档、流量鉴权、服务计费以及售后咨询等能力,大大提升了接入效率。

对于中台侧内部,通过建设统一的接入层网关,实现容灾触发、流量染色、流量控制、异常检测等插件能力,既可以为业务提供便利的技术支持,在中台内部产生技术变更时,也可以做到业务无感知;

从能力输出角度来看,不同产品线的业务特点对于基础能力有着不同的诉求,这就需要中台侧对外能够满足业务需求,对内在架构设计中充分考虑通用化来保证有限的中台人力的研发效率。基于此,我们将接口能力不断抽象,在代码层面上保证低耦合、高内聚,针对不同的产品需求设计组件能力,专项解决痛点问题,同时我们也尝试针对特定的功能场景,提供友好的开发框架,通过与业务侧开源共建的方式来提升需求上线的效率,解放一定的中台人力,也取得了不错的效果。

从系统性能角度来看,接入流量随着新增产品线而日益增长,不断考验中台服务的性能,我们需要承诺核心接口SLA视角99.99%的服务稳定性。从架构上看,去除单点服务,逻辑机房内部形成隔离域,无跨地域请求,考虑极端场景,设计技术方案防止缓存穿透,缓存击穿,服务雪崩,保证服务的最小可用单元,从容量上看,保证高峰期容量满足N+1的冗余,具备单机房切空的能力,核心指标的报警覆盖至运维/研发/测试同学等等;

总体来看,建设思路就是,服务分层治理,不断沉淀中台通用化能力,对于产品和技术的升级,不断完善基础建设。

 4 

挑战与探索

上文以整体视角介绍了百度评论中台的架构设计,下面我们枚举了几个业务发展迭代过程中遇到的具体问题,来详细介绍下百度评论中台是如何进行技术探索并实施落地的。

如何提升服务性能与迭代效率?

背景:

一个系统在历经无数个版本迭代后,能够承载的功能越来越丰富,同时也会面临着开发成本日益增长的问题,业务逻辑夹杂着历史包袱,代码块混乱冗余,牵一发而动全身,这个时候对系统本身的技术升级便势在必行。

评论列表类接口是评论服务中的核心业务,历史上大部分的功能迭代列表类接口都会参与其中,这也促使了列表类接口更快地暴露出问题。

从下图优化前的业务逻辑处理流程不难看出,接口定义模糊,承载功能较多,相关的逻辑交织在一起,导致代码可读性不高;在业务处理部分,数据依赖比较多,不同的数据获取之间还存在着依赖关系,服务调用只能顺次执行,效率低下,这些问题会影响到日常开发的工作效率,并且在性能上也不可控,为系统稳定埋下了隐患。

109c337e4772e9d0a08ebc4163ff9fd3.png

思路:

面对这一系列问题,我们对列表类服务进行了一次大刀阔斧的改革,采用三条路径来解决核心问题:在接口层面,按功能拆分,定义单一职责的接口来解耦逻辑;在数据依赖层面,对下游调用进行调度管理,实现自动化,并行化;在数据渲染层面,采用流水线的装饰器来定义业务主线逻辑与支线逻辑,整体做到优化后的服务接口功能专一,代码边界清晰,依赖服务调度管理,数据打包灵活,可持续拓展,那么我们是如何实现这一过程的?下面介绍下具体的解决方案。

方案:

21be09097de9ea9b47f876b377161b89.png

上图是一个接口下发数据的整体流程,总结起来可分为三个阶段:

第一阶段:作为接口的前置条件校验,对基础参数进行校验,过滤请求;

第二阶段:依赖数据的集中获取,这里是服务优化的核心部分,这里以评论一级列表接口为例,一级评论列表接口的数据下发,包括了一级评论,二级外漏评论,评论总数,主态可见评论数据,标签数据等等,每个数据源存在着一定的依赖关系。

比如,一级评论,主态可见评论,评论总数优先级最高,因为不依赖其他数据源便可以直接请求,二级外漏评论则需要一级评论数据获取到的父级评论列表作为基础依赖才能够执行,这样二级外漏评论的优先级次之,抽象来看,每个业务接口都可以梳理出自己的服务依赖关系,那么接下来的问题就变成如何将这些依赖关系管理、调度起来,这里我们采用了图引擎调度模型来完成这个任务:

该模型实现过程分为三个步骤:

第一步:定义,枚举业务逻辑中所需要的所有依赖服务,并映射成节点,每个节点是数据依赖调用的原子化节点,该节点中不参与接口维度的业务逻辑;

第二步:定义他们之间的关联,生成有向无环图,每个节点维护其依赖节点的个数,用入度值来表示;有向无环图的特点是节点与节点之间只有一个方向,不能成环,这种数据结构恰好符合业务节点之间的执行逻辑,把一个个服务依赖调用映射成有向无环图中的节点,每个节点的入度值来表示该节点的依赖节点数,其中顶点就是图中入度为0的节点,没有任何节点指向它;

第三步:由顶点开始,不断并发执行所有入度值为0的节点,上层节点弹出后,通过依赖关系寻找被依赖的节点,并对该节点的入度值做减操作,通过这种拓扑排序的结果输出,实现自动化的节点运行;

总结来说,将各个接口的节点关系进行配置化管理,当流量请求时,读取该接口的节点配置,生成有向无环图,节点的任务由调度器统一管理执行,每个节点的依赖数据输出会存储到当前请求的调度器中,到下游节点任务执行时,从调度器获取上游的数据结果作为入参,完成本节点的执行逻辑;

第三阶段:数据渲染阶段,通过阶段二获取到所有依赖数据后,从调度器中获取所有节点中的依赖数据结果,定义流水线式的格式化装饰器,按功能拆分,对响应值进行层层修饰,以实现数据渲染的模版化处理。

通过这种方式改造系统后,接口的服务性能大大提升,平均响应耗时在99分位维度上有了明显的降低,同时受益于Go语言的高性能,节省了物理机资源,重构后的代码可维护性也大为提升。

如何构建高性能、低延时的评论排序能力?

背景:

评论是生产用户内容的服务,那么对评论内容的运营则决定着整个评论区的氛围,对于优质/有趣或带有特殊属性的评论内容应该得到更多的曝光率,同时我们也希望低俗/辱骂/无意义的评论内容得到更少的关注,这样用户之间的互动才能得到正向的循环,这就要求评论服务构建一套排序机制,在产品层面上能够满足排序的需求,在技术上也可以做到排序数据快速收敛,不影响服务性能的前提下快速迭代。

思路:

在制定技术方案之前,我们需要考虑到几个核心问题,首先是如何对评论内容进行排序?

最容易想到的方案是为每条评论评估一个分值,按照分值的大小来输出一篇文章下的评论内容,以达到排序的效果;那么既然每条评论有了评分属性,接下来就要定义这个评分的公式,按照这个思路我们可以罗列出很多影响评论分值的因子。

比如一条评论的点赞数,回复数,创建时间等等,同时为这些因子设定相应的权重,组合起来可以计算出总分,在这个过程中,我们需要考虑公式的迭代给系统带来的性能冲击,当一个公式被确定下来,并不能马上推送到线上,而是需要小流量来评估排序结果带来的收益才能决定公式的因子或者因子权重是否是一组正确的组合,这便涉及到可能存在多组公式并存的情况,并且可以预料到公式的调整将会是频繁的迭代。

根据这些思路,我们最终开发出评论排序框架,采用离线计算评论分值,公式配置化,扇出并发模型等技术手段实现了智能化评论排序功能,下面我们详细看下架构设计。

方案:

48b141f9f634360447875f1428e3b60d.png

评论排序服务分为两部分,离线粗排服务与在线精排干预。

首先介绍下离线粗排服务,我们将评估评论分值/输出排序列表的任务放在离线模块中执行,在数据量较大的情况下离线运算不会影响到线上服务。离线模块会监听评论行为队列,例如评论回复,评论点赞,评论删除,评论置顶等能够影响评论列表数据变更的行为,离线排序服务消费到行为数据后通过策略公式计算出评论分值,最终存储到排序索引中,这个流程涉及到的技术点如下:

  • 单排服务;当一条评论数据发生变更时,触发单条评论分值的重新计算,判断是否需要触发全排服务,如果需要则将全排指令写入全排队列中,否责将最新的分值评估更新至排序索引中。

  • 全排服务;从全排队列中读取全排指令,获取到评论所属的主题ID,遍历该主题ID下的所有评论,重新评估每条评论的评分,写入至排序索引中。此处使用了Golang语言的扇出模型,队列通过channel实现,管理多个协程并发消费channel的全排指令,减少数据消息的积压。

  • 排序算子:在评估评论分值过程中,使用调度器并发获取排序因子所需要的数据,例如评论基础信息,主题物料信息,策略模型服务,提权/降权词表,重复内容库等,获取到的元信息通过排序公式的权重完成评估过程。

  • 语义化公式:通过语义化公式识别,实现配置化上线,这里的考量是,线上的效果需要不断调整每个算子的权重来小流量验证,那通过这种方式可以实现快速上线完成验证,对研发效率及产品迭代都是非常高效;

  • 排序索引:排序索引采用Redis作为存储介质,通过zset数据结构来维护一篇文章下的评论排序列表。不同的公式组成不同的策略,在多组策略同时生效时,排序索引会以文章维度生成多个策略的排序结果,同时维护多套ID索引,评论线上服务通过小流量读取策略组来命中不同的排序结果,方便AB实验。

离线粗排服务会针对评论的相关属性输出排序结果,在线部分,我们又对排序结果做了个性化的二次干预,包括个人评论提权,通讯录/关注好友评论提权,以及精排模型干预,这些策略帮助我们更为精准地定位用户群体的喜好,增加用户浏览评论的共鸣感。

如何保证服务的持续稳定性?

背景:

随着系统承载的业务流量越来越大,对服务稳定性建设方向上,评论团队也投入较大的资源/人力占比,一方面持续保证系统服务的高可用,不断提升系统容错能力,突发异常情况下能够快速应对,保障业务的最小可用单元,另一方面在业务逻辑反复迭代过程保证系统服务的高性能,不断提升用户体验。

稳定性建设是个持续优化的过程,我们通过不断探索,调研,选择适合评论服务的技术方案并落地,评论业务特点是面向C端用户,社会热点事件会对业务产生直接影响,会引发读写流量的突增,其中写流量的增加,对下游服务,下游存储会产生不小的负荷,同时,过多的写流量也会考验读流量的缓存命中率,一旦出现某一主依赖异常,整体服务将处于不可用的状态,针对这种风险,通过我们在热点,缓存,降级三个方面着手,为服务的稳定性保驾护航,下面看下具体实现方案:

aac53878bbc7bfd399d1bb234976f724.png

缓存管理:

对于读流量的突增情况的处理方式通过设计多级缓存,提高缓存的命中率来处理,根据评论业务特点,我们设计了评论列表缓存,评论计数缓存以及评论内容缓存等,还使用了空缓存,来针对特定场景下大部分资源无评论的情况,防止缓存穿透。

在接受业务读流量请求时,首先使用LRU的本地缓存抵挡一波流量,查看是否能在最热最近的内存缓存列表中获取结果,本地缓存并没有命中,将会从Redis获取缓存,如果是突发热点,Redis的命中率很低,流量回源到db依然有很大的风险,所以这里使用了一层实例锁,从实例维度控制并发量,只允许一条请求透传到下游,其他请求等待结果,用这种方式来防止缓存击穿。

热点机制:

热点事件往往会引发流量的突增,热点事件产生时,通常会伴随着Push类的通知,更加引发单篇资源的集中式读写请求,而且这种热点事件产生时间比较随机,很难做到提前预判,单篇资源读写流量的升高,会导致缓存命中率下降,甚至缓存彻底失效,大量请求直接打到数据库,进而导致服务雪崩。

为了避免热点事件给系统带来不可控的冲击,我们设计了一套热点自动发现/识别系统:通过消息队列监听资源维度产生的评论行为,例如评论发表,回复,点赞,审核等等,通过计数来判定当前资源是否够热对评论行为进行计数统计。

当一篇资源下的评论行为持续增多,达到某一阀值(动态可配置)时,该资源被判定为热点资源,并将该资源推送至热点配置中心,命中热点的资源,其资源下产生的评论行为将写入热点队列,异步入库,同时,写操作后不再对缓存进行清理,而是重建缓存,来保证命中率。通过这一套机制,我们成功应对了一系列引发全民热议的热点事件,保证了用户体验。

容灾降级:

当出现极端的故障时,对系统的稳定性会产生巨大的影响,比如下游服务承受不住突增的业务流量,请求超时,实例问题引发的单点故障,机房网络问题导致不可用等等,我们的服务每日承载着百亿级别的PV流量,几秒钟的服务不可用就会产生巨大的损失。

因此容灾降级能力是考验系统服务高可用的一个重要标准,我们在这方面做了一系列的措施来提升系统应对风险的能力,建设业务在异常状态下的最小可用单元。

在容灾机制上,容灾触发细分为主动与被动,当业务与到可用性毛刺抖动时,由接入层进行感知,自动进入被动容灾逻辑,写请求进入队列异步入库,读请求直接返回容灾数据,提升容灾数据使用率。

主动容灾与运维平台打通,实现按接口、按机房、按比例来判定服务是否降级成容灾状态;在依赖管理方面,梳理业务弱依赖,一旦发生某一依赖服务异常,可以直接对依赖进行摘除。

在混沌工程方面,为了能够应对线上各种突发状况,对服务进行故障设计、故障注入,并针对服务给予的反馈,制定相应的预案建设,并将故障演练例行化,定期检验系统能够承受的风险级别。

 5 

总结

百度评论中台发展至今,历经了角色定位/技术架构的转变与升级,不断探索应用创新,打造极致的用户体验,目前,评论服务为百度系20+的产品提供评论功能,峰值QPS达到40w+,日均PV达到百亿规模,同时能够保证SLA视角的接口稳定性在99.995%以上。在未来的发展规划中,百度评论中台在服务创新、中台建设、稳定性等方面还会继续深造,助力建设优质的百度社区氛围。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/57062.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSDN - 屏蔽无耻的百度广告

由于CSDN在chrome上显示效果与编辑页面都很友好,所以访问csdn或者维护博客时常使用chrome。 可恶的百度广告总是在左下角和右下角弹出,深恶痛绝啊!! 春天的到来!!—Adblock Plus插件 【1】下载 Adblock P…

在家可以做什么副业,适合新手的四个网上兼职

近期一个月,好多地方因口罩影响,多多少少都要求他们在家隔离,除开每日待在家里,也只能是在社区里散散步。想起很多小伙伴由于疫情在家里不可以工作中,收益逐渐变少少,很有可能的身上也有抵押借款和车辆贷款…

副业赚钱的路子有哪些?分享6种较为实用的副业方式

如今社会的压力越来越大,很多人都开始积极寻找副业赚钱的途径,以缓解生活中的经济压力。副业赚钱的方式多种多样,可以依据个人的兴趣爱好、特长技能来选择。以下分享6种较为实用的副业赚钱方式。 1、跑腿服务 跑腿服务是目前非常受欢迎的副业…

下午有自由时间可以做的副业推荐

对于大部分人来说,工资收入并不足以实现快速攒钱的目标。而且现在社会发展很快,大部分工作都不能保证稳定,所以发展自己的副业很重要。下面小编给大家推荐5个所有人都能做的副业,感兴趣的朋友可以从中选择适合自己的副业坚持做下去…

上班时间适合搞什么副业?最适合普通人的副业:用你的职业技能、生活经验来做

首先我告诉你所谓副业是和主业一样,或者说需要你投入十二分精力去对待的,需要你放弃社交娱乐,本质上就是一套自虐之路,做不到的还是老老实实上班才是正道 其次,你在网上看到所谓的副业介绍都只是别人的“副业”&#…

python网络副业有哪些?以自身经历分享怎么做副业挣钱

网络副业我个人比较看好的是Python,至少我是真实体会到了Python做副业真香,疫情被关在家那段时间也没耽误赚钱,反而比平常赚的还多一点,下图是我疫情期间在家做Python副业收入的部分截图,那会儿我用Excel表格每天记了一…

IT行业可以做的副业

去年一年,新冠疫情的阴霾让大部分职场人都不好过。当加薪和年终奖都遥不可及,不少人开始思考经营一份副业的可能性。 那么有没有什么是适合IT技术人员发展的副业呢?接外单赚取外快?不,这一定不会是最好的选择&#xff…

程序员可以做哪些副业?

原文链接:https://dsx2016.com/?p508 程序员自身的属性决定了副业的天花板。 最理想的情况是副业在赚钱的同时可以对主业进行属性加成。 同时如果主业做得好也能对副业产生积极的作用。 有鉴于996和24小时随机加班是it常态 推荐睡后收入的方式,并且长…

python可以做哪些副业

这是本文的目录 前言Python为什么会大受欢迎python副业有哪些1、兼职处理数据2、兼职查询资料3、兼职P图 零基础Python学习资料领取附上Python学习指南👉Python学习路线汇总👈👉Python必备开发工具👈👉Python学习视频6…

电脑副业能做什么?一台电脑能做的副业

现在很多人都想在工作之余开展一些副业,特别是今年经济形势不好,更让很多人明白了,有一份副业的重要性,这样可以在自己没有工作的时候还能有一份收入,那么有哪些副业可以在网络上做呢?如果你只有一台电脑的…

程序员做什么副业比较好,都有哪些副业可做?

其实对每个普通人来讲,副业有很多形式,不过消耗时间少的副业才是最好的,投入产出比不等的副业那是给自己找麻烦。 一、程序员可以做的副业汇总 1.接私单,赚外快。 难度:极大 成本:时间成本精力成本尾款风…

tracert命令

一、概述 tracert是Windows网络中的Trace Route功能的缩写, 用于确认数据包访问目标IP所经过的路径。 二、用法 tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout] [-R] [-S srcaddr] [-4] [-6] target_name 三、参数 -d 指定不将地址解析为计算机名. -…

如何在 Linux 的 shell 里针对特定用户/组来限制某些命令的使用

0-前言 最近,业务侧有个需求,需要禁止特定用户访问linux特定的命令,如禁止用户A使用rm命令。 我们知道,在linux系统中,一切皆文件。 那么,这个问题也可以泛化为: 如何在linux里限制特定用户…

Android 公历农历

SolarLunarView 公历农历 - 日历View 1.显示中国节假日 2.公历 3.农历 预览 资源 名字资源AARsolar_lunar_view.aarGiteeSolarLunarViewGitHubSolarLunarView Maven 1.build.grade | setting.grade repositories {...maven { url https://jitpack.io } }2./app/build.gra…

php 获取农历,PHP获取农历、阳历转阴历

PHP获取农历、阳历转阴历 <?php class lunar{ #农历每月的天数 var $everyCMontharray( 0>array(8,0,0,0,0,0,0,0,0,0,0,0,29,30,7,1), 1>array(0,29,30,29,29,30,29,30,29,30,30,30,29,0,8,2), 2>array(0,30,29,30,29,29,30,29,30,29,30,30,30,0,9,3), 3>arr…

【微信小程序】农历公历互相转换

文章目录 需求来源实战代码核心方法运行效果工具方法 其他优化 需求来源 之前写了一篇获取农历日期的文章&#xff0c;【微信小程序】获取农历及星期&#xff0c;后来想到我这个小程序【TimeAssistant】中的“远离工作”功能模块还得优化&#xff0c;具体功能界面如下图 此功能…

阳历转换成阴历PHP实现详解

结合上次做的日历&#xff0c;提前粘贴一下效果图 当前月份 下一个月 相关概念 阳历&#xff0c;有很强的规律性。每年12个月&#xff0c;1、3、5、7、8、10、12月都为31天&#xff1b;平年2月份28天&#xff0c;润年2月份29天&#xff0c;其余的月30天。 阴历&#x…

c语言中万年历公历农历转换,公历农历转换,教你切换阳历和阴历生日

公历&#xff0c;又叫阳历&#xff0c;农历&#xff0c;又叫阴历&#xff0c;阳历和阴历所依据的参照物不同&#xff0c;计算方法也不一样&#xff0c;应该如何换算呢&#xff1f;下面就来看看本文关于公历农历转换&#xff0c;教你切换阳历和阴历生日的分析吧。 一、快速切换方…

阳历转阴历,阳历转中国农历

文章目录 阳历转阴历&#xff0c;阳历转中国农历 阳历转阴历&#xff0c;阳历转中国农历 阳历转阴历一直都是很繁琐的过程&#xff0c;所以我制作了一个开发包&#xff0c;来方便我们转换阳历到中国农历。 让我们下载 moon-time&#xff1a; moon-time 是一个将阳历转换为阴…

软件设计师---结构化开发

笔记有错误欢迎直接在评论区进行纠正&#xff01;我将不再维护软件设计师笔记&#xff01; 结构化开发上午题大概4分 模块化 耦合 真题 真题1 真题2 这里不要一看到数据结构就觉得是标记耦合&#xff0c;标记耦合是两个模块传递的是数据结构&#xff0c;而这里没有传递&…