检索系统设计方案(重构)

news/2024/5/7 20:46:42/文章来源:https://blog.csdn.net/weixin_45987569/article/details/128001694

记一次系统重构设计

  • 背景介绍
  • 设计步骤
  • 架构图介绍
  • 架构设计注意点
  • 总结

背景介绍

搜索链路主要部分
在这里插入图片描述
搜索引擎链路都包含这三部分,数据源、搜索引擎服务、搜索业务。

是不是很简单,感觉搜索也没那么难?

搜索链路确实都包括这三部分,但没我说的那么简单,每两个部分之间链路很长,业务非常复杂,举例说下数据源到搜索引擎服务的链路。

首先数据源不是单一数据源、比如说个电商场景的数据源,主要有商家商品数据、用户数据、爬虫数据等多种数据源。

我这次要做的链路是从数据源到搜索引擎服务这一段,简单点就是数据源提供的数据,需要结构化之后入到搜索引擎,这样搜索引擎才能提供搜索服务。

可这数据源真的是五花八门,提供数据的方式也是五花八门的。

设计步骤

背景基本就介绍到这里了,接下来就说说设计一个系统的步骤,说实话,毕竟是第一次做系统设计,当时真的是无从下手,不过帅气的米豆有法宝啊,多请教,多思考,多查资料。

在方案评审之前我已经做了很多方案设计图,这部分的努力主要是为了通过方案评审,这非常重要,通不过评审,老板不会让你做,就没有资源可以用,这项目就搁浅了。

主要发力点:
旧系统摸底:找出旧系统的所有不支持当前业务场景的点,有哪些是对当前业务影响较大的,哪些是对未来业务影响较大的,这些都要细细整理出来。不过这块我做起来还算轻松,旧系统在设计架构上就被我找到很多问题。

可能真的是由于历史原因吧,以前搜索是一个BU,现在只是大数据里的一个组了,这中间经历了多少改朝换代啊,历史包袱重的无法背负了,只能选择抛弃他了。
在这里插入图片描述
从上面的架构图可以很清晰的看出来这个系统有三个严重问题:

第一个
业务层数据到达队列完全依赖于业务方上报。这本来是件无可厚非的事,你要用搜索引擎,那就得上报数据来。就好比你用数据库,你总得把数据存进去吧。

但这事在公司行不通,历史包袱太沉重。业务方完全不想上报数据,虽然勉强上报,经常增量数据丢失。这一丢失数据导致搜索出不来。最终…

总结下,就是业务方不想上报数据、上报数据总是丢失,锅还得搜索来背。

第二个
数据处理完成直接交付给数据应用,这个问题蛮严重的。数据处理其实意味着会消耗大量的计算资源和时间,而一旦数据应用层服务挂掉或者崩溃,将会导致服务短时间无法恢复。

比如1000w的数据处理需要一个24core机器处理12小时,一旦下游的solr或者RS集群崩溃,把一份全量数据恢复回来,需要数据处理系统重新计算12小时,这恢复时间谁顶的住啊?

由于第一个问题存在,也就是数据上报容易丢失,所以必须依靠全量数据来恢复丢失的增量,我们的近200个业务基本每天都会做一次全量,这可是大把的计算资源浪费啊。

资源浪费一点倒也还好,但是这异常情况下的数据恢复时间确实是个大问题,用户可等不及这么长时间啊。

总结下,就是计算资源浪费,数据应用层服务无法做到无状态,恢复成本高昂。

第三个
数据处理系统耦合度太高,系统太复杂,维护困难。数据处理一般包括数据清洗和业务组装,数据清洗可以算作是业务变化较少的,但是业务组装规则是灵活多变的,这部分经常会由于业务方的变动而产生开发的需求。

业务变动频繁、业务繁多导致系统变得复杂,系统复杂耦合度还很高,导致这个系统维护和开发成本很大,日常需求开发已经成为难题了。

业务场景调查。搜索有很多场景,比如电商场景,内容场景,直播场景。场景很多,公司业务形态上也是都有这些,但不是所有的场景都使用了我们的搜索服务。

