第六章--ElasticSearch (ES)--面试题

本文详细介绍了Elasticsearch的面试重点,包括其作为基于Lucene的搜索引擎的特点、分词、倒排索引、段合并策略、文本相似度TF-IDF、写索引逻辑、集群中搜索数据的过程、性能优化方法、查询优化策略、集群架构、分片与副本等,还探讨了Elasticsearch与关系型数据库的对比、选举主节点的过程以及数据同步问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

01 ES 是什么

Elastic是一个基于Lucene的搜索引擎. 提供了具有HTTP Web和无架构JSON文档的分布式,多租户能力的全文搜索引擎.

  • Elasticsearch是一款强大的开源搜索引擎,可帮助我们从海量数据中快速找到需要的内容.
  • 开源分布式搜索引擎, 可用来实现搜索 日志统计 分析 系统监控等功能

Elasticsearch(负责存储 计算 搜索 分析数据)结合kibana(数据可视化) Logstash Beats(数据抓取),也就是elastic stack(ELK). 被广泛应用日志数据分析,实时监控

02 ES 特点
  • 分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索。分发是实时的,被叫做”Push replication”
  • 实时分析的分布式搜索引擎。
  • 可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据。
  • Elasticsearch 完全支持 Apache Lucene 的接近实时的搜索。
  • 处理多租户(multitenancy)不需要特殊配置,而Solr则需要更多的高级设置。
  • Elasticsearch 采用 Gateway 的概念,使得完备份更加简单。
  • 各节点组成对等的网络结构,某些节点出现故障时会自动分配其他节点代替其进行工作。
03 分词 与 倒排索引 与字典树

分词是给检索用的. ( IK 分词器).
英文,一个单词一个词, 词之间空格分隔
汉字,有各种各样分词器,一个强调效率,一个强调准确率. 比如 ‘使用户放心’,使用,户vs使,用户
倒排索引 举例:从文档内容找文档(通过搜索引擎)
传统的我们的检索是通过文章,逐个遍历找到对应关键词的位置。
而倒排索引,是通过分词策略,形成了词和文章的映射关系表,这种词典+映射表即为倒排索引。
有了倒排索引,就能实现 o(1)时间复杂度 的效率检索文章了,极大的提高了检索效率。image.png
倒排索引,相反于一篇文章包含了哪些词,它从词出发,记载了这个词在哪些文档中出现过,由两部分组成——词典和倒排表。
加分项 :倒排索引的底层实现是基于:FST(Finite State Transducer)数据结构。
lucene 从 4+版本后开始大量使用的数据结构是 FST。FST 有两个优点:
1、空间占用小。通过对词典中单词前缀和后缀的重复利用,压缩了存储空间;
2、查询速度快。O(len(str))的查询时间复杂度。
:::info
**有限状态自动机(Finite State Transducer,FST)**是一种常见的字典数据结构,常用于NLP中。它可以表示一组字符串集合,并提供一种有效的方法来在这些字符串上执行查询操作。
FST 可以用于多种不同的任务,包括词形变化、拼写纠正、文本匹配和词义消歧等。
:::

数据结构 优缺点 相关代码
ArrayList…… 二分法查找,不平衡 list.add(“”)
Map…… 内存消耗大 map.put(“”,“”)
Trie 中文领域过于消耗内存 TrieChineseTokenizer.java
Double Array Trie 相比于Trie,更适合中文,缺点是无法动态增删 darts-java扩展
AhoCorasickDoubleArrayTrie 存储大辞典时溢出 AhoCorasickDoubleArrayTrie
Finite State Transducers (FST) Lucene中大量应用,本文重点说明 FST.java
  1. 针对ArrayList、Map这两个基本数据结构,不做过多介绍,直接跳过。
  2. 针对Trie这个数据结构,他更适合于英文,并不适合应用于中文环境。
  3. 中文文本中的字符集非常大,超过了 ASCII 字符集。Trie 数据结构在处理大字符集时,需要存储大量的节点,这会导致空间消耗变得非常大。
  4. 中文文本中的词汇组合非常灵活。中文中的词汇不像英文那样明确定义,并且同一个词可以有多种不同的组合方式。
  5. Trie数据结构在中文文本中,由于其空间和时间效率的限制以及中文文本的复杂性,可能不是最佳选择。
  6. 双数组Trie树是一种基于Trie树的数据结构
  7. DAT 的静态构建是通过将 Trie 树转换为两个数组实现的。其中一个数组存储 Trie 树中的节点信息,另一个数组则存储节点的孩子节点信息。这种实现方式具有很好的压缩性和查找效率。
  8. 当需要删除 Trie 树中的一个节点时,需要将该节点从 Trie 树中删除,并且可能需要对其祖先节点进行修改,以确保删除后的 Trie 树仍然是一棵有效的树。因为 DAT 中的数组是静态分配的,因此删除节点和修改数组可能会破坏原始数据结构的完整性,导致无法保证查找的正确性。
  9. AhoCorasickDoubleArrayTrie
  10. 在实际的应用中,存储大辞典的话,会出现溢出情况,并且在issues中也有他人出现这种问题。
  11. 重点实现 FST 数据机构,详见下面代码
  12. 使用语料库分别加入 AhoCorasickDoubleArrayTrie 和 FST,前者出现溢出情况(400w数据量左右),后者正常使用。
  13. 可以动态增删关键词
import java.io.Serializable;
import java.util.HashMap;

/**
 * FST
 */
public class FST implements Serializable {
   

    private HashMap<Character, FST> transitions = new HashMap<>();
    private boolean isFinalState = false;

    public void addWord(String word) {
   
        if (word.isEmpty()) {
   
            isFinalState = true;
            return;
        }
        char c = word.charAt(0);
        FST nextState = transitions.get(c);
        if (nextState == null) {
   
            nextState = new FST();
            transitions.put(c, nextState);
        }
        nextState.addWord(word.substring(1));
    }

    public boolean isWord(String word) {
   
        if (word.isEmpty()) {
   
            return isFinalState;
        }
        char c = word.charAt(0);
        FST nextState = transitions.get(c);
        if (nextState == null) {
   
            return 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值