Elasticsearch运维经验总结

Elasticsearch运维经验总结

版本说明:5.6.4(要严格注意ES及其插件、第三方工具的版本匹配关系)

系统负载:(日志集群,日均写入10TB,保留7天)

1,出于高可用的考虑,同一个分区的多个副本不会被分配到同一台机器

如下截图所示,Index:queries,设置20副本,5分片。这个集群当前有14个可用数据节点,queries的0分区在这14个数据节点上均有且仅有一个副本,剩余​​的7个副本显示UNASSIGNED,并不会在当前14个节点上重复分配

2,Local Gateway参数生效顺序(仅在重启master时生效)

  • gateway:expected_nodes,只要达到该值,立即可以进入恢复状态,假如有恢复必要的话
  • gateway:recover_after_time,如果未达到expected_nodes值,则需要等待recover_after_time时长,不管你当前有多少个nodes了
  • gateway:recover_after_nodes,在达到recover_after_time的时间后,还需要达到recover_after_nodes的设置值,才能进入恢复状态

3,避免所有索引被删除

  • action.destructive_requires_name:true,通过该参数禁止通过正则进行index的删除操作
  • curl -XDELETE http://localhost:9200/*/

4,避免使用虚拟内存(三选一)

  • 最佳方式:关闭操作系统的swap分区(swapoff -a)
  • 次选:vm.swappiness=0(仅在物理内存不够时才使用swap分区)
  • 最后:bootstrap.memory_lock: true

5,集群各类角色

  • node.master(显示)
  • node.data(显示)
  • node.ingest(显示)
  • node.coordinatint(隐性)
  • Every node is implicitly a coordinating node. This means that a node that has all three node.masternode.data and node.ingest set to false will only act as a coordinating node, which cannot be disabled.

6,master数量至少3个,避免脑裂

  • discovery.zen.minimum_master_nodes: 2

7,操作命令

  • 调整副本数:curl -XPUT http://localhost/yunxiaobai/_settings?pretty -d ‘{“settings”:{“index”:{“number_of_replicas”:”10″}}}’
  • 创建index:curl -XPUT ‘localhost:9200/yunxiaobai?pretty’
  • 插入数据:curl -XPUT ‘localhost:9200/yunxiaobai/external/1?pretty’ -d ‘ { “name”:”yunxiaobai” }’
  • 获取数据:curl -XGET ‘localhost:9200/yunxiaobai/external/1?pretty’
  • 删除索引:curl -XDELETE ‘localhost:9200/jiaozhenqing?pretty’
  • 屏蔽节点:curl -XPUT 127.0.0.1:9200/_cluster/settings?pretty -d ‘{ “transient” :{“cluster.routing.allocation.exclude._ip” : “10.0.0.1”}}’
  • 删除模板:curl -XDELETE http://127.0.0.1:9200/_template/metricbeat-6.2.4
  • 调整shard刷新时间:curl -XPUT http://localhost:9200/metricbeat-6.2.4-2018.05.21/_settings?pretty -d ‘{“settings”:{“index”:{“refresh_interval”:”30s”} }}’
  • 提交模板配置文件:curl -XPUT localhost:9200/_template/devops-logstore-template -d @devops-logstore.json
  • 查询模板: curl -XGET localhost:9200/_template/devops-logstor-template
  • 查询线程池:http://localhost:9200/_cat/thread_pool/bulk?v&h=ip,name,active,rejected,completed

8,集群健康状态

  • green:所有的主分片和副本分片都正常运行。
  • yellow:所有的主分片都正常运行,但不是所有的副本分片都正常运行。
  • red:有主分片没能正常运行。

9,故障节点分片延时分配

  • index.unassigned.node_left.delayed_timeout:1m,该配置表示一个节点故障1m后,系统会开始对该节点上的分片进行恢复操作。如果故障节点上的分片是主分片,那么即使是延时分配,其他节点对应的分片副本也会被置为主分片,否则,该索引无法正常使用,仅仅是延时了副本的故障恢复。之所以有时候需要调整该值,是为了避免一些糟糕情况的发生,例如一台机器死机重启,那么因为启动耗时超过一分钟,所以系统会对该机器上的分片进行故障恢复,恢复完毕后,这台机器启动完毕服务恢复了,那么这台机器上的数据就没有意义了,就被删除了。这时候,因为这是一个空机器了,所以系统还会触发平衡操作,这折腾就大了。设置为0时,表示不等待节点故障立即重新分配。Since elasticsearch 5.x index level settings can NOT be set on the nodes configuration like the elasticsearch.yaml, in system properties or command line arguments.In order to upgrade all indices the settings must be updated via the /${index}/_settings API.
  • cluster.routing.allocation.enable”:”none”,该参数配置生效时,可以创建索引,但是索引是处于不可用状态的

