跳到主要内容

3 篇博文 含有标签「最佳实践」

查看所有标签

Kubernetes集群中如何利用北极星因果指标设置正确的POD规格——CPU篇

· 阅读需 13 分钟
Kindling-OriginX
故障根因推理引擎

在 Kubernetes 容量规划中,追求的是集群的稳定性和资源使用效率之间的平衡:

  • 资源分配过多会造成浪费。
  • 资源分配过少则会导致用户请求时延上升,影响集群的稳定性。

背景

公众号之前翻译了一篇 Sysdig 的文章,Kubernetes 容量规划:如何合理设置集群资源介绍了如何设置合理的资源参数

虽然按照那篇文章设置可以有一定的帮助,但仍然可能存在风险。本文将详细说明这些风险,并介绍如何通过北极星指标对 POD 的规格进行调整,以达到时延和资源的完美平衡。

Kubernetes 中的 POD CPU 规格参数

在 Kubernetes 中,POD 的 CPU 规格主要包括以下两个参数:

  • requests: POD 启动时请求的 CPU 资源量。Kubernetes 调度器会根据这个参数将 POD 调度到能够满足资源需求的节点上。

  • limits: POD 运行时能够使用的最大 CPU 资源量。如果 POD 尝试使用超过这个限制的 CPU 资源,会被限制在定义的 limit 值内。

Kubernetes 中的现存指标

要判断 POD 规格是否合适,需通过合适的指标来评估。当前 Kubernetes 中常见的 CPU 指标包括:

  • CPU 利用率(container_cpu_usage_seconds_total): 通过类似 PQL 语句获得:
irate(container_cpu_usage_seconds_total{namespace="XXXX", container="XXXX"}[5m])

该指标反映了 CPU 利用率。

  • 系统负载:node_load1、node_load5、node_load15 表示系统在 1 分钟、5 分钟和 15 分钟内的平均负载。一般认为负载与 CPU 核数相当即可。

  • CPU 节流(throttle):container_cpu_cfs_throttled_seconds_total, 通过类似 PQL 语句获得:

irate(container_cpu_cfs_throttled_seconds_total{namespace="XXXX", container="XXXX"}[5m])

该指标表示容器由于 CPU 配额不足而被节流的 CPU 核心时间总量。

尽管这些指标对了解 CPU 资源使用情况有帮助,但各自存在局限性,难以单独作为唯一且关键的指标。


北极星指标的应用

所谓北极星指标,是指唯一且最关键的指标。在 Kubernetes 中,该用哪个指标来衡量容器的 CPU 资源是否充足呢?

CPU 利用率指标的局限性

CPU 利用率指标的主要局限性在于:

  • 单一性: CPU 利用率反映了容器对 CPU 资源的需求和使用情况。如果利用率持续高企,可能表明容器需要更多的 CPU 资源。然而,仅凭这一指标无法全面反映系统的性能状态。
  • 响应时间和性能: 需要考虑容器内应用的响应时间和性能。如果响应时间变长或性能下降,即使 CPU 利用率不高,也可能意味着 CPU 资源不足。
  • 并发负载: 在高并发场景下,瞬时的负载高峰可能导致性能问题。CPU 利用率可能无法及时反映这些短期高峰负载的影响。

Load指标的局限性

Load 指标代表有多少执行单元等待调度器执行,但它无法单独衡量 CPU 资源是否充足。

CPU节流指标的局限性

container_cpu_cfs_throttled_seconds_total 指标用于衡量容器因 CPU 资源不足而遭受的 CPU 节流(throttling)。如果该指标的值不为零并且持续增加,通常意味着:

1. CPU 资源不足: 容器的 CPU 使用需求超出了为其分配的 CPU 配额,导致它无法获得足够的 CPU 时间来执行其任务。

2. 性能影响: CPU 节流可能会导致容器内应用的性能下降,因为它们没有足够的 CPU 时间来及时完成任务。

