点一下关注吧!!!非常感谢!!连续更新!!!
目前已经更新到了:
- Hadoop(已更完)
- HDFS(已更完)
- MapReduce(已更完)
- Hive(已更完)
- Flume(已更完)
- Sqoop(已更完)
- Zookeeper(已更完)
- HBase(已更完)
- Redis (已更完)
- Kafka(已更完)
- Spark(已更完)
- Flink(已更完)
- ClickHouse(已更完)
- Kudu(已更完)
- Druid(已更完)
- Kylin(已更完)
- Elasticsearch(正在更新…)
章节内容
上节我们完成了如下的内容:
- Elasticsearch Java API
- 文档操纵 增编削查
倒排索引
Elasticsearch 是一个基于 Lucene 构建的分布式搜刮引擎,它能够以非常高的效率执行全文搜刮查询。在 Elasticsearch 的焦点,倒排索引(Inverted Index) 是最重要的数据结构之一。明白倒排索引的原理对于明白 Elasticsearch 的搜刮性能至关重要。
什么是倒排索引?
倒排索引是一种用于快速查找包罗特定词汇的文档的数据结构。它雷同于一本书的索引页,但结构上是“倒过来”的,因此得名。
正向索引 vs. 倒排索引
0 正向索引(Forward Index) 是基于文档构建的,记录了每个文档中包罗的词汇。对于每个文档,你可以找到它包罗哪些词汇。
- 倒排索引(Inverted Index) 是基于词汇构建的,记录了每个词汇在哪些文档中出现。对于每个词汇,你可以灵敏找到包罗它的文档列表。
比方,假设有三篇文档如下:
- “Elasticsearch 是一个分布式搜刮引擎”
- “分布式系统可以提供高可用性”
- “搜刮引擎使用倒排索引进行高效搜刮”
正向索引会记录每个文档中有哪些词:
- Doc1: ["Elasticsearch", "是", "一个", "分布式", "搜索", "引擎"]
- Doc2: ["分布式", "系统", "可以", "提供", "高", "可用性"]
- Doc3: ["搜索", "引擎", "使用", "倒排索引", "进行", "高效", "搜索"]
复制代码 而倒排索引则会记录每个词在哪些文档中出现:
- "Elasticsearch": [1]
- "分布式": [1, 2]
- "搜索": [1, 3]
- "引擎": [1, 3]
- "倒排索引": [3]
复制代码 这样,当你查询一个词汇时,好比 “搜刮”,Elasticsearch 可以通过倒排索引立即返回它出现在 Doc1 和 Doc3 中,而不必要遍历所有的文档。
倒排索引的构建
在 Elasticsearch 中,文档首先会被分析和处置惩罚,然后生成倒排索引。其过程大致如下:
- 文档分词:每个文档都会颠末 分析器(Analyzer) 的处置惩罚,分析器负责将文档的文本分解成词项(terms)。比方,句子 “Elasticsearch 是一个分布式搜刮引擎” 可能被分解为 [“elasticsearch”, “分布式”, “搜刮”, “引擎”]。
- 标准化和过滤:分词后,分析器通常会进行进一步的处置惩罚,比方将所有词项转为小写、删除停用词(如 “是”, “一个”)等。这一步使得倒排索引更具可查询性。
- 构建倒分列表:倒排索引将每个词项与它所出现的文档ID关联。词项是倒排索引的键,文档ID列表则是值。对于每个词项,Elasticsearch 还可能记录一些额外信息,如词频(TF)和词项在文档中的位置(用于短语匹配和邻近查询)。
倒排索引的结构
倒排索引的焦点部门可以分为以下几个构成部门:
- 词汇表(Term Dictionary):词汇表保存了所有被索引的词项,通常是以字典形式存储。通过这个表,Elasticsearch 可以快速定位某个词项是否存在。
- 倒分列表(Posting List):对于每个词项,倒分列表记录了所有包罗该词项的文档ID。倒分列表还可以包罗附加信息,如:
- 词项频率(Term Frequency, TF):记录该词项在文档中出现的次数。
- 文档频率(Document Frequency, DF):记录该词项在整个索引中出现的文档总数。
位置(Position):词项在文档中的位置,用于支持短语和邻近查询。
比方,对于词项 “搜刮”,倒分列表可能是这样的:
- "搜索": [(Doc1, Position: 5), (Doc3, Position: 3, 7)]
复制代码 这意味着 “搜刮” 在文档1中出现过,而且在文档3中出现过两次,分别位于位置3和7。
倒排索引的查询原理
倒排索引使得 全文搜刮查询 变得非常高效。比方,当你向 Elasticsearch 发起搜刮请求时,好比查找包罗词项 “搜刮引擎” 的文档,Elasticsearch 可以执行以下步调:
查找词项:Elasticsearch 首先在词汇表中查找 “搜刮” 和 “引擎” 这两个词项,找到它们的倒分列表。
合并倒分列表:Elasticsearch 会合并这两个词项的倒分列表,找到同时包罗 “搜刮” 和 “引擎” 的文档。由于每个词项都与它的文档ID相干联,合并列表的操纵非常快速。
计算相干性:在找到匹配的文档后,Elasticsearch 会根据一些算法(如 TF-IDF 或 BM25)对文档进行评分,权衡它们与查询的相干性。这个步调基于词项频率、文档频率等信息,最终返回最相干的文档。
倒排索引的优势
- 快速检索:倒排索引的结构使得对于某个词项的检索速度极快,尤其在海量文档中,查询性能仍能保持在毫秒级别。
- 低内存占用:固然倒排索引记录了大量的词项和文档ID,但通过压缩算法和优化的数据结构,倒排索引可以保持较低的内存使用率。
- 支持复杂查询:倒排索引不仅支持简朴的关键词查询,还支持短语、前缀、邻近查询等复杂的搜刮条件。
测试分析
Elasticsearch使用一种称为倒排索引的结构,它适用于快速的全文搜刮。一个倒排索引由文档中所有不重复的列表构成,对于此中每个词,有一个包罗的它的文档列表。
假设我们有两个文档,每个文档的内容如下:
- 1. The quick brown fox jumped over the lazy dog
- 2. Quick brown foxes leap over lazy dogs in summer
复制代码 要创建倒排索引,首先要将每个文档内容拆分成单独的词,创建一个包罗所有不重复词条的排序列表,然后列出每个词条出现在哪个文档,结果如下图所示:
现在我们想要搜刮 quick down,我们只必要查找包罗每个词条的文档:
两个文档都匹配,但是第一个文档比第二个匹配度更高,假如我们使用仅计算匹配条数量的简朴相似性算法,那么对于我们查询的相干性来讲,第一个文档比第二个文档更佳。
读写流程
创建文档
向Elasticsearch中添加一个文档对象,由于ES是分布式集群而且底层计划了一个索引由浩繁Shard分片,所以添加文档时必要确定该文档属于哪个分片,确定规则为:
- shard = has(routing) % number_of_primary_shards
复制代码
- routing 是一个可变值,默认是文档的ID,也可以设置成一个自定义的值
- routing 通过hash函数生成一个数字,然后这个数字再除以number_of_primary_shards(主分片的数量)后得到余数,这个分布在0到number_of_primary_shards - 1 之间的余数,就是我们寻求的文档所在分片的位置。
写文档流程
以官网的例子进行分析,从图中可看出一个集群由三个节点构成,有两个分片,两个副本。
写操纵必须在主分片上面完成之后,才能被复制到其他节点作为分片副本,新建、索引和删除请求都是写操纵。
- 客户端向Master发送写入请求,该节点作为协调治点
- 根据文档的_id确定分片,图中请求文档属于分片0,协调治点请求转到节点的主分片
- 在节点3上执行请求,成功之后,节点3根据副本数将请求并行转到副本分片对应节点,一旦副本分片执行完成,都向节点3陈诉成功,节点3将协调治点陈诉成功,协调治点向客户端陈诉成功
读文档流程
一个搜刮请求必须询问请求的索引中所有分片的某个副本来进行匹配,假设一个索引由5个主分片,每个主分片有一个副本分片,共10个分片,一次搜刮请求会由5个分片来共同完成,他们可能是主分片,也可能是副分片。也就是说,一次搜刮请求只会命中所有分片副本中的一个。
一次检索流程主要分为两个阶段:
Query阶段
- 客户端发送Search请求到Node3
- Node3将查询请求转发到索引的每个主分片或副分片中
- 每个分片在当地执行查询,并使用当地的Term/DocumentFrequency信息进行打分,添加结果到大小 from+size的当地优先队列中
- 每个分片返回各自优先队列中所有文档的ID和排序值给协调治点,协调治点合并这些值到自己的优先队列中,产生一个全局排序后的列表
Fetch阶段
- 协调治点相干Node发送GET请求
- 分片所在节点向协调治点返回数据
- 协调治点等待所有文档数据被取得,然后返回给客户端
分片所在节点在返回文档时,处置惩罚有可能出现的 _source 字段和高亮参数
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |