(0.9)elasticsearch分布式集群概念
一、分布式系统的可用性与扩展性
1、高可用性
服务可用性:允许节点停止服务
服务可用性:部分节点丢失,不会丢数据
2、可扩展
请求量提升 / 数据的不断增长(将数据分布到所有节点上)
二、分布式特性
1、ES 的分布式架构的好处
存储的水平扩容
提高系统的可用性,部分节点停止服务,整个集群的服务不受影响
2、ES 的分布式架构
a:不同的集群通过不同的名字来区分,默认名字“elasticsearch”
b:通过配置文件修改,或者在命令行中 -E cluster.name=flame进行设定
c:一个集群可以有一个或者多个节点
三、节点
1、节点是一个ES 的实例
a:本质上就是一个java进程
b:一台机器上可以允许多个ES进程,生产环境建议一台机器上只运行一个ES实例。
2、每个节点都有名字,配置文件指定,或者启动时候 -E node.name=node1指定
3、每一个节点在启动之后,会分配一个UID,保存在data 目录下
四、ES集群中节点的角色
参考官网:https://www.bookstack.cn/read/elasticsearch-7.9-en/6d6f6bcdb9a25e89.md#master-node
Master Node
主要负责集群中索引的创建、删除以及数据的Rebalance等操作。Master不负责数据的索引和检索,所以负载较轻。
当Master节点失联或者挂掉的时候,ES集群会自动从其他Master节点选举出一个Leader。为了防止脑裂,常常设置参数为discovery.zen.minimum_master_nodes=N/2+1,其中N为集群中Master节点的个数。建议集群中Master节点的个数为奇数个,如3个或者5个。
设置一个几点为Master节点的方式如下:
node.master: true node.data: false node.ingest: false search.remote.connect: false
Data Node
主要负责集群中数据的索引和检索,一般压力比较大。建议和Master节点分开,避免因为Data Node节点出问题影响到Master节点。
设置一个几点为Data Node节点的方式如下:
node.master: false
node.data: true
node.ingest: false
search.remote.connect: false
Ingest Node
Ingest node专门对索引的文档做预处理,实际中不常用,除非文档在索引之前有大量的预处理工作需要做。Ingest node设置如下:
node.master: false node.master: false node.master: false
node.data: false
node.ingest: true
search.remote.connect: false
Tribe Node
Tribe Node主要用于跨级群透明访问。但是官方已经不建议使用了,在5.4.0版本以后已经废弃掉了,在7.0的版本中将移除该功能。在5.5版本以后建议使用Cross-cluster search替代Tribe Node。
【4.1】Master eligible
1、每个节点启动后,默认就是一个Master eligible 节点
可以设置node.master:false 禁止
2、Master-eligible 节点可以参加选主流程,成为Master节点
3、当第一个节点启动时候,他会将自己选举成为Master节点
4、每个节点都保存了集群的状态,只有Master节点才能修改集群的状态信息
集群状态(Cluster State),维护了一个集群中,必要的信息
a: 所有的节点信息
b: 所有的索引和其相关的Mapping 与Setting信息
c: 分片路由信息
任意节点都能修改信息会导致数据的不一致性
【4.2】Data Node & Coordinating Node
1、Data Node
可以保存数据的节点,叫做Data Node。负责保存分片数据。在数据扩展上起到了至关重要的作用。
2、Coordinating Node
负责接收Client 的请求,将请求分发到合适的节点,最终把结果汇集到一起
每个节点默认都起到了Coordinating Node的职责
【4.3】其他节点角色
1、Hot & Warm Node(日志处理)
不同硬件配置的Data Node,用来实现Hot & Warm 架构, 降低集群部署的成本
Hot 节点配置高: CPU 内存 实现高的吞吐量
Warm 配置低: 存储一些旧的数据
2、Machine Learnibf Node
负责跑机器学习的 job,用来做异常检测
3、Tribe Node
(5.3 开始使用Cross Cluster Serach)Tribe Node 连接到不同的ES 集群,并且支持将这些集群当成一个单独的集群处理。
7.x版本已经移除
【4.4】角色总结
节点角色
-
master eligible node
- 主备节点:管理集群状态,负责index的创建、分片管理、、mapping元数据等
- 机器配置:低cpu\低内存\低磁盘
-
data node
- 负责数据的存储、搜索和聚合计算
- 机器配置:高cpu\高内存\高磁盘
-
ingest node
- 负责索引文档预处理及相关数据处理(不常用)
- 机器配置:高cpu/高内存/低磁盘
-
coordinate node(协调节点)
- 负责接收Client 的请求,将请求分发到合适的节点,最终把结果汇集到一起,每个节点默认都是这个角色
- 扮演loadbance 角色。降低master和node的负载,负责搜索查询结果的聚合和reduce
- 机器配置:高cpu\高内存\低磁盘
-
marching learning node
- 机器学习
五、配置节点类型
1、开发环境中:一个节点可以承担多种角色
2、生产环境中:应该设置单一的角色的节点(dedicated node)
3、每个节点启动的时候会读取yaml配置文件来决定自己承担的角色
(1)节点角色参数配置表
小集群可以不考虑结群节点的角色划分,大规模ES集群建议将Master Node、Data Node和Coordinating Node独立出来,每个节点各司其职。
(2)Node节点组合
节点即有称为主节点的资格,又存储数据
node.master: true node.data: true
节点没有成为主节点的资格,不参与选举,只会存储数据
node.master: false node.data: true
客户端节点(client),也就是 Coordinating Node 节点
不会成为主节点,也不会存储数据,主要是针对海量请求的时候,可以进行负载均衡
node.master: false node.data: false
六、分片(Primary Shard & Replica Shard)
1、主分片:用来解决数据水平扩展的问题。通过主分片,可以将数据分布到集群内的所有节点之上
a: 一个分片是一个运行的Lucene的实例
b: 主分片数在索引创建时指定,后续不允许修改,除非Reindex(所以一开始就要定义好)。修改后查询会出现问题。
2、副本:用来解决数据高可用的问题,分片是主分片的拷贝
a: 副本分片数,可以动态的调整
b: 增加副本数,可以在一定程度上提高服务的可用性(读取的吞吐量)。增加副本会影响聚合的时间=> 权衡
七、分片的设定
1、对于生产环境中分片的设定,需要提前做好容量规划
分片数设置过小
a: 导致后续无法增加节点实现水平扩展
b: 单个分片的数量太大,导致数据重新分配耗时
分片数设置过大, 7.0 开始,默认主分片设置成1,解决了over-sharding的问题
a:影响搜索结果的相关性打分,影响统计结果的准确性
b:单个节点上过多的分片,会导致资源浪费,同时也会影响性能
2、查看集群的健康状况
Green:主分片与副本都正常分配
Yellow:主分片全部正常分配,有副本分片未能正常分配
Red:有主分片未能分配
a: 例如:当服务器的磁盘容量超过85%时,去创建了一个新的索引
【分片案例及思考】概念最佳实践思考
【1.1】分片的具体形式
【1.2】基本概念
集群(cluster): 由一个或多个节点组成, 并通过集群名称与其他集群进行区分
节点(node): 单个 ElasticSearch 实例. 通常一个节点运行在一个隔离的容器或虚拟机中
索引(index): 在 ES 中, 索引是一组文档的集合
分片(shard): 因为 ES 是个分布式的搜索引擎, 所以索引通常都会分解成不同部分, 而这些分布在不同节点的数据就是分片. ES自动管理和组织分片, 并在必要的时候对分片数据进行再平衡分配, 所以用户基本上不用担心分片的处理细节.
副本(replica): ES 默认为一个索引创建 5 个主分片, 并分别为其创建一个副本分片. 也就是说每个索引都由 5 个主分片成本, 而每个主分片都相应的有一个 copy。对于分布式搜索引擎来说, 分片及副本的分配将是高可用及快速搜索响应的设计核心.主分片与副本都能处理查询请求,它们的唯一区别在于只有主分片才能处理索引请求.副本对搜索性能非常重要,同时用户也可在任何时候添加或删除副本。额外的副本能给带来更大的容量, 更高的呑吐能力及更强的故障恢复能力。
【1.3】案例的分析与思考
(1)如上图,有集群两个节点,并使用了默认的分片配置. ES自动把这5个主分片分配到2个节点上, 而它们分别对应的副本则在完全不同的节点上。
其中 node1 有某个索引的分片1、2、3和副本分片4、5,node2 有该索引的分片4、5和副本分片1、2、3。
(2)当数据被写入分片时,它会定期发布到磁盘上的不可变的 Lucene 分段中用于查询。随着分段数量的增长,这些分段会定期合并为更大的分段。
此过程称为合并。 由于所有分段都是不可变的,这意味着所使用的磁盘空间通常会在索引期间波动,因为需要在删除替换分段之前创建新的合并分段。 合并可能非常耗费资源,特别是在磁盘I / O方面。
(3)分片是 Elasticsearch 集群分发数据的单元。 Elasticsearch 在重新平衡数据时可以移动分片的速度,例如发生故障后,将取决于分片的大小和数量以及网络和磁盘性能。
注1:避免使用非常大的分片,因为这会对群集从故障中恢复的能力产生负面影响。 对分片的大小没有固定的限制,但是通常情况下很多场景限制在 50GB 的分片大小以内。
注2:当在ElasticSearch集群中配置好你的索引后, 你要明白在集群运行中你无法调整分片设置. 既便以后你发现需要调整分片数量, 你也只能新建创建并对数据进行重新索引(reindex)(虽然reindex会比较耗时, 但至少能保证你不会停机).
主分片的配置与硬盘分区很类似, 在对一块空的硬盘空间进行分区时, 会要求用户先进行数据备份, 然后配置新的分区, 最后把数据写到新的分区上。
注3:尽可能使用基于时间的索引来管理数据保留期。 根据保留期将数据分组到索引中。 基于时间的索引还可以轻松地随时间改变主分片和副本的数量,因为可以更改下一个要生成的索引。
【1.4】索引和分片是否空闲?
(1)对于每个 Elasticsearch 索引,有关映射和状态的信息都存储在集群状态中。它保存在内存中以便快速访问。
因此,在群集中具有大量索引可能导致较大的群集状态,尤其是在映射较大的情况下。 这可能会变得很慢,因为所有更新都需要通过单个线程完成,以便在更改集群中分布之前保证一致性。
(2)每个分片都有需要保存在内存中的数据并使用堆空间。 这包括在分片级别保存信息的数据结构,但也包括在分段级别的数据结构,以便定义数据驻留在磁盘上的位置。
(3)这些数据结构的大小不固定,并且会根据使用场景不同而有所不同。然而,分段相关开销的一个重要特征是它与分段的大小不严格成比例。
这意味着与较小的分段相比,较大的分段每个数据量的开销较小。 差异可能很大。为了能够为每个节点存储尽可能多的数据,管理堆的使用并尽可能减少开销变得很重要。 节点拥有的堆空间越多,它可以处理的数据和分片就越多。
因此,索引和分片在集群视角下不是空闲的,因为每个索引和分片都存在一定程度的资源开销。
(4)分配的每个分片都是有额外的成本的:
每个分片本质上就是一个Lucene索引, 因此会消耗相应的文件句柄, 内存和CPU资源
每个搜索请求会调度到索引的每个分片中. 如果分片分散在不同的节点倒是问题不太. 但当分片开始竞争相同的硬件资源时, 性能便会逐步下降
ES 使用词频统计来计算相关性. 当然这些统计也会分配到各个分片上。如果在大量分片上只维护了很少的数据, 则将导致最终的文档相关性较差。
注1:小的分片会造成小的分段,从而会增加开销。我们的目的是将平均分片大小控制在几 GB 到几十 GB 之间。对于基于时间的数据的使用场景来说,通常将分片大小控制在 20GB 到 40GB 之间。
注2:由于每个分片的开销取决于分段的数量和大小,因此通过 forcemerge 操作强制将较小的分段合并为较大的分段,这样可以减少开销并提高查询性能。
理想情况下,一旦不再向索引写入数据,就应该这样做。 请注意,这是一项比较耗费性能和开销的操作,因此应该在非高峰时段执行。
注3:我们可以在节点上保留的分片数量与可用的堆内存成正比,但 Elasticsearch 没有强制的固定限制。 一个好的经验法则是确保每个节点的分片数量低于每GB堆内存配置20到25个分片。
因此,具有30GB堆内存的节点应该具有最多600-750个分片,但是低于该限制可以使其保持更好。 这通常有助于集群保持健康。
注4:如果担心数据的快速增长, 建议根据这条限制: ElasticSearch推荐的最大JVM堆空间 是 30~32G, 所以把分片最大容量限制为 30GB, 然后再对分片数量做合理估算。例如, 如果的数据能达到 200GB, 则最多分配7到8个分片。
注5:如果是基于日期的索引需求, 并且对索引数据的搜索场景非常少. 也许这些索引量将达到成百上千, 但每个索引的数据量只有1GB甚至更小. 对于这种类似场景, 建议是只需要为索引分配1个分片。
如果使用ES的默认配置(5个分片), 并且使用 Logstash 按天生成索引, 那么 6 个月下来, 拥有的分片数将达到 890 个. 再多的话, 你的集群将难以工作--除非提供了更多(例如15个或更多)的节点。
想一下, 大部分的 Logstash 用户并不会频繁的进行搜索, 甚至每分钟都不会有一次查询. 所以这种场景, 推荐更为经济使用的设置. 在这种场景下, 搜索性能并不是第一要素, 所以并不需要很多副本。
维护单个副本用于数据冗余已经足够。不过数据被不断载入到内存的比例相应也会变高。
如果索引只需要一个分片, 那么使用 Logstash 的配置可以在 3 节点的集群中维持运行 6 个月。当然你至少需要使用 4GB 的内存, 不过建议使用 8GB, 因为在多数据云平台中使用 8GB 内存会有明显的网速以及更少的资源共享.
【1.5】集群状态基本查询
GET _cluster/health GET _cat/nodes GET _cat/shards GET /_nodes/es7_01,es7_02 GET _cat/nodes?v GET _cat/nodes?v&h=id,ip,port,v,m GET _cluster/health GET _cluster/health?level=shards GET _cat/shards GET /_cluster/health/kibana_sample_data_ecommerce