虽然该指标能够直接反映容器是否遭受 CPU 节流,但仅凭它来判断资源是否充足可能会忽略其他重要的性能指标和系统状态。即使 container_cpu_cfs_throttled_seconds_total 不增长,但如果 CPU 调度器队列很长,仍然可能出现 CPU 资源不足的情况。


北极星因果指标中的 CPU 调度耗时

北极星因果指标中的 CPU 调度耗时能够反映出 CPU 节流和高负载下的 CPU 调度延时,包括以下几种情况:

  • CPU 调度队列长: 当程序执行完数据库等网络操作后,如果CPU充分,应该被立马执行,但是当调度队列长时,就会产生等待被调度到 CPU 上的时间。

  • CPU 节流: 代码执行时间片被执行完后,等待下一个调度周期才能被调度到 CPU 上执行的时间。

北极星因果指标中的 CPU 调度耗时能够反映出 CPU 节流和高负载下的 CPU 调度延时。只要该指标不高,即可说明容器的 CPU 资源是充分的;如果该指标高,则说明容器的 CPU 资源是不充分的。

通过准确监控和调整这些指标,可以实现 Kubernetes 集群的稳定可靠性和资源使用效率之间的最佳平衡。


北极星因果指标的CPU调度耗时实际用法举例

Demo环境的route-service的CPU调度耗时异常修复过程

在云观秋毫的Demo环境中,通过北极星因果指标巡检,发现route-service的CPU调度耗时较长,其90分位线经常超过10ms,甚至达到20ms左右。 此时指标已经说明了route-service的CPU资源不充分。

怎么解决呢?是不是直接去增加POD limit的设置呢?

POD规格调整原则一:如果发现CPU节流(throttling)时间高,才需要增加POD limit的配置

通过查询route-service的CPU节流(throttling)指标,发现其CPU节流时间很少,几乎没有波动。这与route-service北极星因果指标中每次请求都有10ms左右情况不符合,说明北极星因果指标中的CPU调度耗时并不是由于CPU节流导致的,也就意味着提高POD limit无法解决问题。

那这种情况只能说明当时的CPU队列很长,当一次任务如数据库调用完成之后,程序需要重新调度到CPU上而产生了调度耗时。为了验证这点,我们继续查看下其CPU利用率指标和节点的Load指标。

CPU利用率显示其CPU资源是非常充足的,因为route-service所在机器的节点CPU核数为8核,load指标最高位7.13,也是符合预期的。 此时如果没有北极星因果指标,也不知道每次请求有这么高的CPU调度耗时,但是要优化性能,提高容量也就无从谈起了。

为了证明北极星因果指标的正确性,我们将route-service调度到另外一台机器上,在调度之前其load如下:

当调度完成之后,我们再次查看北极星因果指标,发现每次请求CPU调度耗时已经降低了很多,此时调度耗时在90分位线最高也只有8ms,绝大多数请求CPU调度耗时在4ms以下。

此时我们再去查看rout-service的相应延时,发现延时也有了显著的优化:可以看到平均延时在重新调度之前延时是普遍大于20ms的,而调整之后rout-service的延时已经没有高于20ms的了。

Demo环境的order-service的CPU调度耗时异常修复过程

在云观秋毫的Demo环境中,通过北极星因果指标巡检,发现order-service的CPU调度耗时较长,其90分位线经常超过80ms,甚至达到90ms左右。 此时指标已经说明了order-service的CPU资源不充分。

根据POD规格调整原则一,先去查看容器的CPU节流指标,发现其节流时间确实很大,说明POD的规格Limit设置过小了。

如果只看CPU 利用率,其实还好,并不是一直很高,而是周期性飙高。

POD规格调整原则二:调整POD Limit设置之时,不需要翻倍的增加CPU核数,而是一个核增加完之后,观察数据,确保最省资源的方式满足业务需求

当对order-service的limit增加之后,再看节流指标,此时节流已经很少发生了。

