Elasticsearch:搜索架构

Elasticsearch

全文检索的复杂性

为了理解为什么全文搜索是一个很难解决的问题,让我们想一个例子。 假设你正在托管一个博客发布网站,其中包含数亿甚至数十亿的博客文章,每个博客文章包含数百个单词,类似于 CSDN。

执行全文搜索意味着任何用户都可以搜索 “java” 或 “学习编程” 之类的内容,并且你需要在几毫秒内找出出现这些单词的所有博客文章。 不仅如此,你还需要根据多种因素对这些博客文章进行评分,例如,这些单词在这些帖子中出现的频率,或者每个帖子有多少拍手或评论,或者你可能想在顶部显示最近写的帖子,或者你可能想突出显示某些顶级内容创建者,或者你可能想将这些单词出现在标题中的帖子放在更高的位置,等等。

另外,你知道用户可能会意外地犯错,因此你需要处理这个问题。 你还需要考虑单词的顺序,“学习 Java” 应该与 “Java 学习” 具有相似的含义,但有时顺序会更重要,例如 “二氧化碳” 可能与 “化碳二氧” 有很大不同 ”(这只是一个例子,我不知道这是不是一个词,我不懂化学)。

仅仅匹配单词也是行不通的。 有些词比其他词为帖子提供了更多的上下文。 例如,当用户搜索 “Java” 时,标题为 “学习 Java” 的博客文章是相关结果,但当用户仅搜索 “学习” 时,相关性就不那么高了。 当用户搜索 “编程” 时,这也是一篇相关的博客文章,即使该词从未出现在博客文章中!

这些挑战极其复杂,乍一看,它们似乎几乎无法搜索,但你打开一个订餐应用程序,在数千家餐厅的数万种菜肴中进行搜索,或者搜索执行特定工作的人员 每天在 Linkedin 上数亿用户中发挥作用,或在数十亿博客文章中搜索特定主题。

Elasticsearch 是一个旨在解决这个问题的数据库。 让我们看看它是如何工作的。

理解术语

在开始使用 Elasticsearch 之前,我们应该先熟悉一下术语。 为了更好地理解事情,让我们举个例子。 假设你在 Elasticsearch 上存储博客文章。

Nodes

节点只是单独的 Elasticsearch 进程。

通常,你会在每台机器上运行一个 Elasticsearch 进程,因此更容易将它们视为单独的服务器。 这些进程中的每一个都独立于其他进程运行,并且仅通过公共网络连接。 Elasticsearch 通常作为大型分布式系统运行,这意味着你通常会运行多台机器(或节点)。

一旦所有这些节点一起运行,它们就可以形成一个“集群 (cluster)”。 集群不仅仅是各个部分的总和; 它不仅仅是一定数量的孤立运行的节点。 相反,节点知道它们是集群的一部分,并在执行不同操作时相互通信。 在某种程度上,Elasticsearch 集群是一个全新的实体。

Elasticsearch 集群有大量的职责,例如存储文档、搜索这些文档、执行不同的分析和聚合任务、备份数据等。它还必须进行自我管理,例如确保哪些节点是健康的,哪些节点是健康的 因此,在任何大型集群中,为不同的操作域提供不同的节点非常重要。

虽然可能存在许多这样的区别,但其中一个明显的区别是存储数据并执行繁重的数据密集型任务的节点,例如搜索和拥有管理集群的专用节点、确保节点健康、决定将哪个文档发送到哪个节点等。创建这种区别很重要,因为这些节点甚至可能需要不同的硬件资源。 数据节点可能需要更大的机器,具有更高性能的网络和磁盘以及大量内存,而执行更多管理任务的节点可能有完全不同的要求。

存储数据和搜索的节点可以是 “数据 (data)” 节点,执行更多管理任务的节点可以称为 “主 (master)” 节点。

有关节点的更多描述,请阅读文章 “Elasticsearch 中的一些重要概念: cluster, node, index, document, shards 及 replica”。事实上,除了 data 及 master 节点之外,Elasticsearch 还有其它类型的节点。

索引和文档

文档是你存储在 Elasticsearch 中的简单 JSON 对象。 它们与关系数据库中的行或 MongoDB 中的单个文档同义。

对于我们的示例,单个文档可能如下所示 -

{"_id": "9a91473c-522e-4174-bf7f-f55293b8e526","post_title": "Learning about Elasticsearch","author_name": "Zhang san",.....
}

