当前位置: 首页 > news >正文

百度搜索展现服务重构:进步与优化

作者 | 瞭东

导读

本文将简单介绍搜索展现服务发展过程,以及当前其面临的三大挑战:研发难度高、架构能力欠缺、可复用性低,最后提出核心解决思路和具体落地方案,期望大家能有所收货和借鉴。

全文4736字,预计阅读时间12分钟。

01 背景

百度搜索展现服务的主要职责是请求检索系统获取结果,并依次进行模板选择、实时摘要补充、数据适配和结果渲染,将检索结果能以丰富多样的形式精准地展示给用户。在初期,这项服务基于C语言进行开发,迭代效率不尽人意。随着产品的迅速迭代和业务的不断拓展,研发效率问题逐渐凸显,为了解决这一瓶颈,搜索展现服务进化为由PHP开发、HHVM运行的服务。目前,搜索展现服务由数十个产品线、上百个研发RD共同参与研发,承载了数百个精细化的业务展现策略。然而,随着搜索业务的日益复杂化和生成式大模型的崛起,搜索展现服务也开始面临研发难度增大、架构能力不足和复用性低等多重挑战。具体表现如下:

【研发难度高】:搜索展现服务基于过程管理,逻辑复杂,多个策略框架分布于代码的各个阶段,不能满足多业务对于简化管理、易于扩展的效率诉求

【架构能力欠缺】:hhvm基础设施已经停止维护,对于异步/多线程等功能的支持较为有限,流式能力的缺失使其无法满足生成式搜索等需求,因而不能满足服务稳定性和新产品需求迭代的要求。

【可复用性低】:搜索展现层主要服务与通用搜索、垂类搜索等。目前,通用搜索和垂类搜索之间目前缺乏合理的架构设计,这导致相同的需求在通用搜索和垂类搜索中都需要进行重复的开发。

02 解决方案

2.1 整体设计

2.1.1 核心思路

降低研发难度:根据展现层特点,通过设计实现图管理引擎,将展现功能以算子的粒度进行拆分,单个算子的逻辑简单清晰、业务方把工作聚焦在功能(算子)和需求,而非应用整体,同时将搜索展现服务的过程处理升级为DAG图处理,降低流程管理的复杂度。通过实现算子->图->需求的层次管理,推动搜索展现服务的过程研发模式从面向过程到面向功能、面向业务。

提升架构能力:从PHP+HHVM转型GO,基于百度内部GO开发框架搭建搜索展现服务,获得更好的性能和更高的并发处理能力。同时对于异步/协程/流式交互能力支持成本更低。

提升可复用性:通过抽象公共算子和实施基础Lib共建,提高代码的可复用性和可维护性。公共算子可以在多个搜索展现服务中复用,避免了重复开发和维护的代价。基础Lib可以提供通用的功能和工具类,方便开发人员快速开发和维护代码,减少重复开发和出错的可能性。

图片

△搜索展现层架构图

2.1.2 基础设施

GDP(Go Develop Platform):百度内部基于go实现的业务开发平台,具备完善的RPC Server和RPC Client能力,主要用于API、Web以及后端服务开发。

ExGraph: 百度搜索展现团队自研图执行引擎。

:设计了一套简单的图描述语言,不借助任何工具,rd可轻松学习并据此了解模块执行逻辑的全貌,降低接手难度

算子:设计简单的接口,屏蔽实现细节,rd实现算子接口即可执行

执行:灵活设计了串行组、并行组、子图、条件算子、switch算子、中断、等待等机制,以适配复杂的业务流程

效率工具:实现了代码生成器、脚手架等效率工具,可快速创建应用

Datahold:百度搜索展现团队自研数据管理器,主要解决模块数据(比如配置、字典)依赖和加载问题。具备如下能力:

  • 支持热加载,后台监听并解析变更文件后切换到前台使用;提供通用字典、配置解析器,同时支持自定义文件解析器

  • 支持通过配置完成数据对象自动注册、加载和解析,有效管理大型服务中配置/字典不可丢、解析出错及时报警感知等

  • 支持rd线下环境一键部署模块依赖远程数据,提升研发阶段环境部署效率

