ES知识点

Elasticsearch

​ 在生产环境实践经验,最佳的情况下,是仅仅在 ES中就存少量的数据,就是你要用来搜索的那些索引,如果内存留给 filesystem cache 的是 100G,那么你就将索引数据控制在 100G 以内,这样的话,你的数据几乎全部走内存来搜索,性能非常之高,一般可以在 1 秒以内。

结合Hbase优化:Hbase 的特点是适用于海量数据的在线存储,就是对 hbase 可以写入海量数据,但是不要做复杂的搜索,做很简单的一些根据 id 或者范围进行查询的这么一个操作就可以了。从 es 中根据 name 和 age 去搜索,拿到的结果可能就 20 个 doc id ,然后根据 doc id 到 hbase 里去查询每个 doc id 对应的完整的数据,给查出来,再返回给前端。

问题:

你好兄弟,兄弟你好在模糊查询中可能就会有不同的情况

8.1 倒排索引

8.1.1 elasticsearch 的倒排索引是什么

面试官:想了解你对基础概念的认知。
解答:通俗解释一下就可以。传统的我们的检索是通过文章,逐个遍历找到对应关键词的位置。而倒排索引,是通过分词策略,形成了词和文章的映射关系表,这种词典+映射表即为倒排索引。有了倒排索引,就能实现 o(1)时间复杂度的效率检索文章了,极大的提高了检索效率。

请添加图片描述

单词词典是以B+树的形式存在
请添加图片描述

优缺点

查询的时候由于可以一次得到查询关键字所对应的所有文档,所以查询效率高于正排索引

由于每个字或对应的文档数量都在动态变化,所以倒排表的简历和维护都比较复杂,因为要更新B+树

8.2 工作原理

es 写数据过程
1. 客户端选择一个 node 发送请求过去,这个 node 就是 coordinating node (协调节点)
2. coordinating node 对 document 进行路由,将请求转发给对应的 node(有 primary shard)。
3. 实际的 node 上的 primary shard 处理请求,然后将数据同步到 replica node 。
4. coordinating node 如果发现 primary node 和所有 replica node 都搞定之后,就返回响应结果给客户端。

请添加图片描述

数据预热:

举个例子,拿微博来说,你可以把一些大 V,平时看的人很多的数据,你自己提前后台搞个系统,每隔一会儿,自己的后台系统去搜索一下热数据,刷到 filesystem cache 里去,后面用户实际上来看这个热数据的时候,他们就是直接从内存里搜索了,很快。

或者是电商,你可以将平时查看最多的一些商品,比如说 iphone 8,热数据提前后台搞个程序,每隔 1 分钟自己主动访问一次,刷到 filesystem cache 里去。

对于那些你觉得比较热的、经常会有人访问的数据,最好做一个专门的缓存预热子系统,就是对热数据每隔一段时间,就提前访问一下,让数据进入 filesystem cache 里面去。这样下次别人访问的时候,性能一定会好很多。

冷热分离

es 可以做类似于 mysql 的水平拆分,就是说将大量的访问很少、频率很低的数据,单独写一个索引,然后将访问很频繁的热数据单独写一个索引。最好是将冷数据写入一个索引中,然后热数据写入另外一个索引中,这样可以确保热数据在被预热之后,尽量都让他们留在 filesystem os cache 里,别让冷数据给冲刷掉。

基本查询最终都会通过id进行查询

8.3、Elasticsearch查询流程

1.查询阶段

在初始化查询阶段(query phase),查询会向索引中的每个分片副本(原本或副本)广播。每个分片在本地执行搜索并且建立了匹配document的优先队列(priority queue)。

优先队列

一个优先队列(priority queue is)只是一个存有前n个(top-n)匹配document的有序列表。这个优先队列的大小由分页参数from和size决定。例如,下面这个例子中的搜索请求要求优先队列要能够容纳100个document。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a7r38GeT-1651912131806)(/Users/hello/Desktop/面试/image/截屏2022-03-15 19.13.38.png)]

查询阶段包含以下三步:

  • 客户端发送一个 search(搜索) 请求给 Node 3 , Node 3 创建了一个长度为 from+size 的空优先级队列。
  • Node 3 转发这个 搜索请求到索引中每个分片的原本或副本。每个分片在本地执行这个查询并且结果将结果到一个大小为 from+size 的有序本 地优先队列里去。
  • 每个分片返回document的ID和它优先队列里的所有document的排序值给协调节点 Node 3 。
    Node 3 把 这些值合并到自己的优先队列里产生全局排序结果。
2.取回阶段

