跳至主要內容

《Elasticsearch 实战》笔记

钝悟...大约 12 分钟笔记数据库数据库搜索引擎数据库Elasticsearch

《Elasticsearch 实战》笔记

第 1 章 Elasticsearch 介绍

  • Elasticsearch 是构建在 Apache Lucene 基础之上的开源分布式搜索引擎。
  • Elasticsearch 常见的用法是索引大规模的数据,这样可以运行全文搜索和实时数据统计。
  • Elasticsearch 提供的特性远远超越了全文搜索。例如,可以调优搜索相关性并提供搜索建议。
  • 对于数据的索引和搜索,以及集群配置的管理,都可以使用 HTTP API 的 JSON,并获得 JSON 应答。
  • 可以将 Elasticsearch 当作一个 NoSQL 的数据存储,包括了实时性搜索和分析能力。它是面向文档的,默认情况下就是可扩展的。
  • Elasticsearch 自动将数据划分为分片,在集群中的服务器上做负载均衡。这使得动态添加和移除服务器变得很容易。分片也可以复制,使得集群具有容错性。

第 2 章 深入功能

  • Elasticsearch 默认是面向文档的、可扩展的且没有固定模式(schema)的。
  • 尽管可以使用默认设置来组建集群,但在继续前行之前至少应该调整一些配置。例如, 集群的名称和堆的大小。
  • 写请求在主分片中分发,然后复制到这些主分片的副本分片。
  • 搜索在多组完整数据上轮询执行,每组数据由主分片或副本分片组成。接收搜索请求的节点将来自多份分片的部分结果进行聚合,然后将综合的结果返 回给应用程序。
  • 可以通过 HTTP 请求的 JSON 有效载荷,发送新的文档和搜索参数,然后获取 JSON 应答。

第 3 章 索引、更新和删除数据

  • 映射定义了文档中的字段,以及这些字段是如何被索引的。Elasticsearch 是无模式的,是因为映射是自动扩展的。不过在实际生产中,需要经常控制哪些被 索引,哪些被存储,以及如何存储。
  • 文档中的多数字段是核心类型,如字符串和数值。这些字段的索引方式对于 Elasticsearch 的表现以及搜索结果的相关性有着很大的影响。
  • 单一字段也可以包含多个字段或取值。我们了解了数组和多字段,它们让你在单一字段中拥有同一核心类型的多个实例。
  • 除了用于文档的字段,Elasticsearch 还提供了预定义的字段,如 _source_all。配置这些字段将修改某些你并没有显式提供给文档的数据,但是对于性能和功能都有很大影响。例如,可以决定哪些字段需要在 _all里索引。
  • 由于 Elasticsearch 在 Lucene 分段里存储数据,而分段一旦创建就不会修改,因此更新文档意味着检索现存的文档,将修改放入即将索引的新文档中,然后删除旧的索引。
  • 当 Lucene 分段异步合并时,就会移除待删的文档。这也是为什么删除整个索引要比删除单个或多个文档要快——索引删除只是意味着移除磁盘上的文件,而且无须合并。
  • 在索引、更新和删除过程中,可以使用文档版本来管理并发问题。对于更新而言,如果因为并发问题而导致更新失败了,可以告诉 Elasticsearch 自动重试。

第 4 章 搜索数据

  • 人类语言类型的查询,如 match 和 query_string 查询,对于搜索框而言是非常合适的。
  • match 查询对于全文搜索而言是核心类型,但是 query_string 查询更为灵活,也更为复杂,因为它暴露了全部的 Lucene 查询语法。
  • match 查询有多个子类型:boolean、phrase 和 phrase_prefix。主要的区别在于 boolean 匹配单独的关键词,而 phrase 考虑了多个单词在词组里的顺序。
  • 像 prefix 和 wildcard 这样的特殊查询,Elasticsearch 也是支持的。
  • 要过滤某个字段不存在的文档,请使用 missing 过滤器。
  • exists 过滤器恰恰相反,它只返回拥有指定字段值的文档。