公共lib:此外基础设施层还提供了udai(远程数据统一访问cgo扩展)、百度自有签名等等展现团队公共lib,公共Lib建设有统一准入标准,避免重复造轮子,提升研发效率。

2.1.3 公共算子

将搜索展现通用逻辑抽象为接口,基于图引擎提供公共算子,实现一处开发,通用搜索、垂类搜索等多个应用共同使用。目前已经实现抽样、适配、降级、限流、检索请求、落地页点出、渲染等数十个公共算子,开箱即用,快速支持搜索新展现应用搭建。

2.1.4 应用层

通过公共算子、各服务自有展现算子搭建执行图,实现应用业务逻辑。当前搜索展现服务包含通用搜索展现服务、垂类搜索展现服务、生成式搜索展现服务等。

2.2 详细设计

通用搜索相比垂类搜索等业务更具复杂性,本章节将以通用搜索展现服务为例,具体介绍其重构迁移go的落地方案。

图片

_△通用搜索展现服务重构前后对比图

在重构迁移过程中我们主要面临两个难点:

难点1:前文已提到通用搜索展现服务是一个数十个产品线100+RD共同研发的模块,展现策略组1&2&3共有600+业务展现策略,每天平均有4+策略迭代上线,在重构迁移落地过程中,首要解决的问题就是:如何兼容迁移和现有业务迭代效率?如何协同众多业务线迁移?

难点2:搜索展现服务业务逻辑非常复杂,重构项目如何保障用户效果、商业收入和服务稳定性。

对于难点1,主要通过架构业务解耦、平滑迁移机制这两个手段解决;对于难点2将从研发、测试、上线全流程稳定性保障。接下来将详细介绍这两个部分内容。

2.2.1业务解耦&平滑迁移

保障迁移和现有业务迭代效率,并协同多产品线进行业务展现策略迁移核心手段:解耦架构和业务展现逻辑,架构迁移部分先行迁移go,业务展现策略依旧基于php运行,架构逻辑迁移过程中不阻塞业务迭代,尽量避免php&go两个版本同时开发相同的业务逻辑。设计一套机制支持业务展现策略按业务线独立迁移到基于go的搜索展现服务上,并将整个复杂迁移过程拆分成四个阶段有序进行,最终实现整体项目目标。

图片

第一阶段:架构部分图化迁移go+展现策略服务化

将限流、参数处理、检索请求、广告检索请求、http-header渲染等架构逻辑代码基于GDP+Exgraph图化迁移go,基于go的通用搜索展现服务完成检索数据统一处理之后,再请求基于php的展现策略服务进行业务展现逻辑。这样即可以保证迭代相对不频繁的架构逻辑先行迁移go,为后续展现策略迁移做好基础,同时也能保证迭代频繁的展现策略依旧可以按原有研发模式继续迭代。

第二阶段:异步摘要请求全量迁移

首先回答下异步摘要是什么。

检索系统往往为了考虑计算资源和响应速度,会在各个子系统内部设置cache,cache失效时间至少都是分钟级别,部分场景甚至达到天级别。对于部分需要秒级别就能更新的展现元素,比如搜索结果里需要展现视频播放量、文章点赞数量,以及用户是否对这条结果进行点赞等,cache就没有那么友好了。异步摘要因此诞生,检索请求返回之后基于检索结果请求高时效摘要服务,摘要请求是异步完成的,和普通展现策略并发,既实现了实时摘要补充,又避免了用户响应速度的退化。

为了避免随着展现策略逐渐迁移go,异步摘要请求时间可并行时间缩短,引入旁路系统。异步摘要策略数十个,本身迭代相对普通展现策略较不频繁,请求整体一起迁移go,异步摘要请求成功写入旁路系统,执行完所有普通展现策略(无论是迁移到go执行,还是保留在php上执行),基于PHP的策略服务通过旁路系统获取所有异步摘要并执行实时摘要补充。引入旁路系统本身也需要通信开销,通过以下手段降低:

  • 通过边车化实现旁路服务降低远程通信开销

  • 基于go展现服务不对异步摘要进行解析,将原始序列化结果写入到旁路系统,基于php服务获取数据进行解析。可以有效避免go/php展现重复反序列化数据带来开销。

