ElasticSearch部署架构和容量规划

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ElasticSearch部署架构和容量规划相关的知识,希望对你有一定的参考价值。

参考技术A

前面介绍了ElasticSearch原理和使用相关的内容,在生产环境如何比较科学的进行容量规划、部署、调优、排查问题呢,业界和官方也对相关的问题进行总结,我这边也结合自己的经验对这些使用ElasticSearch经常遇到的问题进行了总结。其中主要包括以下三大模块:

ElasticSearch有多种类型的节点,在前面概述和核心也已经介绍过了。在这里可以重新回顾下。ElasticSearch的部署节点类型如下:

主节点及其候选节点,负责集群状态(cluster state)的管理

配置项:node.master,默认为true

数据节点,负责数据存储及处理客户端请求

配置项:node.data,默认为true

ingest节点,负责数据处理,脚本执行

配置项:node.ingest,默认为true

协调节点

配置项:设置上面三个参数全部为false,那么它就是一个纯协调节点

机器学习节点,收费属于x-pack

在生产环境部署推荐配置整体思路就是:尽量是一个节点只承担一个角色。

因为不同的节点所需要的计算机资源都不一样。职责分离后可以按需扩展互不影响。

资源要求:中高CPU;中高内存;中低磁盘

一般在生产环境中配置3台

一个集群只有1台活跃的主节点,负责分片管理,索引创建,集群管理等操作

资源要求:CPU、内存、磁盘要求都高

资源要求:高配置CPU;中等配置的RAM;低配置的磁盘

资源要求:一般中高CPU;中高内存;低磁盘

协调节点扮演者负载均衡、结果的聚合,在大型的es集群中条件允许可以使用高配的cpu和内存。因为如果客户端发起了深度分页等请求可能会导致oom,这个在之前也有过分析。

注意:

如果和数据节点或者Coordinate节点混合部署,数据节点本来相对有比较大的内存占用。

而Coordinate节点有时候可能会有开销很高的查询导致OOM,这些甚至都有可能影响Master节点,导致集群的不稳定。

搭建一个es集群是由模式可循的。

这是一个基础版的职责分离的部署架构:

但是如果大量的聚合查询等操作,这种架构不太适合了。

当系统中有大量的复杂查询或者聚合时候,我们可增加Coordinating节点,增加查询的性能,这里增加了负载均衡层,通过负载均衡扩展时应用程序无感知。

这样部署部署相互影响,写入多的话,多部署ingetst节点,读的时候聚合查询较多可以多部署协调节点,存储数据量大,可以适当对数据节点进行调优。

我们知道数据有冷热之分,比如写入频繁的日志数据,近期的索引将会频繁写入。es根据数据这些特征引入了hot节点和warm节点。

使用ssd,该节点上的索引不断的有新文档写入和查询,对cpu、io的要求较高。

可以使用HDD,上面的索引不会有写入,查询较少。上面只保存只读索引或者旧索引,使用大容量便宜的机械硬盘。

配置步骤:

针对多机房灾备,ElasticSearch业界有多种不同的通用解决方案:

一个集群中的节点分布在不同的机房

应用程序同时将数据写入两个集群

应用程序先将数据写入消息队列,然后由下游的消费者消费并写入集群

ElasticSearch官方的跨集群复制功能,基于文档操作实现订阅复制

定期将索引备份到外部存储,如hdfs等设备

写请求交给网关,网关实时写入主集群,然后异步写备集群

如下是基于CCR跨集群复制的部署架构,因为篇幅有限,异地多活又是一个很大的话题,其它方案和其细节可以查阅相关资料。

我们知道当es集群的节点数大于索引的分片数时,集群将无法通过水平扩展提升集群的性能。而分片数过多,对于聚合查询以及集群的元数据管理也都有影响。我们可以总结为:

分片数量较多

优点:

缺点:

通常建议一个集群总分片数小于10w。

如何设计分片的数量呢?一个分片保持多大的数据量比较合适呢?

我们需要根据使用场景来设置:

避免使用非常大的分片,因为这会对群集从故障中恢复的能力产生负面影响。而每个分片也会消耗相应的文件句柄,内存和CPU资源,分片太多会互相竞争,影响性能。

主分片数一旦确定就无法更改,只能新建创建并对数据进行重新索引(reindex),虽然reindex会比较耗时,但至少能保证你不会停机。所以我们一定要科学的设计分片数。

这里摘录于官方关于分片大小的建议:

主分片与副本都能处理查询请求,它们的唯一区别在于只有主分片才能处理索引请求。副本对搜索性能非常重要,同时用户也可在任何时候添加或删除副本。额外的副本能给带来更大的容量,更高的呑吐能力及更强的故障恢复能力

3.1.3. 小结

根据实际经验我们稍微总结下:

对于数据量较小(100GB以下)的index

对于数据量较大(100GB以上)的index:

综合考虑整个index的shard数量,如果shard数量(不包括副本)超过50个,就很可能引发拒绝率上升的问题,此时可考虑把该index拆分为多个独立的index,分摊数据量,同时配合routing使用,降低每个查询需要访问的shard数量。

关闭交换分区的方法是:

这里是官方的jvm推荐配置链接:

https://www.elastic.co/cn/blog/a-heap-of-trouble

es的节点提供查询的时候使用较多的内存来存储查询缓存,es的lucene写入到磁盘也会先缓存在内存中,我们开启设计这个es节点时需要根据每个节点的存储数据量来进行判断。这里有一个流行的推荐比例配置:

示例:

有一个业务的数据量预估实际有1T,我们把副本设置1个,那么es中总数据量为2T。

这里31G表示的是jvm设置不超过32g否则不会使用java的指针压缩优化了。

前面也提到过,数据节点推荐使用ssd

可以考虑:

写入的目标在于增大写入的吞吐量,这里主要从两个方面进行优化:

这里可以针对myindex索引优化的示例:

首先有几个原则我们需要清楚:

我们可以通过health相关的api进行查看

我们可以使用profile api来定位慢查询。

在查询条件中设置profile为true的参数,将会显示查询经历的细节。

其结果为:

这里会返回一个shards列表。其中:

主要包含了如下信息:

Profile API让我们清楚地看到查询耗时。提供了有关子查询的详细信息,我们可以清楚地知道在哪个环节查询慢,另外返回的结果中,关于Lucene的详细信息也让我们深入了解到ES是如何执行查询的。

ES记录了两类慢日志:

慢搜索日志

用来记录哪些查询比较慢,每个节点可以设置不同的阈值。

之前我们已经详细分析了ES的搜索由两个阶段组成:

慢搜索日志给出了每个阶段所花费的时间和整个查询内容本身。慢搜索日志可以为查询和取回阶段单独设置以时间为单位的阈值,在定义好每个级别的时间后,通过level决定输出哪个级别的日志。

示例如下

前面参考官方链接:

https://www.elastic.co/guide/en/elasticsearch/reference/7.17/index-modules-slowlog.html

如果出现节点占用CPU很高,我们需要知道CPU在运行什么任务,一般通过线程堆栈来查看。

这里有两种方式可以查看哪些线程CPU占用率比较高:

这里推荐使用hot_threads api

通过返回的结果可以看到什么线程占用更高,正在做什么操作。更详细的内容可以参考官网:

https://www.elastic.co/guide/en/elasticsearch/reference/7.17/cluster-nodes-hot-threads.html

4.3.2 内存使用率过高

1)缓存类型

首先我们需要了解ES中的缓存类型,缓存主要分成如图所示三大类,如下图所示,一个es节点的内存结构:

Node Query Cache(Filter Context)

Shard Query Cache(Cache Query的结果)

Fielddata Cache

Segments Cache

(segments FST数据的缓存),为了加速查询,FST永驻堆内内存,无法被GC回收。该部分内存无法设置大小,长期占用50%~70%的堆内存,只能通过delete index,close index以及force-merge index释放内存

ES底层存储采用Lucene(搜索引擎),写入时会根据原始数据的内容,分词,然后生成倒排索引。查询时,先通过查询倒排索引找到数据地址(DocID)),再读取原始数据(行存数据、列存数据)。

