首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >美团点评广告实时索引的设计与实现

美团点评广告实时索引的设计与实现

作者头像
美团技术团队
发布于 2018-06-07 03:58:49
发布于 2018-06-07 03:58:49
2.7K0
举报
文章被收录于专栏:美团技术团队美团技术团队

总第243篇

2018年 第35篇

背景

在线广告是互联网行业常见的商业变现方式。从工程角度看,广告索引的结构和实现方式直接决定了整个系统的服务性能。本文以美团点评的搜索广告系统为蓝本,与读者一起探讨广告系统的工程奥秘。

领域问题

广告索引需具备以下基本特性:

  1. 层次化的索引结构
  2. 实时化的索引更新

层次投放模型

一般地,广告系统可抽象为如下投放模型,并实现检索、过滤等处理逻辑。

该层次结构的上下层之间是一对多的关系。一个广告主通常创建若干个推广计划,每个计划对应一个较长周期的KPI,比如一个月的预算和投放地域。一个推广计划中的多个推广单元分别用于更精细的投放控制,比如一次点击的最高出价、每日预算、定向条件等。广告创意是广告曝光使用的素材,根据业务特点,它可以从属于广告主或推广计划层级。

实时更新机制

层次结构可以更准确、更及时地反应广告主的投放控制需求。投放模型的每一层都会定义若干字段,用于实现各类投放控制。广告系统的大部分字段需要支持实时更新,比如审核状态、预算上下线状态等。例如,当一个推广单元由可投放状态变为暂停状态时,若该变更没有在索引中及时生效,就会造成大量的无效投放。

业界调研

目前,生产化的开源索引系统大部分为通用搜索引擎设计,基本无法同时满足上述条件。

  • Apache Lucene
    • 全文检索、支持动态脚本;实现为一个Library
    • 支持实时索引,但不支持层次结构
  • Sphinx
    • 全文检索;实现为一个完整的Binary,二次开发难度大
    • 支持实时索引,但不支持层次结构

因此,广告业界要么基于开源方案进行定制,要么从头开发自己的闭源系统。在经过再三考虑成本收益后,我们决定自行设计广告系统的索引系统。

索引设计

工程实践重点关注稳定性、扩展性、高性能等指标。

设计分解

设计阶段可分解为以下子需求。

实时索引

广告场景的更新流,涉及索引字段和各类属性的实时更新。特别是与上下线状态相关的属性字段,需要在若干毫秒内完成更新,对实时性有较高要求。

用于召回条件的索引字段,其更新可以滞后一些,如在几秒钟之内完成更新。采用分而治之的策略,可极大降低系统复杂度。

  • 属性字段的更新:直接修改正排表的字段值,可以保证毫秒级完成
  • 索引字段的更新:涉及更新流实时计算、倒排索引等的处理过程,只需保证秒级完成

此外,通过定期切换全量索引并追加增量索引,由索引快照确保数据的正确性。

层次结构

投放模型的主要实体是广告主(Advertiser)、推广计划(Campaign)、广告组(Adgroup)、创意(Creative)等。其中:

  • 广告主和推广计划:定义用于控制广告投放的各类状态字段
  • 广告组:描述广告相关属性,例如竞价关键词、最高出价等
  • 创意:与广告的呈现、点击等相关的字段,如标题、创意地址、点击地址等

一般地,广告检索、排序等均基于广告组粒度,广告的倒排索引也是建立在广告组层面。借鉴关系数据库的概念,可以把广告组作为正排主表(即一个Adgroup是一个doc),并对其建立倒排索引;把广告主、推广计划等作为辅表。主表与辅表之间通过外键关联。

  1. 通过查询条件,从倒排索引中查找相关docID列表
  2. 对每个docID,可从主表获取相关字段信息
  3. 使用外键字段,分别获取对应辅表的字段信息

检索流程中实现对各类字段值的同步过滤。

可靠高效