要去摸底一下那些没有使用的为啥没用,没用肯定是我们做的不好,摸底的主要目标的就是搞清楚到底哪点不好。深入到业务上去了解,才能更好的设计系统。

新系统设计:前两步骤已经找到了旧系统缺陷和业务问题,新的系统首先要解决之前的问题,其次就是做一些前瞻性的设计。

新系统设计这块包括以下几个步骤:
业务梳理 :这块其实在旧系统摸底和业务调查的时候已经做的差不多了,只需要在精细化的梳理下。

业务抽象 :业务抽象指的是一系列的业务问题,抽象为一种通用的解决方案。这块蛮复杂的,在这块需要花费大量时间。

技术调研 :每一种技术都有他的适用场景。举个例子,使用搜索引擎,到底是用solr还是用es、还是自研呢?这就需要你对技术方案有了解,知道这些技术方案的优缺点,最终才能找出适合业务发展的技术方案。

方案探讨: 好的设计不是一蹴而就的,也不是某个人的智慧象征。好的设计是一群人智慧的结晶,是一个不断迭代的产品,所以需要多讨论。

方案确定 :前面的问题解决了,基本方案差不多也该定下来了。为保证方案不会出现返工情况,你需要再拉上leader开个最终的项目方案评审会加上确定项目排期。

架构图介绍

说了那么多好像还没说到我的设计到底在哪里,接下里就来说说我的设计。

在整个设计中我也做了好几版的设计图,草稿就不放出来了,直接放最终的一版设计方案来说,中间解释的时候会说那些演进的点。

首先我设计这个系统目标有如下:

  • 零上报 指的是数据不依赖业务方上报,有数据变更立刻感知到
  • 准实时 数据变更之后实时进入引擎,提供搜索服务
  • 高吞吐
  • 高容错
  • 低耦合
  • 易维护

这几个目标已经完全解决了之前系统存在的问题,比如上报数据问题,资源浪费问题,紧急恢复时间长的问题。
在这里插入图片描述
整体上我采用了分层设计方案结合微服务的思想,把复杂的问题分层抽象,各层次之间功能单一且分明,耦合度低,维护方便。

当然这样的设计会导致数据链路变得略长,会有多余的网络传输延时。现在的网卡已经够大了,网络传输在这个项目中不是不足为虑。

自上而下,沿着数据流动的方向,逐层解释下为何这么设计:

第一层

业务数据层:这是不变的,一致存在的。目前我们共有快200个业务场景,每个业务方的数据源是不同的,同时也有交叉的,比如商品数据在类目搜索、内容搜索、订单搜索、商品推荐上都使用,他们确是不同的业务场景,数据有交叉也有不同。

但其实这里我们不必太关心业务方的数据来源,不管是何种来源最终都会有一个存储介质,只需要关心数据实际存储在哪里的。

把多种存储介质抽象出来,用一个服务去监听这些介质的数据变更行为,这就是接下来的数据监听层。

第二层

数据监听层:主要负责监听变更的业务数据,把变更的数据获取到,用规定的格式输出到下游队列即可。

第三层

数据缓冲层:数据缓冲一般用在系统与系统之间,通常情况下不要让系统与系统之间直接传递数据,这样的数据传递会有很高的风险,得依赖接收端系统的稳定性。

有了数据缓冲,系统之间就不直接交互数据了,系统之间没什么依赖关系,也不会互相影响。

第四层

数据处理层:这一层最终需要把零散的、不规则的数据处理为一个搜索可用的DOC数据。这块任务蛮艰巨的,当时在讨论这一层的时候,花费了很多时间。

数据处理包括两部分,一部分是一些通用型处理,比如去html标签、数据格式int转string等等处理逻辑;

另一部分是一些变化较多的业务部分,比如一个doc有十五个字段,其中有三个来自A业务,三个来自B业务,而这些来自都是需要实时去业务方拿结果的。

再比如对DOC中的字段会进行一些计算操作,具体计算规则根据业务而定的。

这些操作都很依赖于业务方,变化之多,很难把控。所以这块在设计上需要很灵活。

根据抽取出的这两部分特性,把不变的通用性较强的那部分定义为数据清理,用一个单独服务处理,这里采用spark stream流去实时做数据清洗,处理完成之后输出到kafka队列。

