elasticsearch底层模块解析与实践系列

#作者:猎人

文章目录

底层模块深入解析之threadpool

threadpool module,每个es节点内部多有很多个thread pool,不同的thread pool会处理不同的请求,thread pool module是用来对各种各样的thread pool进行管理的。

每种thread pool都是绑定了一个queue的,因为thread pool的大小有限,比如一个thread pool内部是10个线程,那么此时如果10个线程都被耗尽了,在执行某项任务,此时新的请求要这个thread pool中的线程来处理,默认情况下没有线程处理了,可能就会报错。

但是es的thread pool绑定了一个内存中的队列queue,如果thread pool满了之后,请求可以进这个queue里面来排队,等待线程池出现空的线程来处理queue中的请求,这样就提供了一个buffer。

1、线程池

每个节点都有多个thread pool,这样可以提升多线程处理的能力,这些线程池大多数都有一个对应的queue与其绑定,可以允许线程池满的时候,让pending的请求在队列里排队,而不是将pending请求抛弃掉。

generic thread pool:应付一些普通的操作,比如后台的node discovery,thread pool类型是scaling

index thread pool:用于进行index和delete操作,是fixed类型,大小为cpu core数量,queue大小是200,这个线程池的最大大小是cpu core数量 + 1。

search thread pool:用于search操作,是fixed类型,大小是cpu core数量 * 3 / 2 + 1,queue大小是1000。

get thread pool:用于get操作,是fixed类型,大小是cpu core数量,队列大小是1000。

bulk thread pool:用于bulk操作,是fixed类型,大小是cpu core数量,queue大小是200,最大的线程池大小是cpu core数量 + 1。

snapshot thread pool:用于snapshot/restore操作,是scaling类型,每个线程存活时间为5m,最大数量是min(5, cpu core数量 / 2)。

refresh thread pool:用于refresh操作,是scaling类型,存活时间为5m,最大数量是min(10, cpu core数量 / 2)。

用下面的方式来修改thread pool:

新鲜案例,在实际的项目中,碰到一个case,就是执行bulk操作的时候,说线程池不够了,建议增加queue的数量,bulk thread pool,做一下设置。

在elasticsearch.yml配置文件中,按照下面的格式来进行配置

thread_pool:

bulk:

size: 16

queue_size: 1000

2、线程池类型

fixed类型线程池:线程数量是固定的,同时绑定一个queue用于存放pending request。

scaling类型:这种线程池数量是可变的,根据负载来变化,最小是cpu core数量,最大是其公式定义,keep_alive参数可以控制其线程空闲多长时间被释放。

thread_pool:

refresh:

core: 1

max: 8

keep_alive: 2m

3、cpu core数量设置

在elasticsearch.yml配置文件中去设置

processors: 2

通过上面的参数可以显示设置cpu core数量,意义有下面3点:

(1)如果在一台机器上运行了多个es节点,但是可能只想要让每个es节点使用部分cpu core,而不是物理机上的所有cpu core,就可以手动设置。比如一台物理机,上面的cpu core是16个,运行了两个es节点,此时就可以手动设置processors是8,就是让每个es节点仅仅使用8个cpu core。

(2)默认cpu core的数量最大限制为32个,如果物理机超过了32个cpu core,可手动设置。比如物理机的cpu core是64个,但是es会去使用的cpu core可能是32个,最大限制,此时就是要手动设置processors是64。

(3)有时候可能会捕获到错误的cpu core数量,此时需要手动设置。

底层模块深入解析之plugin

plugin module,主要就是用来负责这个插件的管理,安装插件,查看插件,删除插件,更新插件。在elasticsearch的新版中,演示过了,插件应该怎么玩儿,hdfs repository的一个插件,怎么安装。

安装plugin :elasticsearch-plugin install [plugin_name]

通过url安装plugin:elasticsearch-plugin install [url]

如果机器不能直接连外网,需要将plugin插件下载下来一个包,在本地离线安装这个插件。通过本地包离线安装plugin:elasticsearch-plugin install file:///path/to/plugin.zip

查看plugin list:elasticsearch-plugin list

删除plugin:elasticsearch-plugin remove [pluginname],如果删除了一个plugin,必须重启节点才能生效。

升级/更新plugin:先删除,再安装,然后重启节点。

如果现在升级es节点的版本,就需要对应着升级plugin,自动装的就是最新版的了,装好后需要重启es node才能生效

es jdbc,es spring data,es sql

底层模块深入解析之es node节点角色

node module,主要是用来处理各种不同类型的节点的,es有哪些类型的node,另外就是对这些类型的node有些什么特殊的参数,对于一个较大的集群来说,如何去规划和配置各种各样的node。

一个节点在默认情况会下同时扮演: master eligible,data node 和 ingest node

单一角色: 职责分离的好处

1、Dedicated master eligible nodes:负责集群状态(cluster state)的管理。使用低配置的 CPU,RAM 和磁盘

2、Dedicated data nodes: 负责数据存储及处理客户端请求。使用高配置的 CPU,RAM 和磁盘

3、Dedicated ingest nodes: 负责数据处理。低配置的磁盘 使用高配置 CPU; 中等配置的RAM;

Dedicate Coordinating Only Node (Client Node)

  1. 配置:将 Master,Data,Ingest 都配置成 False
    Medium/High CUP; Medium/High RAM; Low Disk
  2. 生产环境中,建议为一些大的集群配置 Coordinating Only Nodes
    扮演 Load Balancers。降低 Master 和 Data Nodes 的负载
    负责搜索结果的 Gather/Reduce
    有时候无法预知客户端会发送怎么样的请求。大量占用内存的结会提作,一个深度聚会可能会引发 OOM

Dedicate Master Node:

  1. 从高可用 & 避免脑裂的角度出发
    一般在生产环境中配置3台
    一个集群只有1台活跃的主节点。负责分片管理,索引创建,集群管理等操作
  2. 如果和数据节点或者 Coordinate 节点混合部署
    数据节点相对有比较大的内存占用
    Coordinate 节点有时候可能会有开销很高的查询,导致 OOM
    这些都有可能影响 Master 节点,导致集群的不稳定

1、node类型

一个es实例就是一个es node,一些es node就可以组成一个es集群。如果仅仅运行了一个es node,那么也有一个es集群,只是节点数量就是1。集群中的每个node都可以处理http和transport请求,其中transport层是用来处理节点间的通信的,http层是用来处理外部的客户端rest请求的。所有的node都知道集群中的其他node,并且可以将客户端的请求转发到适当的节点上去。

节点的类型包含以下几种:

(1)master-eligible node:即master候选节点,将node.master设置为true(默认就是),一个节点启动后默认就是master-eligible node节点,代表这个node就是master的候选节点,有机会可以被选举为master node,然后控制整个集群。当集群内第一个 Master eligible 节点启动时候,它会将自己选举成 Master 节点。

(2)data node:将node.data设置为true(默认就是),一个节点启动后默认就是data节点,data node可以存储分片数据,同时处理这些数据相关的操作,比如CRUD操作,搜索操作,聚合操作,等等。可以增加数据节点,解决数据水平扩展问题。

(3)ingest node:将node.ingest设置为true(默认),ingest node是用来对document写入索引文件之前进行预处理的。可以对每个document都执行一条ingest pipeline,在document写入索引文件之前,先对其数据进行处理和转化。但是如果要执行的ingest操作太过繁重,那么可以规划单独的一批ingest node出来,然后将node.master和node.data都设置为false即可。

(4)tribe node:tribe node可以通过tribe.*相关参数来设置,它是一种特殊的coordinate node,可以连接到多个es集群上去,然后对多个集群执行搜索等操作。

(5)默认情况下,每个node的node.master,node.data,node.ingest都是true,都是master候选节点,也可以作为data node存储和操作数据,同时也可以作为ingest node对数据进行预处理。对于小于20个节点的小集群来说没问题。但是如果对于大于20个物理机的集群来说,最好是单独规划出master node、data node和ingest node来。

(6)coordinate node 处理请求节点

设置方法:通过将其他类型设置成 False,使其成为 Dedicated Coordinating Node

搜索和bulk等请求可能会涉及到多个节点上的不同shard里的数据,比如一个search请求,就需要两个阶段执行,首先第一个阶段就是一个coordinating node接收到这个客户端的search request。接着,coordinating node会将这个请求转发给存储相关数据的node,每个data node都会在自己本地执行这个请求操作,同时返回结果给coordinating node,接着coordinating node会将返回过来的所有的请求结果进行缩减和合并,合并为一个global结果。

每个node默认都是一个coordinating node。这就意味着如果一个node,将node.master,node.data,node.ingest全部设置为false,那么它就是一个纯粹的coordinating node,仅仅用于接收客户端的请求,同时进行请求的转发和合并。负责路由请求到正确的节点,例如创建索引的请求,需要路由到 Master节点。

如果生产是大集群,最好是单独规划一批node,作为coordinating node,然后让es client全部往这些node上去发送请求。

如果是一个大于20个节点的生产集群,建议将4种node,master node,data node,ingest node,cooridating node,全部分离开来。

集群中有30台机器规划:

master node:3个

