目录
学习来源:https://i12pc3nf6d.feishu.cn/wiki/FnPwwGXGli1ANGkaMz5chvhmn2e#share-OYKJdYhehotnMgxrBiUcZSJJnCb
https://i12pc3nf6d.feishu.cn/wiki/FnPwwGXGli1ANGkaMz5chvhmn2e#share-OYKJdYhehotnMgxrBiUcZSJJnCb
简介
是一个开源的搜索引擎。
它介于应用和数据之间,只要将数据写入 es,应用就可以通过一些关键词搜索到数据。效果就像某度搜索一样。
原理
基础概念
正排:依次遍历文本匹配是否含有关键词
倒排:遍历关键词去搜索对应原始数据的id
分词:对文本进行切分
词项term:分词后的每部分。词项非常多,时间复杂度为O(N),按字典序从小到大排序,二分查找O(lgN)
排好序的词项Term Dictionary:包括term(词项)和对应的文档id(其实还包括词频、偏移量等等)
数据量很大,放内存并不现实,因此必须放在磁盘中。但查询磁盘是个较慢的过程
==》term index
提取词项相同的前缀,构成目录树term index
搜索出来的是文档id,获取文档内容本身==》Stored Fields(行式存储)存放文档id和对应的文档内容
根据某个字段排序文档,但是字段散落在文档中==》空间换时间的思路,再构造一个列式存储结构,将散落在各个文档的某个字段,集中存放
lucene总结
倒排索引用于搜索
Term Index 用于加速搜索【相同前缀,目录树】
Stored Fields 用于存放文档的原始信息
Doc Values 用于排序和聚合。
这些结构共同组成了一个复合文件segment,segment 一旦生成,则不能再被修改,所以旧的segment只负责读,新的segment 负责读和写;segment 一旦变多就有segment merging段合并
而多个segment组成lucene,一个单机的文本检索库
es的进步
es就是在lucene 的基础上实现了
高性能:对数据进行分类写入不同的lucene,把多操作分摊到多个分片shard 中去
高扩展:把shard 分散部署在多台机器
高可用:在不同node添加shard 的副本
涉及到集群部分:
Node角色分化:主节点负责管理集群;数据节点负责存储管理数据,协调节点负责接受客户端搜索查询请求
去中心化:选主,在 Node 间引入协调模块,用类似一致性算法 Raft 的方式,在节点间互相同步数据
实现过程
写入流程
-
当客户端应用发起数据写入请求,请求会先发到集群中协调节点。
-
协调节点根据 hash 路由,判断数据该写入到哪个分片(Shard),找到主分片并写入到 lucene 库里的 segment 内,将数据固化为倒排索引和 Stored Fields 以及 Doc Values 等多种结构。
-
主分片 写入成功后会将数据同步给 副本分片。
-
副本分片 写入完成后,主分片会响应协调节点 ACK
-
最后,协调节点响应客户端应用写入完成。
搜索过程
- 查询阶段
-
当客户端应用发起搜索请求,请求会先发到集群中的协调节点。
-
协调节点根据 index name 的信息,可以了解到 index name 被分为了几个 分片,以及这些分片 分散哪个数据节点上,将请求转发到这些数据节点的 分片 上面。
-
搜索请求到达分片后,分片 底层的 lucene 库会并发搜索多个 segment,利用每个 segment 内部的倒排索引获取到对应文档 id,并结合 doc values 获得排序信息。分片将结果聚合返回给协调节点。
-
协调节点排序聚合多个分片中拿到的数据,舍弃大部分不需要的数据。
- 获取阶段
-
协调节点再次拿着文档 id 请求数据节点里的 分片,分片 底层的 lucene 库会从 segment 内的 Stored Fields 中取出完整文档内容,并返回给协调节点。
-
协调节点最终将数据结果返回给客户端。完成整个搜索过程