灵活变化的部分用一个单独服务处理,业务变更采用脚本方式动态发布,修改灵活、即时生效。

第五层

数据存储层。故名思义就是做一个存储,前面已经计算好了一个完整的DOC数据。整个计算过程已经耗费了计算资源和时间,所以必须存储起来。一旦数据应用层服务数据异常,可以很及时用这里的数据做恢复。

不需要计算,直接拿过去用,恢复起来成本够低了吧。

有了存储层,既可以保证下游服务可以完全无状态,还可以保证快速恢复,同时还可以用作全量数据。

一边写到存储层,也会一边写到kafka队列,数据应用层需要获取kakka队列数据做增量索引。

整个分层的设计架构就是这样了,中间的业务细节就不一一讲解了。

懂搜索的朋友肯定会说了,这里的整个系统说的都是增量,那全量怎么更新。

这就到点上了,全量我采用了主动触发的方式,可以想一想那些场景需要做一次全量。

  • 业务发生了字段级别的变更,比如增加了一个字段,或者某个字段的全部值发生了变化。
  • 第一次接进来的业务,但已经有很大一部分原始数据。
  • 有大批增量丢失,导致无法通过容错机制恢复,而且不是很确定丢失那些增量。
  • 存储层有脏数据。
  • 数据应用层有脏数据或者异常了。

两种方式做全量,一种是需要计算的,通过增量链路计算做一份全量。另一种是直接通过hbase全量数据来做全量。

hbase有脏数据的情况下只能重新计算,或者清理脏数据。

架构设计注意点

整体的系统架构主要由我完成,系统开发那可是集结了全组的功力。总共用时一个Q出了第一版,目前线上已经跑了好几个业务,最高qps能达到100k,截了一个线上运行的7天业务指标图。
在这里插入图片描述
说下一些注意点,希望对大家有用。

设计前

  • 对业务一定要非常熟悉,这样设计出的系统才能更好的服务业务
  • 多做技术方案调查,只有见的多了你才会思考的多了,思考的多了才会有所见解
  • 多沟通,很多问题自己一个人想着可能很完美,但很可能这时你钻到思维的牛角尖了,沟通能减少这样的错误

设计中

  • 多画架构图,画出来便于你更多的思考,图画更具有渲染和说服力,图片的表达能力比文字强
  • 细节地方一定要画流程图,流程图画得好写代码才能轻松
  • 多做项目评审会,项目评审就是一个产品迭代,只是还没做出产品就已经有迭代了
  • 更多的倾听业务,系统设计是为了解决业务问题,是为业务服务的。你的系统可以不是完美的,但对于业务和用户一定是价值最大的

开发中

  • 线上系统异常处理要完善
  • 测试要完善,功能测试、性能测试都得做
  • 系统监控一定要完善,这个非常重要,没有监控和日志,出了问题就是两眼一抹黑
  • 项目排期一定要做好,一般项目开发都是多人协同开发,不能影响整体排期
  • 有风险及时暴露,这点很重要,很多人在项目中遇到问题或者风险点不敢暴露出来,害怕暴漏出来大家怀疑自己的能力,老板会给低绩效等。想着自己能很快解决,一般遇到风险都很难自己独自解决,不然也不会构成风险。暴露出来,大家群策群力,也不会拖延到项目排期。

上线后

  • 及时关注自己的服务监控指标,一般上线前都会经过测试、压测等,很多人就上线关注一会觉得没问题,就去庆功去了,别把庆功酒喝错了味道。业务是实时变化的,你要根据业务变化确定你的观察时机,正确观察几个周期无误后,才可以确定无误,以防年终奖没了。敏感业务都必须灰度很长时间做观测。
  • 听取反馈意见,收集反馈意见及时迭代自己的产品。
  • 挖掘潜在业务需求,提前布局迭代。

总结