然后我们再看北极星因果指标中的每次请求CPU调度耗时指标,数据从原来的80-90ms 降到了1~2ms左右,甚至90分线最高值才5ms,说明其CPU现在是充分供应了。

最后我们再看看调整前后的时延对比,从调整之前的90分位线100ms降到了调整之后不到10ms左右。


利用北极星因果指标轻松识别POD运行的应用是CPU密集型还是IO密集型,并完成调度,保证应用的健康状态是最佳的

在计算机知识中,大家都知道不同应用有着不同特征,典型的分类就是CPU密集型和IO密集型,但是我们怎么判断应用是IO密集型还是CPU密集型呢?绝大多数情况下大家是通过主观经验判断,缺少证据证明。

POD调度原则:根据POD应用类型来实现调度

如果根据北极星因果指标中每次请求CPU执行时间超过了响应时间的一半,一般认为其应用为CPU密集型。 根据这个原则发现绝大多数在线业务都不属于CPU密集型,只有那些执行时间非常短的应用不到20ms的应用,其cpu时间才有可能超过一半。

所以调度原则简化成可以把响应时间短的应用和响应时间长的应用混合调度在一台机器上能够保证应用健康状态是最佳的。

最佳实践:深入理解线程池参数设置

· 阅读需 14 分钟
Kindling-OriginX
故障根因推理引擎

最佳实践:深入理解线程池参数设置

在现代编程中,线程池已经成为了不可或缺的一部分,特别是在Java编程开发中,线程池更是绕不开技术点。然而,要想取得优秀的性能表现,需要对线程池的参数进行调优。本文将深入讲解 Java 线程池的调优方法和技巧,帮你提高编程技能和优化系统性能,并介绍如何使用 Kindling-OriginX 来深入理解线程池参数设置。

最佳实践:深入理解线程池参数设置

什么是线程池

线程池是一种管理和重用线程资源的机制,是利用池化思想设置和管理多线程的工具。线程池维护一定数量的空闲线程,当有任务需要时,就从中选择一个空闲的线程用来执行任务,当使用完成后该线程就会被重新放回线程池中,通过这样循环使用的方式来节省创建线程和销毁线程的各项资源开销。

线程池重要参数解析

线程池中有多个关键参数,需要在创建线程池时对其进行设置,合理的参数设置能够达到最佳的性能,适应任务场景。这里以ThreadPoolExecutor为例,对几个重要的参数进行解析说明。

corePoolSize

核心线程池中线程的数量。当提交一个新任务时,如果当前线程池中的线程数量少于corePoolSize,就会创建新的线程。即使此时有空闲的非核心线程可使用,也会创建线程,直到达到corePoolSize配置数量。

maximumPoolSize

线程池中最大的线程数量。包括核心线程池和非核心线程池,即在任务队列已满的情况下,可以创建的最大线程数。当线程数量超过maximumPoolSize时会执行配置的拒绝策略。

keepAliveTime

线程存活时间。当线程池中的线程数量大于corePoolSize时,超出的空闲线程最大能存活的时间,超过这个时间,线程就会被回收,直到线程数等于corePoolSize。

unit

时间单位

workQueue

任务队列实现。用于存储已提交未被执行的任务。线程池根据任务队列的策略来进行等待任务的调度。常见的队列有:

  • ArrayBlockingQueue:数组实现的有限队列,可以指定队列长度。

  • LinkedBlockingQueue:基于链表的无限队列,长度可以无限扩展。

  • PriorityBlockingQueue:优先级队列,可以设定队列里任务的优先级。

参数设置原理

最佳实践:深入理解线程池参数设置