索引是相似文档的集合。 它们与关系数据库中的表(其中每一行都是单个项目)和 MongoDB 中的集合同义。

因此,对于我们的示例,我们将有一个存储博客文章的索引。 我们称之为 blog_posts。 如果我们想存储一些其他数据,比如说用户,我们可以创建另一个索引,用户。 blog_posts 索引存储各种博客文章文档,每个文档都包含与博客文章相关的字段,而 users 索引存储包含 user_name、email 等字段的用户文档。

Shards - 分片

索引中的文档被分为多个分片。 每个分片存储索引文档的某个子集。 稍后我们会理解为什么将文档划分为多个分片很重要,但现在我们先关注分片的工作原理。

例如,假设我们有一些 blog_posts 文档。

如果我们为此索引创建三个分片(例如分片 A、分片 B、分片 C),那么我们所有的文档都将分为这三个分片。

然后,这些分片将驻留在集群中的不同数据节点中。

这很重要,因为将这些文档分布到多个分片中可以为你带来多种优势,

  1. 搜索可以并行化。 当用户想要执行搜索时,将搜索所有文档。 如果在单个服务器上搜索所有文档,这将非常耗时。 分片允许你将文档分布在多个服务器上,从而允许在不同的硬件上并行执行单个搜索。
  2. 其他查询,例如插入文档(在 Elasticsearch 中称为索引)或通过特定 ID 检索文档,将分布在所有节点之间。

然而,我们的架构仍然不完整。 如果一个节点死亡,它存储的分片(以及这些分片上的数据)将永远丢失。

让我们看看主分片 (primary shard) 和副本分片 (replica shard) 以更好地理解这一点。

主分片、副本分片和不同分片(distinct shards)

只是对到目前为止我们已经介绍过的内容的快速修订:单个分片包含多个文档。 例如,

每个分片都位于一个特定的节点上,

到目前为止,我们架构的一个问题是,如果某个特定节点(假设 10.192.0.3)挂掉或变得不可用,“分片 A”中的数据将永远丢失。 为了解决这个问题,我们引入 “副本分片” 和 “主分片” 的概念。 主分片是我们到目前为止一直在讨论的分片(现在将它们标记为“主(Primary)”),

副本分片 (replica shards) 是仅存储主分片与存储关联的相同文档的分片。 因此,副本分片只是 “复制” 或复制特定的主分片。

在上图中,你可以看到每个主分片都有一个关联的副本分片,并且每个副本分片存储与主分片相同的文档。 在这里,我们每个主分片有一个副本分片,但我们也可以将这个数字修改为更大 —— 每个主分片可以有两个副本。 现在,我们继续每个主分片一个副本。

这些副本分片不需要与主分片位于同一节点上(每个副本位于与其主分片不同的节点上是有意义的)。 主分片和副本分片都分布在集群的所有节点上。

在上图中,每个分片的主分片和副本分片存在于不同的节点上。 单节点故障不会导致数据不可用。 例如,如果节点 10.192.0.3 不可用,则分片 A 和分片 B 的数据都不会丢失。 分片 A 的数据在节点 10.192.0.2 上仍然可用,同样,分片 B 的数据在节点 10.192.0.1 上仍然可用。

这意味着我们的集群可以在单个节点丢失的情况下幸存下来。 然而,我们的集群可能无法在失去两个节点的情况下幸存下来。 例如,10.192.0.3 和10.192.0.2 节点同时丢失将导致分片 A 的文档完全不可用。 我们可以配置更高的复制,例如,每个主分片使用两个副本来缓解这种情况。 但现在,我们继续每个主分片一个副本。

最后,我们来看看 “不同分片(distinct shards)”。 不同分片只是一个术语,用于将相同的主分片和副本分组在一起。 因此,在我们当前的示例中,我们有三个主分片、三个副本分片(每个主分片 1 个副本)、六个总分片(三个主分片 + 三个副本)和三个不同的分片,

将主分片及其相应的副本分片分组为单个 “不同分片” 如此重要的原因将会变得清晰。 重申一下,“不同分片” 只是分片的逻辑分组,并且确实影响了我们到目前为止所绘制的架构。

我们来看几个真实的查询示例

为了结束架构讨论,让我们看看搜索查询和获取查询在我们的示例集群中如何工作。

第一步…

让我们看看执行搜索或获取查询时会发生什么。

这就是我们集群现在的样子,

