ElasticSearch调优实践(二)

📅 2026/7/6 13:56:10
ElasticSearch调优实践(二)
ElasticSearch调优实践(二)ElasticSearch整体结构通过上文在通过图解了解了ES整体的原理后我们梳理下ES的整体结构一个 ES Index 在集群模式下有多个 Node 节点组成。每个节点就是 ES 的Instance (实例)。每个节点上会有多个 shard 分片 P1 P2 是主分片, R1 R2 是副本分片每个分片上对应着就是一个 Lucene Index底层索引文件Lucene Index 是一个统称由多个 Segment 段文件就是倒排索引组成。每个段文件存储着就是 Doc 文档。commit point记录了所有 segments 的信息补充:Lucene索引结构上图中Lucene的索引结构中有哪些文件呢更多文件类型可参考这里在新窗口打开文件的关系如下补充:Lucene处理流程上文图解过程还需要理解Lucene处理流程, 这将帮助你更好的索引文档和搜索文档。创建索引的过程准备待索引的原文档数据来源可能是文件、数据库或网络对文档的内容进行分词组件处理形成一系列的Term索引组件对文档和Term处理形成字典和倒排表搜索索引的过程对查询语句进行分词处理形成一系列Term根据倒排索引表查找出包含Term的文档并进行合并形成符合结果的文档集比对查询语句与各个文档相关性得分并按照得分高低返回补充:ElasticSearch分析器上图中很重要的一项是语法分析/语言处理, 所以我们还需要补充ElasticSearch分析器知识点。分析 包含下面的过程首先将一块文本分成适合于倒排索引的独立的 词条 之后将这些词条统一化为标准格式以提高它们的“可搜索性”或者 recall分析器执行上面的工作。 分析器 实际上是将三个功能封装到了一个包里字符过滤器首先字符串按顺序通过每个 字符过滤器 。他们的任务是在分词前整理字符串。一个字符过滤器可以用来去掉HTML或者将 转化成 and。分词器其次字符串被 分词器 分为单个的词条。一个简单的分词器遇到空格和标点的时候可能会将文本拆分成词条。Token 过滤器最后词条按顺序通过每个 token 过滤器 。这个过程可能会改变词条例如小写化 Quick 删除词条例如 像 a and the 等无用词或者增加词条例如像 jump 和 leap 这种同义词。Elasticsearch提供了开箱即用的字符过滤器、分词器和token 过滤器。 这些可以组合起来形成自定义的分析器以用于不同的目的。内置分析器Elasticsearch还附带了可以直接使用的预包装的分析器。接下来我们会列出最重要的分析器。为了证明它们的差异我们看看每个分析器会从下面的字符串得到哪些词条Set the shape to semi-transparent by calling set_trans(5)* **标准分析器**标准分析器是Elasticsearch默认使用的分析器。它是分析各种语言文本最常用的选择。它根据 Unicode 联盟 定义的 **单词边界** 划分文本。删除绝大部分标点。最后将词条小写。它会产生 set, the, shape, to, semi, transparent, by, calling, set_trans, 5* **简单分析器**简单分析器在任何不是字母的地方分隔文本将词条小写。它会产生 set, the, shape, to, semi, transparent, by, calling, set, trans* **空格分析器**空格分析器在空格的地方划分文本。它会产生 Set, the, shape, to, semi-transparent, by, calling, set_trans(5)* **语言分析器**特定语言分析器可用于 很多语言。它们可以考虑指定语言的特点。例如 英语 分析器附带了一组英语无用词常用单词例如 and 或者 the 它们对相关性没有多少影响它们会被删除。 由于理解英语语法的规则这个分词器可以提取英语单词的 词干 。 英语 分词器会产生下面的词条 set, shape, semi, transpar, call, set_tran, 5 注意看 transparent、 calling 和 set_trans 已经变为词根格式。 ### 什么时候使用分析器 当我们 索引 一个文档它的全文域被分析成词条以用来创建倒排索引。 但是当我们在全文域 搜索 的时候我们需要将查询字符串通过 相同的分析过程 以保证我们搜索的词条格式与索引中的词条格式一致。 全文查询理解每个域是如何定义的因此它们可以做正确的事* 当你查询一个 全文 域时 会对查询字符串应用相同的分析器以产生正确的搜索词条列表。 * 当你查询一个 精确值 域时不会分析查询字符串而是搜索你指定的精确值。 举个例子 ES中每天一条数据 按照如下方式查询 GET /_search?q2014 # 12 results GET /_search?q2014-09-15 # 12 results ! GET /_search?qdate:2014-09-15 # 1 result GET /_search?qdate:2014 # 0 results ! 为什么返回那样的结果* date 域包含一个精确值单独的词条 2014-09-15。 * _all 域是一个全文域所以分词进程将日期转化为三个词条 2014 09 和 15。当我们在 _all 域查询 2014它匹配所有的12条推文因为它们都含有 2014 GET /_search?q2014 # 12 results 当我们在 _all 域查询 2014-09-15它首先分析查询字符串产生匹配 2014 09 或 15 中 任意 词条的查询。这也会匹配所有12条推文因为它们都含有 2014 GET /_search?q2014-09-15 # 12 results ! 当我们在 date 域查询 2014-09-15它寻找 精确 日期只找到一个推文 GET /_search?qdate:2014-09-15 # 1 result 当我们在 date 域查询 2014它找不到任何文档因为没有文档含有这个精确日志 GET /_search?qdate:2014 # 0 results !