ELK(三)—Elasticsearch集群学习
文章目录
Elasticsearch集群搭建
优点
-
高可用性:通过设计减少系统不能提供服务的时间。假设系统一直能够提供服务,那么该系统的可用性是 100%。如果系统在某个时刻宕掉了,比如某个网站在某个时间挂掉了,那么它临时是不可用的。所以,为了保证 Elasticsearch 的高可用性,就应该尽量减少 Elasticsearch 的不可用时间。
- 分片(shard):分片是对数据切分成了多个部分。索引存储时,就是被分片存储的,默认情况下ES会把一个索引分成5个分片。分片就是数据的容器,数据保存在分片内,分片又被分配到集群内的各个节点里。当集群规模扩大或者缩小时,Elasticsearch会自动的在各个节点中迁移分片,使得数据仍然均匀分布在集群里,即一份 数据被分成了多分并保存在不同的主机上。
如果一台主机挂掉了,那么这个分片里面的数据不就无法访问了?别的主机都是存储的其他的分片。其实是可以访问的,因为其他主机存储了这个分片的备份,叫做副本
-
副本(Replica):就是对原分片的复制,和原分片的内容是一样的,Elasticsearch 默认会生成一份副本,所以相当于是五个原分片和五个分片副本,相当于一份数据存了两份,并分了十个分片,当然副本的数量也是可以自定义的。这时我们只需要将某个分片的副本存在另外一台主机上,这样当某台主机宕机了,我们依然还可以从另外一台主机的副本中找到对应的数据
一般来说,Elasticsearch 会尽量把一个索引的不同分片存储在不同的主机上,分片的副本也尽可能存在不同的主机上,这样可以提高容错率,从而提高高可用性。
-
健康状态:
- 绿色(green):这代表所有的主分片和副本分片都已分配。你的集群是 100% 可用的
- 黄色(yellow):黄色。所有的主分片已经分片了,但至少还有一个副本是缺失的。不会有数据丢失,所以搜索结果依然是完整的。不过,高可用性在某种程度上被弱化。如果更多的分片消失,就会丢数据了。所以可把 yellow 想象成一个需要及时调查的警告
- 红色(red):至少一个主分片以及它的全部副本都在缺失中。这意味着你在缺少数据:搜索只能返回部分数据,而分配到这个分片上的写入请求会返回一个异常
如果你只有一台主机的话,其实索引的健康状况也是 yellow,因为一台主机,集群没有其他的主机可以防止副本,所以说,这就是一个不健康的状态,因此集群也是十分有必要
-
存储空间
集群
三节点集群:P0、P1、P2是主分片,R0、R1、R2都是副分片,具有MASTER的节点为主节点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kTkPoT5o-1636454473538)(C:\Users\路小白\IdeaProjects\EleasticSearchStudy\ELK(三)]----Elasticsearch集群.assets\image-20211102101758006.png)
节点类型
- 主节点: 即 Master 节点。主要职责是和集群操作相关的内容,如创建或删除索引,跟踪哪些节点是群集的一部分,并决定哪些分片分配给相关的节点。稳定的主节点对集群的健康是非常重要的。默认情况下任何一个集群中的节点都有可能被选为主节点。索引数据和搜索查询等操作会占用大量的cpu,内存,io资源,为了确保一个集群的稳定,分离主节点和数据节点是一个比较好的选择。虽然主节点也可以协调节点,路由搜索和从客户端新增数据到数据节点,但最好不要使用这些专用的主节点。一个重要的原则是,尽可能做尽量少的工作。
node.master=true,node.data=false
- 数据节点:即Data节点。数据节点主要是存储索引数据的节点,主要对文档进行增删改查操作,聚合操作等。数据节点对 CPU、内存、IO 要求较高,在优化的时候需要监控数据节点的状态,当资源不够的时候,需要在集群中添加新的节点。
node.master=false,node.data=true
- 负载均衡节点:Client节点,也称作客户端节点。当一个节点既不配置为主节点,也不配置为数据节点时,该节点只能处理路由请求,处理搜索,分发索引操作等,从本质上来说该客户节点表现为智能负载平衡器。独立的客户端节点在一个比较大的集群中是非常有用的,他协调主节点和数据节点,客户端节点加入集群可以得到集群的状态,根据集群的状态可以直接路由请求。
node.master=false, node.data=false
- 预处理节点:Ingest节点,在索引数据之前可以先对数据做预处理操作,所有节点其实默认都是支持 Ingest 操作的,也可以专门将某个节点配置为 Ingest 节点。
一个节点其实可以对应不同的类型,如一个节点可以同时成为主节点和数据节点和预处理节点,但如果一个节点既不是主节点也不是数据节点,那么它就是负载均衡节点。具体的类型可以通过具体的配置文件来设置。
在一个生产集群中我们可以对这些节点的职责进行划分,建议集群中设置3台以上的节点作为master节点,这些节点只负责成为主节点,维护整个集群的状态。再根据数据量设置一批data节点,这些节点只负责存储数据,后期提供建立索引和查询索引的服务,这样的话如果用户请求比较频繁,这些节点的压力也会比较大,所以在集群中建议再设置一批client节点(node.master: false node.data: false),这些节点只负责处理用户请求,实现请求转发,负载均衡等功能
性能更优?
- 每个Node更少的Shard,每个Shard资源跟充沛,性能更高
- 扩容极限:6个shard(3 primary,3 replica),最多扩容到6台机器,每个shard可以占用单台服务器的所有资源,性能最好
- 超出扩容极限,动态修改replica数量,9个shard(3primary,6 replica),扩容到9台机器,比3台机器时,拥有3倍的读吞吐量
搭建集群
分别进行es7.15.1-1
、es7.15.1-2
、es7.15.1-3
进行集群配置。
# ================= Elasticsearch Configuration ===================
# 配置es的集群名称, es会自动发现在同一网段下的es,如果在同一网段下有多个集群,就可以用这个属性来区分不同的集群。
cluster.name: elasticsearch
# 节点名称
node.name: node-1
# 指定该节点是否有资格被选举成为node
node.master: true
# 指定该节点是否存储索引数据,默认为true。
node.data: true
# 指定该节点是否为预处理节点
node.ingest: false
# 设置绑定的ip地址还有其它节点和该节点交互的ip地址,本机ip
network.host: 127.0.0.1
# 指定http端口,你使用head、kopf等相关插件使用的端口
http.port: 9200
# 设置节点间交互的tcp端口,默认是9300。
transport.tcp.port: 9300
#用于启动当前节点时,发现其他节点的初始列表
discovery.seed_hosts: ["127.0.0.1:9300","127.0.0.1:9301", "127.0.0.1:9302"]
#设置集群中master节点的初始列表,可以通过这些节点来自动发现新加入集群的节点。
cluster.initial_master_nodes: ["node-1"]
#因为下两台elasticsearch的port端口会设置成9301 和 9302 所以写入两台#elasticsearch地址的完整路径
#discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300","127.0.0.1:9301","127.0.0.1:9302"]
#增加新的参数,这样head插件可以访问es
http.cors.enabled: true
http.cors.allow-origin: "*"
#禁用安全选项
xpack.security.enabled: false
# ================= Elasticsearch Configuration ===================
# 配置es的集群名称, es会自动发现在同一网段下的es,如果在同一网段下有多个集群,就可以用这个属性来区分不同的集群。
cluster.name: elasticsearch
# 节点名称
node.name: node-2
# 指定该节点是否有资格被选举成为node
node.master: true
# 指定该节点是否存储索引数据,默认为true。
node.data: true
# 指定该节点是否为预处理节点
node.ingest: false
# 设置绑定的ip地址还有其它节点和该节点交互的ip地址,本机ip
network.host: 127.0.0.1
# 指定http端口,你使用head、kopf等相关插件使用的端口
http.port: 9201
# 设置节点间交互的tcp端口,默认是9300。
transport.tcp.port: 9301
#用于启动当前节点时,发现其他节点的初始列表
discovery.seed_hosts: ["127.0.0.1:9300","127.0.0.1:9301", "127.0.0.1:9302"]
#设置集群中master节点的初始列表,可以通过这些节点来自动发现新加入集群的节点。
#因为下一台elasticsearch的port端口会设置成9301 所以写入两台#elasticsearch地址的完整路径
#discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300","127.0.0.1:9301","127.0.0.1:9302"]
#增加新的参数,这样head插件可以访问es
http.cors.enabled: true
http.cors.allow-origin: "*"
#禁用安全选项
xpack.security.enabled: false
# ================= Elasticsearch Configuration ===================
# 配置es的集群名称, es会自动发现在同一网段下的es,如果在同一网段下有多个集群,就可以用这个属性来区分不同的集群。
cluster.name: elasticsearch
# 节点名称
node.name: node-3
# 指定该节点是否有资格被选举成为node
node.master: true
# 指定该节点是否存储索引数据,默认为true。
node.data: true
# 指定该节点是否为预处理节点
node.ingest: false
# 设置绑定的ip地址还有其它节点和该节点交互的ip地址,本机ip
network.host: 127.0.0.1
# 指定http端口,你使用head、kopf等相关插件使用的端口
http.port: 9202
# 设置节点间交互的tcp端口,默认是9300。
transport.tcp.port: 9302
#用于启动当前节点时,发现其他节点的初始列表
discovery.seed_hosts: ["127.0.0.1:9300","127.0.0.1:9301", "127.0.0.1:9302"]
#设置集群中master节点的初始列表,可以通过这些节点来自动发现新加入集群的节点。
#因为下一台elasticsearch的port端口会设置成9301 所以写入两台#elasticsearch地址的完整路径
#discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300","127.0.0.1:9301","127.0.0.1:9302"]
#增加新的参数,这样head插件可以访问es
http.cors.enabled: true
http.cors.allow-origin: "*"
#禁用安全选项
xpack.security.enabled: false
discovery.zen.minimum_master_nodes: 用来决定多个个符合主节点条件的节点可以形成法定数量。
在每个节点上一定要正确配置此项设置,并在集群动态扩展时也正确地更新它,这一点至关重要。系统无法检测到用户是否错误配置了此项设置,而且在实践当中,在添加或删除节点后很容易忘记调整此项设置。因此,Zen Discovery 试图通过在每次主节点选举过程中等待几秒来防止出现这种错误配置,并且对其他的超时机制通常也十分保守。这意味着,如果选举的主节点失败,在选择替代节点之前,集群至少在几秒钟内是不可用的。如果集群无法选举出一个主节点,则有时会很难了解是什么原因
127.0.0.1:9200/_cat/nodes 可以查看集群是否部署完毕
脑裂问题
当出现网络问题,一个节点和其他节点无法连接
- Node2和Node3会重新选举Master
- Node1自己还是作为Master,组成一个集群,同时更新Cluster state
- 导致2个Master节点,维护不同的cluster state。当网络恢复时,无法选择正确恢复
如何避免?
- ES7.0之前,限定一个选举条件,设置quorum(仲裁), 只有在Master eligishble 节点数大于quorum时,才能进行选举
- quorum=(master节点数/2) + 1
- 当3个master eligible时,设置discovery.zen.minimum_master_nodes为2,既避免脑裂
- ES7.0之后,无需此配置
- 移除minimum_master_nodes参数,让Elasticsearch自己选择可以形成仲裁的节点
- 典型的主节点选举现在只需要很短的时间就可以晚餐。集群的伸缩变得更安全、更容易、并且可能造成丢失数据的系统配置选项更少了
- 节点更清楚的记录它们的状态,有助于判断为什么它们不能加入集群或为什么无法选举出主节点
分片数设定
- 主分片数过小:例如创建1个primary shard 的index
- 如果该索引增长很快,集群无法通过增加节点实现对这个索引的数据扩展
- 主分片数设置过大:导致单个shard容量很小,引发一个节点上过多分片,影响性能
- 副本分片设置过多,会降低集群整体写入性能
文档到分片的映射算法
- 确保文档能均匀分布在所有分片上,充分利用硬件资源,避免部分机器空闲,部分机器繁忙
- 潜在算法
- 随机/Round Robin。当查询文档1,分片数很多,需要多次查询才可能查到文档1
- 维护文档到分片的映射关系,当文档数据量很大的时候,维护成本高
- 实时计算,通过文档1,自动算出,需要去那个分片上获取文档
文档到分片的路由算法
shard = hash(_routing)%number_of_primary_shards(主分片数量)
- hash算法确保文档均匀分散到分片中
- 默认的_routing值是文档id
- 可以自行限定_ronting数值,例如相同国家的商品,都分配到指定的shard
- 设置Index settings 后,Primary数,不能随意修改的根本原因
写流程
新建、索引和删除请求都是写操作,必须在主分片上面完成之后才能被复制到相关的副本分片
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5q73avuj-1636454473540)(C:\Users\路小白\IdeaProjects\EleasticSearchStudy\ELK(三)]----Elasticsearch集群.assets\image-20211102172346323.png)
- 客户端向Node1发送新建、索引或者删除请求
- 节点使用文档的_id确定文档属于分片0,请求会被转发到Node3,因为分片0的主分片目前被分配在Node3上
- Node3在主分片上面执行请求。如果成功,则将请求并行转发到Node1和Node2的副本分片上。一旦所有的副本分片都报告成功,Node3将向Node1节点(协调节点)报告成功,协调节点向客户端报告成功。
读流程
从主分片或者从其它任意副本分片检索文档
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aR6qL3cd-1636454473543)(C:\Users\路小白\IdeaProjects\EleasticSearchStudy\ELK(三)]----Elasticsearch集群.assets\image-20211102173127918.png)
从主分片或者副本分片检索文档的步骤顺序:
- 客户端向 Node1 发送获取请求。
- 节点使用文档的 _id 来确定文档属于分片 0 。分片 0 的副本分片存在于所有的三个节点上 在这种情况下,它将请求转发到Node2。
- Node2 将文档返回给 Node 1 ,然后将文档返回给客户端。
在处理读取请求时,协调结点在每次请求的时候都会通过轮询所有的副本分片来达到负载均衡。在文档被检索时,已经被索引的文档可能已经存在于主分片上但是还没有复制到副本分片。 在这种情况下,副本分片可能会报告文档不存在,但是主分片可能成功返回文档。 一旦索引请求成功返回给用户,文档在主分片和副本分片都是可用的
更新流程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NFKKqze1-1636454473544)(C:\Users\路小白\IdeaProjects\EleasticSearchStudy\ELK(三)]----Elasticsearch集群.assets\image-20211102173609558.png)
- 客户端向 Node 1 发送更新请求。
- 它将请求转发到主分片所在的 Node 3 。
- Node 3 从主分片检索文档,修改 _source 字段中的 JSON ,并且尝试重新索引主分片的文档。 如果文档已经被另一个进程修改,它会重试步骤 3 ,超过 retry_on_conflict 次后放弃。
- 如果 Node 3 成功地更新文档,它将新版本的文档并行转发到 Node 1 和 Node 2 上的副本分片,重新建立索引。一旦所有副本分片都返回成功, Node 3 向协调节点也返回成功,协调节点向客户端返回成功
当主分片把更改转发到副本分片时, 它不会转发更新请求。 相反,它转发完整文档的新版本。这些更改将会异步转发到副本分片,并且不能保证它们以发送它们相同的顺序到达。 如果 Elasticsearch 仅转发更改请求,则可能以错误的顺序应用更改,导致得到损坏的文档
参考资源
官方测试数据:logs.jsonl.gz accounts.zip shakespeare_6.0.json 点击即可下载
ElasticSearch分片是什么?投票机制是怎样的?脑裂问题如何解决
Elasticsearch Snapshot恢复数据分片显示未分片
ELK之logstash使用-----logstash将txt文本的接送数据导入到ES中
elasticsearch使用BulkProcesssor导入txt大文件
ils/106340355)