客户端 API 向这些节点中的任何一个发送搜索或获取查询。 它发送查询的节点成为 “协调器(coordinator)” 节点。 更大的集群甚至可能有专用的协调器节点(专用协调器节点是不具有任何节点角色的节点,它只可以接收客户端的请求),但我们现在不需要这样做。在文章的开始部分,我们可以看到一个更为详细的架构图。

该协调器节点负责接收请求、与其他节点通信(如果需要)、组合从多个节点接收到的结果并返回结果。

搜索

搜索时,搜索查询必须命中所有不同的分片。 这是因为所有分片都使用它们所保存的文档单独在本地执行搜索。

然后,协调器节点将与多个节点通信,以从每个不同的分片获取数据。 回想一下,在我们的示例中,每个主分片有一个副本,因此查询仅命中集群中的一半分片(主分片或副本分片)。

有关详细的如何完成一个请求,请阅读文章 “Elasticsearch:数据是如何被读取的?”。

根据 id 来进行查询

当通过 ID 对特定文档执行查询时,协调器节点已经知道哪个分片将保存该文档,因此无需命中所有节点。 它只是将请求转发到存储数据的节点并将响应发送回客户端。这是因为每当一个文档进来后,根据文档的 id 会自动进行 hash 计算,并存放于计算出来的 shard 实例中,这样的结果可以使得所有的 shard 都比较有均衡的存储,而不至于有的 shard 很忙。

shard_num = hash(_routing) % num_primary_shards

我们可以根据文档的 id 来计算出来是哪一个 shard。

结论

这是对 Elasticsearch 架构的非常简单的介绍。希望大家能对 Elasticsearch 的集群架构有一个比较清楚的认识。更多关于 Elasticsearch 的术语及概念介绍,请详细阅读文章 “Elasticsearch 中的一些重要概念: cluster, node, index, document, shards 及 replica”。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/133584.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

11月7日 mybatis缓存

mybatis的缓存 缓存的条件:必须要有存在的数据 一级缓存: SqlSession级别缓存.存储的数据.只能在同一个SalSession有效.默认开启 二级缓存: SqlSessionFactory级别的缓存. SqlSessionFactory只有一个的,单例,全局共享的,不同的 SqlSession共享,默认没有…

基于Java+SpringBoot+Mybaties-plus+Vue+ElementUI 失物招领小程序 设计与实现

一.项目介绍 失物招领小程序 用户登录、忘记密码、退出系统 发布失物 和 发布招领 查看我发布的失物和招领信息 失捡物品模块可以查看和搜索所有用户发布的信息。 二.环境需要 1.运行环境:java jdk1.8 2.ide环境:IDEA、Eclipse、Myeclipse都可以&#…

Linux系统下一些配置建议整理

1. 【推荐】高并发服务器建议调小 TCP 协议的 time_wait 超时时间。 说明:操作系统默认 240 秒后,才会关闭处于 time_wait 状态的连接,在高并发访问下,服 务器端会因为处于 time_wait 的连接数太多,可能无法建立新的…

总结Kibana DevTools如何操作elasticsearch的常用语句

一、操作es的工具 ElasticSearch HeadKibana DevToolsElasticHQ 本文主要是总结Kibana DevTools操作es的语句。 二、搜索文档 1、根据ID查询单个记录 GET /course_idx/_doc/course:202、term 匹配"name"字段的值为"6789999"的文档 类似于sql语句中的等…

电子式电表和智能电表哪个更适合家用?

随着科技的发展,家用电力设备也在不断升级。电子式电表和智能电表作为两种常见的电表类型,究竟哪个更适合家用呢?今天,小编将会从多个角度进行全面分析,帮助大家做出明智的选择。 一、工作原理及准确性比较 1.电子式电…

工业控制系统产业联盟理事长辛耀中一行莅临麒麟信安考察交流

11月4日下午,工业控制系统产业联盟理事长辛耀中率联盟专家莅临麒麟信安考察交流,并先后来到麒麟信安、湖南欧拉生态创新中心展厅参观,麒麟信安董事长杨涛、高级副总裁陈松政、副总裁王攀等热情接待。 在麒麟信安展厅,副总裁王攀对…

JSP 学生成绩查询管理系统eclipse开发sql数据库serlvet框架bs模式java编程MVC结构

