工作不到一年,做出了100k系统,老板给我升职加薪
看了下自己上一次发技术文还是在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系统,老板给我升职加薪的更多相关文章
- 前端程序员:月薪 5K 到 5 万,我干了啥
高贵的前端程序猿们: 如何在前端开发这种高精尖的技术领域找到心仪的工作?实现在咖啡馆喝喝咖啡敲敲代码就能升职加薪.买房买车.迎娶白富美走上人生巅峰的职业梦想?这篇<进化论:从 0 到 100,前 ...
- 《杜拉拉升职记》//TODO
目录 简介 杜拉拉升职记 杜拉拉2-年华似水 杜拉拉3-我在这战斗的一年里 杜拉拉大结局-与理想有关 结束语 简介 作者李可,女作家,某名校本科毕业,十余年外企生涯,职业经理人,"李可&qu ...
- 工作的思考十五:升职前需要做的准备(TeamLeader)
当一个人在公司的工作年限以及经验的积累到达一个程度的时候,升职其实是件高兴的事,但面临角色的转变需要提前做些准备的. 其实如果你对你的职业规划很清楚的话,那么你就应该在升职之前就会开始进行角色的转换. ...
- SQL Server DBA工作内容详解
在Microsoft SQL Server 2008系统中,数据库管理员(Database Administration,简称为DBA)是最重要的角色.DBA的工作目标就是确保Microsoft SQ ...
- 一位10年Java工作经验的架构师聊Java和工作经验
从事近十年的 JavaEE 应用开发工作,现任阿里巴巴公司系统架构师.对分布式服务架构与大数据技术有深入研究,具有丰富的 B/S 架构开发经验与项目实战经验,擅长敏捷开发模式.国内开源软件推动者之一, ...
- 使用VSTS的Git进行版本控制(二)——提交保存工作
使用VSTS的Git进行版本控制(二)--提交保存工作 当对文件进行更改时,Git将在本地仓库中记录更改.可以通过选择变更来提交的对应更改.提交总是针对本地的Git仓库,因此不必担心提交是完美的,或者 ...
- 作为一名IT从业者,你在工作和学习中,遇到哪些问题
版权声明:襄阳雷哥的版权声明 https://blog.csdn.net/FansUnion/article/details/28448975 大家都是IT从业者,遇到的问题多少与类似. 假设能把这些 ...
- 转:一位10年Java工作经验的架构师聊Java和工作经验
黄勇( 博客),从事近十年的 JavaEE 应用开发工作,现任阿里巴巴公司系统架构师.对分布式服务架构与大数据技术有深入研究,具有丰富的 B/S 架构开发经验与项目实战经验,擅长敏捷开发模式.国内开源 ...
- ()IT 职场经验)一位10年Java工作经验的架构师的经验分享,感觉很受用。
阿里巴巴技术大牛黄勇的经验分享,感觉很受用. 关于IT 职场经验 1. 把技术当成工具 技术这东西,其实一点都不神秘,它只不过是一个工具,用这个工具可以帮助我们解决实际问题,就这么简单. 我们每天在面 ...
随机推荐
- IC行业常见用语
https://www.cnblogs.com/yeungchie/ Active Devices 有源器件 MOSFET Metal-Oxide-Semicoductor Field-Effect ...
- 为什么switch不支持long
switch 支持的类型 在 Java 语言规范里中,有说明 switch 支持的类型有:char.byte.short.int.Character.Byte.Short.Integer.String ...
- Spring学习总结(8)-接口多个实现类的动态调用
需求描述:当一个接口有2个以上的实现类时,调用方需要根据参数选择只其中一个实现类 Spring版本:5.1.8.RELEASE 1. 接口和实现类 /** * 接口 */ public interfa ...
- C 语言学习 -1
头文件 stdio.h stdlib.h sting.h 先学习上面三个头文件: 1: stdio.h 这个头文件包含了 程序与外界数据交互的各种函数 说白了就是 用来处理 输入/输 ...
- requests-html库轻体验-HTMLSession下载表情包
requests-html实战,HTMLSession下载斗图啦最新表情包 前言 在这篇文章之前,我写了requests入门实践02_下载斗图拉最新表情包用正则表达式提取url,来下载斗图啦最新表情包 ...
- 【av68676164(p31-p32)】Windows和Linux同步机制
4.6.1 Windows同步机制 临界区(CRITICAL_SECTION) 在进程内使用,保证仅一个线程可以申请到该对象 临界区内是临界资源的访问 相关的API函数 初始化临界区 WINBASEA ...
- Python 进程与多线程
10 进程和多线程 10.1 多进程 # -*- coding: utf-8 -*- import os pid=os.fork() print ('process (%s)start ...' %o ...
- vue+element树形结构右键菜单
环境:vue-admin-template vue 2.6.10 element-ui 2.7.0 1.自定义组件,文件位置:src/components/mentContext <temp ...
- 【面经】超硬核面经,已拿蚂蚁金服Offer!!
写在前面 很多小伙伴都反馈说,现在的工作不好找呀,也不敢跳槽,在原来的岗位上也是战战兢兢!其实,究其根本原因,还是自己技术不过关,如果你技术真的很硬核,怕啥?想去哪去哪呗!这不,我的一个读者去面试了蚂 ...
- Python 使用BrowserMob Proxy + selenium 获取Ajax加密数据
BrowserMob Proxy,简称 BMP,它是一个 HTTP 代理服务,我们可以利用它截获 HTTP 请求和响应内容. 第一步:先安装 BrowserMob Proxy 的包. pip inst ...