广告索引结构相对稳定且与具体业务场景耦合较弱,为避免Java虚拟机由于动态内存管理和垃圾回收机制带来的性能抖动,最终采用C++11作为开发语言。虽然Java可使用堆外内存,但是堆外堆内的数据拷贝对高并发访问仍是较大开销。项目严格遵循《Google C++ Style》,大幅降低了编程门槛。

在“读多写少”的业务场景,需要优先保证“读”的性能。检索是内存查找过程,属于计算密集型服务,为保证CPU的高并发,一般设计为无锁结构。可采用“一写多读”和延迟删除等技术,确保系统高效稳定运转。此外,巧妙利用数组结构,也进一步优化了读取性能。

灵活扩展

正排表、主辅表间的关系等是相对稳定的,而表内的字段类型需要支持扩展,比如用户自定义数据类型。甚至,倒排表类型也需要支持扩展,例如地理位置索引、关键词索引、携带负载信息的倒排索引等。通过继承接口,实现更多的定制化功能。

逻辑结构

从功能角度,索引由Table和Index两部分组成。如上图所示,Index实现由Term到主表docID的转换;Table实现正排数据的存储,并通过docID实现主表与辅表的关联。

分层架构

索引库分为三层:

  1. 接口层:以API方式对外提供索引的构建、更新、检索、过滤等功能
  2. 能力层:实现基于倒排表和正排表的索引功能,是系统的核心
  3. 存储层:索引数据的内存布局和到文件的持久化存储

索引实现

本节将自底向上,从存储层开始,逐一描述各层的设计细节和挑战点。

存储层

存储层负责内存分配以及数据的持久化,可使用mmap实现到虚拟内存空间的映射,由操作系统实现内存与文件的同步。此外,mmap也便于外部工具访问或校验数据的正确性。

将存储层抽象为分配器(Allocator)。针对不同的内存使用场景,如对内存连续性的要求、内存是否需要回收等,可定制实现不同的分配器。

以下均为基于mmap的各类分配器,这里的“内存”是指调用进程的虚拟地址空间。实际的代码逻辑还涉及复杂的Metadata管理,下文并未提及。

简单的分配策略

  • LinearAllocator
    • 分配连续地址空间的内存,即一整块大内存;当空间需要扩展时,会采用新的mmap文件映射,并延迟卸载旧的文件映射
    • 新映射会导致页表重新装载,大块内存映射会导致由物理内存装载带来的性能抖动
    • 一般用于空间需求相对固定的场景,如HashMap的bucket数组
  • SegmentAllocator
    • 为解决LinearAllocator在扩展时的性能抖动问题,可将内存区分段存储,即每次扩展只涉及一段,保证性能稳定
    • 分段导致内存空间不连续,但一般应用场景,如倒排索引的存储,很适合此法
    • 默认的段大小为64MB

集约的分配策略

频繁的增加、删除、修改等数据操作将导致大量的外部碎片。采用压缩操作,可以使占用的内存更紧凑,但带来的对象移动成本却很难在性能和复杂度之间找到平衡点。在工程实践中,借鉴Linux物理内存的分配策略,自主实现了更适于业务场景的多个分配器。

  • PageAllocator
    • 页的大小为4KB,使用伙伴系统(Buddy System)的思想实现页的分配和回收
    • 页的分配基于SegmentAllocator,即先分段再分页

在此简要阐述伙伴分配器的处理过程,为有效管理空闲块,每一级order持有一个空闲块的FreeList。设定最大级别order=4,即从order=0开始,由低到高,每级order块内页数分别为1、2、4、8、16等。分配时先找满足条件的最小块;若找不到则在上一级查找更大的块,并将该块分为两个“伙伴”,其中一个分配使用,另一个置于低一级的FreeList。

下图呈现了分配一个页大小的内存块前后的状态变化,分配前,分配器由order=0开始查找FreeList,直到order=4才找到空闲块。

