Elasticsearch 管理集群和节点

在Elasticsearch生态系统中,监控节点和集群以管理和提高其性能和状态很重要。在集群级别可能会出现几个问题,例如:

  • 节点开销:某些节点可能会分配太多的分片,并成为整个集群的瓶颈
  • 节点关闭:这可能由于许多原因,例如磁盘空间满了,硬件故障和电源问题而发生
  • 分片重分配问题或损坏:某些碎片无法获取在线状态
  • 分片太大:如果分片太大,则由于大量的Lucene segments合并,索引性能下降
  • 空索引和碎片:它们浪费内存和资源,但是由于每个分片都有很多活动线程,如果有大量未使用的索引和分片,则一般集群性能下降

检测故障或性能不佳可以通过API或通过某些前端进行,这篇文章就简单的介绍一些Elasticsearch提供的相关api

查看集群健康状态

curl -XGET 'http://localhost:9200/_cluster/health?pretty'

返回结果为:

{
    "cluster_name": "elasticsearch",
    "status": "yellow",
    "timed_out": false,
    "number_of_nodes": 1,
    "number_of_data_nodes": 1,
    "active_primary_shards": 7,
    "active_shards": 7,
    "relocating_shards": 0,
    "initializing_shards": 0,
    "unassigned_shards": 7,
    "delayed_unassigned_shards": 0,
    "number_of_pending_tasks": 0,
    "number_of_in_flight_fetch": 0,
    "task_max_waiting_in_queue_millis": 0,
    "active_shards_percent_as_number": 50
}

每个Elasticsearch节点保持集群状态。 状态可以有三种类型,如下所示:

  • green:表示一切正常
  • yellow:这意味着某些节点或分片丢失,但它们不会影响集群功能。 主要是一些副本丢失(一个节点关闭或副本的节点不足),但每个活动分片至少有一个副本;
    读写正在工作。 黄色状态在开发阶段非常普遍,通常当用户通常启动一个Elasticsearch服务器时,集群的状态就是yellow
  • red:这表示某些主分片丢失,这些索引处于红色状态。 您不能写入红色状态的索引,结果可能不完整,或仅可能返回部分结果。
    通常,您需要重新启动已关闭的节点,并可能创建一些副本。

如果某些节点处于恢复模式,黄色/红色状态可能是暂态的。 在这种情况下,只需等待恢复完成。
群集健康包含大量信息,如下所示:

  • cluster_name:这是集群的名称。
  • timeout:这是一个布尔值,指示REST API是否触发了调用中设置的超时。
  • number_of_nodes:这表示集群中的节点数。
  • number_of_data_nodes:可以存储数据的节点数
  • active_primary_shards:活动的主分片数; 执行写操作的master分片的数量
  • active_shards:显示活动分片的数量。 这些分片可以用于搜索。
  • relocating_shards:显示正在重定位的分片数,从节点迁移到另一个节点。 这主要是由于集群节点的平衡。
  • initializing_shards:显示初始化状态下的分片数。 初始化过程在分片启动时完成。 在变得活跃状态之前,这是一个暂态,它由几个步骤组成,其中最重要的是如下:
    • 复制分片数据复制(如果是另一个副本)
    • 检查Lucene索引
    • 根据需要处理事务日志
  • unassigned_shards:未分配给节点的分片数。 这通常是由于设置的副本数大于节点数。 在启动期间,尚未初始化或初始化的分片将在此计数。
  • delayed_unassigned_shards:这将显示分配的分片数,但是它们的节点被配置为延迟分配。 您可以访问https://www.elastic.co/guide/en/elasticsearch/reference/5.0/delayed-allocation.html获取有关延迟分片分配的更多信息。
  • number_of_pending_tasks:这是集群级别的待处理任务数,例如集群状态更新,创建索引和分片重定位。 它很少是0以外的任何东西。
  • number_of_in_flight_fetch:必须在分片中执行的集群更新数。 因为集群更新是异步的,这个数字是跟踪分片中还需要执行的数量。
  • task_max_waiting_in_queue_millis:这是某些集群任务在队列中等待的最长时间。 它很少是0以外的任何东西。如果值不同于0,这意味着集群的某些资源饱和了或者类似的问题
  • active_shards_percent_as_number:这是集群中,集群所需要的活动分片数量占总数的百分比。 在生产环境中,除了一些搬迁和分片初始化之外,它几乎与100%不同。

也可以获取几个索引的健康状态:

curl -XGET 'http://localhost:9200/_cluster/health/index1,index2,indexN'

获取集群的待处理任务:

curl -XGET 'http://localhost:9200/_cluster/pending_tasks'

查看集群详细信息

如果想知道集群的更加详细的信息,那么可以使用:

curl -XGET 'http://localhost:9200/_cluster/state'

查询集群节点信息

curl -XGET 'http://localhost:9200/_nodes'
curl -XGET 'http://localhost:9200/_nodes/<nodeId1>, <nodeId2>'

这个api允许对必须返回的部分进行过滤。 在这个例子中,我们已经返回了全部信息。 我们可以选择以下一个或多个部分:

  • http
  • thread_pool
  • transport
  • jvm
  • os
  • process
  • plugins
  • modules
  • ingest
  • settings

比如我们想看os和pluin信息:

curl -XGET 'http://localhost:9200/_nodes/os,plugins'

获取节点统计信息

用于收集节点的实时指标,如内存使用情况,线程使用情况,索引数量,搜索等等

curl -XGET 'http://localhost:9200/_nodes/stats'
curl -XGET 'http://localhost:9200/_nodes/<nodeId1>,<nodeId2>/stats'
curl -XGET 'http://localhost:9200/_nodes/stats/os,http'

使用task management API

Elasticsearch 5.x 容许用户定义一些行为,比较常用的是:

  • delete_by_query
  • update_by_query
  • reindex

当这些行为被调用的时候,会创建一个server端的任务,task management API容许你管理这些行为
为了获取任务信息,我们需要进行下面的调用

curl -XGET 'http://localhost:9200/_tasks'
curl -XGET 'http://localhost:9200/_tasks?nodes=<nodeId1, nodeId2>'
curl -XGET 'http://localhost:9200/_tasks?nodes=<nodeId1, nodeId2>&actions=cluster:'

返回的结果类似于下面的:

{
    "nodes": {
        "7NwnFF1JTPOPhOYuP1AVNQ": {
            "name": "7NwnFF1",
            "transport_address": "127.0.0.1:9300",
            "host": "127.0.0.1",
            "ip": "127.0.0.1:9300",
            "roles": [
                "master",
                "data",
                "ingest"
            ],
            "tasks": {
                "7NwnFF1JTPOPhOYuP1AVNQ:9822": {
                    "node": "7NwnFF1JTPOPhOYuP1AVNQ",
                    "id": 9822,
                    "type": "transport",
                    "action": "cluster:monitor/tasks/lists",
                    "start_time_in_millis": 1477993984920,
                    "running_time_in_nanos": 102338,
                    "cancellable": false
                },
                "7NwnFF1JTPOPhOYuP1AVNQ:9823": {
                    "node": "7NwnFF1JTPOPhOYuP1AVNQ",
                    "id": 9823,
                    "type": "direct",
                    "action": "cluster:monitor/tasks/lists[n]",
                    "start_time_in_millis": 1477993984920,
                    "running_time_in_nanos": 62786,
                    "cancellable": false,
                    "parent_task_id": "7NwnFF1JTPOPhOYuP1AVNQ:9822"
                }
            }
        }
    }
}

下面简单的介绍一些上面的一些属性

  • node 执行任务的节点
  • id 任务的唯一id
  • action action的名字,它通常由操作类型,分隔符和详细操作组成。
  • cancellable 标记某个任务是否可以被取消,delete/update by query or reindex都是可以取消的,其他的一般都不能取消
  • parent_task_id 定义了一组任务。 一些任务可以在几个子任务中拆分和执行。 该值可用于将这些任务分配给父项。

该任务的id可用于通过API调用中的node_id参数过滤响应:

curl -XGET 'http://localhost:9200/_tasks/7NwnFF1JTPOPhOYuP1AVNQ:9822'

如果你想监控一组任务,可以使用parent_task_id:

curl -XGET 'http://localhost:9200/_tasks ? parent_task_id=7NwnFF1JTPOPhOYuP1AVNQ:9822'

Hot thread API

有时候,由于CPU使用量大,您的集群会减慢,您需要了解原因。Elasticsearch提供了监控热线程以便能够了解问题所在的能力。
在Java中,热线程是使用大量CPU并需要很长时间才能执行完成的线程。

curl -XGET 'http://localhost:9200/_nodes/hot_threads'
curl -XGET 'http://localhost:9200/_nodes/{nodesIds}/hot_threads'