一、源码特点 JSP 学生成绩查询管理系统 是一套完善的web设计系统,对理解JSP java编程开发语言有帮助,比较流行的servlet框架系统具有完整的源代码和数据库,eclipse开发系统主要采用B/S模式 开发。 java 学生成绩查询管理系统 代码下载链接…

解决SpringBoot项目端口被占用的问题

问题描述: 在Window环境下,运行SpringBoot 项目时,出现端口被占用的问题: 解决方案: 1. 查看对应端口的进程号 netstat -ano | findstr 80802. 查看对应进程号的信息 tasklist | findstr 477963. 根据进程号 kill 进程…

【Web】在前端中,HTML<meta>标签

<meta>实例 <head><meta name"description" content"免费在线教程"><meta name"keywords" content"HTML,CSS,XML,JAVASCRIPT"><meta name"author" content"runoob"><meta char…

2.3 - 网络协议 - ICMP协议工作原理,报文格式,抓包实战

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 ICMP协议 1、ICMP协议工作原理2、ICMP协议报文格式…

[C/C++]数据结构 链表OJ题: 反转链表

描述: 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表 示例: 方法一: 让链表指向反向 如图所示: 代码思路: struct ListNode* reverseList(struct ListNode* head) {struct ListNode* n1NULL;struct ListNode* n2head;struct ListNode*…

Moco框架初探

一、简介 Moco是一个搭建模拟服务器的工具&#xff0c;其支持API和独立运行两种方式&#xff0c;前者通常在junit等测试框架中使用&#xff0c;后者则是通过运行一个jar包开启服务。 二、用途 主要用于实现mock技术 1、后端接口开发未完成情况下&#xff0c;通过moco模拟接…

猫头虎分享从Python到JavaScript传参数:多面手的数据传递术

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

网络数据包传感器简化流量监控

数据包捕获基于数据包镜像的概念&#xff0c;可用于深度数据包检查、测量应用程序的响应时间以及监视服务器、网络和用户行为&#xff0c;该技术还可用于对需要特定信息的某些区域进行广泛分析&#xff0c;尽管它有效&#xff0c;但并非在所有情况下都是必要的。要分析和管理流…

企业数字化转型与供应链效率-基准回归复刻(2007-2022年)

参照张树山&#xff08;2023&#xff09;的做法&#xff0c;本团队对来自统计与决策《企业数字化转型与供应链效率》一文中的基准回归部分进行复刻。文章实证检验企业数字化转型对供应链效率的影响。用年报词频衡量上市公司数字化转型程度&#xff0c;以库存周转天数来衡量供应…

mysql 全文检索 demo

mysql5.6.7之后开始支持中文全文检索一直没用过&#xff0c;这次试试。 创建表 CREATE TABLE articles (id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,title VARCHAR (200),body TEXT,FULLTEXT (title, body) WITH PARSER ngram ) ENGINE INNODB DEFAULT CHARSETut…

Docker学习——④

文章目录 1、Docker Image&#xff08;镜像&#xff09;2、镜像命令详解2.1 docker rmi2.2 docker save2.3 docker load2.4 docker image inspect2.5 docker history2.6 docker image prune 3、镜像综合实战3.1 离线镜像迁移3.2 镜像存储的压缩与共享 1、Docker Image&#xff…

你知道在游戏开发中怎么将算法与其作用的对象隔离开来吗?

点击上方亿元程序员关注和★星标 引言 你可能知道的设计模式-访问者模式 大家好&#xff0c;今天我们要来聊一聊在游戏开发中非常实用的设计模式——访问者模式。访问者模式是一种将算法与对象结构分离的软件设计模式&#xff0c;它可以让代码更加灵活、可扩展&#xff0c;同…

那些年遇到过的问题与解决方案

目录 一、当我们想进行数据回显并且只是让用户查看信息不能编辑时&#xff0c;置灰处理 二、多选框初始化加载问题 三、时间处理 获取当前年月日 时间自定义格式化 时间脱敏处理&#xff0c;去掉秒 四、input输入框处理 input输入框设定为只能输入0与正整数 刚进页面…

UE4 Niagara Module Script 初次使用笔记

这里可以创建一个Niagara模块脚本 创建出来长这样 点击号&#xff0c;输出staticmesh&#xff0c;点击它 这样就可以拿到对应的一些模型信息 这里的RandomnTriCoord是模型的坐标信息 根据坐标信息拿到位置信息 最后的Position也是通过Map Set的号&#xff0c;选择Particles的P…