极牛技术分享活动
极牛技术实践分享系列活动是极牛联合顶级VC、技术专家,为企业、技术人提供的一种系统的线上技术分享活动。
每期不同的技术主题,和行业专家深度探讨,专注解决技术实践难点,推动技术创新。隔周三20点通过极牛线上技术分享群准时开课。欢迎各个机构、企业的行业专家、技术人报名参加。
本期主题
垂类搜索引擎的架构
嘉宾介绍
郭涛,深圳市有信网络技术有限公司技术总监,枫藤互动技术有限公司CEO。技术路线为自然语言处理、搜索架构、推荐算法、机器学习。12年-14年,高德搜索引擎团队资深工程师;14年-16年百度LBS事业部位置大数据部技术经理。目前专注于技术管理、产品研发、团队管理。本科毕业于华中科技大学,硕士毕业于中国科学院。
大家好。我叫郭涛,目前是深圳市有信网络技术有限公司总监,北京枫藤互动技术有限公司CEO。在高德地图从事过地图搜索引擎的开发,在百度从事过搜索引擎、推荐引擎的开发和技术管理。有创业经验,而且目前也在创业中。很荣幸能和各位分享技术,希望大家多多交流,相互学习。
目前,以C++为语言,专门从事复杂的搜索引擎的团队确实不多了。现在后台大多使用java、php,因为更加快捷,这也是技术的进步。C++、C更为底层,对CPU资源的控制、内存的控制更加直接和随意,因此用来实现高效的算法是很合适的,当然也很危险,一个core文件都可能好几十G,core出来都需要十几分钟,而且你压根不知道怎么回事。所以对工程师而言,也确实更加受虐。但是我觉得对这类技术的了解还是很有必要的,无论大家的主流的工具是java还是php、python,了解这类业务的对后续自己实现复杂的业务逻辑有帮助。
我之前完整的经历过一套搜索引擎、一套推荐引擎的研发工作。现在就高德地图搜索引擎的构建逻辑和业务逻辑分享给大家。当然,一套完整的搜索引擎的细节其实有很多的,但就一个分词,就足够说上1-2个小时。而且里面除了架构之外,还有大量的nlp处理、排序算法、索引结构,我们一次分享也不可能说的很细致。但是我尽可能在架构层面上把一些点说到。
当时我们希望新的引擎,能达到以下目标:
1、相同机器的情况下,qps由原来的200上升到1000,单个请求的平均耗时控制的50ms;
2、优化搜索效果,整体的ndcg评测能上升10%以上;
整体的架构图如下:
Broker:
Broker 做为引擎的唯一入口,包括如下几个功能:
1、 检索流程调度:
接收和解析前端下发的查询请求,结合query processor 语义分析的结果,调度整个检索流程,返回检索结果给前端。
2、 对下游模块的调度管理,做到对下游的负载均衡和服务容错。
3、 整合排序:
根据下游searcher返回结果和离线调权模块weight trimmer的结果、结合产品的特殊需要进行整合排序,挑出最好的结果。
4、 运营服务数据的统计上报,支持监控。
Broker 模块存在的意义:
1、 broker 模块做为引擎的唯一入口,可以给我们提供完备的实时统计数据,这些完备的实时统计数据,可以支持对系统的实时监控,也可以让我们更好的了解系统的运营情况。
2、 对于一次检索来说,broker 是当次检索的数据汇聚点(searcher 是整个系统的数据的汇聚点, broker 是当次检索的数据的汇聚点),我们可以从 broker 中落地一些中间数据,这些数据可以提供给我们离线做一些挖掘,甚至是一些实时的挖掘,而这些挖掘又可以指导我们下一次的检索。
3、 提高系统的稳定性:用 broker 做下游模块的调度管理之后(动态负载均衡、下游服务器的异常处理),可以极大的提高整个引擎的稳定性;老系统是由运维的同事在 sisserver 模块之上做了一个容错的功能,由于各种原因,其对系统异常状态的识别和处理的灵敏性都不可能太高。
query processor:
query processor子系统,相当于语义分析系统。主要处理对查询含义的理解,它做的工作主要包括以下方面:
1、基本的nlp处理,其中包括分词、纠错、近义词;
2、GEO地理编码分析;
3、查询方案的理解。
GEO地理编码是地图类搜索引擎特有的nlp系统,主要是当用户输入一个地址之后,它能智能的分析出搜索词的“地址片段”,并将其转化成地图的经纬度坐标表。比如当用户输入“我在北京,我想要去香格里拉,云南的”,那么GEO系统就需要抽象出目的地是“云南省香格里拉”,起点是“北京市”。GEO系统是一套非常复杂的系统,里面有完整的索引、语义分析,相当于一个小的搜索引擎。
“查询方案”怎么理解呢?
大家平时用地图可能不会怎么关注,认为地图的搜索应该不难。其实还是挺难的。比如当你在北京输入“香格里拉”,那么计算机就需要分析出你真正的意图是什么,比如有以下几种可能:
1、北京的香格里拉酒店、所有带香格里拉的商铺;
2、云南的香格里拉;
比如用户输入“北京海淀医院”,那么也有几种可能:
1、用户是想去“海淀医院”;
2、用户是想看看在海淀区的所有医院;
这些查询意图的理解,随着用户输入的随意,输入查询词的量逐步扩大,系统也越来越复杂了。
至于分词、纠错、近义词,这些偏传统的nlp处理,这里不做深入分析了。因为这类研究太深了。只是这里可以分享的是,商业化的搜索引擎,对传统的nlp处理,一般是数据 > 规则 > 算法。完善的丰富的数据+精细化的规则+算法辅助,才能保证95%以上的准确率。传统的nlp算法一般是70%左右的准确率(类似命名实体识别),这样是不能达到商业化要求的。说白了,就是会被老板天天骂。
Searcher:
Searcher 模块为整个引擎提供基础检索,其包括的主要功能如下:
1、 提供基础检索
接收 broker 传下来的语法树,获取对应的索引数据,进行语法运算,最后返回 n 条结果给 broker
2、 支持实时数据更新
searcher 为了能够支持实时数据更新,同时为了避免去修改大索引,searcher 维护两个索引表,分别是大索引和实时索引。实时数据更新的时候,searcher 只需要修改实时索引(由于实时索引一般不会很大,所以修改实时索引的代价不是很大),当实时索引变的很大的时候,会通知 indexer 离线合并索引,然后在分镜像的推送给各个 searcher。
3、 基础相关性计算
基础相关性计算只负责在线计算当次检索出来的 doc 的权重,不负责最终的排序。
index:
一、索引子系统主要包括三个功能:
1、 做为实时数据更新的客户端:
indexer 周期性的从数据库拉取需要更新的数据,生成更新请求发送给 searcher 模块。
2、 建增量索引:
建增量索引的目的是把目前需要上线提供服务的数据建成一套统一的索引,和目前 lse 里面把三个索引进行合并的目的是一样的。
建增量索引的触发条件是:①每天凌晨周期性的触发;②searcher中的实时索引的数据量很大的时候(searcher 只有一个大索引和一个实时索引)。③人工触发;主要目的是提供一个人可以控制的接口 (场景:分词上线版本)
3、 建全量索引:
全量索引和增量索引的目的是一样的,不同的地方是:全量索引需要从 DB 中获取原始数据,增量索引可以从本地获取原始数据。
全量索引由于要从 DB 中读取大量的数据,所以建数据的过程会比较长。
全量索引只有在发现之前上线的数据有大量错误,或者是部署 indexer 和 searcher 服务器全部死掉的情况下才会触发,触发的概率极低。
下图,展示出一个完整请求的处理流程:
首先讲一下架构。无论是broker、query processor、searcher,都是可以横向扩展的服务器。当哪一个部分遇到了瓶颈,就往哪一个部分部署机器就ok。这样的设计保证后续扩容的方便。
各个系统之间处理请求,是“异步”的。这个异步和我们在端口请求之前的异步不一样。这个异步是从业务上理解而言的。举个例子。假设我们去医院,我们一般是先挂号、之后是问诊、化验、回诊、付款、取药。如果医院的服务人员的处理,是来一个病人,通通走完流程之后,再服务下一个,我们认为这是“同步”的,这种方式非常低效,但是一个优点是,用户不需要记录自己的信息,比如现在到哪一步了,因为医院一直在为你一个人服务,医院会记录你的进度信息。
而现实中不是如此。用户每个人都有自己的一个“病例”和医院的流程单,用户自己记录着下一步应该做什么,而医院里不再记录。这样医院中的资源就独立服务所有用户。用户自己决定自己的流程,这就是异步。
在搜索引擎中,比如broker,在队列中抽取出来的request就有可能是不同的请求,比如“需要语义解析”、“需要排序”、这样,每次抽取出来请求包之后,程序会根据请求的id从用户信息池中抽取出相应的处理信息,并得出下一步应该做什么,然后再转发到相应的模块处理。所以,同一个服务,同一个线程,在这样的架构里面,有可能是在处理完全不同的事情。
接下来我们说一下searcher:
seacher的主要工作是基础检索处理。模块的输入是broker发送的基础检索请求;输出是基础检索结果,结果主要包括召回的docid+weight列表。模块主要功能包括:①解析基础检索请求包,构造查询语法树;②根据查询语法树读取倒排数据,做语法运算;③根据检索结果做重查和模糊匹配;④对语法运算的结果做基础赋权;⑤根据基础赋权得分选取前1000条结果返回给broker。如果结果不足1000条则全部返回。
这里面有一些名词,大家可能不是很明白,比如语法树,比如模糊匹配。大家可以不用太纠结。如果有人有兴趣,我后续再答复各位。简而言之,searcher的主要功能是读取倒排索引,接收查询词信息,然后根据查询词的语义分析信息,查找到对应的地址,然后对找到的各种地址排序,之后返回。
最后介绍一下weight trimmer。其实就是一个调权系统。我们会把大量的查询词抽取出来,然后去输入到我们竞争对手的地图搜索系统中,爬取出对方的结果,然后对结果进行干预调权。也就是,某一个结果在竞争对手那边的排序,会作为我们本次请求结果排序的一个因子。如果在竞争对手那里排名靠前,在我们这边排名也不会落后到那里去,反之亦然。这样可以大量的解决掉一些长尾的badcase。使得搜索质量提升。
整体的架构介绍就是如此。这个架构是从google那边继承过来的一个变形体。很多网页搜索系统也是同样的架构,只是网页的数据量更大而已。
在此,仅仅只是比较简单的介绍了整体的架构和用途。关于里面的细节,大家有想了解的可以和我继续交流。关于搜索算法、推荐引擎、nlp、数据挖掘方面都可以。关于如何去学习、进阶,也可以和我交流。谢谢!
Q&A
Q1:垂直搜索使用哪些常用算法
A1:搜索引擎是一整套架构,里面任何一个模块都设计到不少算法。比如说索引就涉及到数据结构的设计,检索系统设计到语法书的数据结构设计、排序算法用到了机器学习训练、分词系统用到了HMM、CRF等算法,空间索引有四分数、GEOHash等等,算法太多了。
Q2:数据存储,持久存储与缓存选择哪些?
A2:我们存储数据,就是内存和硬盘。至于持久存储,我了解不多,对不同的介质似乎不同,我之前了解有光盘矩阵涉及到持久存储的,我们没有涉及到那么多的存储介质。而且搜索引擎,除了原始数据是存在数据库里面,其余所有的数据不是数据库存的,例如100多G的索引直接就是文件存储。对于部分高频需求我们需要缓存加速,缓存当时也不是用的redis,而是自己写的一套缓存系统,因为我们对于缓存的策略有自己的需求,而且也没有设计到分布式,也不希望落地存储。只有完全内存才能达到我们的速度要求。
Q3:老引擎和索引技术自己实现还是使用第三方?
A3:无论是新老引擎,索引结构设计和检索流程都是自己实现的,没有用到第三方库或者服务。
Q4:创业公司技术能力有限,推荐和机器学习,如何选择合适的第三方服务?
A4:问题中提到了推荐和机器学习。这里分开说。推荐服务是一个强产品的技术类服务,推荐算法的结构和搜索还不同,搜索的架构,不同的产品之间相似性可能还不少,但是推荐的服务在不同的产品之间可能就很不同。推荐技术业内也都说:先有推荐产品,后有推荐架构和算法。所以,产品不同,哪怕是自身的架构和需求差异都很大,也就不存在统一和固定的第三方服务了。
目前我只知道百度开放了自己的推荐架构和算法,但是一般业务放都不会使用。因为自由根据自身业务定制化的推荐服务才是最好的。至于机器学习,目前大多都是开放的算法架构。没有统一提供第三方服务的。因为这类算法太底层,从底层到最上层的业务,这中间的业务形态变化太多,没有很好的办法标准化,所以也不可能像云服务一样提供服务。一般都是找到相应的算法架构,然后根据自己的业务设置参数,结合自己的数据训练,结果的好坏取决于对业务的理解和对模型的熟悉程度。
报名请关注极牛公号并回复技术分享
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。