将该空闲块分为页数为8的2个伙伴,使用前一半,并将后一半挂载到order=3的FreeList;逐级重复此过程,直到返回所需的内存块,并将页数为1的空闲块挂在到order=0的FreeList。

当块释放时,会及时查看其伙伴是否空闲,并尽可能将两个空闲伙伴合并为更大的空闲块。这是分配过程的逆过程,不再赘述。

虽然PageAllocator有效地避免了外部碎片,却无法解决内部碎片的问题。为解决这类小对象的分配问题,实现了对象缓存分配器(SlabAllocator)。

  • SlabAllocator
    • 基于PageAllocator分配对象缓存,slab大小以页为单位
    • 空闲对象按内存大小定义为多个SlabManager,每个SlabManager持有一个PartialFreeList,用于放置含有空闲对象的slab

对象的内存分配过程,即从对应的PartialFreeList获取含有空闲对象的slab,并从该slab分配对象。反之,释放过程为分配的逆过程。

综上,实时索引存储结合了PageAllocator和SlabAllocator,有效地解决了内存管理的外部碎片和内部碎片问题,可确保系统高效稳定地长期运行。

能力层

能力层实现了正排表、倒排表等基础的存储能力,并支持索引能力的灵活扩展。

正向索引

也称为正排索引(Forward Index),即通过主键(Key)检索到文档(Doc)内容,以下简称正排表或Table。不同于搜索引擎的正排表数据结构,Table也可以单独用于NoSQL场景,类似于Kyoto Cabinet的哈希表。

Table不仅提供按主键的增加、删除、修改、查询等操作,也配合倒排表实现检索、过滤、读取等功能。作为核心数据结构,Table必须支持频繁的字段读取和各类型的正排过滤,需要高效和紧凑的实现。

为支持按docID的随机访问,把Table设计为一个大数组结构(data区)。每个doc是数组的一个元素且长度固定。变长字段存储在扩展区(ext区),仅在doc中存储其在扩展区的偏移量和长度。与大部分搜索引擎的列存储不同,将data区按行存储,这样可针对业务场景,尽可能利用CPU与内存之间的缓存来提高访问效率。

此外,针对NoSQL场景,可通过HashMap实现主键到docID的映射(idx文件),这样就可支持主键到文档的随机访问。由于倒排索引的docID列表可以直接访问正排表,因此倒排检索并不会使用该idx。

反向索引

也称作倒排索引(Inverted Index),即通过关键词(Keyword)检索到文档内容。为支持复杂的业务场景,如遍历索引表时的算法粗排逻辑,在此抽象了索引器接口Indexer。

具体的Indexer仅需实现各接口方法,并将该类型注册到IndexerFactory,可通过工厂的NewIndexer方法获取Indexer实例,类图如下:

当前实现了三种常用的索引器:

  • NoPayloadIndexer:最简单的倒排索引,倒排表为单纯的docID列表
  • DefaultPayloadIndexer:除docID外,倒排表还存储keyword在每个doc的负载信息。针对业务场景,可存储POI在每个Node粒度的静态质量分或最高出价。这样在访问正排表之前,就可完成一定的倒排优选过滤
  • GEOHashIndexer:即基于地理位置的Hash索引

上述索引器的设计思路类似,仅阐述其共性的两个特征:

  • 词典文件term:存储关键词、签名哈希、posting文件的偏移量和长度等。与Lucene采用的前缀压缩的树结构不同,在此实现为哈希表,虽然空间有所浪费,但可保证稳定的访问性能
  • 倒排表文件posting:存储docID列表、Payload等信息。检索操作是顺序扫描倒排列表,并在扫描过程中做一些基于Payload的过滤或倒排链间的布尔运算,如何充分利用高速缓存实现高性能的索引读取是设计和实现需要考虑的重要因素。在此基于segmentAllocator实现分段的内存分配,达到了效率和复杂度之间的微妙平衡

