看了下自己上一次发技术文还是在6月15日,算了算也是两个来月了。别怕,短暂的离开,是为了更好的相遇。

来到新公司以后啊,发现公司的搜索业务是真的太多了,大大小小有几百个搜索业务。来了之后得先梳理、熟悉业务,才能有所产出嘛。

但是,在工作了大概一个月的时候,优秀的龙叔发现,这组内的系统优化空间很大啊,简直可以说巨大啊。

所以说,即便是完善的大公司,机会也是有的,大家在自己的工作岗位上也要好好把握机会。在公司想要得到好的提升,主要有三方面可以发力:

  • 第一、直接业务价值显著,比如具体的PV、UV值提升了多少个点;
  • 第二、系统架构迭代升级或者重构,间接带来了用户体验、或者业务价值;
  • 第三、技术突破,在某个领域方向上做到技术突破或者创新;

小伙伴们,升职加薪指日可待啊...

这些系统都是历史包袱沉重啊,是不是感觉历史包袱这个词很熟悉,对于去搞一些历史包袱很沉重的工程,我们惯用的方法是是什么呢?当然是直接重构

这对于工作不满一年的龙叔来说还是蛮有挑战的,但咱不怕,去做更具挑战性的事,才能更好的锻炼我们的能力,才会意义非凡。

反复思考,反复琢磨了几天后,向leader提出了系统重构的大致方案。一般在公司你想做什么都可以和leader提出来,互联网公司还是比较open的,但是leader会不会采纳你的方案就不一定了。

其实,龙叔对于自己已经画了很多方案图,调查很多业务场景、做了很多讨论之后做的方案还是蛮有信心的。

做就做好准备,不然就是浪费机会。

好了,接下来就不废话了,从几个方面说说这次系统设计:

背景介绍

大家都知道龙叔是做搜索的,所以这次的系统肯定是和搜索相关的,先和大家唠唠搜索整体链路,搜索链路主要分这几个部分,给大家画个图。

搜索引擎链路都包含这三部分,数据源、搜索引擎服务、搜索业务。是不是很简单,感觉搜索也没那么难。

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

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

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

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

设计步骤

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

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

这部分主要从以下几个步骤发力:

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

可能真的是由于历史原因吧,以前搜索是一个BU,现在只是大数据里的一个组了,这中间经历了多少改朝换代啊,历史包袱重的无法背负了,只能选择抛弃他了。

从上面的架构图可以很清晰的看出来这个系统有三个严重问题:

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

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

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

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

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

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

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

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

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

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

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

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

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

新系统设计这块包括以下几个步骤:

业务梳理 这块其实在旧系统摸底和业务调查的时候已经做的差不多了,只需要在精细化的梳理下。

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

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

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

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

架构图介绍

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

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

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

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

这几个目标已经完全解决了之前系统存在的问题,比如上报数据问题,资源浪费问题,紧急恢复时间长的问题。

整体上我采用了分层设计方案结合微服务的思想,把复杂的问题分层抽象,各层次之间功能单一且分明,耦合度低,维护方便。

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

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

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

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

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

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

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

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

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

数据处理包括两部分,一部分是一些通用型处理,比如去html标签、数据格式int转string等等处理逻辑;另一部分是一些变化较多的业务部分,比如一个doc有十五个字段,其中有三个来自A业务,三个来自B业务,而这些来自都是需要实时去业务方拿结果的。再比如对DOC中的字段会进行一些计算操作,具体计算规则根据业务而定的。

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

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

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

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

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

有了存储层,既可以保证下游服务可以完全无状态,还可以保证快速恢复,同时还可以用作全量数据。龙su简直是个设计天才,前途无量啊....

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

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

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

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

第一、业务发生了字段级别的变更,比如增加了一个字段,或者某个字段的全部值发生了变化。

第二、第一次接进来的业务,但已经有很大一部分原始数据。

第三、有大批增量丢失,导致无法通过容错机制恢复,而且不是很确定丢失那些增量。

第四、存储层有脏数据。

第五、数据应用层有脏数据或者异常了。

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

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

架构设计注意点

整体的系统架构主要由我完成,系统开发那可是集结了全组的功力。总共用时一个Q出了第一版,目前线上已经跑了好几个业务,最高qps能达到100k,截了一个线上运行的7天业务指标图。

说下一些注意点,希望对大家有用。

设计前

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

设计中

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

开发中

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

上线后

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

总结

龙su是第一次做系统性设计,两个重要的点给大家说说

第一、想清楚在做,想清楚就是指前期需要花费大量的时间去做系统架构调研、讨论,细节构思清楚。我的这个系统设计花在调研、探讨、设计上的时间占据总时间的五分之二。构思和测试的时间是最长的,开发的时间是最短的。前期想的越清楚,开发难度越小。更有甚者,开发到中途发现设计不通,再开始返工。

第二、小步快跑,试错迭代,借用Pony老师的总结。现在互联网公司的项目都是要求很快速上线的,所以在开发上我们需要快速出产品,然后再不断迭代。不能一开始就做一个完美产品,这样用户是等不住的。

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

我是龙su,一个在互联网大器晚成的帅叔叔,我们下期见。