为了最大程度利用线程池的资源,充分发挥线程池的执行效率,需要对线程池的主要参数进行合理的设置,对于不同的业务和场景,也需要根据实际情况来进行调整。

  • 核心线程池大小corePoolSize和最大线程池大小maximumPoolSize一般需要根据实际场景设置,主要与执行任务的类型和数量相关。一般最佳实践建议是将核心线程池设置为CPU核心数 + 1,最大线程池大小设置为CPU核心数 x 2。

  • KeepAliveTime线程存活时间,一般根据任务处理的耗时配置。如果任务密集且耗时长,则可以适当增加空闲线程的存活时间,根本目的是尽可能减少线程的创建和销毁操作,原则上不超过60s。

  • workQueue阻塞队列的类型及大小需要根据具体场景来设置。通常来讲任务数量多或并发高,选择无界队列,避免任务被拒绝。任务数量可控选择有界队列。


虽然参数设置原理看似简单,但实际使用中仍存在一些问题:

  • 人员经验和能力不同,经常以个人习惯或理解进行设置,没有标准或者数据依据。

  • 执行情况和任务类型、并发情况、机器配置都有关系,导致同样参数也可能运行起来情况有差异。

  • 同一个应用中可能存在多个不同业务类型的线程池。

常见线程池参数配置方案及其问题

上面参数设置大多基于经验,是否有科学的方式能够根据场景对其进行计算或者评估?

常见理论方案

这里以美团技术团队调研的业界一些线程池参数配置方案为例:

最佳实践:深入理解线程池参数设置

  • 第一种方案过于理论化,偏离任务场景。

  • 第二种方案也不符合实际情况,应用中往往不可能只存在一个线程池。

  • 第三种方案过于理想,正常情况下流量存在高峰低谷,同时大促、秒杀等运营活动期间流量更不可能是均衡的。

其他方案

在《linux多线程服务器端编程》中有一个思路,CPU计算和IO的阻抗匹配原则,根据这个原则可以推出估算公式:

最佳线程数目 = (线程等待时间与线程CPU时间之比 + 1)* CPU数目

这也是网络上流传的比较多的方法之一,包括其衍生出的案例:

假如一个程序平均每个线程CPU运行时间为0.5s,而线程等待时间(非CPU运行时间,比如IO)为1.5s,CPU核心数为8,那么最佳的线程数应该是?

根据上面这个公式估算得到最佳的线程数:((0.5+1.5)/0.5)*8=32。

这个方法看似严谨,但也存在很大问题,因为其结论可以简单等价为线程等待时间所占比例越高,需要越多线程,忽略了线程切换开销和锁,同时也忽略应用CPU密集型、IO密集型、内存型区别,以及硬件环境不同带来的差异性。

上面的这些方案看似合理,但是在实际场景下却未必合理,实际情况下都需要结合系统实际情况和硬件环境,通过合适的工具尝试达到一个符合实际场景需求的合理估算值。

使用 Kindling-OriginX 进行参数调优

最佳实践:深入理解线程池参数设置

这里以 Kindling-OriginX 为例,说明如何使用其提供的北极星指标体系进行线程参数配置的优化。

北极星指标

cpu

程序代码执行所消耗的CPU cycles

runq

线程的状态是Ready,如果CPU资源是充分,线程应该被调度到CPU上执行,但是由于各种原因,线程并未调度到CPU执行,从而产生的等待时间。

net

网络时间,主要包括DNS,TCP建连,常规网络调用

futex

通常指的是一个线程在尝试获取一个futex锁时因为锁已经被其他线程占用而进入等待状态的时间。在这段时间内,线程不会执行任何操作,它会被内核挂起。

file

存储操作时间

通过上述指标的具体时间,我们就可以知道每一次调用程序具体耗时在哪些地方,该从哪些方向进行优化,cpu资源是否被充分使用,还是时间都被消耗在了线程切换上等等。

调优案例解析

下面以使用 Kindling-OriginX 为例,说明如何对线程池进行参数设置与优化,并找出系统链路中的真实性能瓶颈。对于单一线程池可以通过 Kindling-OriginX 确定其是cpu密集型还是说IO密集型任务,对于多线程池可以通过 Kindling-OriginX 以数据为基础,对多个线程池综合调优,使应用达到最佳状态。

案例一

最佳实践:深入理解线程池参数设置

从北极星指标中可以看到,该次调用futex时间很长,可能是存在Full GC导致,也可能是程序中产生了锁等待,锁的竞争非常激烈,此时增大线程池也并不可能提高性能,可以考虑从优化任务执行代码入手。如果该服务是上游服务,则可以考虑加大下游服务的线程池尝试增强处理能力。

案例二

最佳实践:深入理解线程池参数设置

runq是一个表示cpu等待的概念,它是一个系统活动的队列,用于存储正在等待cpu资源的进程,本例中runq数值很高,说明cpu资源紧张,没有资源分配给线程使用,可以认为该线程池处理的任务为cpu密集型任务,一方面配置参考Ncpu + 1的方式,尽可能提高利用率,减少上下文切换,同时考虑减少目前配置大小,合理配置线程池队列长度,设置合理的拒绝策略,避免导致上游方法或服务产生大量锁等等。另一方面需要考虑扩充资源或查看机器监控等指标,分析是否出现了异常的资源抢占。

案例三

最佳实践:深入理解线程池参数设置

在北极星指标中,file一般指代存储相关操作。该例中,主要操作耗时是磁盘存储操作,在不考虑存储设备异常的前提下,该线程池可被认为是一个负责处理IO密集型任务的线程池,这种情况下可以考虑对该线程池采用Ncpu * 2的方式进行配置,并酌情增大。

对于单个或多个线程池的参数调优,亦可以Trace的角度出发,通过链路分析的方式,对单一节点的调用耗时进行分析来判断该服务中线程池的优化方向,单个线程池可以根据任务类型参考业内最佳实践,多个线程池可以根据北极星指标分别针对性的调整后综合分析,以求达到多个线程池的最佳资源利用状态。

小结

对于业务中的线程池问题,需要对线程池的工作原理及各参数含义有深入理解,同时也需要能合理根据实际场景选用合理的工具对其参数进行调优,不能一味生搬硬套业内经验。可以通过 Kindling-OriginX 等工具对程序执行的各项指标进行分析,以数据为导向,合理调配,才能真正提高线程的复用和效率,适用不同的业务场景,提供系统性能,结合实际情况和真实数据才是最佳实践。

最佳实践:高并发之扩容思路

· 阅读需 16 分钟
Kindling-OriginX
故障根因推理引擎

最佳实践:高并发之扩容思路

系统在业务平峰期间运行稳定、性能良好,但在大流量时就会出现各种各样的问题,例如接口时延变大,CPU占用率升高、频繁发生Full GC、代码中出现死锁等等。大流量意味着高并发,高并发也是很多开发人员所期望拥有的经验,一方面能够接触更加复杂的业务场景,提高自身能力,另一方面对于高并发的解决思路需要依靠经验积累,通过踩坑填坑的方式不断精进。而这其中扩容又是最常见的应对高并发场景的思路。

最佳实践:高并发之扩容思路

什么是扩容

扩容,通常指为了提高系统的处理能力,而采取的增加计算或其他资源的一系列措施,以此来提升系统的性能。

传统意义上的扩容一般只单单针对硬件计算资源,策略上可以分为两种,一种是对单机整体扩容,也就是整机的CPU、内存、磁盘等等;另一种就是扩容对应的组件,例如提高CPU性能,升级读写性能更优秀的磁盘等。而在云原生、微服务等技术越来越普及后,扩容的概念也不再单单指计算资源,而是扩展到架构领域,例如流量高峰期针对某一中间件资源进行扩容,或针对某一核心服务进行扩容,这使得扩容能够更高效、更有目的性。

随着技术的发展和业务的复杂度的上升,也要求扩容更有目标性,更快速,这就要求在实践中对于扩容的目标、策略、方法,以及系统的架构设计都要有深入的理解,同时也需要有合适的工具对其进行技术支撑。

