为什么执行elasticsearch的api会出错
533 条件运算符和条件表达式
如果在条件语句中,只执行单个的赋值语句时, 常可使用条件表达式来实现。不但使程序简洁,也提高了运行效率。
条件运算符为和:,它是一个三目运算符,即有三个参与运算的量。
由条件运算符组成条件表达式的一般形式为:
表达式1 表达式2: 表达式3
其求值规则为:如果表达式1的值为真,则以表达式2 的值作为条件表达式的值,否则以表达式2的值作为整个条件表达式的值。
条件表达式通常用于赋值语句之中。
例如条件语句:
if(a>b) max=a;
else max=b;
可用条件表达式写为
max=(a>b)a:b;
启动过程
当ElasticSearch节点启动时,使用广播技术来发现同一集群中的其他节点(配置文件中的集群名称)并于它们连接。集群中会有一个节点被选为管理节点(master node),负责集群的状态管理以及在集群拓扑变化时做出反应,分发索引分片至集群的相应节点。
es写数据
1)客户端选择一个node发送请求,这个node就是coordinating node(协调节点)
2)协调节点对document进行路由,将请求转发给对应的node
3)node上的primary shard处理请求,然后将数据同步到replica shard
①先写入内存,并将 *** 作写入translog(数据不能被搜索,translog会在每隔5秒或者每次写入完成后写入磁盘)
②es每隔1秒(配置)进行一个刷新(refresh),写入内存到新数据被写入文件缓存中,并构成一个segement(数据能被搜索,未写入磁盘,可能丢失)
③每隔30分钟或者translog大小达到阈值,触发commit,执行fsync *** 作,当前translog被删除
(merge:每次refresh都会生成一个segment,segment过多会消耗资源,搜索变慢。A和B两个segment,小segmentC,A,B被读到内存中和Cmerge,生产大segement D,触发commit)
4)返回响应结果给客户端
es删除数据
磁盘上每个segment都有一个del文件关联,当发送删除请求时,在del中标记为删除,文档仍能够被搜索到,但会从结果中过滤掉。merge时del文件中标记但数据不会被包括在新的segment中
es读数据
1)客户端发送请求到协调节点
2)协调节点将请求转发到对应的shard(通过对doc key进行哈希( Murmur哈希算法 ),判断出doc在哪个shard上,然后对该shard查询)
3)每个shard将搜索结果(doc id)返回给协调节点,由协调节点进行数据的合并、排序、分页等 *** 作
4)协调节点根据doc id去各节点拉取document,返回给客户端
es更新数据
创建新文档时,es会为该文档分配一个版本号。对文档但每次更新都会产生一个新的版本号。当执行更新时,旧版本在del文件中标记删除,并且新版本在新segment中写入索引
并发控制
基于乐观锁和版本号
master选举
①如果集群中存在master,认可该master,加入集群
②如果集群中不存在master,从具有master资格的节点中选id最小的节点作为master
实时性(FileSystem Cache)
一个Index由若干segment组成,搜索时按segment搜索,索引一条segment后,每个段会通过fsync *** 作持久化到磁盘,而fsync *** 作比较耗时。
es中新增的document会被收集到indexing buffer区后被重写成一个segment,然后直接写入FileSystem Cache中,只要sengment文件被写入cache后,这个sengment就可以打开和查询,从而确保在短时间内就可以搜到。
ES支持集群模式,是一个分布式系统,其好处主要有两个∶
es集群由多个ES 实例组成。不同集群通过集群名字来区分,可通过 clustername 进行修改,默认为elasticsearch。每个ES实例本质上是一个 JVM 进程,且有自己的名字,通过 nodename 进行修改
ES集群相关的数据称为 cluster state ,主要记录如下信息∶节点信息,比如节点名称、连接地址等;索引信息,比如索引名称、配置等
可以修改 cluster state 的节点称为master节点,一个集群只能有一个 cluster state 存储在每个节点上,master维护最新版本并同步给其他节点
master节点是通过集群中所有节点选举产生的,可以被选举的节点称为 master-eligible 节点 ,相关配置如下: nodemaster: true
处理请求的节点即为coordinating节点,该节点为所有节点的默认角色,不能取消。路由请求到正确的节点处理,比如创建索引的请求到master节点
存储数据的节点即为data节点,默认节点都是data类型,相关配置如下∶ nodedata: true
谈及副本和分片两个概念之前,我们先说一下这两个概念存在的意义: 解决系统可用性和增大系统容量
我们想象这样一个场景,我们的数据只存放在一台ES服务器上,那么一旦这台ES出现宕机或者其他不可控因素影响的话,我们除了丧失了服务的可用性外,可能还存在着数据丢失的可能。同时,单机服务的存储容量也无法应对项目对大数据量的要求。
系统可用性可以分为 服务可用性 和 数据可用性
服务可用性 含义为:当前服务挂掉后,是否有其他服务器顶替当前节点提供服务支持。
数据可用性 含义为:当前服务挂掉后,存储在当前服务器上的数据,是否还可以对外提供访问和修改的服务。
副本可以理解为是某个数据的复制体,副本和源数据内容一致。副本的存在可以有效地满足系统可用性的需求,比如说,我们可以在原有节点的基础上复制一个和源节点一模一样的节点,这样一旦原有节点挂掉了,另外一个节点也还是可以替代源节点提供服务,而且复制出来的节点拥有和源节点一样的数据,这样也保障了数据可用性。
我们在上一小节讲到可以使用副本来解决系统可用性的问题,但是这里存在一个问题,不管存在多少个副本(节点),都无法增大源节点的存储空间。在这个问题上,ES引入了Shard分片这个概念来解决问题。
看完分片的特点后可能还有人不太清楚到底什么是分片,其实分片是n/1个源节点数据。比如说原ES集群中只有一个主节点,所有的索引数据都存储在这个节点上。现在我们将某个索引数据分成3份,分别存放在3个ES节点上,那么每台ES服务器上就各自有1个分片shard。该索引的所有节点Shard分片的集合,就是索引的全部数据。
下面我们来演示一下:
为了更好的了解ES的分片机制,大家不妨在上面的案例上进一步思考两个问题:
答案是不能。原因是我们创建索引时定义的分片数量只有3个,且都已经落在了3个节点上。所以即使再增加多一个节点,也不会有对应的Shard分片可以落在新的节点上,并不能扩大 test_shard_index 的数据容量。
答案是不能。因为新增的副本也是分布在这3个节点上,还是利用了同样的资源。如果要增加吞吐量,还需要新增节点。
通过上面两个问题,相信大家已经可以认识到分片的重要性,分片数过小,会导致后续无法通过增加节点实现水平扩容;(副本)分片数过大会导致一个节点上分布过多分片,造成资源浪费,同时会影响查询性能
集群健康状况,包括以下三种: green健康状态,指所有主副分片都正常分配; yellow指所有主分片都正常分配,但是有副本分片未正常分配; red表示有主分片未分配
我们可以通过这个api查看集群的状态信息: GET _cluster/health
我们也可以通过cerebro或者head插件来直接获取当前集群的状态
需要注意的是,即使当前集群的状态为 red ,也并不代表当前的ES丧失了提供服务的能力。只是说未被分配主分片的索引无法正常存储和 *** 作而已。
这里故障转移的意思是,当ES集群出现某个或者多个节点宕机的情况,ES实现服务可用性的应对策略。
这里我们新建一个分片为3,副本为1的索引,分片分别分布在三个节点,此时集群为 green
当master节点所在机器宕机导致服务终止,此时集群会如何处理呢
我们可以看到,从node1主节点宕机到ES恢复集群可用性的过程中,ES有着自己的故障转移机制,保障了集群的高可用性。我们也可以在自己的本地上去进行试验,建好索引后,kill掉主节点,观察集群状态就行。
同时,此时就算node2宕机了,那么node3也能够很快的恢复服务的提供能力。
我们知道,我们创建的文档最终会存储在分片上,那么在分布式集群的基础上,ES集群是怎么判断当前该文档最终应该落在哪一个分片上呢?
很显然,我们需要一个可以实现文档均匀分布到各个分片上的映射算法,那么常见的随机算法和round-robin(轮询)算法可以满足需要吗?答案是不可以,这两个算法虽然可以实现文档均匀分布分片的存储需要,但是当我们通过 DocumentId 查询文档时,ES并不能知道这个文档ID到底存储在了哪个节点的分片上,所以只能够从所有分片上检索,时间长。如果我们为这个问题建立一个文档和分片映射关系的表,虽然确实可以快速定位到文档对应的存储分片,但是当文档的数据量很大的时候,那么检索的效率也会随之变低。
对于上面这个问题,ES提供的解决方法是 建立文档到分片的映射算法
es 通过如下的公式计算文档对应的分片:
hash算法 保证可以将数据均匀地分散在分片中
routing 是一个关键参数,默认是文档id,也可以自行指定
number_of_primary_shards 是主分片数
我们可以看到,该算法与主分片数相关, 这也是分片数一旦确定后便不能更改的原因
我们已经知道了ES是如何将文档映射到分片上去了,下面我们就来详细讲解一下文档创建、读取的流程。
脑裂问题,英文为 split-brain ,是分布式系统中的经典网络问题,如下图所示:
3个节点组成的集群,突然node1的网络和其他两个节点中断
解决方案为 仅在可选举master-eligible节点数大于等于quorum时才可以进行master选举
在讲文档搜索实时性之前,先讲一下倒排索引的不可变更特性。由于倒排索引一旦生成,不可变更的特定,使得其有着以下3点好处:
下面,将针对Lucene实现文档实时性搜索的几个动作进行讲解,分析其是如何在新增文档后实现ES的搜索实时性的。
我们从上面的描述中知道,当我们新增了一个文档后会新增一个倒排索引文件 segment ,但是 segment 写入磁盘的时间依然比较耗时(难以实现实时性),所以ES借助文件系统缓存的特性, 先将 segment 在缓存中创建并开放查询来进一步提升实时性 ,该过程在es中被称为refresh。
在refresh之前文档会先存储在一个buffer中,refresh时将 buffer中的所有文档清空并生成 segment
es默认每1秒执行一次refresh,因此文档的实时性被提高到1秒 ,这也是es被称为近实时(Near Real Time)的原因
reflush虽然通过 将文档存放在缓存中 的方式实现了秒级别的实时性,但是如果在内存中的segment还没有写入磁盘前发生了宕机,那么其中的文档就无法恢复了,如何解决这个问题呢
ES 引入 translog 机制。写入文档到 buffer 时,同时将该 *** 作写入 translog 中。
translog文件会即时写入磁盘(fsync),在ES 6x中,默认每个请求都会落盘,我们也可以修改为每5秒写一次,这样风险便是丢失5秒内的数据,相关配置为indextranslog。同时ES每次启动时会检查translog 文件,并从中恢复数据。
flush 负责将内存中的segment写入磁盘,主要做如下的工作:
Reflush和Flush执行的时机
ES的做法是 首先删除文档,然后再创建新文档
我们上面提到,新增文档是通过新建segment来解决,删除文档是通过维护del文件来进行的,假如现在我们设置的 reflush 时间间隔为1秒,那么一小时单个ES索引就会生成3600个segment,一天下来乃至一个月下来会产生的segment文件数量更是不可想象。为了解决Segment过多可能引起的性能下降问题,ES中采用了Segment Merging(即segment合并)的方法来减少segment的数量。
执行合并 *** 作的方式有两种,一种是ES定时在后台进行 Segment Merging *** 作,还有一种是我们手动执行 force_merge_api 命令来实现合并 *** 作。
Elasticsearch 是位于 Elastic Stack 核心的分布式搜索和分析引擎。Logstash 和 Beats 有助于收集、聚合和丰富您的数据并将其存储在 Elasticsearch 中。Kibana 使您能够以交互方式探索、可视化和分享对数据的见解,并管理和监控堆栈。Elasticsearch 是索引、搜索和分析魔法发生的地方。
Elasticsearch为所有类型的数据提供近乎实时的搜索和分析。无论您拥有结构化或非结构化文本、数字数据还是地理空间数据,Elasticsearch都能以支持快速搜索的方式高效地存储和索引它。您可以超越简单的数据检索和聚合信息来发现数据中的趋势和模式。随着您的数据和查询量的增长,Elasticsearch的分布式特性使您的部署能够随之无缝增长。
相关内容:
cluster:代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的。es的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部来看es集群,在逻辑上是个整体,你与任何一个节点的通信和与整个es集群通信是等价的。
shards:代表索引分片,es可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上。构成分布式搜索。分片的数量只能在索引创建前指定,并且索引创建后不能更改。
replicas:代表索引副本,es可以设置多个索引的副本,副本的作用一是提高系统的容错性,当某个节点某个分片损坏或丢失时可以从副本中恢复。二是提高es的查询效率,es会自动对搜索请求进行负载均衡。
recovery:代表数据恢复或叫数据重新分布,es在有节点加入或退出时会根据机器的负载对索引分片进行重新分配,挂掉的节点重新启动时也会进行数据恢复。
一个 Elasticsearch 集群由一个或多个节点(Node)组成,每个集群都有一个共同的集群名称作为标识。
一个 Elasticsearch 实例即一个 Node,一台机器可以有多个实例,正常使用下每个实例应该会部署在不同的机器上。Elasticsearch 的配置文件中可以通过 nodemaster、nodedata 来设置节点类型。
nodemaster:表示节点是否具有成为主节点的资格
nodedata:表示节点是否存储数据
节点即有成为主节点的资格,又存储数据。这个时候如果某个节点被选举成为了真正的主节点,那么他还要存储数据,这样对于这个节点的压力就比较大了。Elasticsearch 默认每个节点都是这样的配置,在测试环境下这样做没问题。实际工作中建议不要这样设置,这样相当于主节点和数据节点的角色混合到一块了。
节点没有成为主节点的资格,不参与选举,只会存储数据。在集群中需要单独设置几个这样的节点负责存储数据,后期提供存储和查询服务。主要消耗磁盘,内存。
不会存储数据,有成为主节点的资格,可以参与选举,有可能成为真正的主节点。普通服务器即可(CPU、内存消耗一般)。
不会成为主节点,也不会存储数据,主要是针对海量请求的时候可以进行负载均衡。普通服务器即可(如果要进行分组聚合 *** 作的话,建议这个节点内存也分配多一点)
在生产环境下,如果不修改 Elasticsearch 节点的角色信息,在高数据量,高并发的场景下集群容易出现脑裂等问题。
一个集群下可以有多个索引,每个索引是一系列相同格式文档的集合 (Elasticsearch 6x 已不支持一个索引下多个Type) 。
每个索引有一个或多个分片,每个分片存储不同的数据。分片可分为主分片( primary shard)和复制分片(replica shard),复制分片是主分片的拷贝。默认每个主分片有一个复制分片(默认一个索引创建后会有5个主分片,即:5主+5复制=10个分片),一个索引的复制分片的数量可以动态地调整,复制分片从不与它的主分片在同一个节点上(防止单点故障)。
复制分片有两个作用:
根据以下说明调整 elasticsearchyml 对应参数配置,node2、node3 其他配置与node1一致。
到目前位置,集群的配置就完成了,下面我们分别启动每个实例。
根据配置文件中的注释:
所以我们配置了 discoveryzenminimum_master_nodes: 2 ,所以必须有两个主节点启动成功,集群才算生效。
进入目录 elasticsearch-621-1 启动第一个节点,执行命令:bin\elasticsearchbat。从日志中可以看出并没有成功,因为没发现足够的master节点。
当第二个master节点启动成功时,整个集群状态变为正常。
3个节点全部启动成功,通过 elasticsearch-head 插件查看集群状态,通过集群健康值:green,表示集群一切正常。目前集群内没有任何数据,所以看不出索引与分片的情况。
Elasticsearch 一般会配合 Kibana + X-Pack 对集群数据分析、监控等,官方标配。这里使用了 elasticsearch-head 插件,一个比较小巧的工具。插件的安装方法请看: elasticsearch-head 安装介绍
添加测试数据:
从截图可以看出,目前一共3个节点,一个索引 test,test 索引有5个主分片(边框加粗),5个复制分片(边框不加粗),分片会别均匀的分布到每个节点中。
我们尝试干掉node3,node3 从集群退出之后,集群在短时间内会对分片进行重新分布,当然依赖遵循主、复制分片不会在同一个Node。
如果我们继续把node2干掉,那么整个集群就挂了,集群健康值:未连接。因为当前可用的主节点数 1 < discoveryzenminimum_master_nodes 设置的 2。
我们尝试把 discoveryzenminimum_master_nodes 设置成 1,然后重启启动一个节点,会发现有一个 Unassigned 的节点,集群健康值:yellow (5 of 10)。这种情况下代表主分片全部可用,存在不可用的复制分片,5个复制分片没有分配到节点上,不过此时的集群是可用的,我们任何请求都能处理,只是所有的 *** 作都落到主分片上,而且可能引发单点故障。当我们把第二个节点启动后,一切就恢复正常了,主分片的数据会同步到复制分片。
实际生产环境,每个节点可能设置不同的节点类型,我们在3个节点的基础上再增加两个节点,然后调整 nodemaster 和nodedata 的值,最终设置为2个主节点,2个数据节点,1个客户端节点。
node1 和 node2 是具有主节点选举权限的节点,这里 node1 被选举为master节点。node3 和 node4 是数据节点,所以数据分片只会分配在这两个节点上。node5 是客户端节点,最终是对请求起到负载均衡的作用。
如果是Linux环境下,启动可能没有这么顺利,可以参考 Linux 环境下安装 elasticsearch 5x、6x 问题汇总 。
环境 windows
1、进入官网下载 Elasticsearch : Elasticsearch-7133
2、选择一个盘,新建目录 ES(可自行定义),将下载的文件放到 ES 目录中,并将文件解压后复制两份,分别自定义命令为:elasticsearch-node-master、elasticsearch-node-1、elasticsearch-node-2
解释:每一个文件夹就是 ES 集群的一个节点 node,标记为 master 将作为主节点
4、修改每个节点的配置文件
1)master节点的配置文件
C:ESelasticsearch-node-masterconfigelasticsearchyml
2)node-1 节点的配置文件修改
C:ESelasticsearch-node-1configelasticsearchyml
3)node-2 节点的配置文件修改
C:ESelasticsearch-node-2configelasticsearchyml
5、启动 Elasticsearch
方法一:单独启动 ES
window环境下可以直接点击 bin 目录下的 elasticsearchbat 文件;或者 cmd 命令窗口进入到 bin目录,执行以下命令
按照以上步骤分别开启 node-1 、node-2 两个节点
方法二:批量启动 ES 的方法
windows下如果为了测试,建立多个节点,可以 bat 一键即可同时启动多个 ES,步骤如下
在桌面建立 startbat 文件,用 txt 打开文件,输入以下代码,保存后双击 startbat 即可
6、检测 Elasticsearch 是否启动成功
浏览器输入以下地址
节点启动看到有这个标志则表示节点启动成功
浏览器验证
至此,Elasticsearch 集群部署完成。
问题:如何直观地查看集群是否真的有三个节点呢?
答案:安装 Elasticsearch-head 前端插件可查阅集群和节点信息
请看下一篇文章:windows 安装 Elasticsearch-head
安装 Elasticsearch-head 前端插件可查阅集群和节点信息
请看下一篇文章:windows 安装 Elasticsearch-head
以上就是关于为什么 elasticsearch 获取节点信息失败全部的内容,包括:为什么 elasticsearch 获取节点信息失败、ElasticSearch-工作流程、ElasticSearch核心之——分布式特性等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)