第三阶段:展现策略迁移

协同各个产线线完成展现策略组1、展现策略组2、展现策略组3迁移到基于go的搜索展现服务。该阶段支持产品线按策略粒度、按业务小流量迁移;同时新展现策略(不包括异步摘要策略)可以直接基于go的搜索展现服务开发。

迁移准则:按展现策略有无依赖分类迁移。依赖常见场景:策略执行依赖其他非本业务的展现策略先执行,这种场景必须被依赖策略先迁移;策略内部依赖了架构能力,但这部分能力没有迁移go等。

迁移优先级:

(1)优先迁移无依赖的展现策略,可以独立迁移开发、实验、推全

(2)对于存在依赖的展现策略,协同被依赖方一起完成迁移

第四阶段:全量迁移

整体完成异步摘要策略迁移、渲染、后置任务迁移。

该部分逻辑迭代也相对不频繁,为什么不提前迁移go?

主要限制因素是响应速度。如果将基于php展现策略服务发回给基于go的展现服务,再进行渲染、后置任务,php->go会再增加一次序列化、反序列化以及通信时间,会造成速度退化,这部分速度退化迁移go之后无法带来速度优化弥补抵消。

2.2.2 全流程稳定性保障

通用搜索展现服务重构项目的用户效果、商业收入和服务稳定性主要通过全流程稳定性保障。全流程稳定性主要包含研发、测试、上线稳定性保障。

研发保障

迁移过程不仅仅是简单功能平迁,通用搜索展现服务已经迭代了数十年,本身存在诸多不合理设计,如数据冗余、历史飞线逻辑较多、代码复用低等,我们基于以上问题进行数据治理、飞线包袱清理、重新抽象设计公共算子等。这些对研发质量提出了更高的要求,一方面通过单元测试和自动化流水线测试(数据diff&UI-DIFF,测试保障介绍)保障代码质量,另一方面通过日志打点分析对历史包袱进行提前下线避免不合理、不必要的迁移。

测试保障

功能测试:

数据Diff:协同qa建设自动化数据diff功能,录制线上请求进行回放,将关键数据如检索请求、广告请求、输出给渲染服务的数据等等进行全面自动化例行数据diff,通过数据diff发现潜在问题,累计发现并消除上万数据diff。

UI-Diff: 搜索结果页结果类型众多,比如天气阿拉丁、股票阿拉丁等等,共有上千个资源类型,每种资源类型都有各个的展现模板。效果回归成本高且难度大,根据资源展现量大小作为优先级,利用ui-diff平台(html页面像素级diff)自动挖掘线上query进行基线和策略线自动化ui-diff,重点关注diff差异超过阈值的效果问题,通过这种方式累计发现并修复40+效果类问题。

端到端测试:数据diff&UI-diff这两个自动化测试手段已经能够覆盖绝大多数效果类场景,除此此外,QA对搜索重点场景比如落地页跳转、翻页、广告效果等人工效果测试回归。通过自动化测试+人工效果测试保障重构改造后的展现效果。

稳定性测试: 通过引流线上流量进行长时间压力测试,模拟线上运行环境,保障服务线上稳定性。

性能测试:通过性能火焰图发现系统性能热点并优化点;通用线上实例峰值qps进行性能测试以及极限压测获取服务极限qps,提前预估线上资源容量是否充足,响应数据是否存在退化。

上线保障

上线阶段稳定性保障主要手段包括:上线前资源/响应时间预估等进行稳定性评审、监控&报警、降级、内测、全网小流量等。

03 总结