10,名词解释

  • indexes和indices区别
    • indices一般在数学,金融和相关领域使用,而indexes使用则相对广泛
    • indexes在美国、加拿大等国的英语里比较常见。但indices盛行于除北美国家以外的英语里。
  • index和lucene的区别
    • 在集群级别上的索引称为index
    • 在节点级别(各个分片都是一个lucene索引)称为lucene

11,滚动升级(升级期间,集群处于不可用状态)

  • Disable shard allocation
    • curl -XPUT http://localhost:9200/_cluster/settings?pretty -d ‘{ “persistent”: {“cluster.routing.allocation.enable” : “none” } } ‘,此时可以创建索引,但是索引不可用
  • Stop non-essential indexing and perform a synced flush
    • curl -X POST “localhost:9200/_flush/synced” 此时集群不对外进行响应
  • Shut down a single node
  • Upgrade the node you shut down
  • Upgrade any plugins
  • Start the upgraded node
  • Reenable shard allocation
    • curl -XPUT http://localhost:9200/_cluster/settings?pretty -d ‘{ “persistent”: {“cluster.routing.allocation.enable” : “all” } } ‘
  • Wait for the node to recover
  • Repeat

12,关键指标(参考x-pack)

  • indices.search.query_current/indices.search.query_total
  • indices.search.query_time_in_millis
  • indices.indexing.index_current/indices.indexing.index_total
  • indices.indexing.index_time_in_millis
  • jvm.mem.heap_used_percent
  • number_of_nodes(_cat/health)
  • active_shards_percent_as_number(_cat/health)
  • status(_cat/health)

13,如何设置索引的分片数比较合适

条件:

  • 每GB的堆对应的分片数量应低于20个
  • 每个节点有jvm堆内存 30G
  • fielddata 大小9G
  • 磁盘容量1490GB,则可用的磁盘容量为:1490GB*12.8%=1299.28GB约1299GB
  • 尽量保持分片大小一致

结论:

索引主分片规模为:
单个分片容量:1200GB/(30*20)=2.165GB
对于一个新建索引,预测总大小10GB,则共设置主分片:10GB/2GB=5个

14,集群的索引副本数如何确定

  • 当ES的查询操作较少时(每秒少于一个查询操作),副本数为1即可保证了数据的冗余(况且还有备份)
  • ES副本数为2时,可以提高查询性能(副本可以分担索引的查询操作):代价为CPU,内存和文件句柄

参考文献:https://www.elastic.co/guide/en/elasticsearch/guide/2.x/replica-shards.html

https://qbox.io/blog/optimizing-elasticsearch-how-many-shards-per-index

15,es 配置多个 data path 时的分配策略

参考资料:https://cyberdak.github.io/es/2018/07/08/es-disk-allocate-strategy

16,ES集群的备份和恢复

官方给出的ES集群的数据备份方式

  • S3 Repository
  • Azure Repository
  • HDFS Repository
  • Google Cloud Storage Repository

以下是使用HDFS进行数据备份和恢复,HDFS备份是基于增量备份方式进行备份的,需要安装repository-hdfs插件并重启集群才能生效。

对于使用HDFS来进行备份的方式,这是一种增量备份的方式(同一个存储库下,数据是增量备份的,每次备份,系统仅备份发生变化的segment)

使用的API:

#HDFS配置和创建存储库

curl -XPUT  “http://localhost:9200/_snapshot/ my_backup”  -d ‘

 { 

       “type”: “hdfs”, 

       “settings”: {

                    “path”: “/back/es/”, #存储库路径

                    “load_defaults”: “true”, #加载Hadoop默认配置

                    “compress”: “true”, 

                    “uri”: “hdfs://localhost:8020” } #Hadoop IP地址

 }

#创建快照

# snapshot_1为快照名称

curl -XPUT “http://localhost:9200/_snapshot/my_backup/snapshot_1?wait_for_completion=true ” -d ‘{

         “indices”: “index_1,index_2”, //注意不设置这个属性,默认是备份所有索引                           

         “include_global_state”: false 

}

 

#ES数据恢复

#本集群恢复,查找要恢复的快照ID,执行如下命令恢复数据

curl -XPOST   http://localhost:9200/_snapshot/my_backup/backup_1/_restore’

17,curator插件–ES索引管理插件

  • curator安装

pip install elasticsearch-curator

  • curator的配置文件

curator需要两个文件来对集群进行操作:curator.yml(curator的配置文件),action_file.yml(curator执行的动作)

curator.yml格式:

更改hosts和port连接集群的地址和端口,更改logfile为日志路径。

action_file.yml格式:

1:模式是匹配

2.:匹配的索引的名称,支持正则

3,4:指删除7天前的索引

5:多个任务需要按照顺序添加

  • curator的执行命令

curator –config curator.yml action_file.yml

以上命名需要加上文件的路径

  • 执行成功后,会将执行的过程写入日志文件中–logfile中。

18,自动任务

通过系统的crontab来执行自动任务

  • 新建执行脚本

对于自动删除索引这个任务来说,可以新建shell脚本curator.sh

#!/bin/sh

/usr/bin/curator –config /root/.curator/curator_config.yml /root/.curator/action_file.yml

  • 新建自动任务

crontab -e

crontab格式

30 3 * * * /data1/curator/curator.sh

  • 查看自动任务

crontab -l

19,监控

核心监控项:集群健康状态,功能监控,索引延迟,流量监控

黑:黑盒监控

白:白盒监控

监控项介绍:

  • pendin_task

pending task 反应了master节点尚未执行的集群级别的更改任务(例如:创建索引,更新映射,分配分片)的列表。pending task的任务是分级别的(优先级排序:IMMEDIATE>URGENT>HIGH>NORMAL>LOW>LANGUID),只有当上一级别的任务执行完毕后才会执行下一级别的任务,这也说明了:当出现HIGH级别以上的pending task任务时,备份和创建索引等一些低级别任务虽然任务对资源占用不多,也将不会执行,返回异常,“ProcessClusterEventTimeoutException”。

20,kibana调优

  • 在启动文件的开头添加如下配置项:NODE_OPTIONS=”–max-old-space-size=4096″   其中4096的单位为MB

21,推荐插件

    • X-pack
    • ElasticHQ

  • x-pack许可证书过期的问题

x-pack许可证书分为试用的许可证书和注册后的许可证书。安装证书不用重启节点

当x-pack禁用security functionality可以通过如下步骤来安装证许可证书:

  1. 注册elasticsearch
  2. 收到许可证邮件,下载许可证json文件
  3. 通过如下API来进行安装
curl -XPUT u elastic 'http://0.0.0.0:9200/_xpack/license?acknowledge=true&pretty' -H "Content-Type;application/json" -d @json

22,数据直接写入ES还是使用ELK?

  • 直接写入ES:适用于非核心场景,简单直接依赖少
  • 需要引入Kafka:适用于核心场景,通过Kafka作为代理层,既可以提升ELK集群整体的稳定性,也可以引入Hadoop生态做形式的数据分析。
    • 基于多ES集群消费实现多集群热备,实现单集群故障后快速切换到其他可用集群
    • ES故障期间Kafka作为数据缓冲避免数据丢失,故障恢复后继续消费故障期间的数据
    • 控制消费速率,避免ES被突增流量压死
    • 实现批量写操作,提升ES性能,分布式直接写入ES很难做聚合

23,ES引入代理的优势

  • 封禁部分高危操作,如调整集群参数,删除操作等
  • 封禁部分业务访问,如非授权用户,测试用户等

24,集群出现UNASSIGNED shards

集群分片分配机制

  1.  
    ES集群的分片分配由“allocators”和“deciders”控制,“allocators”负责返回给“deciders”一个满足要求的nodes列表,“deciders”从列表中确定到底分片应分配到哪个nodes。
  2.  
    “allocators”按照各节点的分片数量来获得合适的nodes列表(如果有分配权重则另说)
  3.  
    “deciders”根据一些过滤器来确定最终的分配nodes(分配的设置要求)
  4.  
    对于一个分片的分配,分为新建索引的分片分配,对于已经存在的索引,分为主分片和副本分片的分配
  5.  
    对于新建的索引,“allocators”寻找nodes列表的原则是保持集群的平衡(各个nodes上的分片数尽量保持一致,不是nodes的size)
  6.  
    对于已经存在的索引的主分片:只会允许分配到良好的最新的副本分片上,之后会选择其他副本(数据将有丢失)
  7.  
    参考资料:https://www.elastic.co/blog/red-elasticsearch-cluster-panic-no-longer

原因:

  • 有目的的延迟

  • 分片太多,节点不够

  • 需要重启分片分配

  • 磁盘量达到限制,禁止写入新的索引

  • ES集群的版本不一样

处理流程:

  1. 查看有哪些索引有UNASSIGEMED shards  注1

  2. 若对应的索引没用(数据没有用,索引可以删除)直接删除

  3. 查看UNASSIGNED shards的详细未分配原因  注2

  4. 针对不同的原因提供不同的解决办法

注1:

curl -XGET “http://hb-dev-es.jdcloud.com:80/_cat/shards?h=index,shard,prirep,state,unassigned.reason” | grep UNASSIGNED

注2:

curl -XGET “http://hb-dev-es.jdcloud.com:80/_cluster/allocation/explain?pretty”

25,ES集群重启预案及影响分析

ES集群重启预案

es每个节点均是有状态,不同索引分片配置设置不同,单个分片可能有冗余,可能有1备份。因此,为不影响服务,升级或者重启es服务需要逐个依次进行(滚动重启)

  1.  
    #注:重启操作应在集群状态为green时进行,重启任一一个节点前后,都要保证在集群状态恢复到green状态时。
  2.  
    #步骤1-禁用分片分配
  3.  
    #如果不禁止,当停止某一节点后,分片分配进程会进行UNASSIGNED分片的分配(当集群状态达到recovery要求,触发恢复阈值时)。这样的情况下,会造成大量的IO操作。但是禁用分片后,功能上会禁止新建索引。
  4.  
    curl -X PUT http://0.0.0.0:9200/_cluster/settings?pretty -d '{"transient": {"cluster.routing.allocation.enable": "none"}}'
  5.  
    #步骤2-验证修改后的配置:
  6.  
    curl -X GET http://0.0.0.0:9200/_cluster/settings?pretty
  7.  
    #步骤3-执行同步刷新
  8.  
    #这一步操作的原因是:当有分片在集群重启过程中并没有发生更新,则跳过对这些分片的同步校验,提高分片恢复的速度
  9.  
    curl -XPOST "http://0.0.0.0:9200/_flush/synced?pretty"
  10.  
    #步骤4-重启client-node节点
  11.  
    #重启client-node组节点有小概率导致写入丢失(由于LB的轮询策略:当一个节点离线后,10s内不会再将请求分配到该节点。可以通过不要立即重启另外的client节点来避免此问题)
  12.  
    ##子步骤1--重启一个client-node组的节点
  13.  
    ##子步骤2--确认节点加入集群
  14.  
    ##通过命令查看集群状态和查看节点数
  15.  
    curl -XGET http://0.0.0.0:9200/_cluster/health?pretty
  16.  
    ##子步骤3--按照子步骤1-2重启剩余的client-node节点
  17.  
    #步骤5-重启master节点
  18.  
    ##子步骤1--重启一个master-node的非master节点
  19.  
    ##子步骤2--确认节点加入集群
  20.  
    ##子步骤3--重复子步骤1-2重启剩余的非master节点
  21.  
    ##子步骤4--重复子步骤1-2重启剩余的master节点
  22.  
    ##子步骤5--检查master是否重新选举成功(30s后会开始选举:原因discovery.zen.ping_timeout:30s)
  23.  
    ##master选举过程中会堵塞写操作,对search无影响,堵塞API的操作
  24.  
    #步骤6-重启data-node节点
  25.  
    ##子步骤1--重启一个data-node组的data-node节点
  26.  
    ##子步骤2--确认节点加入集群
  27.  
    ##子步骤3--重复子步骤1-2重启剩余的data节点
  28.  
    #步骤7-启用分片分配
  29.  
    curl -X PUT http://0.0.0.0:9200/_cluster/settings?pretty -d '{"transient": {"cluster.routing.allocation.enable": "all"}}'
  30.  
     
  31.  
     

最后,常见日志错误

 

  • 集群名称不一致:java.lang.IllegalStateException: handshake failed, mismatched cluster name
  • 配置文件报错:java.lang.IllegalArgumentException: node settings must not contain any index level settings
  • org.elasticsearch.cluster.metadata.ProcessClusterEventTimeoutException: failed to process cluster event (put-mapping) within 30s
  • cluster state update task [put-mapping[type-2018-05-20-22-25-1526826326]] took [57.2s] above the warn threshold of 30s
  • [o.e.a.a.i.m.p.TransportPutMappingAction] failed to put mappings on indices [[[tpmonitor-elasticsearch/Vzr0MlOKRimGGCcMb0wIdA]]], type [type-2018-05-21-22-18-1526912288]
  • Failed to connect to server: 10.1.1.1/10.1.1.1:9000: try once and fail.
  • [2018-05-22T16:50:59,473][WARN ][o.e.b.ElasticsearchUncaughtExceptionHandler] [172-0] uncaught exception in thread [main]
    org.elasticsearch.bootstrap.StartupException: java.lang.IllegalStateException: Unable to access ‘path.data’ (/data10/elasticsearch)
posted @ 2019-07-09 17:44  Bigben  阅读(5077)  评论(1编辑  收藏  举报