Elasticsearch集群容量的自适应管理
作者|范桥青 单超
编辑|陈乐
供稿|DI Pronto
本文共6298字,预计阅读时间15分钟
更多干货请关注“eBay技术荟”公众号
概述
Elasiticsearch 作为一款成熟的分布式数据产品,因其在日志分析,数据检索,以及离线数据分析的卓越表现,在ebay内部得到了广泛的推广和使用。过去几年来,Pronto 作为ebay内部Elasticsearch云平台的管理者,一直致力于提供高效可靠的云平台服务,但我们时常会遇到这样一些问题。
统一的资源配比方式导致冷热节点的出现,致使不同业务场景下硬件资源使用不均衡。
旺季突发的流量增长,导致部分读写失败。
有限资源下,资源闲置制约了客户规模的增长。
试想一下,当服务于卖家产品分析的集群在销售期间,因固定大小的集群规模无法服务于快速增长的用户流量,从而导致了原服务的超时失败,使得工程师们不得不24小时坐在电脑前,思考需要扩容的数量和类型,这中间耗费的精力是巨大的。那如果这样的集群有10个,有100个呢?
目前Pronto维护着上百个Elasticsearch集群,维护着过万的K8S Pods。我们迫切需要一个弹性的扩容系统,它能结合多变客户使用场景,快速敏锐地嗅探出客户流量的变化趋势,整合现有的资源,并精确地制定集群容量方案,最终快速地把资源调配到不同业务的集群中。
因此针对此系统,本文将从如下章节展开叙述:
弹性计算与容量管理。
Pronto多集群模式下容量管控存在的问题。
Elasticsearch中的自适应容量管理策略。
Pronto中的最佳实践。
阶段性工作总结。
弹性计算与容量管理
高可用/可靠的服务提供是所有云平台追求的主要指标,如果用户端流量的变化引起集群性能的波动,甚至导致部分机器的宕机,严重者将影响线上应用,直接影响终端用户,这是致命的。所以在这种场景下快速检测出问题,按需扩容,并从故障中快速恢复是保证服务高可用性的重要手段。
弹性计算是云服务平台自适应扩容的抽象描述,最早出现于Amazon的EC2(Elastic compute cloud)中,随后各大厂商包括Microsoft/Alibaba/Elastic都有自己独立的ECS(Elastic Compute Service)且均有独立的设计实现。
在《弹性计算—无处不在的算力》[1]中,它要求云平台根据业务流量自动对业务进行扩容,不需要人工干预,避免流量激增扩容不及时而导致的系统故障,以及平时大量闲置资源造成的浪费,文中认为完备的弹性计算系统需具备如下特点:
简单可控:便捷获取计算资源,实力部署简单高效。
快速弹性:秒级启动和弹性伸缩,快速预警和快速扩容。
按需使用:容器实例按需创建释放,不需要预先准备底层资源。
因此高效的弹性计算系统可以让云平台在高可用/可靠上更上一阶,特别是在计算资源的供给、平台管理和运维效率上带来了巨大提升。
基于此,弹性计算要求云服务平台提供一系列工具来保证服务的高效稳定,容量管理便应运而生。在ebay,云平台主要服务于内部客户,在预算设限甚至资源超售的情况下,更加要求各PAAS平台对有限资源的高效利用。Greeneideas公司IT基础设施主管Joe Greene撰写了一篇文章[2],分析了在云计算环境中的容量管理挑战的主题。他将容量问题抽象为两种:第一个是性能,组织会发现给定应用程序对于其当前位置而言太多了(需要迁移到更好的运营环境)。第二个是总体容量管理(这将确保组织可以为给定的容器或虚拟机提供足够的资源)。所以针对容量管理的一般思路他提出:
需要建立所有利益相关者都能从自己的角度理解的容量模型。
采用应用程序团队在配置容量时可能并不真正知道他们需要什么。
要求比较苛刻的应用程序必须以不同的方式处理。
清理不是自然发生的,并将会浪费容量。
IAAS、PAAS和XAAS高效整合,从防火墙安全性到操作系统、磁盘速度,需要各平台的通力合作。
所以,Pronto开始搭建自己的容量管理平台。
Pronto多集群模式下容量管控存在的问题
Pronto并没有采用统一接入、集中管理、接口隔离的方式来对内提供Elasticsearch服务。Elasticsearch 作为开源的搜索分析引擎,因其支持各种数据类型(包括文本、数字、地理、结构化、非结构化),以及简单的 REST API而被广泛使用。单一或有限集群的方式可以方便管控用户行为,减少因错误的数据配置带来的性能问题,但同时又制约了客户在ES/Kibana上的使用自由,不同用例在不同功能上的依赖导致了在相同资源上不同程度的竞争,以及带来索引资源共享的风险。且随着集群规模的增长,更多用例的加入,这种共享模式下的集群易出现一损俱损的现象,运维成本极高。
所以我们采用了单例独立部署、独立使用的方式,用户开箱即用、全功能支持(x-pack除外),开放了完备的Elasticsearch/Kibana给每个客户。这种部署模式避免了不同类型的用例在计算资源上的相互竞争,减少了故障影响面,对平台稳定性带来极大的提升。但脱离了统一接入模式下产品专家对于每个用例使用规范的审批以及最佳实践的建议,受限于每个客户对Elasticsearch的理解不同,往往导致资源的低效使用,主要有:
不合理的字段映射设计带来冗余的索引开销,造成MEM/DISK浪费。
不均衡的分片大小导致冷热节点的出现,造成CPU/MEM/DISK 浪费。
低效的查询语句,造成MEM/CPU 浪费。
过多索引和分片拖累Master节点,导致整个集群性能不佳。
此外Pronto统一的机型配售方式虽然能安全的让所有应用上线,但忽视了不同用例在硬件资源配比上的差异,比如:
Logging 用例需求更大的磁盘空间
Searching 用例 需求更多的CPU。
不同类型节点Master/Data/Client需求不同的CPU/MEM/DISK配比。
Hot-Warm 用例的甄别与迁移。
目前Pronto维护着数百个Elasticsearch集群,管理着过万的 K8s Pods。如Joe GREENE所说,客户们可能自己都不知道流量未来会变成什么样,更不知道如何制定符合Elasticsearch使用方式的容量计划。
于是Pronto制定了一系列策略来为不同的业务制定容量计划。它可以识别业务中流量模式,调整容量计划,及时清理与回收空闲资源,在服务可用性和资源成本之间取得平衡,甚至一定程度降低运维人员的工作负担,提高了效率。
图3-1容量管理核心
Elasticsearch中的自适应容量管理策略
图4-1云平台自动中的容量管理
ElasticSearch 自身有一套优秀的分片管理机制[3],它很好地面向客户隐藏了复杂的处理机制,我们不用关心数据是如何分片,落入到哪个分片中,以及最后分片落在哪个节点上,Elasticsearch会自适应地根据节点上的分片总数维持所有节点平衡,这种机制给集群的水平扩展带来极大便利:我们只需将新实例加入与集群同一个网络即可。
1. 用例场景
在制定容量管理策略之前,我们首先需要知道用例的使用场景。目前Elasticseach常见应用场景主要有:
Logging,几乎很少的读取,对写入性能要求高。
Searching,很少的写入,对读性能要求高。
数据分析,查询复杂度高,但响应时间要求低,且有一定的写入性能要求。
2. 监控指标
监控指标是我们用来观测集群健康程度的主要手段之一,但哪些指标是用来观测Elasticsearch性能的呢?一般我们将MEM、CPU和DISK作为衡量集群资源使用情况的三大基础指标,此外还要考虑吞吐量和服务响应时间。
MEM:内存使用率。在一个Elasticsearch 实例中内存是怎么被分配的?一般我们将50%的实力分配给JVM,其中10%分配于NodeQueryCache负责查询Filter缓存,10%分配给IndexingBuffer用于数据写入,另外还有1%用于ShardReqeustCache用于缓存结果,其余被用作FieldDataCache,使用于字段的排序和聚合。另外50%堆外存主要服务于OS缓存服务,比如LuceneSegments、Pagecache。Pronto主要观测的是堆内存使用情况。
CPU:CPU使用率。每个Elasticsearch实例为不同的操作分配不同的线程池,而且还有与之关联的队列配置。重要的线程池有generic/index/search/search/get/bulk/search,具体大小可以参考[4]。容器部署方式下,CPU使用率观测不易,/_cat/nodes的输出得到的是K8S节点的使用率。我们采用从/_nodes/stats中读取指标CGroup指标转换获得CPU使用率,公式cgroup_usage_nanos/(elaspsed_periods*quota_micros*1000)。
DISK:磁盘使用率。常规SSD我们配备1TB~2TB,Hot-Warm架构下,Warm节点配备10TB。
吞吐量:单节点每秒钟最大字节写入量。
Response Time: 响应时间。按照每个节点的线程数量,结合查询平均响应时间,获得满足读取请求的最小节点个数. 这种方式可以防止线程池队列的增长速度超过消耗速度。避免由于计算资源不足,搜索请求可能会被丢弃的问题。
最高线程数量 = 向上取整(每秒线程数 * 平均响应毫秒时间 / 1000 毫秒)
线程池大小 = 向上取整((节点核心数 * 每个核心线程数 * 3 / 2) + 1)
数据节点个数 = 向上取整(最高线程数量 / 线程池大小)
此外我们还将队列Rejections、API Node Latency、单节点分片个数作为扩/缩容的后安全性判别的参考指标。
Rejections:Write/Search Rejections,读写拒绝发生的次数。观测这个指标可以有助于我们判断,部分节点异常有助于判断是否存在热节点问题,而所有节点Rejections的上升可以判断集群性能是否存在瓶颈。
API Node Latency:单个节点上API调用的响应时间。因Elasticseach采用保证所有节点分片数量大致相等的分配策略,所以不同的分片大小会导致数据总量存在差异,从而使得节点在元数据的维护和管理成本上存在差异。数据过多的节点会容易成为整个集群性能瓶颈,极端情况下会拖累Master节点并带动PendingTasks上升。
单节点分片个数:<200。
3. 指标阈值约定
基于经验,当以上指标处于如下区间时,我们定义集群资源使用处于合理水平。
CPU: 5%~40%, 建议~20%
HEAP: 60%~90%,建议~80%
DISK: 40%~65%,建议~55%
吞吐量:8MB/s~20MB/s 建议~8MB/s
Write/Search Rejections: 建议0
API Node Latency: 建议<1500ms
单节点分片个数:建议<600。
4. Elasticsearch节点分类
Master Node:集群元数据管理、任务切分,只分配MEM和CPU。
Client Node:读取请求转发、收集、结果排序以及支撑Kibana服务,只分配MEM和CPU。
Data(Hot/Warm) Node:存储数据,文档索引、查询和打分。分配了MEM、CPU和Disk。
5. 策略制定
不同的类型节点在资源需求上是不同的,例如Master节点往往需求更多CPU,Client节点需求更多的CPU和MEM。而Data节点更为复杂,在不同的业务场景下,Logging 用例需求更多的Disk,Searching用例需求更多的CPU,数据分析型则需求更多CPU和Memory。
所以准确的识别出不同的业务场景,是制定对应的资源分配策略开始。如下是Pronto容量管理的基本组件。
图4-2容量管理的基本组件
5.1 Pre-Check。
识别用例应用场景(Logging/Searching/数据分析)。每个用例在使用Pronto集群之前都登记过集群具体使用场景,但部分客户在长期使用之后会变更行为,这部分用例没办法跟踪,一般我们需要根据资源使用情况以索引命名方式结合数据内容修正,数据统计修正之后需人工审批。
Logging用例我们会增加默认的配置来调整IndexBuffer/Translog/RefreshInterval以充分使用资源,改善性能。
5.2 Analysis
指标分析,主要是流量分析,识别周期性流量和非周期性流量。对于周期性流量,分析获得流量的周期性,趋势和峰值。非周期性流量的集群,我们默认一个月为一个周期。
获取一个周期内CPU/MEM/DISK/吞吐量/单节点分片个数的使用峰值,按照指标阈值约定,分别计算最少节点个数,建议节点个数=使用率*节点个数/建议使用率。
获得周期内QPS峰值,按照公式4-1计算满足最小响应时间所需要的数据节点个数。
如果用例场景为Logging,Data节点取满足DISK/吞吐量使用要求的最大节点个数。Client节点取按照满足CPU使用要求的节点个数。
如果用例场景为Searching,在满足磁盘使用标准的情况下,Data节点取满足CPU使用要求和最小响应时间要求所需节点的最大值。Client节点取按照满足CPU使用要求的最大节点个数。
如果用例场景为数据分析,在满足磁盘使用标准的情况下,Data节点取满足CPU/MEM使用要求和最小响应时间要求所需节点的最大值。Client节点取满足CPU/MEM使用要求的最大节点个数。
5.3 Throtting
时间序列的数据因外部环境等诸多原因,随着时间维度的扩大易出现超出寻常的极大值,这类毛刺数据的出现虽然可以在Pre-Check中的过程中被平滑处理,但是还是会有平滑后的结果超出常值,这类数据的出现需要及时告警。
为了保证集群稳定,同一个集群在连续两个流量周期内不会做资源缩放。
Node API Latency过大的集群(>1500ms)需立即停止自适应容量操作,并告警团队。
节点规模调整过大也需告警团队。
如果是缩容,在移除空闲节点之前,需要确认节点是否有HOT节点问题,比如避免超过 10% 的节点磁盘使用率超过 80%,以及部分节点MEM/CPU使用过热。对于这类节点的出现,我们需要跟客户提出改进。
告警团队关于不合理的索引设计(字段映射、分片大小、分片个数)。
告警团队CPU使用率过低,但DISK使用全满的集群,此类集群需变更机型,配比更大的磁盘。
5.4 Scaling
扩容:根据实际计算得到的节点个数,将节点个数增加集群中。
客户制定的流量计划,我们需要按此提前2天将资源分配给客户。
非计划型流量,按照分析得到的节点个数在批准的资源上限内分配给客户。得益于K8S容器调度的高效,以及Eleasticsearch优秀的水平扩展能力,自带的Allocator和Decider可以自适应地调配数据分片到新加入的节点上[5]。
缩容:
避免在流量高峰和元数据变化高峰(1.创建索引,2.Hot-warm移动分片) 时操作。
先移除节点上的数据,每次最多10个节点,此目的在于移除数据后,如果集群性能出现问题,可以快速恢复。
等待所有分片移除后再移除下一批10个节点,并确认Latency&Rejections没有增长。
所有节点数据等待一个流量周期,确认没有任何性能问题后从集群中摘除节点。
如果Latency/Rejections指标异常,需要快速告警团队,并回滚所有操作。
Pronto中的最佳实践
图5-1 Autoscaling结构图
Autoscaling是Pronto容量管理的内部实现。依托于内部监控平台Sherlock的监控数据,Diagnose 分析工具会定期扫描所有集群的监控数据,结合自行开发的Index Management Tool分索引数据行为,并按照上述Pre-Check和Analysis生成的分析结果,Throttling模块定义的行为告警和通知团队,最后再由运维人员确认后进行扩容(ScalingUp)和缩容(ScalingDown)操作。
实际使用中,容量管理的“快速弹性”和服务的“安全可靠”是难以同时满足的,Pronto为了保证服务可靠,在流程中引入了经理和客户的审批来确保扩/缩容的安全性,如下图。
图5-2 Autoscaling workflow
Diagnose在根据Analysis结果对集群进行扩/缩容前,会开出通知经理和客户Review,Reject请求会让整个Scaling Flow回滚,并阻塞该集群未来30天内的所有Scaling操作。
1. 制定的流量计划
Pronto跟内部Cloud 平台集成,新客户在正式上线到Pronto时,可以按照需求制定流量计划,Autoscaling会按照制定的计划分阶段的把所有节点增加到用户集群中。
图5-3流量计划制定
图5-4集群规模变化曲线
清晰的集群容量跟踪有助于客户观测和监控集群行为,并及时作出容量调整(Use-Case Adjustment)。上半部分是集群规模变化时序图,蓝色的线表示集群已有规模,红色的线表示根据当前资源使用情况容量管理建议的最佳节点个数,绿色的线表示用户制定的流量计划,Pronto会按照客户制定的流量计划提前两天将节点增加到位。
2. Scaling up
监控数据分析动态扩容。按照监控数据,分析用户行为,计算所需要的最佳节点个数。Approved Quota是用户在上线到Pronto时审批得到的资源总数,但可能在后续的使用过程中,因流量变化导致冗余,Autoscaling进行了缩容操作。所以Autoscaling会根据实际流量,将这部分移除的节点按量再加回集群,但不会超出Approved的总量。
Precheck (预检查)
Throttling(告警阀)
Metrics Analysis(监控数据分析)
Quota Prepare(准备节点)
Approval Request(工单审批)
Scaling(扩容)
Notification(通知客户/Pronto团队)
3. Scaling down
监控数据分析动态缩容。按照监控数据,分析用户行为,计算所需要的最佳节点个数。新客户由于不会将流量全部上线,导致资源长期闲置,需要及时回收这部分资源。
Precheck
Throttling
Metrics Analysis
Approval Request
Scaling(缩容)
Postcheck(操作后检查)
Rollback(回滚)
Notification
缩容请求审批界面,罗列了用于判断操作安全性的重要指标。
图5-4-1 缩容工单审批 节点个数变化
图5-4-2 缩容工单审批指标1
图5-4-2 缩容工单 审批指标2
阶段性工作总结
Autoscaling在Pronto已经运行良久,虽然在节省资源和提高效率上取得了显著的效果,但仍有诸多需要改进的地方,比如
引入时序数据预测模型,改善时序数据预测效果。
不同类型的指标存在错峰的行为,进一步完善容量管理策略。
结合用户具体行为,优化Searching和数据分析业务场景下容量推算结果。
监控数据维度大、分析缓慢,引入增量指标存储提高扩/缩容效率。
这些问题制约了Autoscaling的运行效率,虽然离广义上的“弹性计算”有一定的差距,但已经做到了在保证集群可用性下安全地对容量进行管控。我们也相信在未来不断的迭代中,上述问题必将得以优化。
参考
1.https://developer.aliyun.com/article/793834spm=a2c6h.14164896.0.0.30792c60XhvyUN
2.https://www.51cto.com/article/638783.html
3.https://www.jianshu.com/p/1b1dc6e14ac3
4.https://doc.codingdict.com/elasticsearch/437/
5.https://www.elastic.co/guide/cn/elasticsearch/guide/current/_scale_horizontally.html
往期推荐
点击“阅读原文”, 一键投递
eBay大量优质职位虚席以待
我们的身边,还缺一个你