本文介绍了搜索展现服务发展过程以及当前面临主要挑战:研发难度高、架构能力不足、可复用性低,然后提出基于图执行引擎+公共算子+重构迁移go方式解决上述问题,最后基于通用搜索展现服务详细阐述了方案的落地。本文旨在通过将搜索展现服务重构思考分享给大家,期望大家有所借鉴和收获,当然也可能存在不足之处,也期望大家留言共同探讨。

搜索技术平台研发部正在招募 AI 研发工程师,欢迎感兴趣的同学投递简历至linzecheng@baidu.com

——END——

推荐阅读

百度APP iOS端包体积50M优化实践(七)编译器优化

百度搜索内容HTAP表格存储系统

大模型时代,“人人可AI”的百度开发者平台长什么样?

数十万QPS,百度热点大事件搜索的稳定性保障实践

百度搜索万亿规模特征计算系统实践

相关文章:

百度搜索展现服务重构:进步与优化

作者 | 瞭东 导读 本文将简单介绍搜索展现服务发展过程,以及当前其面临的三大挑战:研发难度高、架构能力欠缺、可复用性低,最后提出核心解决思路和具体落地方案,期望大家能有所收货和借鉴。 全文4736字,预计阅读时间12…...

icmp协议、ip数据包 基础

icmp协议、ip数据包 ICMP 协议 1 定义与用途: ICMP(Internet Control Message Protocol)定义: ICMP 是 Internet Control Message Protocol(互联网控制消息协议)的缩写。它是 TCP/IP 网络模型中的一个核…...

es6从url中获取想要的参数

第一种方法 很古老,通过 split 方法慢慢截取,可行是可行但是这个方法有一个弊端,因为 split 是分割成数组了,只能按照下标的位置获取值,所以就是参数位置一旦发生变化,那么获取到的值也就错位了 let user…...

【elementui笔记:el-table表格的输入校验】

之前做得比较多的校验是在el-form表单里做的,但有时也遇到,需要在table内输入数据,然后校验输入的数据是否符合要求的情况。因此记录一下。 思路: 1.需要借助el-form的校验,el-table外层嵌套一层el-form,使…...

每天五分钟计算机视觉:GoogLeNet的核心模型结构——Inception

本文重点 当构建卷积神经网络的时候,我们需要判断我们的过滤器的大小,这往往也作为一个超参数需要我们进行选择。过滤器的大小究竟是 11,33 还是 55,或者要不要添加池化层,这些都需要我们进行选择。而本文介绍的Inception网络的作用就是代替你来决定,把它变成参数的一部…...

卡片C语言(2021年蓝桥杯B)

分析&#xff1a;我们用一个数组来记录卡牌&#xff0c;我们每使用一张卡牌&#xff0c;就减一张&#xff0c;当卡牌数为-1的时候&#xff0c;说明不够用了&#xff0c;此时我们就打印上一个组合的数字。 #include <stdio.h> int main(){int num[10],i,m,n,j;for(i0;i&l…...

数据库动态视图和存储过程报表数据管理功能设计

需求&#xff1a;需要将ERP的报表数据挪到OA中&#xff0c;但是OA表单设计不支持存储过程动态传参&#xff0c;所以需要设计一个系统&#xff0c;可以手动配置&#xff0c;动态显示原本ERP的报表数据&#xff0c;ERP报表是存在数据库的视图和存储过程中 思路&#xff1a;因为E…...

css+js 选项卡动画效果

选项卡上下左右翻转动画效果 <template><div class"web-box"><div class"topTitle"><div class"topTitle1">标题标题</div></div><div class"info-wrap"><div style"width: 100%;h…...

[C错题本]转义字符/指针与首元素/运算

\a响铃 \b退格 \f换页 \r回车 \t水平制表 \v垂直制表 \单引号 \"双引号 \\反斜杠 \0dd八进制&#xff08;0-7&#xff09; \xdd(0-f)注意x一定不能大写 而且十六进制千万不能写\0xint main() {char s[]"ABCD", *p;for (p s 1; p < s 4; p)printf("%s…...

Layui继续学习

1、简单评论区代码&#xff1a; <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>社区评论区</title> <link rel"stylesheet" href"https://cdn.staticfile.org/layui/2.6.8/css/…...