两个重要的点

  • 想清楚在做,想清楚就是指前期需要花费大量的时间去做系统架构调研、讨论,细节构思清楚。我的这个系统设计花在调研、探讨、设计上的时间占据总时间的五分之二。构思和测试的时间是最长的,开发的时间是最短的。前期想的越清楚,开发难度越小。更有甚者,开发到中途发现设计不通,再开始返工。
  • 小步快跑,试错迭代,借用Pony老师的总结。现在互联网公司的项目都是要求很快速上线的,所以在开发上我们需要快速出产品,然后再不断迭代。不能一开始就做一个完美产品,这样用户是等不住的。

事实上不存在一开始做出来就是完美的产品,只有手机大量用户意见,不断迭代、不断改进、不断创新的产品才有可能是好产品。

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

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

相关文章

详解:网络虚拟化卸载加速技术的演进

在传统的应用场景中,服务器资源过剩情况普遍,为了充分利用服务器资源,产生了虚拟化技术。虚拟化技术以牺牲部分效率为代价提升了资源的使用率,将原来需要硬件完成的工作,通过软件模拟的方式,满足多个云租户…

软件测试员如何在恶劣的内卷环境下脱颖而出?

内卷,是现在热度非常高的一个词汇,随着热度不断攀升,隐隐到了“万物皆可卷”的程度。 我一个很要好的朋友,现在就读大三,像很多大学生一样面临着能否顺利毕业的压力和考证的焦虑,看着寝室四个人每天都在玩&…

ShellBrowser Delphi,Delphi组件功能和工具

ShellBrowser Delphi,Delphi组件功能和工具 ShellBrowser基本上被描述为集合的一部分,它能够为用户和开发人员提供Delphi的程序员,以便轻松灵活地访问windows shell性能。ShellBrowserComponents Delphi的使用基本上是能够模拟windows资源管理器的变体。…

gitlab-runner 的安装使用(含 .gitlab-ci.yml 的简单使用)

简介 GitLab Runner 是一个开源项目,用于运行您的作业并将结果发送回 GitLab。它与 GitLab CI 一起使用,GitLab CI 是 GitLab 随附的开源持续集成服务,用于协调作业。 简单理解就是一个服务放在那儿,当你提交代码时,…

Revit修改:网格角度,体量轮廓,梁随斜板

一、Revit中使幕墙系统网格改变角度 绘制幕墙系统时,若幕墙系统出现如下图情况: 若想改变该网格的角度,使其与该幕墙上下边界平行或垂直则选中该幕墙,修改属性栏的中的网格角度。如下图所示: 修改完所需角度后&#xf…

【kafka】五、kafka工作流程

kafka工作流程 工作流程 kafka中消息是以topic进行分类的,生产者生产消息,消费者消费消息,都是面向topic的。 topic是逻辑上的概念,而partition是物理上的概念,每一个partition对应一个log文件,该log文件…

QT中的OpenGLWidget

