Fork me on GitHub

Elasticsearch温热集群架构

目录

  • 背景
  • 第一部分 温热集群整体架构
  • 第二部分 架构配置
  • 第三部分 架构维护相关
  • 第四部分 基于hot-warm架构的读写分离实现
  • 总结
  • 参考文献及资料

背景

Elasticsearch集群通常有下面两种常见组织架构:

  • 同质集群架构。即所有数据节点会负载所有的index存储和查询,节点配置均相同。
  • 温热集群架构。此架构中数据节点有两种类型:温节点、热节点。

特别针对日志型数据和时间序列指标类数据处理,温热架构较为常见。使用该架构通常有这样的前提:数据通常是不可更改的。每个index仅包含特定时间段的数据,用户可通过删除整个index来管理数据生命周期。

当Elasticsearch用于大量实时数据分析的场景时,推荐使用基于时间的索引然后使用三种不同类型的节点(Master, Hot-Node 和 Warm-Node)进行结构分层。

第一部分 温热集群整体架构

1.1 Master 节点

通常推荐每个集群运行三个专用的Master节点来提供最好的弹性。三个专用的Master节点,专门负责处理集群的管理以及加强状态的整体稳定性。Master节点不存储实际数据、不实际参与搜索以及索引操作。因此不太可能会因为垃圾回收而导致停顿。所以在服务器资源规划上,Master节点的CPU,内存以及磁盘配置可以比Data节点少很多。

建议将 discovery.zen.minimum_master_nodes setting 参数设置为2,避免集群出现脑裂。

1.2 Hot 节点

Hot节点会完成集群内所有的索引工作。这些节点同时还会保存近期的一些频繁被查询的索引。由于进行索引非常耗费CPU和I/O,因此这些节点的服务器建议配置SSD存储来支撑。

1.3 Warm 节点

这种类型的节点是为了处理大量的而且不经常访问的只读索引而设计的。由于这些索引是只读的,Warm节点倾向于挂载大量磁盘(普通磁盘)来替代SSD。但是CPU和内存配置建议和Hot节点保持一致。

第二部分 架构配置

Hot-Warm架构实现主要有以下几点:

  1. 有3台机器作为master节点
  2. 有若干台实例tag设置为hot(hot节点),有若干实例tag设置为warm(warm节点)
  3. hot节点中只存最近查询需求较高的索引
  4. 设定定时任务每天将前一天的索引标记为warm
  5. elasticsearch根据tag将hot数据迁移到warm

2.1 实例配置

2.1.1 索引级路由配置

实例标签设置在 elasticsearch.yml 配置文件中,参数名称为: node.attr.box_type

1
2
3
4
#设置该节点的tag为hot
node.attr.box_type:hot
# 设置该节点的tag为warm
node.attr.box_type:warm

也可以在启动实例时使用 ./bin/elasticsearch -Enode.attr.box_type=hot 参数指定

另外box_type名称也是自定义的,例如也可以为:zone

通过以下配置(索引路由分布策略)创建索引,索引分片只会分配写入hot实例节点。

1
2
3
4
5
6
PUT /logs_2016-12-26
{
"settings": {
"index.routing.allocation.require.box_type": "hot"
}
}

当索引不再需要大量检索时,可以将索引迁移到warm实例节点。通过API更新索引配置如下:

1
2
3
4
5
6
PUT /logs_2016-12-26/_settings 
{
"settings": {
"index.routing.allocation.require.box_type": "warm"
}
}
2.1.2 集群路由分布策略设置

对于一个物理机上多个elasticsearch实例的场景,多个实例可能是hot和warm节点。这是就会存在索引主从分片分配在同一个物理机上,这不满足数据的高可用。所以需要设置集群路由分布策略。

1
2
"cluster.routing.allocation.awareness.attributes": "box_type"
"cluster.routing.allocation.awareness.force.box_type.values": "hot,warm"

集群路由分布策略高于索引级路由策略

2.2 模板设置

在hot-warm架构下,需要对索引模板(index template)进行设置。如果索引模板在logstash或者beats中管理,那么索引模板需要做一些更新,包括分配过滤器。”index.routing.allocation.require.box_type” : “hot” 这个配置会使新的索引创建在Hot节点上。例如:

1
2
3
4
5
{
"template" : "indexname-*",
"version" : 50001,
"settings" : {
"index.routing.allocation.require.box_type": "hot"

或者给集群中的所有索引设置一个普通模板,所有新增索引首先写入hot实例节点:

1
2
3
4
5
{
"template" : "*",
"version" : 50001,
"settings" : {
"index.routing.allocation.require.box_type": "hot"

后续可以通过更新它的索引配置:”index.routing.allocation.require.box_type” : “warm”,完成迁移。

2.3 其他优化设置

warm节点开启压缩配置。在elasticsearch.yml配置文件中:

1
index.codec: best_compression

warm节点合并分段。当数据迁移到Warm节点后,可以调用 _forcemerge API 来合并分段。可以节约内存, 磁盘空间以及更少的文件句柄。

第三部分 架构维护相关

在日常集群维护中,我们希望重复的维护工作,能通过工具或自动化手段完成。例如如何使用Curator这个工具来自动处理这些事情。在Elasticsearch6.8版本开始,可以通过索引生命周期管理(ILM)模块完成这些自动化管理。

下面的例子中我们使用curator 4.2从Hot节点移动三天前的索引到Warm节点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
actions:
1:
action: allocation
description: "Apply shard allocation filtering rules to the specified indices"
options:
key: box_type
value: warm
allocation_type: require
wait_for_completion: true
timeout_override:
continue_if_exception: false
disable_action: false
filters:
- filtertype: pattern
kind: prefix
value: logstash-
- filtertype: age
source: name
direction: older
timestring: '%Y.%m.%d'
unit: days
unit_count: 3

最后我们可以使用curator来强制合并索引。执行优化之前要确保等待足够长的时间进行索引重新分配。你可以设置操作1中 wait_for_completion,或者修改操作2中的 unit_count 来选择4天前的索引.这样就有机会在强制合并之前完全合并。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2:
action: forcemerge
description: "Perform a forceMerge on selected indices to 'max_num_segments' per shard"
options:
max_num_segments: 1
delay:
timeout_override: 21600
continue_if_exception: false
disable_action: false
filters:
- filtertype: pattern
kind: prefix
value: logstash-
- filtertype: age
source: name
direction: older
timestring: '%Y.%m.%d'
unit: days
unit_count: 3

注意 timeout_override 要比默认值 21600 秒大,不过它可能会更快或者慢一点,这取决于你的配置。

从Elasticsearch 5.0开始我们还可以使用 Rollover 和 shrink api 来减少分片数量,可以以更简单高效的方式来管理基于时间的索引。你可以在这个博客中找到更多细节。

3.2 数据温热迁移shell脚本

日常运维中可以定时执行shell脚本完成hot数据的迁移。

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash
Time=$(date -d "1 week ago" +"%Y.%m.%d")
Hostname=$(hostname)
arr=("cron" "messages" "secure" "tomcat" "nginx-access" "nginxtcp" "nginxerror" "windows" ".monitoring-es-6" ".monitoring-beats-6" ".monitoring-kibana-6" ".monitoring-logstash-6" "metricbeat-6.5.3")
for var in ${arr[@]}
do
curl -H "Content-Type: application/json" -XPUT http://$Hostname:9200/$var-$Time/_settings?pretty -d'
{
"settings": {
"index.routing.allocation.require.box_type": "cold"
}
}'
done

3.3 warm数据的清理

对于warm节点的数据,可以用下面的shell脚本完成历史数据的定期清理。

1
2
3
4
5
6
#! /bin/bash
# 清理7天前的index
echo "Begin @ `date +%Y%m%d%H%M%S`"
d7=$(date +%Y.%m.%d --date '7 days ago')
curl -XDELETE "http://192.168.1.30:9200/logstash-$d7?pretty"
echo "End @ `date +%Y%m%d%H%M%S`"

第四部分 基于hot-warm架构的读写分离实现

目标:使主分片分配在SSD磁盘上,副本落在SATA磁盘上,读取时优先从副本中查询数据,SSD节点只负责写入数据。

实现步骤:

  1. 修改集群路由分配策略配置

    增加集群路由配置

    1
    2
    "allocation.awareness.attributes": "box_type",
    "allocation.awareness.force.box_type.values": "hot,cool"
  2. 提前创建索引

    提前创建下一天的索引,索引配置如下(可写入模板中):

    1
    2
    3
    4
    5
    6
    7
    PUT log4x_trace_2018_08_11
    {
    "settings": {
    "index.routing.allocation.require.box_type": "hot",
    "number_of_replicas": 0
    }
    }

    此操作可使索引所有分片都分配在SSD磁盘中。

  3. 修改索引路由分配策略配置

    索引创建好后,动态修改索引配置

    1
    2
    3
    4
    5
    PUT log4x_trace_2018_08_11/_settings
    {
    "index.routing.allocation.require.box_type": null,
    "number_of_replicas": 1
    }

4、转为冷数据

动态修改索引配置,并取消副本数

1
2
3
4
5
PUT log4x_trace_2018_08_11/_settings
{
"index.routing.allocation.require.box_type": "cool",
"number_of_replicas": 0
}

总结

参考文献和资料

1、Elasticsearch 主节点和暖热节点 https://dongbo0737.github.io/2017/06/06/elasticsearch-hot-warm/

0%