第 5 章 分析数据

  • 分析是通过文档字段的文本,生成分词的过程。在 match 查询这样的查询中,搜索字符串会经过同样的过程,如果一篇文档的分词和搜索字符串的分词相匹配,那么它就会和搜索匹配。
  • 通过映射,每个字段都会分配一个分析器。分析器既可以在 Elasticsearch 配置或索引设置中定义,也可以是一个默认的分析器。
  • 分析器是处理的链条,由一个分词器以及若干在此分析器之前的字符过滤器、在此分词器之后的分词过滤器组成。
  • 在字符串传送到分词器之前,字符过滤器用于处理这些字符串。例如,可以使用映射字符过滤器将字符“&”转化为“and”。
  • 分词器用于将字符串切分为多个分词。例如,空白分词器将使用空格来划分单词。
  • 分词过滤器用于处理分词器所产生的分词。例如,可以使用词干提取来将单词缩减为其词根,并让搜索在该词的复数和单数形式上都可以正常运作。
  • N 元语法分词过滤器使用单词的部分来产生分词。例如,可以让每两个连续的字符生成一个分词。如果希望即使搜索字符串包含错误拼写,搜索还能奏效,那么这个就很有帮助了。
  • 侧边 N 元语法就像 N 元语法一样,但是它们只从单词的头部或结尾开始。例如,对于 “event”可以获得 e、ev 和 eve 分词。
  • 在词组级别,滑动窗口分词过滤器和 N 元语法分词过滤器相似。例如,可以使用词组里每两个连续的单词来生成分词。当用户希望提升多词匹配的相关性时,例如,在产品的简短描述中,这一点就很有帮助。

第 6 章 使用相关性进行搜索

  • 词条的频率和词条出现在文档中的次数被用于计算查询词条的得分。
  • Elasticsearch 有很多工具来定制和修改得分。
  • 重新计算部分文档的得分将会减小评分机制的影响。
  • 使用解释 API 接口来理解文档是如何被评分的。
  • Function_score 查询使用户拥有了对文档得分最终极的控制权。
  • 理解字段数据缓存,将有助于用户理解 Elasticsearch 集群是如何使用内存的。
  • 如果字段数据缓存消耗了过多的内存,可以使用像 doc_values 这样的替换方案。

第 7 章 使用聚集来探索数据

  • 通过结果文档的词条计数和统计值计算,聚集帮助用户获得查询结果的概览。
  • 聚集是 Elasticsearch 中一种新形式的切面,拥有更多类型,还可以将它们组合以获取对数据更深入的理解。
  • 主要有两种类型的聚集:桶型和度量型。
  • 度量型聚集计算一组文档上的统计值,如某个数值型字段的最小值、最大值或者平均值。
  • 某些度量型聚集通过近似算法来计算,这使得它们具有比精确聚集更好的扩展性。百分位 percentiles 和 cardinality 聚集就是如此。
  • 桶型聚集将文档放入 1 个或多个桶中,并为这些桶返回计数器。例如,某个论坛中最流行的帖子。用户可以在桶型聚集中嵌入子聚集,对于父聚集所产生的每个桶一次性地运行子聚集。比如,对于匹配每个标签的博客帖,可以使用嵌套来获得该结果集的平均评论数。
  • top_hits 聚集可以用作一种子聚集,来实现结果的分组。
  • terms 聚集通常用于发现活跃的用户、常见地址、热门的物品等场景。其他的多桶型聚集是 terms 聚集的变体,如 signif icant_terms 聚集,返回了相对于整体索引而言,查询结果集中经常出现的词。
  • range 和 date_range 聚集用于对数值和日期数据的分类。而 histogram 和 date_histogram 聚集是类似的,不过它们使用固定的间距而不是人工定义的范围。
  • 单桶型聚集,如 global, filter, filters 和 missing 聚集,可以修改用于其他聚集运行的文档集合,因为默认情况下文档集合是由查询所确定的。

第 8 章 文档间的关系

  • 对象映射,对于一对一关系最有用。
  • 嵌套文档和父子结构,处理了一对多的关系。
  • 反规范化和应用端的连接,对于多对多的关系而言最有帮助。

