29、Elasticsearch 集群管理与优化指南

Elasticsearch 集群管理与优化指南

在使用 Elasticsearch 时,对集群进行有效的管理和优化是确保系统性能和稳定性的关键。本文将详细介绍如何控制索引分配、手动移动分片、设置预热查询等重要操作,帮助你更好地管理 Elasticsearch 集群。

1. 显式控制索引分配

在某些情况下,我们希望将不同的索引放置在不同的集群节点上,以提高性能。例如,我们有三个索引: shop users promotions ,我们希望 shop 索引放在一些节点上, users 索引放在其他节点上,而 promotions 索引则放在 shop users 索引所在的所有节点上。

为了实现这个目标,我们可以将集群划分为不同的区域(zone)。假设我们有四个节点,将更强大的节点 1 和 2 划分为 zone_one ,资源较少的节点 3 和 4 划分为 zone_two 。具体配置步骤如下:
1. 节点配置 :在节点 1 和 2 的 elasticsearch.yml 配置文件中添加以下属性:

node.zone: zone_one

在节点 3 和 4 的 elasticsearch.yml 配置文件中添加:

node.zone: zone_two
  1. 索引创建
    • 创建 shop 索引 :将其放置在 zone_one 的节点上。
curl -XPUT 'http://localhost:9200/shop' -d '{
 "settings" : {
  "index" : {
   "routing.allocation.include.zone" : "zone_one"
  }
 }
}'
- **创建 `users` 索引**:将其放置在 `zone_two` 的节点上。
curl -XPUT 'http://localhost:9200/users' -d '{
 "settings" : {
  "index" : {
   "routing.allocation.include.zone" : "zone_two"
  }
 }
}'
- **创建 `promotions` 索引**:将其放置在 `zone_one` 和 `zone_two` 的所有节点上。
curl -XPOST 'http://localhost:9200/promotions'
curl -XPUT 'http://localhost:9200/promotions/_settings' -d '{
 "index.routing.allocation.include.zone" : "zone_one,zone_two"
}'

除了指定索引放置的节点,我们还可以排除某些节点。例如,若要使 pictures 索引不放置在 zone_one 的节点上,可以运行以下命令:

curl -XPUT 'localhost:9200/pictures/_settings' -d '{
 "index.routing.allocation.exclude.zone" : "zone_one"
}'

此外,我们还可以使用 index.routing.allocation.require 属性来指定分片分配到节点必须满足的规则。例如,为 pictures 索引设置以下规则:

curl -XPUT 'localhost:9200/pictures/_settings' -d '{
 "index.routing.allocation.require.size" : "big_node",
 "index.routing.allocation.require.zone" : "zone_one"
}'

这将使 pictures 索引的分片仅放置在 node.size 属性为 big_node node.zone 属性为 zone_one 的节点上。

我们还可以使用 IP 地址来指定分片和副本的分配。例如,将 shop 索引仅放置在 IP 地址为 10.1.2.10 10.1.2.11 的节点上:

curl -XPUT 'localhost:9200/shop/_settings' -d '{
 "index.routing.allocation.include._ip" : "10.1.2.10,10.1.2.11"
}'
2. 基于磁盘的分片分配

Elasticsearch 1.0 引入了基于磁盘的分片分配方法,允许我们根据节点的磁盘使用情况设置分配规则,避免磁盘空间不足。

2.1 启用基于磁盘的分片分配

默认情况下,基于磁盘的分片分配是禁用的。我们可以通过设置 cluster.routing.allocation.disk.threshold_enabled 属性为 true 来启用它。可以在 elasticsearch.yml 文件中设置,也可以使用集群设置 API 动态设置:

curl -XPUT localhost:9200/_cluster/settings -d '{
 "transient" : {
  "cluster.routing.allocation.disk.threshold_enabled" : true
 }
}'
2.2 配置基于磁盘的分片分配

有三个属性控制基于磁盘的分片分配行为,这些属性可以动态更新或在 elasticsearch.yml 配置文件中设置:
- cluster.info.update.interval :默认值为 30 秒,定义 Elasticsearch 更新节点磁盘使用信息的频率。
- cluster.routing.allocation.disk.watermark.low :默认值为 0.70,表示 Elasticsearch 不会将新分片分配到磁盘使用率超过 70% 的节点。
- cluster.routing.allocation.disk.watermark.high :默认值为 0.85,表示当节点磁盘使用率达到或超过 85% 时,Elasticsearch 将开始重新分配分片。

这两个水印属性可以设置为百分比值(如 0.60 表示 60%)或绝对值(如 600mb 表示 600 兆字节)。

3. 集群范围的分配

我们可以在集群级别指定所有索引的分配规则,而不仅仅是在索引级别。例如,将所有新索引放置在 IP 地址为 10.1.2.10 10.1.2.11 的节点上:

curl -XPUT 'localhost:9200/_cluster/settings' -d '{
 "transient" : {
  "cluster.routing.allocation.include._ip" : "10.1.2.10,10.1.2.11"
 }
}'
4. 每个节点的分片和副本数量

我们还可以指定单个索引在单个节点上可以放置的最大分片数。例如,若希望 shop 索引每个节点只有一个分片,可以运行以下命令:

curl -XPUT 'localhost:9200/shop/_settings' -d '{
 "index.routing.allocation.total_shards_per_node" : 1
}'

需要注意的是,如果 Elasticsearch 无法分配所有主分片,集群可能会处于红色状态。

5. 手动移动分片和副本

在某些情况下,我们可能需要手动移动分片,例如在关闭单个节点之前,将该节点上的所有分片移动到其他节点。Elasticsearch 提供了 _cluster/reroute REST 端点来实现这一功能,支持以下操作:
- 移动分片 :将 shop 索引的第二个分片从 es_node_one 节点移动到 es_node_two 节点。

curl -XPOST 'localhost:9200/_cluster/reroute' -d '{
 "commands" : [ { 
  "move" : {
   "index" : "shop", 
   "shard" : 1, 
   "from_node" : "es_node_one", 
   "to_node" : "es_node_two" 
  }
 } ]
}'
  • 取消分片分配 :取消 shop 索引在 es_node_one 节点上的第 0 个分片的分配。
curl -XPOST 'localhost:9200/_cluster/reroute' -d '{
 "commands" : [ {
  "cancel" : {
   "index" : "shop", 
   "shard" : 0, 
   "node" : "es_node_one"
  }
 } ]
}'
  • 强制分片分配 :将 users 索引的第 0 个未分配分片分配到 es_node_two 节点。
curl -XPOST 'localhost:9200/_cluster/reroute' -d '{
 "commands" : [ {
  "allocate" : {
   "index" : "users", 
   "shard" : 0, 
   "node" : "es_node_two"
  }
 } ]
}'

我们还可以在单个 HTTP 请求中包含多个命令,例如:

curl -XPOST 'localhost:9200/_cluster/reroute' -d '{
 "commands" : [
  {"move" : {"index" : "shop", "shard" : 1, "from_node" : "es_node_one", "to_node" : "es_node_two"}},
  {"cancel" : {"index" : "shop", "shard" : 0, "node" : "es_node_one"}}
 ]
}'
6. 预热查询

有时候,我们需要为 Elasticsearch 做一些准备工作,以更好地处理查询。例如,加载字段数据缓存或预热操作系统的 I/O 缓存。Elasticsearch 允许我们为类型和索引定义预热查询。

6.1 定义新的预热查询

预热查询实际上是存储在 Elasticsearch 中名为 _warmer 的特殊索引中的普通查询。以下是一个示例查询:

{
  "query" : {
    "match_all" : {}
  },
  "facets" : {
    "warming_facet" : {
      "terms" : {
        "field" : "tags"
      }
    }
  }
}

将该查询存储为 library 索引的预热查询:

curl -XPUT 'localhost:9200/library/_warmer/tags_warming_query' -d '{
  "query" : {
    "match_all" : {}
  },
  "facets" : {
    "warming_facet" : {
      "terms" : {
        "field" : "tags"
      }
    }
  }
}'

我们还可以为特定类型定义预热查询,例如为 library 索引的 book 类型定义预热查询:

curl -XPUT 'localhost:9200/library/book/_warmer/tags_warming_query' -d '{
  "query" : {
    "match_all" : {}
  },
  "facets" : {
    "warming_facet" : {
      "terms" : {
        "field" : "tags"
      }
    }
  }
}'

添加预热查询后,在 Elasticsearch 允许搜索新段之前,会对该段运行定义的预热查询,从而使 Elasticsearch 和操作系统缓存数据,加快搜索速度。

6.2 获取定义的预热查询
  • 获取 library 索引名为 tags_warming_query 的预热查询:
curl -XGET 'localhost:9200/library/_warmer/tags_warming_query?pretty=true'
  • 获取 library 索引的所有预热查询:
curl -XGET 'localhost:9200/library/_warmer'
  • 获取 library 索引所有以 tags 开头的预热查询:
curl -XGET 'localhost:9200/library/_warmer/tags*'
6.3 删除预热查询
  • 删除 library 索引名为 tags_warming_query 的预热查询:
curl -XDELETE 'localhost:9200/library/_warmer/tags_warming_query'
  • 删除 library 索引的所有预热查询:
curl -XDELETE 'localhost:9200/library/_warmer/_all'
  • 删除 library 索引所有以 tags 开头的预热查询:
curl -XDELETE 'localhost:9200/library/_warmer/tags*'
6.4 禁用预热功能

若要完全禁用预热查询,但将其保留在 _warmer 索引中,可以将 index.warmer.enabled 配置属性设置为 false 。例如,禁用 library 索引的预热功能:

curl -XPUT 'http://localhost:9200/library/_settings' -d '{
  "index.warmer.enabled" : false
}'
6.5 选择预热查询

通常,我们应该选择执行成本高且需要填充缓存的查询作为预热查询。例如,包含分面和基于索引字段排序的查询、父子查询以及包含常用过滤器的查询。我们还可以通过查看慢查询日志来选择需要预热的查询。

例如,在 elasticsearch.yml 文件中设置以下日志配置:

index.search.slowlog.threshold.query.warn: 10s
index.search.slowlog.threshold.query.info: 5s
index.search.slowlog.threshold.query.debug: 2s
index.search.slowlog.threshold.query.trace: 1s

logging.yml 配置文件中设置以下日志级别:

logger:
 index.search.slowlog: TRACE, index_search_slow_log_file

当查询执行时间超过 1 秒(在单个分片上,而非总计)时,会将其记录到慢日志文件中。通过查看慢日志,我们可以找到执行时间过长的查询,这些查询可能是需要预热的候选查询。

需要注意的是,不要在 Elasticsearch 集群中设置过多的预热查询,以免花费过多时间进行预热而影响生产查询的处理。

综上所述,通过合理控制索引分配、手动移动分片、设置预热查询等操作,我们可以更好地管理 Elasticsearch 集群,提高系统性能和稳定性。

以下是一个简单的 mermaid 流程图,展示手动移动分片的流程:

graph LR
    A[开始] --> B[确定要移动的分片信息]
    B --> C[使用 _cluster/reroute 端点发送移动命令]
    C --> D[检查操作结果]
    D --> E{操作成功?}
    E -- 是 --> F[结束]
    E -- 否 --> B

另外,为了更清晰地展示不同索引分配规则的设置,我们可以使用表格:
| 操作类型 | 示例命令 | 说明 |
| ---- | ---- | ---- |
| 显式控制索引分配 | curl -XPUT 'http://localhost:9200/shop' -d '{ "settings" : { "index" : { "routing.allocation.include.zone" : "zone_one" } } }' | 将 shop 索引放置在 zone_one 的节点上 |
| 排除节点分配 | curl -XPUT 'localhost:9200/pictures/_settings' -d '{ "index.routing.allocation.exclude.zone" : "zone_one" }' | 使 pictures 索引不放置在 zone_one 的节点上 |
| 基于磁盘的分片分配 | curl -XPUT localhost:9200/_cluster/settings -d '{ "transient" : { "cluster.routing.allocation.disk.threshold_enabled" : true } }' | 启用基于磁盘的分片分配 |
| 集群范围的分配 | curl -XPUT 'localhost:9200/_cluster/settings' -d '{ "transient" : { "cluster.routing.allocation.include._ip" : "10.1.2.10,10.1.2.11" } }' | 将所有新索引放置在指定 IP 地址的节点上 |
| 每个节点的分片数量 | curl -XPUT 'localhost:9200/shop/_settings' -d '{ "index.routing.allocation.total_shards_per_node" : 1 }' | 限制 shop 索引每个节点的分片数为 1 |
| 手动移动分片 | curl -XPOST 'localhost:9200/_cluster/reroute' -d '{ "commands" : [ { "move" : { "index" : "shop", "shard" : 1, "from_node" : "es_node_one", "to_node" : "es_node_two" } } ] }' | 将 shop 索引的第二个分片从 es_node_one 移动到 es_node_two |
| 定义预热查询 | curl -XPUT 'localhost:9200/library/_warmer/tags_warming_query' -d '{ "query" : { "match_all" : {} }, "facets" : { "warming_facet" : { "terms" : { "field" : "tags" } } } }' | 为 library 索引定义预热查询 |

通过这些操作和配置,你可以根据实际需求灵活管理 Elasticsearch 集群,确保系统的高效运行。

Elasticsearch 集群管理与优化指南

7. 索引分配规则总结

为了更全面地理解和运用不同的索引分配规则,下面对前面提到的各种规则进行总结:

规则类型 作用 示例命令
显式包含 指定索引应放置的节点 curl -XPUT 'http://localhost:9200/shop' -d '{ "settings" : { "index" : { "routing.allocation.include.zone" : "zone_one" } } }'
显式排除 排除索引不应放置的节点 curl -XPUT 'localhost:9200/pictures/_settings' -d '{ "index.routing.allocation.exclude.zone" : "zone_one" }'
必需属性 要求节点具备特定属性才能分配索引 curl -XPUT 'localhost:9200/pictures/_settings' -d '{ "index.routing.allocation.require.size" : "big_node", "index.routing.allocation.require.zone" : "zone_one" }'
基于 IP 分配 根据节点 IP 地址分配索引 curl -XPUT 'localhost:9200/shop/_settings' -d '{ "index.routing.allocation.include._ip" : "10.1.2.10,10.1.2.11" }'
集群范围分配 为集群内所有索引指定分配规则 curl -XPUT 'localhost:9200/_cluster/settings' -d '{ "transient" : { "cluster.routing.allocation.include._ip" : "10.1.2.10,10.1.2.11" } }'
每个节点分片数限制 限制单个索引在单个节点上的最大分片数 curl -XPUT 'localhost:9200/shop/_settings' -d '{ "index.routing.allocation.total_shards_per_node" : 1 }'
8. 磁盘分配规则详细解析

基于磁盘的分片分配是 Elasticsearch 中一个重要的特性,它能够根据节点的磁盘使用情况动态调整分片的分配,避免磁盘空间不足的问题。下面详细解析其三个关键属性:

  • cluster.info.update.interval :该属性控制 Elasticsearch 更新节点磁盘使用信息的频率。默认值为 30 秒,意味着每 30 秒 Elasticsearch 会检查一次节点的磁盘使用情况。如果你的集群磁盘使用情况变化频繁,可以适当缩短这个时间间隔;反之,如果磁盘使用相对稳定,可以增大该值以减少系统开销。

  • cluster.routing.allocation.disk.watermark.low :这是一个下限水印,默认值为 0.70(即 70%)。当节点的磁盘使用率超过这个阈值时,Elasticsearch 不会将新的分片分配到该节点。例如,如果一个节点的磁盘使用率达到了 75%,那么新的分片将不会被分配到这个节点上。

  • cluster.routing.allocation.disk.watermark.high :这是一个上限水印,默认值为 0.85(即 85%)。当节点的磁盘使用率达到或超过这个阈值时,Elasticsearch 会开始将该节点上的分片重新分配到其他磁盘使用率较低的节点上,以避免磁盘空间耗尽。

以下是一个 mermaid 流程图,展示基于磁盘的分片分配流程:

graph LR
    A[开始] --> B[检查节点磁盘使用率]
    B --> C{磁盘使用率 < 低水印?}
    C -- 是 --> D[可分配新分片]
    C -- 否 --> E{磁盘使用率 >= 高水印?}
    E -- 是 --> F[重新分配分片]
    E -- 否 --> G[不分配新分片]
    D --> H[结束]
    F --> H
    G --> H
9. 手动操作分片的最佳实践

在手动移动、取消或强制分配分片时,需要遵循一些最佳实践,以确保操作的顺利进行和集群的稳定性。

  • 移动分片 :在移动分片之前,需要确保目标节点有足够的资源(如磁盘空间、内存等)来接收新的分片。同时,要注意移动分片可能会对集群的性能产生一定的影响,尤其是在高并发的情况下。因此,建议在业务低谷期进行分片移动操作。

  • 取消分片分配 :取消分片分配通常用于处理异常情况,如节点故障或磁盘空间不足。在取消分配之前,要明确取消分配的原因,并确保有其他合适的节点可以重新分配该分片。

  • 强制分片分配 :强制分片分配可以用于解决一些分配失败的问题,但要谨慎使用。在强制分配之前,要确保目标节点满足分片分配的所有条件,否则可能会导致分配失败或数据不一致。

以下是一个手动操作分片的步骤列表:
1. 确定操作类型(移动、取消或强制分配)。
2. 收集相关信息,如索引名称、分片编号、源节点和目标节点等。
3. 检查目标节点的资源情况和分配条件。
4. 使用 _cluster/reroute 端点发送相应的命令。
5. 监控操作结果,确保操作成功。

10. 预热查询的性能优化

预热查询的目的是提前填充缓存,提高查询性能。为了达到最佳的性能优化效果,需要注意以下几点:

  • 选择合适的查询 :如前面所述,选择执行成本高且需要填充缓存的查询作为预热查询。可以通过分析慢查询日志来确定哪些查询是性能瓶颈,从而将这些查询作为预热查询的候选。

  • 控制查询数量 :不要设置过多的预热查询,以免占用过多的系统资源。建议根据集群的实际情况和业务需求,选择少量关键的查询进行预热。

  • 定期更新预热查询 :随着业务的发展和数据的变化,某些查询的执行成本可能会发生变化。因此,需要定期检查慢查询日志,更新预热查询列表,确保始终选择最优的查询进行预热。

以下是一个选择预热查询的流程图:

graph LR
    A[开始] --> B[分析慢查询日志]
    B --> C[筛选执行成本高的查询]
    C --> D{查询需要填充缓存?}
    D -- 是 --> E[添加到预热查询列表]
    D -- 否 --> C
    E --> F[定期更新列表]
    F --> G[结束]
11. 集群管理的综合策略

在实际的 Elasticsearch 集群管理中,需要综合运用前面提到的各种方法和技巧,制定一套适合自己业务需求的集群管理策略。以下是一个简单的综合策略示例:

  1. 初始化配置 :在集群搭建初期,根据节点的硬件资源和性能特点,将节点划分为不同的区域(如 zone_one zone_two ),并为每个区域的节点配置相应的属性。

  2. 索引分配 :根据业务需求和数据特点,为不同的索引设置合适的分配规则。例如,将重要的索引放置在性能较高的节点上,将对磁盘空间要求较大的索引分配到磁盘空间充足的节点上。

  3. 磁盘管理 :启用基于磁盘的分片分配功能,并根据集群的实际情况调整磁盘水印和更新间隔。定期监控节点的磁盘使用情况,及时清理不必要的数据,确保磁盘空间的合理利用。

  4. 分片操作 :在必要时,手动移动、取消或强制分配分片。但要遵循前面提到的最佳实践,确保操作的安全性和稳定性。

  5. 预热查询 :选择合适的查询作为预热查询,定期更新预热查询列表,提高查询性能。

通过以上综合策略的实施,可以有效地管理 Elasticsearch 集群,提高系统的性能和稳定性,为业务的发展提供有力的支持。

总之,Elasticsearch 集群管理是一个复杂而重要的任务,需要我们不断地学习和实践,根据实际情况灵活运用各种方法和技巧,才能确保集群的高效运行。希望本文介绍的内容能够帮助你更好地管理和优化 Elasticsearch 集群。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值