出于业务考虑,没有采用Lucene的Skip list结构,因为广告场景的doc数量没有搜索引擎多,且通常为单个倒排列表的操作。此外,若后续doc数量增长过快且索引变更频繁,可考虑对倒排列表的元素构建B+树结构,实现倒排元素的快速定位和修改。

接口层

接口层通过API与外界交互,并屏蔽内部的处理细节,其核心功能是提供检索和更新服务。

配置文件

配置文件用于描述整套索引的Schema,包括Metadata、Table、Index的定义,格式和内容如下:

可见,Index是构建在Table中的,但不是必选项;Table中各个字段的定义是Schema的核心。当Schema变化时,如增加字段、增加索引等,需要重新构建索引。篇幅有限,此处不展开定义的细节。

检索接口

检索由查找和过滤组成,前者产出查找到的docID集合,后者逐个对doc做各类基础过滤和业务过滤。

  • Search:返回正排过滤后的ResultSet,内部组合了对DoSearch和DoFilter的调用
  • DoSearch:查询doc,返回原始的ResultSet,但并未对结果进行正排过滤
  • DoFilter:对DoSearch返回的ResultSet做正排过滤

一般仅需调用Search就可实现全部功能;DoSearch和DoFilter可用于实现更复杂的业务逻辑。

以下为检索的语法描述:

/{table}/{indexer|keyfield}?query=xxxxxx&filter=xxxxx

第一部分为路径,用于指定表和索引。第二部分为参数,多个参数由&分隔,与URI参数格式一致,支持query、filter、Payload_filter、index_filter等。

由query参数定义对倒排索引的检索规则。目前仅支持单类型索引的检索,可通过index_filter实现组合索引的检索。可支持AND、OR、NOT等布尔运算,如下所示:

query=(A&B|C|D)!E

查询语法树基于Bison生成代码。针对业务场景常用的多个term求docID并集操作,通过修改Bison文法规则,消除了用于存储相邻两个term的doc合并结果的临时存储,直接将前一个term的doc并入当前结果集。该优化极大地减少了临时对象开销。

由filter参数定义各类正排表字段值过滤,多个键值对由“;”分割,支持单值字段的关系运算和多值字段的集合运算。

由Payload_filter参数定义Payload索引的过滤,目前仅支持单值字段的关系运算,多个键值对由“;”分割。

详细的过滤语法如下:

此外,由index_filter参数定义的索引过滤将直接操作倒排链。由于构造检索数据结构比正排过滤更复杂,此参数仅适用于召回的docList特别长但通过索引过滤的docList很短的场景。

结果集

结果集ResultSet的实现,参考了java.sql.ResultSet接口。通过cursor遍历结果集,采用inline函数频繁调用的开销。

实现为C++模板类,主要接口定义如下:

  • Next:移动cursor到下一个doc,成功返回true,否则返回false。若已经是集合的最后一条记录,则返回false
  • GetValue:读取单值字段的值,字段类型由泛型参数T指定。如果获取失败返回默认值def_value
  • GetMultiValue:读取多值字段的值,返回指向值数组的指针,数组大小由size参数返回。读取失败返回null,size等于0

更新接口

更新包括对doc的增加、修改、删除等操作。参数类型Document,表示一条doc记录,内容为待更新的doc的字段内容,key为字段名,value为对应的字段值。操作成功返回0,失败返回非0,可通过GetErrorString接口获取错误信息。

  • 增加接口Add:将新的doc添加到Table和Index中
  • 修改接口Update:修改已存在的doc内容,涉及Table和Index的变更
  • 删除接口Delete:删除已存在的doc,涉及从Table和Index删除数据

更新服务对接实时更新流,实现真正的广告实时索引。

更新系统

除以上描述的索引实现机制,生产系统还需要打通在线投放引擎与商家端、预算控制、反作弊等的更新流。

挑战与目标

数据更新系统的主要工作是将原始多个维度的信息进行聚合、平铺、计算后,最终输出线上检索引擎需要的维度和内容。