查询阶段辨别出那些满足搜索请求的document,但我们仍然需要取回那些document本身。这就是取回阶段的工作,如图分布式搜索的取回阶段所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GFebNzeJ-1651912131806)(/Users/hello/Desktop/面试/image/截屏2022-03-15 19.13.27.png)]

分发阶段由以下步骤构成:

  • 协调节点辨别出哪个document需要取回,并且向相关分片发出 GET 请求。

  • 每个分片加载document并且根据需要丰富(enrich)它们,然后再将document返回协调节点。

  • 一旦所有的document都被取回,协调节点会将结果返回给客户端。 协调节点先决定哪些document是实际(actually)需要取回的。例如,我们指定查询 { “from”: 90, “size”: 10} ,那么前90 条将会被丢弃,只有之后的10条会需要取回。这些document可能来自与原始查询请求相关的某个、某些或者全部分片。

  • 协调节点为每个持有相关document的分片建立多点get请求然后发送请求到处理查询阶段的分片副本。 分片加载document主体—— _source field。如果需要,还会根据元数据丰富结果和高亮搜索片断。一旦协调节点收到所有结 果,会将它们汇集到单一的回答响应里,这个响应将会返回给客户端。
    原文链接:https://blog.csdn.net/xiaozhangnomoney/article/details/123083615

总流程

es 最强大的是做全文检索,就是比如你有三条数据:
你根据 java 关键词来搜索,将包含 java 的 document 给搜索出来。es 就会给你返回:java 真好玩儿啊,java 好难学啊。

  • 客户端发送请求到一个 coordinate node 。
  • 协调节点将搜索请求转发到所有的 shard 对应的 primary shard 或 replica shard ,都可以。
  • query phase:每个 shard 将自己的搜索结果(其实就是一些 doc id )返回给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最终结果。
  • fetch phase:接着由协调节点根据 doc id 去各个节点上拉取实际的 document 数据,最终返回给客户端。

写请求是写入 primary shard,然后同步给所有的 replica shard;读请求可以从 primary shard 或 replica shard 读取,采用的是随机轮询算法。

4、倒排索引的更新策略

搜索引擎需要处理的文档集合往往都是动态集合,即在建好初始的索引后,不断有新文档进入系统,同时原先的文档集合内有些文档可能被删除或更改。

动态索引通过在内存中维护临时索引,可以实现对动态文档和实时搜索的支持服务器内存总是有限的,随着新加入系统的文档越来越多,临时索引消耗的内存也会随之增加。

当最初分配的内存将被使用完时,要考虑将临时索引的内容更新到磁盘索引中,以释放内存空间来容纳后续的新进文档。

索引基本更新思想:

  • 倒排索引就是对初始文档集合建立的索引结构,一般单词词典都存储在内存,对应的倒排列表存储在磁盘文件中
  • 临时索引是在内存中实时建立的倒排索引,其结构和前述的倒排索引是一样的,区别在于词典和倒排列表都在内存中存储
  • 新文档进入系统时,实时解析文件并将其加入到临时索引结构中。
  • 删除文档列表则用来存储已被删除的文档的相应的文档ID,形成一个文档ID列表
  • 修改文档可以认为是旧文档先被删除,然后系统在增加一篇新的文档,通过这种间接方式实现对内容更改的支持。

5、倒排索引四种更新策略

常用的索引更新策略主要有四种:完全重建策略、再合并策略、原地更新策略及混合策略

  • 完全重建策略:新增文档到达一定数量,将新增文档和原先的老文档整合,然后利用静态索引创建方法对所有文档重建索引,新索引建立完成后老索引会被遗弃。此法代价高,但是主流商业搜索引擎一般是采用此方式来维护索引的更新(这句话是书中原话)
  • 再合并策略:当新增文档进入系统,解析文档,之后更新内存中维护的临时索引,文档中出现的每个单词,在其倒排表列表末尾追加倒排表列表项;一旦临时索引将指定内存消耗光,即进行一次索引合并,这里需要倒排文件里的倒排列表存放顺序已经按照索引单词字典顺序由低到高排序,这样直接顺序扫描合并即可。其缺点是:因为要生成新的倒排索引文件,所以对老索引中的很多单词,尽管其在倒排列表并未发生任何变化,也需要将其从老索引中取出来并写入新索引中,这样对磁盘消耗是没必要的。
  • 原地更新策略:试图改进再合并策略,在原地合并倒排表,这需要提前分配一定的空间给未来插入,如果提前分配的空间不够了需要迁移。实际显示,其索引更新的效率比再合并策略要低。
    - 混合策略:出发点是能够结合不同索引更新策略的长处,将不同索引更新策略混合,以形成更高效的方法。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43673156/article/details/124633775
今日推荐