ingest node:视具体情况而定,具体取决于ingest预处理操作有多么的复杂,耗费多少资源,但是一般情况下来说,es ingest node用的比较少的,ingest node也可以不用单独规划一批出来。

coordinate node:视具体情况而定,但是对于大集群来说,最好是单独拆几个节点出来,用于接收客户端的请求,3个节点。生产并发访问量很重要,比如集群最大的QPS是10,或者是100,那么3个节点足够。如果QPS是1000,或者是10000,就要规划10个coordinate node,或者100个。

data node:24个data node,data node会是分配的是最多的,主要用来存储数据,执行各种对数据的操作么,资源耗费也是最多。

2、master eligible node

(1)master-eligible node的介绍以及配置

master node负责轻量级的集群管理工作,比如处理创建和删除索引等请求。追踪集群中的每个node,决定如何将shards分配给各个node或哪个node上。维护并更新cluster state等功能。对于集群来说,有一个稳定的master node,是非常关键的。然后master-eligible node都有机会被选举为一个master node,同时master node必须有权限访问path.data指定的data目录,因为master node需要在data目录中存储cluster state。

对数据进行index和search操作,会耗费大量的cpu,内存,磁盘io,以及网络io,耗费的是每个node的资源。因此必须要确保master node非常稳定,压力不大,对于大集群来说,比较好的办法是划分出单独的master node和data node。如果不拆开,一个node又要是data node,要复杂存储数据,处理各种操作,同时又要负责管理集群,可能就会不稳定,出问题。

同时因为默认情况下,master node也能扮演coordinating node的角色,并且将search和index请求路由到对应的data node上去执行,最好是不要让master node来执行这些coordinate操作。因为msater node的稳定运行对于整个集群来说非常重要,相比利用master node资源来执行一些coordinate操作要重要的多。

Master Eligible Nodes & 选主的过程:

互相 Ping 对方,Node ld 低的会成为被选举的节点。其他节点会加入集群,但是不承担 Master 节点的角色。一旦发现被选中的主节点丢失就会选举出新的 Master 节点。

集群状态:

1、集群状态信息 (Cluster State) ,维护了一个集群中,必要的信息。如所有的节点信息、所有的索引和其相关的 Mapping 与 Setting 信息、分片的路由信息

2、在每个节点上都保存了集群的状态信息

3、但是,只有 Master 节点才能修改集群的状态信息,并负责同步给其他节点。因为,任意节点都能修改信息会导致 Cluster State 信息的不一致。

如果要设置一个node为专门的master-eligible node,需要做如下的设置:

必须考虑master单点问题,可设多节点,一个挂了,确保有其他候选节点

node.master: true

node.data: false

node.ingest: false

(2)通过minimum_master_nodes来避免脑裂问题

Split-Brain,分布式系统的经典网络问题,当出现网络问题,一个节点和其他节点无法连接。

要预防数据的丢失,就必须设置discovery.zen.minimum_master_nodes参数为一个合理的值,这样的话,每个master-eligible node才知道至少需要多少个master-eligible node才能组成一个集群。

例如有一个集群,其中包含两个master-eligible nodes。然后一个网络发生了故障,这两个节点之间丢失了联络。每个节点都认为当前只有一个master-eligible node,就是它们自己。此时如果discovery.zen.minimum_master_nodes参数的默认值是1,那么每个node就可以让自己组成一个集群,选举自己为master node即可。结果就会导致出现了两个es集群,这就是脑裂现象。即使网络故障解决了,但是这两个master node是不可能重新组成一个集群。除非某个master eligible node重启,然后自动加入另外一个集群,但是此时写入这个节点的数据就会彻底丢失。

如果有3个master-eligible node,同时将discovery.zen.minimum_master_nodes设置为2.如果网络故障发生了,此时一个网络分区有1个node,另外一个网络分区有2个node,只有一个node的那个网络分区,没法检测到足够数量的master-eligible node,那么此时它就不能选举一个master node出来组成一个新集群。但是有两个node的那个网络分区,它们会发现这里有足够数量的master-eligible node,那么就选举出一个新的master,然后组成一个集群。当网络故障解除之后,那个落单的node就会重新加入集群中。

discovery.zen.minimum_master_nodes,必须设置为master-eligible nodes的quorum,quorum的公式为:(master_eligible_nodes / 2) + 1。

换句话来说,如果有3个master-eligible nodes,那么那个参数就必须设置为(3 / 2) + 1 = 2,比如下面这样:

discovery.zen.minimum_master_nodes: 2

随着集群节点的上线和下限,这个参数都是要重新设置的,可以通过api来设置

复制代码
PUT _cluster/settings
{
  "transient": {
    "discovery.zen.minimum_master_nodes": 2
  }
}