业务场景导致上游触发可能极不规律。为避免更新流出现的抖动,必须对实时更新的吞吐量做优化,留出充足的性能余量来应对触发的尖峰。此外,更新系统涉及多对多的维度转换,保持计算、更新触发等逻辑的可维护性是系统面临的主要挑战。

吞吐设计

虽然更新系统需要大量的计算资源,但由于需要对几十种外部数据源进行查询,因此仍属于IO密集型应用。优化外部数据源访问机制,是吞吐量优化的主要目标。

在此,采取经典的批量化方法,即集群内部,对于可以批量查询的一类数据源,全部收拢到一类特定的worker上来处理。在短时间内,worker聚合数据源并逐次返回给各个需要数据的数据流。处理一种数据源的worker可以有多个,根据同类型的查询汇集到同一个worker批量查询后返回。在这个划分后,就可以做一系列的逻辑优化来提升吞吐量。

分层抽象

除生成商家端的投放模型数据,更新系统还需处理针对各种业务场景的过滤,以及广告呈现的各类专属信息。业务变更可能涉及多个数据源的逻辑调整,只有简洁清晰的分成抽象,才能应对业务迭代的复杂度。

工程实践中,将外部数据源抽象为统一的Schema,既做到了数据源对业务逻辑透明,也可借助编译器和类型系统来实现完整的校验,将更多问题提前到编译期解决。

将数据定义为表(Table)、记录(Record)、字段(Field)、值(Value)等抽象类型,并将其定义为Scala Path Dependent Type,方便编译器对程序内部的逻辑进行校验。

可复用设计

多对多维度的计算场景中,每个字段的处理函数(DFP)应该尽可能地简单、可复用。例如,每个输出字段(DF)的DFP只描述需要的源数据字段(SF)和该字段计算逻辑,并不描述所需的SF(1)到SF(n)之间的查询或路由关系。

此外,DFP也不与最终输出的层级绑定。层级绑定在定义输出消息包含的字段时完成,即定义消息的时候需要定义这个消息的主键在哪一个层级上,同时绑定一系列的DFP到消息上。

这样,DFP只需单纯地描述字段内容的生成逻辑。如果业务场景需要将同一个DF平铺到不同层级,只要在该层级的输出消息上引用同一个DFP即可。

触发机制

更新系统需要接收数据源的状态变动,判断是否触发更新,并需要更新哪些索引字段、最终生成更新消息。

为实现数据源变动的自动触发机制,需要描述以下信息:

  • 数据间的关联关系:实现描述关联关系的语法,即在描述外部数据源的同时就描述关联关系,后续字段查询时的路由将由框架处理
  • DFP依赖的SF信息:仅对单子段处理的简单DFP,可通过配置化方式,将依赖的SF固化在编译期;对多种数据源的复杂DFP,可通过源码分析来获取该DFP依赖的SF,无需用户维护依赖关系

生产实践

早期的搜索广告是基于自然搜索的系统架构建的,随着业务的发展,需要根据广告特点进行系统改造。新的广告索引实现了纯粹的实时更新和层次化结构,已经在美团点评搜索广告上线。该架构也适用于各类非搜索的业务场景。

系统架构

作为整个系统的核心,基于实时索引构建的广告检索过滤服务(RS),承担了广告检索和各类业务过滤功能。日常的业务迭代,均可通过升级索引配置完成。

此外,为提升系统的吞吐量,多个模块已实现服务端异步化。

性能优化

以下为监控系统的性能曲线,索引中的doc数量为百万级别,时延的单位是毫秒。

后续规划

为便于实时索引与其他生产系统的结合,除进一步的性能优化和功能扩展外,我们还计划完成多项功能支持。

JNI

通过JNI,将Table作为单独的NoSQL,为Java提供本地缓存。如广告系统的实时预估模块,可使用Table存储模型使用的广告特征。

SQL

提供SQL语法,提供简单的SQL支持,进一步降低使用门槛。提供JDBC,进一步简化Java的调用。