react+datav+echarts实现可视化数据大屏

&#x1f4d3;最近有点闲&#xff0c;就学习了下react&#xff0c;没想到就把react学完了&#xff0c;觉得还不错&#xff0c;就打算出一把reactdatav的简易版可视化数据大屏供大家做个参考。 &#x1f4d3;效果如下 1下载必要的框架 &#x1f4d3; react路由 npm install re…...

CSS新手入门笔记整理:CSS浮动布局

文档流概述 正常文档流 “文档流”指元素在页面中出现的先后顺序。正常文档流&#xff0c;又称为“普通文档流”或“普通流”&#xff0c;也就是W3C标准所说的“normal flow”。正常文档流&#xff0c;将一个页面从上到下分为一行一行&#xff0c;其中块元素独占一行&#xf…...

微服务组件Sentinel的学习(1)

Sentinel学习笔记&#xff08;1&#xff09; Sentinel基本概念Sentinel功能和设计理念流量控制熔断降级系统负载保护 Sentinel基本概念 资源 资源是Sentinel的关键概念。它可以是 ava应用程序中的任何内容&#xff0c;例如&#xff0c;由应用程序提供的服务&#xff0c;或由应…...

小程序 -网络请求post/get

1.1网络请求的概念(post和get) 1.2步骤 1.3 应用函数 js里面写&#xff0c;用bindtap绑在控件上&#xff0c;就不讲了 实例代码&#xff1a; //发起get数据请求get_info(){wx.request({url:https://www.escook.cn/api/get,//请求的接口地址,必须基于https协议//请求的方式met…...

Elasticsearch 8.10之前同义词最佳实践

1、同义词在搜索引擎领域用途 同义词在搜索引擎领域的用途可概括如下: 增强搜索的准确性——当用户输入一个关键词时,可能与他们实际意图相关的文档使用了一个不同的关键词或短语。同义词允许搜索引擎理解和识别这些情况,返回更准确的结果。如:“遥遥领先”和“华为Meta60…...

芯知识 | 什么是OTP语音芯片?唯创知音WTN6xxx系列:低成本智能语音解决方案

什么是OTP语音芯片&#xff1f; OTP&#xff0c;即一次性可编程&#xff08;One-Time Programmable&#xff09;&#xff0c;语音芯片是一类具有独特编程特性的嵌入式语音存储解决方案。与可重复擦写&#xff08;Flash型&#xff09;语音芯片不同&#xff0c;OTP语音芯片一经烧…...

Linux内核密钥环

Linux内核密钥环&#xff08;Linux Kernel Keyring&#xff09;是Linux内核中的一个机制&#xff0c;用于管理和存储各种类型的密钥和安全相关的数据。它是Linux内核提供的一种可编程的安全子系统&#xff0c;用于处理密钥的生成、存储、检索和删除等操作。 Linux内核密钥环的…...

web前端之正弦波浪动功能、repeat、calc

MENU 效果图htmlstylecalcrepeat 效果图 html <div class"grid"><span class"line"></span><span class"line"></span><span class"line"></span><span class"line"><…...

使用工具 NVM来管理不同版本的 Node.js启动vue项目

使用工具如 NVM&#xff08;Node Version Manager&#xff09;来管理不同版本的 Node.js。NVM 允许你在同一台计算机上安装和切换不同版本的 Node.js。以下是一些步骤&#xff0c;以便同时在你的系统中安装两个 Node.js 版本&#xff1a; 安装 NVM: 首先&#xff0c;你需要安装…...

Xcode编写基于C++的动态连接库(dylib)且用node-ffi-napi测试

创建一个dylib工程示例 在 Xcode 中创建一个动态链接库&#xff08;.dylib 文件&#xff09;的步骤如下&#xff1a; 打开 Xcode&#xff1a; 打开 Xcode 应用程序。 创建新的工程&#xff1a; 选择 "Create a new Xcode project"&#xff0c;或者使用菜单 File &g…...

WPF-UI HandyControl 简单介绍