此时将master node和data node分离的好处就出来了,一般如果单独规划一个master nodes的话,只要规划固定的3个node是master-eligible node就可以了,那么data node无论上线和下限多少个,都无所谓的。

3、data node

data node负责存储shard的数据,也就是那些document。data node可以处理各种操作,比如CRUD,搜索,聚合。这些操作全都是很耗费IO,内存和cpu资源的。因此监控这些资源的使用是很重要的,同时如果资源过载了,那么就要添加更多的data node。

如果要设置一个专门的data node,需要做出如下的设置:

node.master: false

node.data: true

node.ingest: false

4、ingest node

Ingest node可以执行预处理pipeline,包含了多个ingest processors。不同的ingest processor执行的操作类型是不同的,那么对资源的需求也是不同的,不过还是最好是规划一批单独的ingest node出来,不要跟master node和data node混合在一起。

如果要配置一个单独的ingest node:

node.master: false

node.data: false

node.ingest: true

search.remote.connect: false

5、cooridnating only node

如果我们规划了一批专门的master node,data node以及ingest node,那么此时还遗留下来了一种node,那就是coordinating node,这些node专门用来接收客户端的请求,同时对请求进行路由和转发,并对请求的结果进行合并。

coordinating only nodes对于大集群来说,可以使用专门的node来负载coordinate操作,而不是让coordinate操作的工作负载集中到master node和data node上去。coordinating node也会加入cluster,同时可以获取到完整的cluster state,它们主要是用cluster state中包含的node info来进行请求转发。

如果在一个集群中规划太多的coordinating node可能会加重整个集群的负担,因为被选举出来的master node必须要从所有的node上得到cluster state update的ack,如果coordinating nodes过多,那么可能会加重master node的负担。

如果要设置coordinating only node的话:

node.master: false

node.data: false

node.ingest: false

search.remote.connect: false

6、node data path设置

(1)path.data

每个data和master-eligible node都需要能够访问data目录,在那里存储了每个shard的数据,包括cluster state也存储在那里。path.data默认是指向$ES_HOME/data目录的,但是在生产环境中,肯定是不能这样设置的,因为在升级es的时候,可能会导致数据被清空或者覆盖。

此时一般需要在elasticsearch.yml中设置path.data:

path.data: /var/elasticsearch/data

(2)node.max_local_storage_nodes

data目录可以被多个node共享,即使是不同集群中的es node,也许他们在一个物理机上启动了。这个共享的方式对于测试failover很有意义,以及在开发机上测试不同的配置。但是在生产环境下,绝对不用这么做,一个data目录就给一个es node使用即可。默认情况下,es被配置成阻止超过一个node共享data目录中的数据,如果要允许多个node共享一个data目录,需要设置node.max_local_storage_nodes为一个超过1的数字。

7、水平扩展的痛点:

单集群一当水平扩展时,节点数不能无限增加。当集群的 meta 信息(节点,索引,集群状态)过多,会导致更新压力变大,单个 Active Master 会成为性能瓶颈,导致整个集群无法正常工作。

早期版本,通过 Tribe Node 可以实现多集群访问的需求,但是还存在一定的问题。Tribe Node 会以 Client Node 的方式加入每个集群。集群中 Master 节点的任务变更需要 Tribe Node 的回应才能继续。Tribe Node 不保存 Cluster State 信息,一旦重启,初始化很慢。当多个集群存在索引重名的情况时,只能设置一种 Prefer 规则。

相关推荐
Elasticsearch2 小时前
Elasticsearch:没有 “AG” 的 RAG?
elasticsearch
喜欢猪猪15 小时前
系统架构师---基于规则的系统架构
大数据·elasticsearch·搜索引擎
小吕学编程15 小时前
ES练习册
java·前端·elasticsearch
三块钱079416 小时前
【原创】从s3桶将对象导入ES建立索引,以便快速查找文件
大数据·elasticsearch·搜索引擎·s3
Elasticsearch19 小时前
Elastic Security 简化了预构建 SIEM 检测规则的自定义
elasticsearch
舒一笑20 小时前
一文简单记录打通K8s+Kibana流程如何启动(Windows下的Docker版本)
后端·elasticsearch·kibana
TracyCoder1231 天前
ElasticSearch深入解析(五):如何将一台电脑上的Elasticsearch服务迁移到另一台电脑上
大数据·elasticsearch·jenkins
Lucky GGBond1 天前
解决 Elasticsearch 启动错误:failed to obtain node locks
大数据·elasticsearch·搜索引擎
曾经的三心草1 天前
Git-基本操作
大数据·git·elasticsearch