即使是在本地进行,连接操作仍然损害了性能。所以,通常情况下将尽量多的属性放入单个 文档是个好主意。对象映射能起到作用是因为它允许文档中存在层级结构。这里搜索和聚集就像在扁平结构的文档上一样运作。需要使用全路径来指向字段,就像 location.nameopen in new window

  • 嵌套文档通常是在索引的时候进行连接,将多个 Lucene 文档放入单个分块。对于应用,分块看上去就像一篇单独的 Elasticsearch 文档。
  • _parent 字段允许你在同一索引中将一篇文档指向其父辈,也就是另一篇不同类型的文档。Elasticsearch 将使用路由来确保父辈和子辈存储在同一分片上,这样查询的时候只需 要进行本地连接。

可以使用下面的查询和过滤器来搜索嵌套和父子文档。

  • nested 查询和过滤器。
  • has_child 查询和过滤器。
  • has_parent 查询和过滤器。

第 9 章 向外扩展

  • Elasticsearch 集群是如何组建的、是如何由多个节点构成的,每个节点包含了多个索引,而每个索引又是由多个分片组成。
  • 当节点加入 Elasticsearch 集群的时候会发生什么。
  • 主节点是如何选举的。
  • 删除和停用节点。
  • 使用 __cat API 接口来了解你的集群。
  • 什么是过度分片,以及如何使用它来规划集群的未来成长。
  • 如何使用别名和路由来提升集群的灵活性和可扩展性。

第 10 章 提升性能

  • 使用 bulk 批量 API 接口将多个 index、create、update 或者 delete 操作合并到同一个请求。
  • 为了组合多个 get 或多个 search 请求,你分别可以使用多条获取或多条搜索的 API。
  • 当索引缓冲区已满、事务日志过大或上次冲刷过去太久的时候,冲刷的操作将内存中的 Lucene 分段提交到磁盘。
  • 刷新使得新的分段,无论是否冲刷,都可以用于搜索。在索引操作密集的时候,最好降低刷新的频率或者干脆关闭刷新。
  • 合并的策略可以根据分段的多少来调优。较少的分段使得搜索更快,不过合并需要花费更多的 CPU 时间。较多的分段使得合并时间更少、索引更快,但是会导致搜索变慢。
  • 优化的操作会强制合并,对于处理很多搜索请求的静态索引,这可以很好的运作。
  • 存储限流可能会使合并落后于更新,限制了索引的性能。如果你的高速的 I/O, 放宽或者取消这个限制。
  • 组合使用在 bool 过滤中的位集合过滤器和 and/or/not 过滤中的非位集合过滤器。
  • 如果你的索引是静态不变的,在分片查询缓存中缓存数量和聚集。
  • 监控 JVM 堆的使用情况,预留足够的内存空间,这样就不会遇到频繁的垃圾回收或者 OOM 错误,但是同时也要给操作系统的缓存留出一些内存。
  • 如果首次查询太慢,而且你也不介意较慢的索引过程,请使用索引预热器。
  • 如果有足够的空间存储较大的索引,请使用 N 元语法和滑动窗口而不是模糊、通配或词组查询,这会使你的搜索运行得更快。
  • 在索引之前,使用所需的数据在文档中创建新的字段,这样通常可以避免使用脚本。
  • 合适的时候,在脚本中尝试使用 Lucene 表达式、词条统计和字段数据。
  • 如果脚本不会经常变化,请参考附录 B, 学习如何在 Elasticsearch 插件中书写一个本地脚本。
  • 如果在多个分片之中没有均衡的文档频率,使用 dfs_query_then_fetcho
  • 如果不需要任何命中的文档,请使用 count 搜索类型。如果需要很多命中的文档,请使用 scan 搜索类型。

第 11 章 管理集群

  • 默认映射为索引中重复的相似映射创建提供了便利。
  • 别名允许使用单个名字查询多个索引,因此让你可以按需分割数据。
  • 集群健康的 API 提供了一个简单的方式来测量集群、节点和分片的整体健康状态。
  • 使用慢索引和慢查询的日志,有助于诊断可能影响集群性能的索引和查询操作。
  • 充分理解 JVM 虚拟机、Lucene 和 Elasticsearch 是如何分配和使用内存的,可以预防操作 系统将进程交换到磁盘。
  • 快照 API 为使用网络存储的集群提供了便捷的备份和恢复方法,资料库插件将这个功能 扩展到了共用的云服务之上。

参考资料

评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.7