扩容目标

扩容是为了确保系统在面临高并发访问、大数据处理等场景时,能够保持良好的性能和稳定性,不会因为资源不足而出现服务响应缓慢、系统崩溃等问题。

扩容是一个系统性的工程,需要综合考虑成本、性能、可靠性等因素,并采取适当的策略和技术来实现。目标具体来看主要有以下几点。

提高系统并发能力:通过增加系统资源,提高系统处理请求的能力,从而应对高并发访问。

保证系统稳定性:在扩容过程中,确保系统运行稳定,避免因资源分配不当导致的性能波动。

降低成本:在满足业务需求的前提下,合理利用现有资源,降低扩容成本。

易于实现:能够快速做出响应,同时不影响正常的业务功能设计和开发。

常见扩容思路

最佳实践:高并发之扩容思路

架构层面

从架构上来看扩容可以分为两大类:

横向扩展(scale-out)

又名水平扩展,即用更多的机器来支撑大量的请求。常见的集群模式往往就是这种思路。以运送货物为例,当大量货物需要运输时,使用更多的货车进行运输。

纵向扩展(scale-up)

又名垂直扩展,扩展一个节点或单一机器的能力,使一个点能够支撑更大的请求。例如使用高性能计算服务器,其往往有更强的单体计算能力。同样以运送货物为例,当大量货物需要运输时,将货车升级,让每个货车更大更快。

业务层面

从业务类型上来看扩容也可以分为:

读操作扩展

如果系统中读操作占大多数,那么可以通过找到关键的资源瓶颈,对其进行扩容或增加其资源进行扩展。例如MySQL是资源瓶颈,那么增加多个只读从库,业务高峰期扩展只读库副本数进行横向扩展,亦可以提高MySQL服务器的性能采用垂直扩展的思路增强其处理能力;增加一个或多个redis将热点数据进行缓存等。这都是通过读写分离的思想,针对性的以业务角度出发对读操作进行扩展。

写操作扩展

如果系统中写操作为主,往往提高单个节点的能力性价比较低,通常考虑使用HBase、MiniIO等分布式存储方案,方便后期不断进行水平扩展。

异步处理

将一些有延迟、等待任务放入消息队列中,利用中间件实现业务功能,提高系统吞吐量。或通过异步的方式对服务进行解耦,一方面便于针对性进行扩容,另一方面将时延敏感度较低的业务分离,提高核心资源利用率。

利用云服务、CDN等第三方能力

对于一些静态资源或大文件读写场景,使用CDN缓存的方式来减少自身服务器的压力,同时云服务厂商很多功能目前都已提供弹性扩容能力,按需付费即可获得自动化的扩容缩容能力。以阿里云函数计算为例,预留模式中只需要配置好弹性伸缩规则,即可自动根据流量情况进行实例的扩容缩容。

实际业务场景中,往往不是单一地使用某一种扩容方法就能解决问题,选择哪种扩容思路取决于具体的业务需求、系统架构、预算以及预期的性能目标。最佳实践应当是结合多种扩容策略,实现灵活、高效、成本合理的系统扩展。

评估扩容需求的步骤和方法

最佳实践:高并发之扩容思路

评估是否需要扩容以及需要扩容哪些资源,通常需要进行全面的系统分析和性能监控,并且要能够准确地识别系统运行状态。

1. 性能监控:

使用监控工具(如Prometheus)来收集系统的性能数据,包括CPU使用率、内存使用率、磁盘I/O、网络流量、响应时间等。

分析性能数据,找出系统的瓶颈所在。例如CPU使用率经常处于高位,则可能需要增加计算资源;如果磁盘I/O压力大,可能需要升级磁盘或使用更快的存储解决方案。

2. 容量规划:

根据业务增长趋势和用户需求预测,进行容量规划。考虑未来的数据增长、用户增长和交易量增长等,预测所需的资源量。