热线程API非常特别。 它返回当前正在运行的热线程的文本表示,以便可以使用堆栈跟踪来检查每个线程的减速的原因。为了控制返回的值,还有一些附加参数可以作为查询参数提供,如下所示:

  • threads:这是要提供的热线程数(默认3)
  • interval:这是线程采样的间隔(默认为500ms)
  • type:这允许控制不同类型的热线程,例如检查等待和阻塞 状态(默认cpu,可能的值为cpu / wait / block)
  • ignore_idle_threads:这用于过滤掉已知的空闲线程(默认为true)

管理分片分配

在正常的es使用过程中,没有必要更改分片分配,因为默认设置在所有标准场景下都能很好地运行。 有时,由于大量重定位,或由于节点重新启动或某些其他集群问题,有必要监视或定义定制分片。
获取有关未分配的分片分配的当前状态的信息,我们可以这么做:

curl -XGET 'http://localhost:9200/_cluster/allocation/explain?pretty'

返回结果类似于:

{
    "shard": {
        "index": ".monitoring-es-2-2016.10.27",
        "index_uuid": "cD30b-qtQc2qw62yF-tirA",
        "id": 0,
        "primary": false
    },
    "assigned": false,
    "shard_state_fetch_pending": false,
    "unassigned_info": {
        "reason": "CLUSTER_RECOVERED",
        "at": "2016-10-30T15:09:54.626Z",
        "delayed": false,
        "allocation_status": "no_attempt"
    },
    "allocation_delay_in_millis": 60000,
    "remaining_delay_in_millis": 0,
    "nodes": {
        "7NwnFF1JTPOPhOYuP1AVNQ": {
            "node_name": "7NwnFF1",
            "node_attributes": {},
            "store": {
                "shard_copy": "AVAILABLE"
            },
            "final_decision": "NO",
            "final_explanation": "the shard cannot be assigned because allocation deciders return a NO decision",
            "weight": 8.15,
            "decisions": [
                {
                    "decider": "same_shard",
                    "decision": "NO",
                    "explanation": "the shard cannot be allocated on the same node id [7NwnFF1JTPOPhOYuP1AVNQ] on which it already exists"
                }
            ]
        }
    }
}

Elasticsearch允许不同的分片分配器机制。 有时您的分片并没有被分配给节点,这个api有助于调查为什么Elasticsearch没有进行分配。这个api调用会返回许多关于
未分配分片的信息,但是最重要的是其中的decisions。在上面的例子中,决策结果为the shard cannot be allocated on the same node id [7NwnFF1JTPOPhOYuP1AVNQ] on which it already exists",由于分片需要副本,因为该集群仅由一个节点组成,因此无法在集群中初始化已复制的分片。
集群分配说明了API提供的功能来筛选搜索特定分片的结果:如果您的集群有很多分片,这是非常方便的。 这可以通过增加参数来完成:

  • index 分片所属于的索引
  • shard 分片的数量,从0开始
  • primary 要检查的分片是否是主分片
curl -XGET 'http://localhost:9200/_cluster/allocation/explain' -d '
{
    "index": ".monitoring-es-2-2016.10.27",
    "shard": 0,
    "primary": false
}'

要手动重新分配碎片,Elasticsearch提供了一个Cluster Reroute API,允许在节点之间迁移碎片。 以下是此API的示例

curl -XPOST 'localhost:9200/_cluster/reroute' -d '
{
    "commands": [
        {
            "move": {
                "index": "test-index",
                "shard": 0,
                "from_node": "node1",
                "to_node": "node2"
            }
        }
    ]
}'

如果强制迁移分片,群集将开始移动其他分片以重新平衡本身。

监控segments

 curl -u elastic:changeme -XGET 'http://localhost:9200/.monitoring-es-2-2017.05.08/_segments?pretty'

其中.monitoring-es-2-2017.05.08为index 名称
返回结果类似于:

{
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "indices" : {
    ".monitoring-es-2-2017.05.08" : {
      "shards" : {
        "0" : [
          {
            "routing" : {
              "state" : "STARTED",
              "primary" : true,
              "node" : "FKSUo1wuRaynp43r4v-pdA"
            },
            "num_committed_segments" : 9,
            "num_search_segments" : 9,
            "segments" : {
              "_4w4" : {
                "generation" : 6340,
                "num_docs" : 51125,
                "deleted_docs" : 14,
                "size_in_bytes" : 18632090,
                "memory_in_bytes" : 33808,
                "committed" : true,
                "search" : true,
                "version" : "6.4.2",
                "compound" : false
              },
              "_5fv" : {
                "generation" : 7051,
                "num_docs" : 5715,
                "deleted_docs" : 14,
                "size_in_bytes" : 2115070,
                "memory_in_bytes" : 20168,
                "committed" : true,
                "search" : true,
                "version" : "6.4.2",
                "compound" : false
              },
              "_5ha" : {
                "generation" : 7102,
                "num_docs" : 414,
                "deleted_docs" : 14,
                "size_in_bytes" : 212960,
                "memory_in_bytes" : 31481,
                "committed" : true,
                "search" : true,
                "version" : "6.4.2",
                "compound" : true
              },
              "_5hb" : {
                "generation" : 7103,
                "num_docs" : 9,
                "deleted_docs" : 14,
                "size_in_bytes" : 62047,
                "memory_in_bytes" : 9895,
                "committed" : true,
                "search" : true,
                "version" : "6.4.2",
                "compound" : true
              },
              "_5hc" : {
                "generation" : 7104,
                "num_docs" : 9,
                "deleted_docs" : 14,
                "size_in_bytes" : 62081,
                "memory_in_bytes" : 9975,
                "committed" : true,
                "search" : true,
                "version" : "6.4.2",
                "compound" : true
              },
              "_5hd" : {
                "generation" : 7105,
                "num_docs" : 9,
                "deleted_docs" : 14,
                "size_in_bytes" : 62071,
                "memory_in_bytes" : 9927,
                "committed" : true,
                "search" : true,
                "version" : "6.4.2",
                "compound" : true
              },
              "_5he" : {
                "generation" : 7106,
                "num_docs" : 9,
                "deleted_docs" : 14,
                "size_in_bytes" : 62080,
                "memory_in_bytes" : 9975,
                "committed" : true,
                "search" : true,
                "version" : "6.4.2",
                "compound" : true
              },
              "_5hf" : {
                "generation" : 7107,
                "num_docs" : 9,
                "deleted_docs" : 14,
                "size_in_bytes" : 62079,
                "memory_in_bytes" : 9975,
                "committed" : true,
                "search" : true,
                "version" : "6.4.2",
                "compound" : true
              },
              "_5hg" : {
                "generation" : 7108,
                "num_docs" : 23,
                "deleted_docs" : 0,
                "size_in_bytes" : 62018,
                "memory_in_bytes" : 9975,
                "committed" : true,
                "search" : true,
                "version" : "6.4.2",
                "compound" : true
              }
            }
          }
        ]
      }
    }
  }
}

Indices Segments API返回有关索引中段的统计信息。 这是指标健康状况的重要指标。 它返回以下信息:

  • num_docs:索引中存储的文档数。
  • deleted_docs:索引中已删除文档的数量。 如果这个值很高,索引中的tombstone文件会浪费很多空间。
  • size_in_bytes:segments的大小(以字节为单位)。 如果这个值太高,写入速度会很低。
  • memory_in_bytes:segments占用的内存(以字节为单位)。
  • committed:segments是否提交到磁盘。
  • search:该segments是否用于搜索。 在强制合并/索引优化期间,新的segments由API创建和返回,但是在优化结束之前它们不可用于搜索。
  • version:用于创建索引的Lucene版本。
  • compound:索引是否是复合的。

监视segments的最重要的元素是deleted_docssize_in_bytes,因为它们意味着浪费磁盘空间或者分片太大。 如果分片太大(10 GB以上),为了提高写入性能,最好的解决方案是使用大量分片重新索引索引。由于大量数据在节点之间移动,因此拥有大的分片也会导致重定位问题。
确定分片的完美尺寸是不可能的。 通常,不需要频繁更新的分片的大小在10 GB到25 GB之间。

清除缓存

在执行过程中,Elasticsearch缓存数据以加快搜索速度,如缓存结果,项目和过滤结果。要释放内存,有必要清理缓存API。

curl -XPOST 'http://localhost:9200/test-index/_cache/clear'

结果返回:

{
    "_shards": {
        "total": 10,
        "successful": 5,
        "failed": 0
    }
}

缓存清理API释放用于缓存es的内存。一般来说,清理缓存并不是一个好主意,因为Elasticsearch内部自己管理缓存并清除过时的值,但是如果节点内存不足或要强制完成高速缓存清理,那么非常方便。

本文版权归作者所有,禁止一切形式的转载,复制等操作
赞赏

微信赞赏支付宝赞赏

发表评论

电子邮件地址不会被公开。 必填项已用*标注