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
-
索引创建
:
-
创建
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 集群管理中,需要综合运用前面提到的各种方法和技巧,制定一套适合自己业务需求的集群管理策略。以下是一个简单的综合策略示例:
-
初始化配置 :在集群搭建初期,根据节点的硬件资源和性能特点,将节点划分为不同的区域(如
zone_one和zone_two),并为每个区域的节点配置相应的属性。 -
索引分配 :根据业务需求和数据特点,为不同的索引设置合适的分配规则。例如,将重要的索引放置在性能较高的节点上,将对磁盘空间要求较大的索引分配到磁盘空间充足的节点上。
-
磁盘管理 :启用基于磁盘的分片分配功能,并根据集群的实际情况调整磁盘水印和更新间隔。定期监控节点的磁盘使用情况,及时清理不必要的数据,确保磁盘空间的合理利用。
-
分片操作 :在必要时,手动移动、取消或强制分配分片。但要遵循前面提到的最佳实践,确保操作的安全性和稳定性。
-
预热查询 :选择合适的查询作为预热查询,定期更新预热查询列表,提高查询性能。
通过以上综合策略的实施,可以有效地管理 Elasticsearch 集群,提高系统的性能和稳定性,为业务的发展提供有力的支持。
总之,Elasticsearch 集群管理是一个复杂而重要的任务,需要我们不断地学习和实践,根据实际情况灵活运用各种方法和技巧,才能确保集群的高效运行。希望本文介绍的内容能够帮助你更好地管理和优化 Elasticsearch 集群。
超级会员免费看
1121

被折叠的 条评论
为什么被折叠?