但由于Lucene会为原始数据中的每个词都生成倒排索引,数据量较大。所以倒排索引对应的倒排表被存放在磁盘上。

这样如果每次查询都直接读取磁盘上的倒排表,再查询目标关键词,会有很多次磁盘IO,严重影响查询性能。为了解磁盘IO问题,Lucene引入排索引的二级索引FST[Finite State Transducer]。原理上可以理解为前缀树,加速查询

2)节点的内存查看

3)案例分析

如果节点出现了集群整体响应缓慢,也没有特别多的数据读写。但是发现节点在持续进行Full GC。

常见原因:

Segments个数过多,导致Full GC

我们可以通过查看ElasticSearch的内存分析命令发现:

segments.memory占用很大空间。

解决方案:

Field data cache 过大,导致Full GC

我们可以查看ElasticSearch的内存使用,发现fielddata.memory.size占用很大空间。同时,数据不存在写入和更新,也执行过segments merge。

解决方案:

复杂的嵌套聚合,导致集群Full GC

节点响应缓慢,持续进行Full GC。导出Dump分析。发现内存中有大量 bucket对象,查看日志,发现复杂的嵌套聚合

解决方案:

4)断路器

es有多种断路器,我们可以合理使用,避免不合理操作引发的OOM,每个断路器可以指定内存使用的限制。

关于es的断路器使用可以参考官网文档:

https://www.elastic.co/cn/blog/improving-node-resiliency-with-the-real-memory-circuit-breaker

在排查es问题时,我们会使用一些常见的命令来分析cpu、io、网络等问题。常见的命令如下

我们这里按照1s的频率输出磁盘信息

如果想查看和进程关联的信息,可以使用pidstat或者iotop。

例如,下面为iotop的输出结果

sar命令可以诊断操作系统内存相关情况。

PS:我们需要关闭内存交换,内存交换会严重损害性能

我们知道,操作系统有内核态和用户态,该命令可以输出相关信息

Recv-Q和Send-Q代表该连接在内核中等待发送和接收的数据长度。

如果改数据太多,可能原因为应用程序处理不及时或者对端的数据接收不及时,比如网络拥塞之类

本片文章先介绍了es的部署架构,回顾了es节点类型以及它们的配置方式,也了解了不同类型对硬件的要求不一样。然后总结了几种不同的架构模式,比如基础部署、读写分离、冷热分离、异地多活等架构模式,在生产环境中一般我们推荐读写分离架构模式,如果可以最好加上冷热分离,不过配置可能稍微复杂点。

对于容量规划与调优,首先要明确存储的数据量和使用场景,推荐内存磁盘比为:搜索类比例(1:16),日志类(1:48);比如2T的总数据,搜索如果要保持良好的性能的话,每个节点31*16=496G。每个节点实际有400G的存储空间。那么2T/400G,则需要5个es存储节点,每个节点分片数多少合适,文中也有介绍。副本分片数需要根据我们的容错需求。我们还总结了集群配置和jvm配置相关的优化。

es的使用优化,我们分别总结了写入和查询的优化。写入是其单次数据量、索引refresh、分词等情况都会影响其吞吐量,我们需要根据实际情况来优化。针对于查询,我们可以使用api工具进行分析,分析慢耗时发在在哪一步。当es集群出现异常时,如cpu过高、内存fullgc、卡顿、变红,我们逐一分析了可能的原因和解决办法,同时也介绍了一些常见的诊断工具和监控api。

我们需要先了解es内部运作的原理,这样才能根据实际情况正确的设置集群参数和数据模型,还需要结合实际工作遇到的问题不断的总结经验,才能用好ElasticSearch。

elasticsearch认证,节点部署,容量规划,性能优化--《elasticsearch核心技术与实战》笔记

开启并配置X-Pack的认证和授权


第三步是修改kibana.yml文件,将elasticsearch.username, elasticsearch.password,修改为kibana使用的账号和密码,配置完这步,打开kibana还是提示登录,还是需要输入账号和密码的,所以可以理解为该配置只是kibana程序自身使用,实际登录还需使用其他账户。

Elasticsearch常见的集群部署方式

  • 不同角色的节点

Master eligible, Data, Ingest, Coordinating, Machine Learning

  • 在生产环境中,根据数据量,写入和查询的吞吐量,选择合适的部署方式,建议设置单一角色的节点。


各个单一角色考虑的配置



[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SDX2gYGO-1627222714254)(https://cdn.nlark.com/yuque/0/2021/png/12674217/1627083581172-7b4e7c32-9c40-4e26-86b0-9ad6c1a67ec2.png#align=left&display=inline&height=421&originHeight=421&originWidth=649&size=64872&status=done&style=none&width=649)]

部署策略

Hot Warm架构



配置Hot & Warm Architecture

  1. 标记节点

  1. 配置Hot数据

  1. 旧数据迁移到Warm节点,当发现索引不再更新,将索引迁移到Warm节点上

Rack Awareness

通过Rack Awareness的机制,可以尽可能避免将同一个索引的主副分片同时分配在一个机架节点上。

分片的设计与管理

  • 分片过多带来的副作用

  • 如何确定主分片数

  • 如何确定副本分片数

  • 调整分片总数设定,避免分配不均衡

如何对集群进行容量规划




容量规划案例

  • 案例一,搜索类型


  • 案例二,日志类型数据




集群扩容

生产环境常用配置和上线清单

  • elasticsearch支持development和production模式,是通过http.host和bind_host字段判断是哪种模式的。

  • 运行在production模式的bootstrapChecks






集群的写入性能优化



  • 高质量建模回顾

  • 极致性能取舍

  • elasticsearch写入数据的过程

  • refreshInterval调参逻辑


refresh Interval控制着buffer生成segment(lucene索引的存储文件)的频率,所以增大refreshInterval会降低搜索的实时性,但是可以增加写入性能,因为segment变少了,IO也少了,更多的是在内存操作了。

  • Translog调参逻辑


translog类似于InnoDB的redolog

  • 分片设定调参逻辑

  • Bulk,线程池和队列大小调参逻辑

  • 一个索引设定的例子

集群读性能优化

  • 尽可能地使用反范式,从而获得最佳性能




使用Filter利用上elasticsearch的cache


诊断集群潜在问题

  • 集群诊断的维度


解决集群Yellow与Red的问题

红: 至少有一个主分片没有分配; 黄: 至少有一个副本没有分配; 绿: 主副本分片全部正常分配;

  • 集群健康度API



  • rerouteAPI将分片移动到另一个节点上

段合并优化

  • Merge优化


  • Force Merge

缓存及使用Circuit Breaker限制内存使用

  • es缓存分类

  • Node Query Cache

  • Shard Request Cache

  • Fielddata Cache

  • 缓存何时失效

  • 管理内存的重要性

  • es内存状况API

  • elasticsearch 的内存问题案例



  • es提供了断路器,防止es节点OOM

监控es集群



设置慢查询语句阈值

Full Restart的步骤

运维常用的命令




使用Shrink与Rollover API管理索引

  • 使用Rollover API,使得满足一定条件,alias指向一个新的索引


rolloverAPI只会将alias指向一个新的索引。这意味着,如果不触发rollover,数据一直都是往当前alias对应的索引写入,直到触发了rollover API,将alias指向新的索引。

  • 配置alias在rollover时保留旧索引,即alias读取时指向的的是一批索引,但是写入时指向的最新的索引

索引全生命周期管理

这些生命周期的管理,需要自动化支持,es官方有一个elasticsearch Curator,这里只是告诉有这么一个工具,具体如何使用仍需要查看文档

以上是关于ElasticSearch部署架构和容量规划的主要内容,如果未能解决你的问题,请参考以下文章

elasticsearch Elasticsearch集群规模和容量规划的底层逻辑

Elasticsearch 7.X 进阶实战视频课上线

Elasticsearch 7.X 进阶实战视频课上线

Elasticsearch 7.X 进阶实战视频课上线

ELK在广告系统监控中的应用 及 Elasticsearch简介

ElasticSearch架构思考(转)