文章目录 前言我的网易云专栏和Gitee仓库HandyControlHandyControl示例相关资源地址 我的运行环境快速开始和Material Design功能对比手风琴右键菜单自动补充滚动条轮播图消息通知步骤条托盘按钮 结尾 前言 最近我在研究如何使用WPF做一个比较完整的项目&#xff0c;然后我就先…...

golang学习笔记——数据结构进阶

文章目录 数据结构进阶mapmap示例sliceinterfaceembedded 数据结构进阶 常见数据结构实现原理 本章主要介绍常见的数据结构&#xff0c;比如channel、slice、map等&#xff0c;通过对其底层实现原理的分析&#xff0c;来加深认识&#xff0c;以此避免一些使用过程中的误区。 …...

TrustZone之总线请求

接下来&#xff0c;我们将查看系统中的总线请求者&#xff0c;如下图所示&#xff1a; 系统中的A型处理器具有TrustZone感知&#xff0c;并在每个总线访问中发送正确的安全状态。然而&#xff0c;大多数现代SoC还包含非处理器总线请求者&#xff0c;例如GPU和DMA控制器。 与完成…...

vue2+Echarts数据可视化 【帕累托图】

接口得到的数据如下 要经过排序 &#xff0c;计算累计百分比得到数据 蓝色 柱状图数据&#xff1a; 取count字段值 横坐标&#xff1a;取 id值 折线图&#xff1a;根据柱状图的数据计算累计百分比 getInterface(data) {getParetoChart(data).then((res) > {if (res) {thi…...

imazing 2.17.16中文版怎么备份iPhone手机照片

imazing 2.17.16中文版备份功能非常强大&#xff0c;在进行备份之前&#xff0c;需要对其进行设置&#xff0c;才能充分使用备份功能。当移动设备与电脑第一次连接成功后&#xff0c;会询问是否要立即备份&#xff0c;个人的建议是选择“稍后”&#xff0c;小伙伴可以先对软件进…...

05 python数据容器

5.1 数据容器认识 5.2 python列表 5.2.1 列表的定义 演示数据容器之&#xff1a;list 语法&#xff1a;[元素&#xff0c;元素&#xff0c;....] #定义一个列表List List [itheima,uityu,gsdfg] List1 [itheima,6666,True] print(List) print(List1) print(type(List)) pr…...

相机倾斜棋盘格标定全记录 vs200+opencv安装

论文参考是这个 Geiger A, Moosmann F, Car , et al. Automatic camera and range sensor calibration using a single shot[C]//Robotics and Automation (ICRA), 2012 IEEE International Conference on. IEEE, 2012: 3936-3943. 代码是这个github 花了一上午配好了c环境。。…...

QT- QT-lximagerEidtor图片编辑器

QT- QT-lximagerEidtor图片编辑器 一、演示效果二、关键程序三、下载链接 功能如下&#xff1a; 1、缩放、旋转、翻转和调整图像大小 2、幻灯片 3、缩略图栏&#xff08;左、上或下&#xff09;&#xff1b;不同的缩略图大小 4、Exif数据栏 5、内联图像重命名 6、自定义快捷方式…...

PyQt 如何通过连续点击托盘图标显示隐藏主窗口并且在主窗口隐藏时调整界面到托盘图标附近

不废话直接看代码 # -*- codingutf-8 -*- # # author: Ruben # mail: 773849069qq.com # time: 2023/12/8 # u""" 一个托盘图标的小部件 """ from Qt import QtWidgets, QtGui, QtCore# --*--*--*--*--*--*--*--*--*--…...

什么是纯净IP?如何判断IP地址的纯净度?有哪些干净IP推荐?

您是否想知道什么使代理“干净”或如何确保您的代理不会将您列入网站的黑名单&#xff1f;对于通过代理访问网络的人来说&#xff0c;干净的代理是无缝在线体验的重要组成部分。在这篇文章中&#xff0c;我们将深入研究干净代理的世界&#xff0c;并探讨决定其质量的因素。 一、…...