前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >搜索技术的秘密(一):概览

搜索技术的秘密(一):概览

作者头像
老钱
发布2019-08-30 16:22:51
4470
发布2019-08-30 16:22:51
举报
文章被收录于专栏:码洞

「多字段搜索」是一个非常复杂的话题,设想你有一堆日志记录,有很多字段。然后产品经理希望可以通过各种组合字段进行搜索,比如根据时间段、用户 ID、行为类型、目标 ID 等,得出满足条件的日志记录。

如果是单字段搜索,那很好办,把日志记到关系数据库中,在必要的字段上加索引就可以了。但是一旦涉及到复合条件查询,关系数据库会捉襟见肘。也许你会想到复合字段索引,这确实也是一种很好的解决方案,但是解决的能力也相对比较有限。在遇到复合字段搜索时,我们通常会借助于专业的搜索引擎,比如互联网领域广为使用的 Elasticsearch,本系列文章将会带读者一同潜入 ElasticSearch 的搜索技术,了解一下搜索领域的常用底层解决方案。

搜索引擎的最基础的技术就是倒排索引,它是关键词到文档列表的映射。给倒排索引提供一个原子的查询词汇,倒排索引可以得到与它相关的文档ID 列表。这个文档 ID 在本例中就是一条日志记录的主键 ID,通过这个主键 ID 就可以得到整条日志,这是因为搜索引擎除了倒排索引之外还会存储所有的日志记录,也就是日志 ID 到日志内容 Document 的映射。

代码语言:javascript
复制
class InvertedIndex {
  Map<String, List<Long>> key2docs;
}

class Documents<T> {
  Map<Long, T> docs;
}

在一个日志表上会有多个倒排索引,每个被搜索的字段都会生成一个倒排索引。这样当我们使用复合字段搜索时,通过每个倒排索引都会得到一个 文档ID 列表,然后对这多个文档ID 列表进行交集运算,就可以得到同时满足多个搜索条件的文档 ID 列表。这个交集运算算法也是搜索引擎的另一个重要的秘密之一,它对搜索性能的影响至关重要。

代码语言:javascript
复制
class Table<T> {
  Documents<T> docs;
  Map<String, InvertedIndex> field2Indexes;
}

我们的日志表内容和倒排索引不可能全部放在内存里,所以我们必须决定什么样的数据需要放在内存里,什么样的数据需要放在磁盘上。也许是简单的 LRU 算法,也许是背后有一个类似于 LevelDB 的存储引擎存储了所有的文档 ID 到文档内容,LevelDB 自己会决定哪些文档在内存里哪些文档在磁盘上,以及如何以最小化的 IO 代价拿到磁盘上的文档。如何降低内存又不会显著增加 IO 成本,这又是搜索引擎的又一个重难点之一。类似于 LevelDB 这样的存储引擎能帮我们搞定文档库大字典 docs 的存储,但是倒排索引跟文档库似乎又不太一样,单个 key 对应的文档 ID 列表可以非常长,如果将这个文档 ID 列表看成一个特殊的整体文档,那么这个整体文档会无比巨大,让他在内存里会消耗内存,让它在磁盘上频繁的序列化反序列化 IO 又会导致极高的 IO 成本。这也是一个无比头疼的问题,但是 Elasticsearch 有办法搞定它。

磁盘的成本固然低廉,但是如果使用普通的磁盘估计搜索引擎的效率也会大打折扣,因为搜索引擎不可避免会涉及到磁盘 IO,单次搜索往往会涉及到多次磁盘 IO。并发搜索进一步让磁盘的磁头繁忙的不可开销。所以对于 Elasticsearch,官方推荐的磁盘依然是 SSD,有了 SSD 磁盘,搜索性能就可以飞起来。如果没有 SSD,至少搜索引擎也是可用的,但是在高并发场景下可能会慢的让你咬牙切齿。

如果使用了昂贵的 SSD,那我们就必须考虑高效的磁盘存储。我们会使用一些特殊的压缩算法,以解决磁盘空间,同时呢又不能让解压缩算法拖慢搜索效率,因为解压缩的过程会涉及到 密集的 CPU 运算。这也是搜索技术的另一个重要当不必要的考虑点之一,尽可能地节约硬件成本。

既然搜索引擎是一个分布式系统,自然我们也不能只考虑单机的存储和计算,我们还需要面对的是它的分片、它的高可用这些复杂的话题。这里会涉及到分片算法、选举算法、查询分割、查询聚合等一系列高阶难题。我们还要搞定一系列网络故障,硬件故障,数据安全性等问题。

搜索引擎还要支持模糊查询,这就涉及到查询范围的扩大化、查询结果的相似度计算以及排序算法。就我们这些提及的讨论点来说,实现一个可用的易用的安全的搜索引擎有多难,而 Elasticsearch 搞定了这些,但是这世界上的搜索引擎非常之多,能够让 Elasticsearch 登顶了纳斯达克的原因不仅仅是这些技术上的因素,还有生态、服务、市场等我们作为程序员难以控制的范畴。这也超出了我的个人能力,在后面的系列文章中,我只会对 Elasticsearch 内部的技术点进行讨论,非技术因素恕我能力有限,互联网上也应该有非常多的文章在讨论 Elasticsearch 成功的秘诀,大家可以自行搜索。这一系列文章在形式上会自由散漫好一些,不会写的像掘金小册那样写的非常精细结构性非常强,有时候可能会为了图快完成任务而没有写的特别丰富多彩,出现一些细微的错误也在所难免,还请大家勇于指正。

下面是字节跳动的内推入口,找出自己心意的职位后,请勇于投递你的个人简历,内部系统的数据安全性做得非常到位,我是看不到你们的简历内容的,所以不必太担心个人隐私问题。北京、上海、深圳、杭州、成都、广州等城市的职位都有,Python、Java、Golang、算法、数据、分布式计算和存储的岗位也都有,个人发挥自己的搜商,进去自行寻找吧。

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

本文分享自 码洞 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
Elasticsearch Service
腾讯云 Elasticsearch Service(ES)是云端全托管海量数据检索分析服务,拥有高性能自研内核,集成X-Pack。ES 支持通过自治索引、存算分离、集群巡检等特性轻松管理集群,也支持免运维、自动弹性、按需使用的 Serverless 模式。使用 ES 您可以高效构建信息检索、日志分析、运维监控等服务,它独特的向量检索还可助您构建基于语义、图像的AI深度应用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档