对比当前资源容量和预测的资源需求,确定是否需要扩容以及需要扩容的规模。

3. 压力测试:

通过模拟高负载场景来测试系统的性能极限。这可以帮助确定系统在压力下的表现,以及哪些资源会成为瓶颈。

分析负载测试结果,找出系统在哪些方面需要改进或增加资源。

4. 应用分析和优化:

分析应用代码和架构,找出性能优化点。通过优化代码或改进架构,减少对资源的依赖。

使用 Kindling-OriginX 确定扩容策略

这里以 Kindling-OriginX 为例,说明如何使用其提供的北极星指标体系找到高并发场景下的瓶颈点,为扩容方向提供明确指引。

北极星指标

cpu

程序代码执行所消耗的CPU cycles

runq

线程的状态是Ready,如果CPU资源是充分,线程应该被调度到CPU上执行,但是由于各种原因,线程并未调度到CPU执行,从而产生的等待时间。

net

网络时间,主要包括DNS,TCP建连,常规网络调用

futex

通常指的是一个线程在尝试获取一个futex锁时因为锁已经被其他线程占用而进入等待状态的时间。在这段时间内,线程不会执行任何操作,它会被内核挂起。

file

存储操作时间

通过上述指标的具体时间,我们就可以知道每一次调用程序具体耗时在哪些地方,结合SLO实时异常检测确认是否出现了影响用户体验的问题,即可快速对是否需要进行扩容,哪些节点,哪些资源需要扩容做出判断。

实战案例解析

下面以使用 Kindling-OriginX 为例,说明在实际生产环境中,如何有针对性地确定和实施扩容策略。以数据为导向,告别盲目使用扩容、升配试一试的方式应对高并发场景下的各种问题。

案例一

业务高峰期间通过SLO入口检测发现业务入口延迟变大,已经影响到用户体验。

最佳实践:高并发之扩容思路

通过查看慢调用的链路传播链,定位到造成影响的服务节点是ts-train-service

最佳实践:高并�发之扩容思路

查看节点的北极星指标可以看到runq耗时异常,参照runq指标的含义,说明当前CPU不足,这种情况下优先考虑对该服务进行扩容。

最佳实践:高并发之扩容思路

案例二

该案例中定位到产品问题的节点是ts-order-service

最佳实践:高并发之扩容思路

同样利用北极星指标分析,发现是由于file耗时异常导致, 此时盲目进行横向扩容并不能解决问题,对该存储相关操作异常的原因继续下钻分析。

最佳实践:高并发之扩容思路

下钻后 Kindling-OriginX 将会定位到具体文件,及该文件具体的读写指标数据,通过这些数据首先分析该读写操作是否是正常业务行为,如果是正常业务行为,接下来根据读写情况来看是否需要对其进行读或者写扩展。如果文件读写较为平均,那么考虑对问题节点或机器的磁盘性能进行增加,采取垂直扩展的思路先解决问题,之后从代码设计层面和系统架构层面考虑重新设计该文件操作的业务流程。

最佳实践:高并发之扩容思路

最佳实践:高并发之扩容思路

通过上面两个案例可以看到,高并发场景下很多性能问题都可以通过扩容解决,但同样不存在银弹,盲目的扩大服务容量或提高机器性能,都可能只是无效扩容。没有合适的工具发现瓶颈点,选择了错误的扩容策略和方向,只会浪费时间、金钱、人力,却不能真正解决问题。

小结

最佳实践:高并发之扩容思路

在高并发场景中选择合适的扩容策略,往往要对系统整体架构和各个业务系统非常熟悉,同时也要对常见系统性能优化方式有深入了解,这都需要大量的经验积累和技术能力,也需要能合理根据实际场景选用先进的工具获取系统中的关键运行信息,不能一味生搬硬套业内经验。可以通过 Kindling-OriginX 等工具对系统执行过程进行无盲区的观测,以数据为导向,采取对症下药的扩容方式。