性能优化及容量规划

什么情况下需要性能优化?

  1. 新应用上线前在性能上无法满足需求,这个时候需要对系统进行性能调优;
  2. 随着系统数据量的不断增长、访问量的不断上升,系统的响应速度通常越来越慢,不满足业务需要,这个时候也需要对系统进行性能调优

什么是 Benchmark?

Benchmark 基准测试,对某个特定目标场景的某些性能指标进行定量的和可对比的测试。

常用于对一些组件如 Nginx,Redis,MySQL 等进行基准测试,得到结果;在之后进行某些优化或者变更时,以同样条件进行测试,再与之前的基准测试结果进行对比,得到优化的效果。

不同的组件通常会有自己的基准测试工具,常用的比如:ab,JMH

压测和基准测试区别是什么?

  1. 目的不同

    压测的目的:通过模拟高负载场景,测试系统是否能够在高负载下保持稳定。

    基准测试的目的:基准测试旨在建立系统的性能基准,评估系统在正常工作负载下的性能水平。它用于确定系统的参考性能指标,作为后续性能优化和比较的依据。

  2. 方法不同

    压力测试通过增加负载、并发用户或数据量等方式,使系统处于极限或超过正常工作负载的状态,以观察系统的行为和性能表现。它主要关注系统的稳定性、承载能力和资源消耗情况,并尝试找出系统在高负载下的瓶颈和故障点。

    基准测试通过使用一组标准化的测试用例和工作负载来评估系统的性能。它旨在测量系统在各种指标下的性能表现,如响应时间、吞吐量、资源利用率等。基准测试通常会多次运行测试,并计算平均性能结果。

二者相互补充,共同用于评估和优化软件系统的性能。

性能优化相关指标是哪些?

指标是我们衡量很多事物,以及做出行为决策的重要参考。例如在生活中,当你打算买汽车时,会关注很多指标,比如动力性、燃油经济性、制动性、操纵稳定性、平顺性、通过性、排放与噪声等,而这些指标也都有相关的测试和参数,同时也会对这些指标进行一一参考。

这些指标大家都懂,但是在性能优化上,很多人只能知道优化后的 QPS 增加多少,RT 减到多少,但问到具体的衡量指标有哪些?却因为缺少理论依据,很难表达出一二三来。

在衡量一项优化是否能达到目的之时,不能仅靠感觉,它同样有一系列的指标来衡量你的改进。

所谓性能,就是使用有限的资源有限的时间内完成工作。最主要的衡量因素就是时间,所以很多衡量指标,都可以把时间作为横轴。

相关的指标包括 RT、吞吐量(QPS、TPS)、并发数、内存使用率、错误率等等。

后端系统响应时间受哪些因素影响?

受到数据库查询、RPC调用、网络IO、逻辑计算复杂度、JVM垃圾回收等多方面因素影响。

参考 美团境外业务性能优化实践

性能优化整体应该怎么做?

  1. 了解、衡量系统现状

    高效地进行性能优化,需要采集当前的性能数据以建立性能基线。

    需要采集的性能数据通常包含以下内容:

    • 用户响应时间的平均值和长尾值(如P99)、应用系统的吞吐(QPS、 TPS)
    • 数据库时间、Query 延迟和 QPS 等数据库性能数据。
    • 资源使用率,包含 CPU、IO 和网络等资源
    • 配置信息,比如应用系统、缓存系统、数据库和操作系统的配置
  2. 确定优化目标(指标:吞吐量、响应时间等且需要量化)

    不同类型系统优化目标不同。例如,对于一个金融核心的 OLTP 系统,优化目标可能是降低交易的长尾延迟;对于一个财务结算系统,优化目标可能是更充分利用硬件资源,缩短批量结算任务时间。

    一个好的优化目标应该是容易量化的,比如:

    • 好的优化目标:”业务高峰期上午 9 点到 10 点,转账交易的 p99 延迟需要小于 200 毫秒“
    • 差的优化目标:”系统太慢了没有响应,需要优化“

    定义一个清晰的优化目标有助于指导后续的性能优化工作。

  3. 定位性能瓶颈(使用工具)

    • 通过全链路监控确定响应时间瓶颈具体的节点
    • 单节点利用日志、Arthas、JProfiler、VisualVM等等工具定位性能瓶颈
    • 针对不同的组件(例如分布式缓存、数据库等)有不同的方式进行定位
  4. 提出优化方案,评估每种方案的收益、风险和成本

    通过性能分析确定系统瓶颈点之后,根据实际情况提出低成本、低风险、并能获得最大的收益的优化方案。

    根据阿姆达尔定律,性能优化的最大收益,取决于优化的部分在整个系统的占比。因此,你需要根据性能数据,确认系统瓶颈和相应的占比,预估瓶颈解决或者优化之后的收益。

    需要注意的是,即使某个方案针对最大瓶颈点的优化潜在收益最大,也需要同时评估该方案的风险和成本。例如:

    • 对于资源过载的系统,最直接的优化方案是扩容,但是实际中可能因为扩容方案成本太高而无法被采纳。
    • 当某个业务模块里的一个慢 SQL 导致整个模块的响应时间很慢时,升级到数据库新版本的方案可以解决这个慢 SQL 问题,但是同时可能影响原来没有问题的模块,因此该方案可能存在潜在的高风险。一个低风险的方案是不升级数据库版本,直接改写现有慢 SQL,在当前数据库版本中解决该问题。
  5. 实施优化

    综合考量收益、风险和成本,选定一种或者多种优化方案进行实施,并对生产系统的变更进行周全的准备和详细的记录。

  6. 评估优化结果

    实施优化之后,需要评估优化结果。

    • 如果达到优化目标,整个优化项目顺利完成。
    • 如果未达到优化目标,你需要重复步骤 2 到 6,直到达到优化目标。

    达到优化目标之后,为了应对业务的增长,你可能还需要进一步做好系统的容量规划。