1、在生成的UI中,通过控件OpenGL Widget来布置相应的空间(后续讲通过promoted widget将此控件与派生的OpenGLWidget进行绑定) 2、添加一个widget类,该类派生于 QOpenGLWidget, QOpenGLFunctions_*_*_Core(*代表版本号…

基于VGG与LSTM实现针对图片的问答任务 数据+代码 可以作为毕设

任务描述:本教程将通过深度学习的方式实现一个简单的视觉问答模型,视觉问答的任务内容是将一张图片和一个自然语言问题作为输入,结合这两种信息,机器生成一条自然语言答案。本教程通过数据准备,视觉问答模型构建,视觉问答模型训练,视觉问答模型评估,视觉问答模型预测等…

嵌入式驱动初级-字符设备驱动基础

文章目录前言一、驱动学习预备知识1.什么是设备驱动程序2.向内核添加新功能方法2.1新功能源码与Linux内核源码不在同目录下2.2在Ubuntu下加载和删除ko文件步骤2.3在开发板下加载和删除ko文件步骤2.4内核模块基础代码解析二、字符设备驱动框架2.1Linux内核对设备的分类2.2字符设…

Python(PyQt5)制作帮助文档查看器(可显示后缀名为md的文件)同时显示文本和图片

先看完整效果图: 帮助文档查看器是很多程序中必备要素,而利用Qt中的QTreeView组件可以很方便的查看文件,而QTextBrowser可以直接显示格式化的MarkDown文本。因此可以利用这两个组件制作一个帮助文件查看器。 未优化 效果图: 问题优化: 你会发现QT treeView列宽设置不成功问题…

2023年系统规划与设计管理师-第二章信息技术知识

1. 软件工程 2. 面向对象 3. 开发模型 4. 开发方法 4.1 敏捷开发方法 4.2 RUP 5. 数据仓库和网络技术 5.1 网络七层结构 5.2 各设备位于哪一次 5.3 各层的协议 5.4 TCP分层 5.5 IPv6 VS IPv4 5.6 IPv4 :A类、B类、C类地址的划分 A类地址的第一组数字为1&#xff5…

255-261BFC,媒体的类型,媒体的特性,浏览器前缀,媒体查询,逻辑操作符,

◼ 有时候可能会看到有些CSS属性名前面带有:-o-、-xv-、-ms-、mso-、-moz-、-webkit- ◼ 官方文档专业术语叫做:vendor-specific extensions(供应商特定扩展) ◼ 为什么需要浏览器前缀了?  CSS属性刚开始并没有成为标准,浏览器为了防止后续会修改名字给新的属性添加了浏…

软件测试面试,一定要准备的7个高频面试题(附答案,建议收藏)

收集了2022年最新的面试题后,负责就业的黑马讲师们整理出了7个高频出现的面试题,一起来看看。 高频问题1:请自我介绍下? 高频问题2:请介绍下最近做过的项目? 高频问题3:请介绍下你印象深刻的…

光学测量精度极限—光谱共焦位移传感器的六大行业应用

科技的不断发展,在半导体,高精密制造领域中都是采用微米及以上的加工工艺,并与之匹配高精度测量技术进行品质控制。光谱共焦的测量原理是一束白光经过镜头将不同的波长聚焦到光轴上,色散地形成一条彩虹状分布带,照射到…

力合精密装备科技:操纵盒按键说明

使用摇杆(操纵盒): 不同的控制系统配备不同样式的操作杆,操作杆最常用的功能是用来手动移动机器来进行测量操作; 一般的操作杆上包含以下功能键: 急停按钮:紧急情况时按下急停按钮停止机器运…

ORB-SLAM2 ---- Tracking::TrackReferenceKeyFrame函数

目录 1.函数作用 2.步骤 3.code 4.函数解析 4.1 将当前帧的描述子转化为BoW向量 4.2 总体解释 1.函数作用 用参考关键帧的地图点来对当前普通帧进行跟踪。 2.步骤 Step 1:将当前普通帧的描述子转化为BoW向量 Step 2:通过词袋BoW加速当前帧与参考帧…

Go运行时的内存分配器以及消耗指定大小的内存(C语言)

对于go语言在运行时的一些内存分配,想要详细的了解,我们会用到自带的runtime.MemStats,有很多具体的细节实现,而不是简单的只看任务管理器中的内存分配。 我们先来看下这个记录内存分配器的结构体 type MemStats struct {Alloc …

一文了解 Go 中的指针和结构体

一文了解 Go 中的指针和结构体前言指针指针的定义获取和修改指针所指向变量的值结构体结构体定义结构体的创建方式小结耐心和持久胜过激烈和狂热。 前言 前面的两篇文章对 Go 语言的基础语法和基本数据类型以及几个复合数据类型进行介绍,本文将对 Go 里面的指针和结…

MySQL索引底层数据结构

索引简介 索引是一个排好序的数据结构,包含着对数据表里所有记录的引用指针,如下图所示。索引文件和数据文件一样都存储在磁盘中,数据库索引的目的是在检索数据库时,减少磁盘读取次数。 常见的索引数据结构包括二叉树、红黑树、…

跬智信息 (Kyligence) 荣获信创“大比武”重要奖项,坚持做大做实国产软件

近日,为期两个月的 2022 信创“大比武”活动圆满闭幕。经过层层筛选和考核,跬智信息 (Kyligence) 凭借“企业级智能多维数据分析解决方案”项目脱颖而出,在整体方案的技术架构、服务体系、安全架构、信创生态等方面得到了评委的高度认可&…