系统性能优化:并行、多任务与陷阱规避
1. 并行化:双刃剑
并行化是一种隐藏延迟的方式,其目的是通过利用未使用的系统容量来减少任务的响应时间。然而,并行化并非没有代价。虽然并行操作可以缩短响应时间,但它并不会减少系统负载,实际上还会增加系统负载。这是因为并行算法需要额外的指令来在并行进程之间划分工作负载,并收集这些进程完成的工作。
例如,一个串行算法可能需要 10 秒来返回结果,消耗 10 秒的资源。而一个并行算法可能在 5 秒内返回相同的结果,但却消耗了 50 秒的资源。并行算法看似诱人,因为它速度快了一倍,但却给系统带来了五倍的负载。
如果只有一个人使用并行算法,这种负载的增加可能不易被察觉。但当所有人都开始使用并行化来缩短响应时间时,系统的流量强度会迅速增加,导致系统性能下降。
并行化在某些情况下是有用的,比如在系统空闲时运行长时间的批量作业。但在高并发的交互式系统中使用并行操作可能会很危险。例如,让 1000 个用户将他们的工作并行化为 8 个并发线程,就相当于给系统增加了 7000 个用户。
2. 让系统崩溃:Oracle 系统的实验
在 2012 年的一次课程中,大家对 Oracle Exadata 数据库机器进行了测试。这台机器经过精心设计,是性能卓越的 Oracle 硬件平台。工程师们不仅选择了最好的硬件组件,还以独特而优雅的方式将 Oracle 数据库软件集成到硬件中。
为了测试这台机器在高负载下的性能,大家决定玩一个“融化系统”的游戏,即不断增加负载,直到系统出现性能问题,最终无法正常运行。
一种方法是编写一个小程序连接到数据库实例,执行一些小事务,然后断开连接。可以通过 shell 脚本循环调用这个程序,并使用
&
运算符将工作放入后台,以增加并发程序的执行数量。
但大家选择了一种更简单的方法:创建一个巨大的表,并将该表的 Oracle 并行度声明为 256。这样,每次学生查询这个大表时,Oracle 会创建 512 个新的数据库进程,足以让系统崩溃。
使用并行执行功能很容易给系统增加负载,这是并行化的工作方式,并非系统的 bug。系统管理员有责任防止用户滥用并行化。
3. 多任务处理:计算机与人类的差异
计算机通过一种称为抢占式多任务的调度算法,让多个用户感觉“同时”得到服务。例如,在一个单核心 CPU 的计算机上,有两个用户分别请求执行需要 2 秒 CPU 时间的程序。第一个用户在时间 0 发出请求,第二个用户在时间 1 发出请求。
- 时间 0:第一个用户的程序开始执行,CPU 每秒发送 100 次调度中断给操作系统,由于没有其他程序等待,调度器将 CPU 控制权交回该程序。
- 时间 1:第二个用户的程序加入运行队列,调度器进行上下文切换,将第一个用户的程序放入运行队列等待,第二个用户的程序开始执行。
- 时间 3:第一个用户的程序完成,此时第二个用户的程序独自运行,直到时间 4 完成。
最终,两个程序的响应时间都是 3 秒,包括 1 秒的排队延迟和 2 秒的服务时间。
现代计算机通常有多个核心和多个 CPU,但抢占式多任务的基本原理是相同的。所有系统用户都需要为这种多任务处理付出一定的代价,即排队延迟。
然而,人类的多任务处理与计算机不同。计算机的上下文切换只需要几微秒,而人类的上下文切换大约需要 25 分钟。研究还发现,多任务处理会导致压力荷尔蒙和肾上腺素的释放,可能导致长期健康问题,并导致短期记忆丧失。因此,为了提高自身的性能,人们应该避免多任务处理,让计算机来完成这项工作。
4. 性能指标的陷阱
在评估系统性能时,我们常常会陷入一些陷阱。
4.1 邪恶精灵的陷阱
有时候,我们的工具可能会误导我们。例如,仅仅因为 CPU 利用率处于绿色区域,就认为用户一定满意,这是不正确的。这是一个代理问题,我们追求的(绿色区域的 CPU 利用率)与我们真正想要的(用户满意)并不相同。
就像邪恶精灵一样,它会满足你的愿望,但结果可能并非你所期望的。我们在使用测量工具时,要小心我们所追求的指标是否真的代表了我们想要的东西。可以通过想象“一个邪恶精灵能否在不满足我真正需求的情况下满足我的愿望”来进行测试。
4.2 被掩埋的异常值
在数据分析中,异常值很容易被掩埋。例如,在一个包含 100 万个
pwrite
调用的统计中,除了一个调用花费了 18.6 秒外,其他调用都只花费了 0.001 秒,那么平均调用时间约为 0.001019 秒。即使有 5 个 18.6 秒的异常值,平均时间的增加也不到十分之一毫秒。
因此,仅仅因为一个数字看起来不合理,并不意味着它没有发生。在分析数据时,我们需要注意异常值的存在。
4.3 小心许愿
有时候,我们需要与客户沟通,明确我们真正想要实现的目标。例如,一个 IT 总监希望在下午的高峰时段让 CPU 至少有 40% 的空闲时间。但实际上,降低 CPU 利用率并不是他真正想要的。
可以通过安装慢速的旧磁盘驱动器来降低 CPU 利用率,满足他的要求,但这会导致程序运行时间变长,与他真正的需求相悖。他真正想要的是高峰时段的程序能够高效运行并更快完成。
通过追踪程序的执行时间和原因,可以获得评估系统性能的有效反馈。
5. 百分位数规范:定义真正的性能需求
当我们与应用服务提供商协商任务的响应时间时,仅仅关注平均响应时间可能是不够的。例如,你每天执行一个任务数百次,你能容忍的每次执行时间为 5 秒,你与服务提供商约定平均响应时间不超过 5 秒。
但实际使用中,你可能会发现即使平均响应时间满足要求,你仍然不满意。这是因为平均响应时间可能掩盖了一些长时间的执行情况。
服务提供商可能会提供一个新的协议,让你定义可以接受的失望率。例如,你可以选择将失望率设定为 10%,即不超过 10% 的执行时间超过 5 秒。
但在实际使用中,你可能会发现即使满足了这个条件,仍然有一些过长的执行时间(如 41 秒)会影响你的体验。
最终,你可能会与服务提供商达成以下百分位数规范:
- 至少 90% 的执行时间不超过 5 秒。
- 至少 99% 的执行时间不超过 10 秒。
这种百分位数规范可以帮助你明确你真正想要的性能。
以下是一个简单的流程图,展示了并行化的影响:
graph TD;
A[任务请求] --> B{选择执行方式};
B -->|串行| C[串行执行];
B -->|并行| D[并行执行];
C --> E[完成任务];
D --> F[增加系统负载];
F --> G{系统负载过高?};
G -->|是| H[系统性能下降];
G -->|否| E[完成任务];
表格:串行与并行算法对比
| 算法类型 | 响应时间 | 资源消耗 | 系统负载 |
| ---- | ---- | ---- | ---- |
| 串行算法 | 10 秒 | 10 秒资源 | 低 |
| 并行算法 | 5 秒 | 50 秒资源 | 高 |
系统性能优化:并行、多任务与陷阱规避
6. 并行化操作的深入分析
并行化虽然能在一定程度上提升单个用户的体验,但对系统整体的影响需要我们深入分析。以下是并行化操作的详细流程:
1.
任务划分
:将一个大任务分割成多个小任务,以便并行处理。例如,在处理一个大型数据集合时,可以将数据分成若干子集,每个子集由一个并行进程处理。
2.
资源分配
:为每个并行进程分配所需的资源,如 CPU 时间、内存等。这需要根据任务的特点和系统的资源状况进行合理分配。
3.
并行执行
:各个并行进程同时执行各自的任务。在这个过程中,需要注意进程之间的同步和通信,避免出现数据冲突等问题。
4.
结果合并
:当所有并行进程完成任务后,将它们的结果合并成最终结果。
并行化操作的流程可以用以下 mermaid 流程图表示:
graph LR;
A[大任务] --> B[任务划分];
B --> C[资源分配];
C --> D[并行执行];
D --> E[结果合并];
E --> F[最终结果];
7. 多任务处理的调度算法
计算机的抢占式多任务调度算法是实现多用户“同时”服务的关键。以下是该算法的详细步骤:
1.
任务到达
:用户提交任务请求,任务进入运行队列等待执行。
2.
调度中断
:CPU 按照一定的频率(通常为每秒 100 次)发送调度中断给操作系统。
3.
调度器执行
:操作系统的调度器接收到中断后,检查运行队列中的任务。
4.
上下文切换
:如果有更合适的任务需要执行,调度器进行上下文切换,将当前正在执行的任务暂停,将新任务加载到 CPU 上执行。
5.
任务执行
:新任务在 CPU 上执行,直到下一次调度中断。
多任务处理调度算法的流程可以用以下表格表示:
| 步骤 | 操作 |
| ---- | ---- |
| 1 | 任务到达,进入运行队列 |
| 2 | CPU 发送调度中断 |
| 3 | 调度器检查运行队列 |
| 4 | 进行上下文切换(如果需要) |
| 5 | 新任务执行 |
8. 性能指标陷阱的应对策略
为了避免陷入性能指标的陷阱,我们可以采取以下策略:
1.
明确目标
:在评估系统性能之前,明确我们真正想要实现的目标,而不是仅仅关注一些表面的指标。例如,用户满意度、程序执行效率等。
2.
综合分析
:使用多种指标进行综合分析,而不是依赖单一指标。例如,除了 CPU 利用率,还可以关注内存使用率、响应时间、吞吐量等。
3.
异常值处理
:在数据分析过程中,注意异常值的存在,并对其进行深入分析。可以使用统计方法来识别和处理异常值。
4.
百分位数规范
:采用百分位数规范来明确我们对性能的要求,而不是仅仅关注平均值。例如,规定至少 90% 的任务响应时间不超过 5 秒,至少 99% 的任务响应时间不超过 10 秒。
以下是一个简单的列表,总结了应对性能指标陷阱的策略:
- 明确真正的目标
- 综合使用多种指标
- 处理异常值
- 采用百分位数规范
9. 系统性能优化的最佳实践
为了优化系统性能,我们可以遵循以下最佳实践:
1.
合理使用并行化
:在系统空闲时使用并行化处理长时间的批量任务,避免在高并发的交互式系统中过度使用并行操作。
2.
优化多任务调度
:根据系统的负载情况和任务的特点,优化抢占式多任务调度算法,减少排队延迟。
3.
避免多任务处理
:对于人类用户,尽量避免多任务处理,专注于一项任务,提高工作效率。
4.
关注关键指标
:关注与系统性能密切相关的关键指标,如 CPU 利用率、内存使用率、响应时间等,并及时进行调整。
以下是一个流程图,展示了系统性能优化的最佳实践流程:
graph TD;
A[系统性能评估] --> B{是否需要优化?};
B -->|是| C[选择优化策略];
C --> D[实施优化措施];
D --> E[再次评估性能];
E --> B{是否需要优化?};
B -->|否| F[维持现状];
10. 总结
系统性能优化是一个复杂的过程,涉及到并行化、多任务处理、性能指标评估等多个方面。并行化虽然能提升单个用户的体验,但可能会增加系统负载;多任务处理让多个用户感觉“同时”得到服务,但人类多任务处理会带来诸多问题。在评估系统性能时,我们要警惕各种性能指标的陷阱,采用合理的策略和最佳实践来优化系统性能。通过明确目标、综合分析、处理异常值和采用百分位数规范等方法,我们可以更好地满足用户的需求,提高系统的整体性能。
总之,在系统性能优化的道路上,我们需要谨慎选择和使用各种技术和方法,避免陷入各种陷阱,以实现系统性能的最大化和用户体验的最优化。
超级会员免费看
237

被折叠的 条评论
为什么被折叠?



