ElasticSearch集群的动态伸缩-构建千亿级日志分析系统

在介绍索引的优化和集群的动态伸缩前,我们需要先了解文档是如何分布到集群的,又是如何从集群获取的。

1、文档是如何分布到集群的,又是如何从集群获取的

当索引一个文档的时候,文档会被存储到一个主分片中。 Elasticsearch 如何知道一个文档应该存放到哪个分片中呢?当我们创建文档时,它如何决定这个文档应当被存储在分片 1 还是分片 2 中呢?

首先这肯定不会是随机的,否则将来要获取文档的时候我们就不知道从何处寻找了。实际上,这个过程是根据下面这个公式决定的:

shard = hash(routing) % number_of_primary_shards

routing 是一个可变值,默认是文档的 _id ,也可以设置成一个自定义的值。 routing 通过 hash 函数生成一个数字,然后这个数字再除以 number_of_primary_shards (主分片的数量)后得到 余数 。这个分布在 0 到 number_of_primary_shards-1 之间的余数,就是我们所寻求的文档所在分片的位置。

这就解释了为什么我们要在创建索引的时候就确定好主分片的数量 并且永远不会改变这个数量:因为如果数量变化了,那么所有之前路由的值都会无效,文档也再也找不到了。

因此,当我们试图通过扩容来提升集群的吞吐量时需要修改分片的数量,保证数据能够均匀的分布到新的节点上。

你可能觉得由于 Elasticsearch 主分片数量是固定的会使索引难以进行扩容。实际上当你需要时有很多技巧可以轻松实现扩容。扩容设计参考如下链接:

https://www.elastic.co/guide/cn/elasticsearch/guide/current/scale.html

2、动态伸缩

扩容

合理的设置分片数量

分片数量的设置需要根据请求量来计算,单个节点上的分片数量越多并发写入的能力越高,但是要综合考虑CPU和IO、内存的情况,不是越多越好。

比较好的办法去评估分片数据是观察CPU、IO、内存,如果有很大的空闲可以增加分片数据,一般来说可以先设置每台机器两个主分片。

index.number_of_shards = 2 * 机器节点数

curl -u elastic -XPUT http://localhost:9200/_template/log -d '{

  "template":"log-*",

  "settings" : {

    "index.number_of_shards" : 6,

    "number_of_replicas" : 1,

    "index.refresh_interval" : "60s",

    "index.mapping.total_fields.limit": 2000

  }

}'

上面的脚本我们为log-*的索引设置了一个模板,接下来如果我们按天创建索引,例如log-20200101,将会使用上面的配置。

模板的设置可参考如下链接:

https://www.elastic.co/guide/cn/elasticsearch/guide/current/index-templates.html

当我们需要扩容时,给集群增加节点,更新上面的模板,根据集群的节点数量修改index.number_of_shards的值,新产生的索引将按上面的配置创建分片。

ElasticSearch官方建议如果数据量增加,可以将数据写入新的索引,上面的模板也是参考这个建议。

搜索 1 个有着 50 个分片的索引与搜索 50 个每个都有 1 个分片的索引完全等价:搜索请求均命中 50 个分片。

回收

通常情况下我们的日志量会一直上涨,很少情况出现日志减少,这里还是介绍如何回收资源。

当我们的系统容量有较大冗余需要回收资源时,分以下几个步骤:

1) 首先修改模板,修改index.number_of_shards的值与节点数对应;

2) 然后将需要停服回收的节点设置为不可写入;

3) 接下来停掉对应的节点,观察集群状态,此时数据会进行重平衡集群状态是Yellow,重平衡的时间和集群的数据量大小有关系;

4) 集群状态恢复Green时可以继续回收资源,注意回收过程会出现节点数是偶数,要注意设置ElasticSearch的配置:

discovery.zen.minimum_master_nodes = (n/2+1) (n为节点数)

回收资源的过程要谨慎操作,谨防脑裂。

注意

ElasticSearch默认会给新的索引设置5个分片,意味着我们最多可以将数据均匀分布到5个节点上,如果不增加分片数据只添加节点将不会再增加系统的吞吐量。

分片不是越多越好,我们的方案是要把数据均匀的分配到集群的节点上,同时还要有较高的吞吐量和低延迟,单个节点上的分配数过多会导致资源竞争,此时我们要考虑增加节点。

因此,我们在设计架构时要考虑一段时间内的分片数量,不要轻易变动,如果要变更一个索引的分片意味着要将分片内的数据重新索引一遍,但我们一般不建议你这么做。

ElasticSearch提供了重新索引的方案,可参考如下链接(注意找到你对应的ElasticSearch版本,版本不同语法上可能有差异):

https://www.elastic.co/guide/cn/elasticsearch/guide/current/reindex.html

最佳实践

作为日志分析系统,比较好的方案是按时间建索引,例如按天建索引,如果业务日志上升可以调整下一天的分片数量,同时,我们对过期的数据可以进行按天清理。

如果日志量再继续上升,分片数量可以继续增加,一般来说单个分不要超过50GB,这取决于你的系统内存。

3、容量规划

容量的规划没有万能的解决方案,我们可以从以下几方面去考虑:

1) 单分片的大小,预先设置好单分配的大小,这样我们就可以根据集群的大小来决策何时需要增加资源;

2) 观察你的CPU,长时间超过50%你可能就要考虑增加资源;

3) 观察你的主机IO,如果磁盘经常写满那么你可能要考虑增加磁盘的IOPS;

4) 观察你的主机内存,如果内存不够ElasticSearch可能会宕机,你需要在合适的时间考虑扩容。

当查询较慢,主机节点的资源利用率不高时可以适当的增加副本,通过增加副本可以提供吞吐量。

4、索引的优化

昨日的日志不会再发生变化,如果我们将每个分片合并至一个段(Segment),它会占用更少的资源更快地响应查询。 我们可以通过optimize API来做到。参考链接:

https://www.elastic.co/guide/cn/elasticsearch/guide/current/merge-process.html#optimize-api

对不常用的查询我们可以关闭,数据还在集群里

POST /logs_2014-01-*/_flush

POST /logs_2014-01-*/_close

POST /logs_2014-01-*/_open

参考链接:

https://www.elastic.co/guide/cn/elasticsearch/guide/current/retiring-data.html#optimize-indices

5、定期删除

ElasticSearch提供了Delete API来进行索引删除,对于日志系统,我们按天或半天、小时创建索引,当对应的日志过期,我们可以将整个索引删除。例如删除2020年1月的数据:

DELETE /logs-20200101

如果有审计或其他回溯场景,可以将数据转存到其他存储介质上,可以是共享磁盘,可以是AWS S3,详细说明参考链接:

https://www.elastic.co/guide/en/elasticsearch/reference/5.6/modules-snapshots.html

索引性能调优,参考如下链接:

https://www.elastic.co/guide/cn/elasticsearch/guide/current/indexing-performance.html

Kibana设置超时

实际应用中应合理设置Kibana的超时时间,建议不要超过15s,如果设置的时间过大可能会对ElasticSearch造成很大的冲击,例如一个模糊的全量查询,搜索集群内的所有数据,可能会给集群带来很大的冲击,因此尽量注意不要查询太大规模的数据。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值