工作不到一年,做出了100k系统,老板给我升职加薪的更多相关文章

  1. 前端程序员:月薪 5K 到 5 万,我干了啥

    高贵的前端程序猿们: 如何在前端开发这种高精尖的技术领域找到心仪的工作?实现在咖啡馆喝喝咖啡敲敲代码就能升职加薪.买房买车.迎娶白富美走上人生巅峰的职业梦想?这篇<进化论:从 0 到 100,前 ...

  2. 《杜拉拉升职记》//TODO

    目录 简介 杜拉拉升职记 杜拉拉2-年华似水 杜拉拉3-我在这战斗的一年里 杜拉拉大结局-与理想有关 结束语 简介 作者李可,女作家,某名校本科毕业,十余年外企生涯,职业经理人,"李可&qu ...

  3. 工作的思考十五:升职前需要做的准备(TeamLeader)

    当一个人在公司的工作年限以及经验的积累到达一个程度的时候,升职其实是件高兴的事,但面临角色的转变需要提前做些准备的. 其实如果你对你的职业规划很清楚的话,那么你就应该在升职之前就会开始进行角色的转换. ...

  4. SQL Server DBA工作内容详解

    在Microsoft SQL Server 2008系统中,数据库管理员(Database Administration,简称为DBA)是最重要的角色.DBA的工作目标就是确保Microsoft SQ ...

  5. 一位10年Java工作经验的架构师聊Java和工作经验

    从事近十年的 JavaEE 应用开发工作,现任阿里巴巴公司系统架构师.对分布式服务架构与大数据技术有深入研究,具有丰富的 B/S 架构开发经验与项目实战经验,擅长敏捷开发模式.国内开源软件推动者之一, ...

  6. 使用VSTS的Git进行版本控制(二)——提交保存工作

    使用VSTS的Git进行版本控制(二)--提交保存工作 当对文件进行更改时,Git将在本地仓库中记录更改.可以通过选择变更来提交的对应更改.提交总是针对本地的Git仓库,因此不必担心提交是完美的,或者 ...

  7. 作为一名IT从业者,你在工作和学习中,遇到哪些问题

    版权声明:襄阳雷哥的版权声明 https://blog.csdn.net/FansUnion/article/details/28448975 大家都是IT从业者,遇到的问题多少与类似. 假设能把这些 ...

  8. 转:一位10年Java工作经验的架构师聊Java和工作经验

    黄勇( 博客),从事近十年的 JavaEE 应用开发工作,现任阿里巴巴公司系统架构师.对分布式服务架构与大数据技术有深入研究,具有丰富的 B/S 架构开发经验与项目实战经验,擅长敏捷开发模式.国内开源 ...

  9. ()IT 职场经验)一位10年Java工作经验的架构师的经验分享,感觉很受用。

    阿里巴巴技术大牛黄勇的经验分享,感觉很受用. 关于IT 职场经验 1. 把技术当成工具 技术这东西,其实一点都不神秘,它只不过是一个工具,用这个工具可以帮助我们解决实际问题,就这么简单. 我们每天在面 ...

随机推荐

  1. 【NOIP2017】跳房子 题解(单调队列优化线性DP)

    前言:把鸽了1个月的博客补上 ----------------- 题目链接 题目大意:机器人的灵敏性为$d$.每次可以花费$g$个金币来改造机器人,那么机器人向右跳的范围为$[min(d-g,1),m ...

  2. 阿里Canal中间件的初步搭建和使用

    一.前言 Binlog是MySQL数据库的二进制日志,用于记录用户对数据库操作的SQL语句(除了数据查询语句)信息.而Binlog格式也有三种,分别为STATEMENT.ROW.MIXED.STATM ...

  3. Mixed Precision Training —— caffe-float16

    简介 最近有了突如其来的想法,如何把caffe的变得更小更快.后来翻到Nvidia开发caffe-float16,同时也看到它的论文.看完大致了解一番后,就做一下记录. 该工作的目标是,减少网络的所需 ...

  4. webgl实现发光线框(glow wireframe)效果

    在之前这篇文章, WebGL 单通道wireframe渲染 我们介绍了webgl如何实现单通道wireframe的效果. 本篇文章就是在此技术原理基础之上,来实现发光的wireframe效果. 要实现 ...

  5. C#LeetCode刷题之#389-找不同(Find the Difference)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4062 访问. 给定两个字符串 s 和 t,它们只包含小写字母. ...

  6. .Net 桌面程序(winform,wpf,跨平台avalonia)打安装包部署到windows 入门

    .Net 桌面程序(winform,wpf,跨平台avalonia)部署到windows 入门 本文以为avalonia为例,用Setup Factory 将.Net桌面程序(winform,wpf, ...

  7. Umlet和draw.io 使用心得

    文章目录 软件使用心得 1. Umlet 画图软件 1.1 前言 1.2 优点 1.3使用小trick 1.3.1 灵活改变箭头形式 1.3.2 整体复制 1.3.3 快速复制 2. draw.io ...

  8. 使用 VMware Workstation Pro 让 PC 提供云桌面服务——学习笔记(一)

    最终效果: 能够通过xshell等终端设备, 远程访问虚拟机 操作步骤 1. 安装VMware 网上自行下载VMware 软件,这里不给出详细操作 2. 下载安装系统 这里使用 Centos 的lin ...

  9. Mybatis——ResultMap(结果集映射)的使用

    ResultMap的使用 在Mybatis中,可以使用resultMap(结果集映射)作为sql的返回类型 一般用来解决如下问题: 数据库表字段名和实体类属性名不一致的问题: 多对一问题: 例如:多个 ...

  10. Name jms can't bind to context问题解决

    需要把gis-datamanage包中的配置test改成compile