如何根据用户量/日活预估访问量?

假设我们没有历史数据可以参考,我们可以采用二八定律来进行估算。

  • 假设有 1000W 用户,每天访问网站的用户占比为 20%,那么每天大约有 200W 用户访问。
  • 假设每个用户平均点击 50 次,那么总的页面浏览量 PV=1 亿。
  • 一天有 24 小时,根据二八定律,每天大部分用户活跃的时间点集中在(24 * 0.2) 约等于 5 个小时以内,而大部分用户指的是(1 亿点击 * 80%)约等于 8000W(PV), 意味着在 5 个小时以内,大概会有 8000W 点击进来,也就是每秒大约有 4500 (8000W/5 小时) 个请求。
  • 4500 只是一个平均数值。在这 5 小时内,请求量并不一定均匀,可能会出现大量用户集中访问的情况(比如像淘宝这样的网站,日访问量高峰时间段集中在下午 14:00 和晚上 21:00,其中 21:00 是一天中访问量的最高峰)。通常情况下,访问量高峰时段的请求量是平均请求量的 3 到 4 倍(这是一个经验值),我们按照 4 倍来计算。那么在这 5 小时内,可能会出现每秒 18000 个请求的情况。因此,问题由原本的支撑 1000W 用户,变成了一个具体的问题,就是服务器端需要能够支撑每秒 18000 个请求(QPS=18000)

如何进行服务器能力预估?

服务器容量预估前,我们需要知道单个机器能够支持多少并发。那么一般会采用压力测试的方式得到单机性能指标。以我们的 Tomcat 服务为例,会影响服务并发能力的因素包括:

  1. 系统资源

    在 Linux 操作系统中,每一个 TCP 连接都会占用一个文件描述符(fd),当文件描述符超过 Linux 系统当前的限制时,会出现“Socket/File:Can’t open so many files”等类似异常。可以通过下述命令查看一个进程能够打开的 fd 上限以及系统的总限制:

    // 单进程
    ulimit -a  或 ulimit -n // 查看设置
    ulimit -n XXX // 修改设置
    
    // 系统总限制
    cat /proc/sys/fs/file-max
    
  2. JVM 配置(内存/GC)

  3. Tomcat 配置(线程池)
  4. 业务线程池、组件连接数
  5. 外部服务性能
  6. 更多细节需要经过压测发现

如何进行服务器数量预估?

简单来说:

假设一个 Tomcat 节点的 QPS 为 500,如果要支持高峰时期的 QPS 为 18000,那么需要 40 台服务器。

但这还不够

  • QPS = 并发量 / 平均响应时间
  • 并发量= QPS * 平均响应时间

假设我们的 RT 为 3s,那么服务器端的并发数=18000 * 3=54000,即同时有 54000 个连接打到服务器端。因此,服务端需要同时支持的连接数为 54000。

RT 越大,意味着积压的连接越多,这些连接会占用内存资源/CPU 资源等,容易造成系统崩溃。

同时,当连接数超过阈值时,后续的请求无法进入,用户会得到一个请求超时的结果,这不是我们希望看到的。因此,我们必须缩短 RT 的值,所以只有在进行单机性能优化后,服务器容量规划(水平扩容)才有意义。

参考

TiDB 性能优化

如何进行服务容量预估

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

Scroll to Top