参考资料

  • Apache Lucene http://lucene.apache.org/
  • Sphinx http://sphinxsearch.com/
  • "Understanding the Linux Virtual Memory Manager" https://www.kernel.org/doc/gorman/html/understand/
  • "The Art of Computer Programming"
  • "Computer Systems: A Programmer's Perspective"
  • Kyoto Cabinet http://fallabs.com/kyotocabinet/
  • GNU Bison https://www.gnu.org/software/bison/

作者简介

仓魁:广告平台搜索广告引擎组架构师,主导实时广告索引系统的设计与实现。擅长C++、Java等多种编程语言,对异步化系统、后台服务调优等有深入研究。

晓晖:广告平台搜索广告引擎组核心开发,负责实时更新流的设计与实现。在广告平台率先尝试Scala语言,并将其用于大规模工程实践。

刘铮:广告平台搜索广告引擎组负责人,具有多年互联网后台开发经验,曾领导多次系统重构。

蔡平:广告平台搜索广告引擎组点评侧负责人,全面负责点评侧系统的架构和优化。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-05-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 美团技术团队 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
干货 | 广告系统架构解密
广告、增值服务、佣金,是互联网企业最常见的三种盈利手段。在这3大经典中,又以广告所占的市场份额最大,几乎是绝大部分互联网平台最主要的营收途径,业务的重要性不言而喻。
Java识堂
2020/08/28
5.2K0
干货  |  广告系统架构解密
美团外卖搜索基于Elasticsearch的优化实践
美团外卖搜索工程团队在Elasticsearch的优化实践中,基于Location-Based Service(LBS)业务场景对Elasticsearch的查询性能进行优化。该优化基于Run-Length Encoding(RLE)设计了一款高效的倒排索引结构,使检索耗时(TP99)降低了84%。本文从问题分析、技术选型、优化方案等方面进行阐述,并给出最终灰度验证的结论。
美团技术团队
2022/12/16
1.4K0
美团外卖搜索基于Elasticsearch的优化实践
深入了解Elasticsearch搜索引擎篇:倒排索引、架构设计与优化策略
倒排索引是一种用于快速检索的数据结构,常用于搜索引擎和数据库中。与传统的正排索引不同,倒排索引是根据关键词来建立索引,而不是根据文档ID。
努力的小雨
2023/11/10
2.8K0
广告系统架构:要啥自行车!
(上)(中)(下)全文目录 引言 广告=>互联网广告:“您好,了解一下” 互联网广告=>计算广告:指哪儿打哪儿! 计算广告四君子:谁在弄潮? 计算广告关键技术:这孙子怎么什么都知道? 广告系统架构:
大数据文摘
2018/05/25
3.4K3
Elasticsearch 亿级数据检索性能优化案例实战!
https://www.cnblogs.com/mikevictor07/p/10006553.html
用户5224393
2019/10/29
1.1K0
Elasticsearch 亿级数据检索性能优化案例实战!
美团点评效果广告实验配置平台的设计与实现
效果广告的主要特点之一是可量化,即广告系统的所有业务指标都是可以计算并通过数字进行展示的。因此,可以通过业务指标来表示广告系统的迭代效果。那如何在全量上线前确认迭代的结果呢?通用的方法是采用AB实验(如图1)。所谓AB实验,是指单个变量具有两个版本A和B的随机实验。在实际应用中,是一种比较单个(或多个)变量多个版本的方法,通常是通过测试受试者对多个版本的反应,并确定多个版本中的哪个更有效。Google工程师在2000年进行了首次AB实验,试图确定在其搜索引擎结果页上显示的最佳结果数。到了2011年,Google进行了7000多次不同的AB实验。现在很多公司使用“设计实验”的方法来制定营销决策,期望在实验样本上可以得到积极的转化结果,并且随着工具和专业知识在实验领域的发展,AB实验已成为越来越普遍的一种做法。
美团技术团队
2019/12/04
1.4K0
得物社区亿级ES数据搜索性能调优实践
2020年以来内容标注结果搜索就是社区中后台业务的核心高频使用场景之一,为了支撑复杂的后台搜索,我们将社区内容的关键信息额外存了一份到Elasticsearch中作为二级索引使用。随着标注业务的细分、迭代和时间的推移,这个索引的文档数和搜索的RT开始逐步上升。下面是这个索引当前的监控情况。 图片
得物技术
2023/05/19
5600
得物社区亿级ES数据搜索性能调优实践
Elasticsearch 内部数据结构深度解读
最近知识星球里几个问题都问到了 doc values、store field、fielddata 等的概念。
铭毅天下
2020/10/26
6.2K0
Elasticsearch 内部数据结构深度解读
搜索引擎原理解析:从0开始实现一个搜索引擎
打开谷歌, 输入关键词, 谷歌往往可以很精准的返回你所需要的内容, 这个是怎么实现的呢?简单的思考一下就能得出一个结论:一定是关键词能极为快速和准确的命中具体的内容及地址, 但是搜索引擎的收录页面数量往往是千亿万亿级别的,从这个量级里面检索到你要的数据可以说是大海捞针一点也不夸张。那么搜索引擎是如何让你在数据的汪洋大海里捞到你想要的那根针的那?这就要说到所有的搜索引擎都离不开一个概念: 索引。
政采云前端团队
2023/12/19
1.5K0
搜索引擎原理解析:从0开始实现一个搜索引擎
ES系列十之深入理解倒排索引
话不多说,今天开始深入理解一下es中所谓的“倒排索引”。其实在索引中包括正排索引也就是根据id去直接检索数据,其实mysql中数据底层存储的主键索引就是正排索引,这个后续会讲到的,感兴趣可以关注一下哟;还有一种索引就是我们今天要讲的倒排索引,所谓的倒排索引呢,就是倒排索引它记录的是词,和词所存在的文档id的所有列表。通过这种索引结构的存储方式,其查询速率可想而知。其数据格式为
热心的大肚皮
2023/02/28
9800
ES系列十之深入理解倒排索引
倒排索引
倒排索引源于实际应用中需要根据属性的值来查找记录。这种索引表中的每一项都包括一个属性值和具有该属性值的各记录的地址。由于不是由记录来确定属性值,而是由属性值来确定记录的位置,因而称为倒排索引(inverted index)。带有倒排索引的文件我们称为倒排 索引文件,简称 倒排文件(inverted file)。
全栈程序员站长
2021/10/25
8330
得物自研DSearch3.0搜索核心引擎升级之路
随着交易和社区搜索业务稳步快跑,基建侧引擎越来越复杂,之前搜索底层索引查询结构已经存在较为严重的性能瓶颈。成本和运维难度越来越高。在开发效率上和引擎的稳定性上,也暴露出了很多需要解决的运维稳定性和开发效率短板。而在引擎的业务层部分也需要逐步升级,来解决当前引擎中召回层和业务层中各个模块强耦合,难维护,迭代效率低下等问题。
得物技术
2025/05/14
1460
得物自研DSearch3.0搜索核心引擎升级之路
详解Elasticsearch 的性能优化
Elasticsearch(后文简称 ES)的基础是 Lucene,所有的索引和文档数据是存储在本地的磁盘中,具体的路径可在ES 的配置文件../config/elasticsearch.yml中配置,如下:
烂猪皮
2020/09/11
1.1K0
详解Elasticsearch 的性能优化
ES性能优化实战,几十亿数据查询 3 秒返回!
原文链接:https://www.cnblogs.com/mikevictor07/p/10006553.html
业余草
2019/12/03
1.9K0
搜索引擎分布式系统思考实践
搜索引擎在数据量逐步扩大之后,分布式搜索是必经之路。搜索引擎的分布式除了要考虑数据分片之外,更重要还需要考虑数据的有状态以及各组件的状态流转。在这里分享一下基于ZK设计分布式搜索引擎的一些经验和思考落地情况,包含了从单机版本到分布式版本的演进。
得物技术
2022/08/23
4900
腾讯全文检索引擎 wwsearch 正式开源
背景 企业微信作为典型企业服务系统,其众多企业级应用都需要全文检索能力,包括员工通讯录、企业邮箱、审批、汇报、企业CRM、企业素材、互联圈子等。下图是一个典型的邮件检索场景。 由于过去几年业务发展迅速,后台检索架构面临挑战: 1. 系统在亿级用户,xxx万企业下,如何高效+实时地检索个人企业内数据和所在企业全局数据。 2. 业务模型众多,如何满足检索条件/功能多样化需求。 3. 数据量庞大,检索文本几十TB,如何节约成本。 业界有被广泛使用的开源全文检索引擎,比如:lucene、sphinx等。它
腾讯开源
2019/11/27
2.2K0
腾讯全文检索引擎 wwsearch 正式开源
【迅搜03】全文检索、文档、倒排索引与分词
今天还是概念性的内容,但是这些概念却是整个搜索引擎中最重要的概念。可以说,所有的搜索引擎就是实现了类似的概念才能称之为搜索引擎。而且今天的内容其实都是相关联的,所以不要以为标题上有四个名词就感觉好像内容很多一样,其实它们都是联系紧密的,一环套一环的。
硬核项目经理
2023/11/24
7190
【迅搜03】全文检索、文档、倒排索引与分词
Lucene的索引系统和搜索过程分析
前言:目前自己在做使用Lucene.net和PanGu分词实现全文检索的工作,不过自己是把别人做好的项目进行迁移。因为项目整体要迁移到ASP.NET Core 2.0版本,而Lucene使用的版本是3.6.0 ,PanGu分词也是对应Lucene3.6.0版本的。不过好在Lucene.net 已经有了Core 2.0版本(4.8.0 bate版),而PanGu分词,目前有人正在做,貌似已经做完,只是还没有测试~,Lucene升级的改变我都会加粗表示。
ShenduCC
2018/07/24
2.4K0
Lucene的索引系统和搜索过程分析
美团点评联盟广告的场景化定向排序机制
前言 在美团点评的联盟广告投放系统(DSP)中,广告从召回到曝光的过程需要经历粗排、精排和竞价及反作弊等阶段。其中精排是使用CTR预估模型进行排序,由于召回的候选集合较多,出于工程性能上的考虑,不能一次性在精排过程中完成候选集的全排序,因此在精排之前,需要对候选广告进行粗排,来过滤、筛选出相关性较高的广告集合,供精排使用。 本文首先会对美团点评的广告粗排机制进行概要介绍,之后会详细阐述基于用户、天气、关键词等场景特征的广告粗排策略。 广告粗排机制简介 广告粗排框架对引擎端召回的若干广告进行排序,并将排序的结
美团技术团队
2018/03/13
1.9K0
美团点评联盟广告的场景化定向排序机制
深入搜索引擎之 Elasticsearch 必知必会(一):开发视角
两句话了解它是什么 1. 搜索引擎。提供了数据存储、数据处理、数据查询、聚合统计的能力。 2. 创始人说:“不要求你必须是一个数据科学家才能把它用好” 前言 Elasticsearch 是一个很有意思的产品,不同岗位的人,对它的关注维度区别比较大 主要可以分三个层面 开发 基本功能 底层工作原理 数据建模最佳实践 运维 容量规划 性能优化 问题诊断 滚动升级 搜索结果优化 查全率、查准率等指标 搜索与如何解决搜索的相似性问题 具体场景下的调优 对比传统数据库的区别主要在于 传统关系型数据库 事务性 Joi
QQ音乐技术团队
2022/01/06
1.4K0
推荐阅读
相关推荐
干货 | 广告系统架构解密
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档