Red Hat Training

A Red Hat training course is available for RHEL 8

监控并管理系统状态和性能

Red Hat Enterprise Linux 8

优化系统吞吐量、延迟和功耗

Red Hat Customer Content Services

摘要

本文档集合提供了在不同场景中如何监控和优化 Red Hat Enterprise Linux 8 的吞吐量、延迟和功耗的说明。

使开源包含更多

红帽承诺替换我们的代码、文档和网页属性中存在问题的语言。我们从这四个术语开始: master、slave、blacklist 和 whitelist。这些更改将在即将发行的几个发行本中逐渐实施。如需了解更多详细信息,请参阅 CTO Chris Wright 信息

对红帽文档提供反馈

我们感谢您对文档提供反馈信息。请让我们了解如何改进文档。要做到这一点:

  • 关于特定内容的简单评论:

    1. 请确定您使用 Multi-page HTML 格式查看文档。另外,确定 Feedback 按钮出现在文档页的右上方。
    2. 用鼠标指针高亮显示您想评论的文本部分。
    3. 点在高亮文本上弹出的 Add Feedback
    4. 按照显示的步骤操作。
  • 要提交更复杂的反馈,请创建一个 Bugzilla ticket:

    1. 进入 Bugzilla 网站。
    2. 在 Component 中选择 Documentation
    3. Description 中输入您要提供的信息。包括文档相关部分的链接。
    4. Submit Bug

第 1 章 性能监控选项概述

以下是 Red Hat Enterprise Linux 8 中提供的一些性能监控和配置工具:

  • Performance Co-Pilot(pcp)用于监控、可视化、存储和分析系统级性能测量。它允许监控和管理实时数据,以及记录和检索历史数据。
  • Red Hat Enterprise Linux 8 提供了几个工具,您可以从命令行用来监控运行级别之外的系统 5。以下是内置命令行工具:

    • topprocps-ng 软件包提供。它为正在运行的系统中的进程提供动态视图。它显示各种信息,包括系统摘要和当前由 Linux 内核管理的任务列表。
    • psprocps-ng 软件包提供。它捕获所选活动进程的快照。默认情况下,检查的组仅限于由当前用户拥有且与执行 ps 命令的终端相关联的进程。
    • 虚拟内存统计信息(vmstat)由 procps-ng 软件包提供。它提供系统进程、内存、分页、块输入/输出、中断和 CPU 活动的即时报告。
    • 系统活动报告器(sar)由 sysstat 软件包提供。它收集和报告目前为止发生的系统活动信息。
  • perf 使用硬件性能计数器和内核追踪点来跟踪其他命令和应用程序对系统的影响。
  • bcc-tools 用于 BPF 编译器集合(BCC)。它提供了 100 多个 eBPF 脚本来监控内核活动。有关每个工具的更多信息,请参阅说明如何使用该工具及其执行的功能的 man page。
  • turbostatkernel-tools 软件包提供。它报告 Intel 64 处理器上的处理器拓扑、频率、空闲电源状态统计信息、温度和电源使用情况。
  • iostatsysstat 软件包提供。它监控和报告系统 IO 设备加载,以帮助管理员决定如何在物理磁盘之间平衡 IO 负载。
  • irqbalance 跨处理器分布硬件中断,以提高系统性能。
  • ss 打印有关套接字的统计信息,让管理员能够随着时间的推移评估设备性能。红帽建议在 Red Hat Enterprise Linux 8 中使用 ss over netstat
  • numastatnumactl 软件包提供。默认情况下,numastat 显示每个节点 NUMA 显示内核内存分配器中未命中的系统统计信息。最佳性能由高 numa_hit 值和低 numa_miss 值表示。
  • numad 是自动 NUMA 关联性管理守护进程。它监控系统中 NUMA 拓扑和资源使用情况,以动态提高 NUMA 资源分配、管理和系统性能。
  • SystemTap 监控和分析操作系统活动,特别是内核活动。
  • valgrind 通过在复合 CPU 上运行应用并检测执行时的现有应用代码来分析应用。然后它会打印清楚应用程序执行涉及的每个进程到用户指定的文件、文件描述符或网络套接字的信息。它也可用于查找内存泄漏。
  • pqosintel-cmt-cat 软件包提供。它监控和控制最近 Intel 处理器上的 CPU 缓存和内存带宽。

其它资源

第 2 章 Tuned 入门

作为系统管理员,您可以使用 Tuned 应用程序针对各种用例优化系统性能配置集。

2.1. Tuned 的目的

tuned 是一种监控系统并优化特定工作负载下性能的服务。Tuned 的核心是配置集,它们根据不同的用例对系统进行调优。

tuned 附带许多预定义配置集用于用例,例如:

  • 高吞吐量
  • 低延迟
  • 节能功能

可以修改为每个配置集定义的规则,并自定义如何调优特定的设备。当您切换到另一个配置集或取消激活 Tuned 时,上一个配置集对系统设置所做的所有更改都会恢复到其原始状态。

您还可以配置 Tuned 以响应设备使用的变化,并调整设置以提高活跃设备的性能并减少不活跃设备的功耗。

2.2. tuned 配置集

对系统的详细分析可能非常耗时。tuned 提供许多预定义配置集,适用于典型的用例。您还可以创建、修改和删除配置文件。

Tuned 提供的配置集分为以下类别:

  • 节能配置集
  • 性能提升配置集

性能提升配置集包括侧重于以下方面的配置集:

  • 存储和网络的低延迟
  • 存储和网络的高吞吐量
  • 虚拟机性能
  • 虚拟化主机性能

配置集配置语法

tuned.conf 文件可以包含一个 [main] 部分,以及用于配置插件实例的其它部分。但是,所有部分都是可选的。

以 hash 符号(#)开头的行是注释。

其它资源

  • tuned.conf(5) man 手册.

2.3. 默认 Tuned 配置集

在安装过程中,系统的最佳配置集会被自动选择。目前,默认配置集会根据以下可自定义规则选择:

环境默认配置集目标

计算节点

throughput-performance

最佳吞吐量性能

虚拟机

virtual-guest

最佳性能.如果您对最佳性能不感兴趣,您可以将其改为 balancedpowersave 配置集。

其他情况

balanced

平衡性能和功耗

其它资源

  • tuned.conf(5) man 手册.

2.4. 合并 Tuned 配置集

作为实验性功能,可以同时选择更多配置集。tuned 将尝试在负载期间合并它们。

如果存在冲突,则最后一个指定的配置集中的设置具有优先权。

例 2.1. 虚拟客户机中的低功耗

以下示例优化了系统在虚拟机中运行以获得最佳性能,并同时针对低功耗进行调整,而低功耗则是优先级:

# tuned-adm profile virtual-guest powersave
警告

合并可以自动完成,无需检查生成的参数组合是否有意义。因此,这个功能可能会以相反的方式调整一些参数,这可能是计数器:例如,使用 throughput-performance 配置集设置磁盘以实现高吞吐量,并同时将磁盘降序设置为 spindown-disk 配置集的低值。

其它资源

  • tuned.conf(5) man 手册.

2.5. Tuned 配置集的位置

在以下目录中调优存储配置集

/usr/lib/tuned/
发行版相关的配置文件存储在 目录中。每个配置集都有自己的目录。该配置集由名为 tuned.conf 的主配置文件以及其他可选文件组成,如 helper 脚本。
/etc/tuned/
如果需要自定义配置集,请将配置集目录复制到用于自定义配置集的 目录中。如果同一名称有两个配置集,则使用 /etc/tuned/ 中的自定义配置集。

其它资源

  • tuned.conf(5) man 手册.

2.6. RHEL 提供的调优配置集

以下是在 Red Hat Enterprise Linux 上安装 Tuned 的配置集列表

注意

可能提供更多特定于产品或第三方调优配置集。此类配置文件通常由单独的 RPM 软件包提供。

balanced

默认节能配置文件.它旨在成为性能和能耗之间的妥协。它尽可能使用自动扩展和自动调整。唯一缺点是增加了延迟。在当前的 Tuned 版本中,它启用了 CPU、磁盘、音频和视频插件并激活 conservative CPU 调控器。如果支持,radeon_powersave 选项使用 dpm-balanced 值,否则将其设置为 auto

它将 energy_performance_preference 属性更改为 normal 能源设置。它还将 scaling_governor 策略属性改为 conservativepowersave CPU 调控器。

powersave

用于最大节能性能的配置文件。它可以限制性能,从而最大程度减少实际的功耗。在当前的 Tuned 版本中,它为 SATA 主机适配器实现 USB autosuspend、WiFi 节能和 Aggressive Link Power Management(ALPM)节能。它还为低唤醒率的系统调度多核功率节省,并激活 ondemand 调控器。它可节省 AC97 音频功率,或者根据您的系统节省 HDA-Intel 功耗,而超时为 10 秒。如果您的系统包含启用了 KMS 的 Radeon 图形卡,配置集将其配置为自动节能。在 ASUS Eee PC 上启用动态 Super Hybrid Engine。

它将 energy_performance_preference 属性更改为 powersavepower 能源设置。它还将 scaling_governor 策略属性改为 ondemandpowersave CPU 调控器。

注意

在某些情况下,与 powersave 配置集相比,balanced 配置集更高效。

请考虑需要执行一系列明确的工作,例如需要转码的视频文件。如果在全功率上执行转码,因为任务很快完成,计算机开始空闲,并且可以自动步入到非常高效的节能模式,您的机器可能会消耗较少的能源消耗。另一方面,如果您用限流机器对文件进行转换,则计算机在转码期间消耗的功率较少,但这个过程需要更长的时间,总体消耗的能源可能会更高。

因此,balanced 配置集通常是一个更好的选择。

throughput-performance

针对高吞吐量优化的服务器配置文件。它禁用节能机制并启用 sysctl 设置,以提高磁盘和网络 IO 的吞吐量性能。CPU 调控器被设置为 performance

它将 energy_performance_preferencescaling_governor 属性更改为 performance 配置集。

accelerator-performance
accelerator-performance 配置集包含与 throughput-performance 配置集相同的调优。另外,它会将 CPU 锁定为低 C 状态,从而使延迟少于 100us。这提高了某些加速器(如 GPU)的性能。
latency-performance

针对低延迟而优化的服务器配置文件。它禁用节能机制并启用可提高延迟的 sysctl 设置。CPU 调控器被设置为 performance,CPU 锁定为低 C 状态(通过 PM QoS)。

它将 energy_performance_preferencescaling_governor 属性更改为 performance 配置集。

network-latency

低延迟网络调优配置文件。它基于 latency-performance 配置集。它还禁用透明巨页和 NUMA 平衡,并调整其他几个网络相关的 sysctl 参数。

它继承了将 energy_performance_preferencescaling_governor 属性更改为 performance 配置集的 latency-performance 配置集。

hpc-compute
针对高性能计算优化的配置集。它基于 latency-performance 配置集。
network-throughput

用于吞吐量网络调优的配置文件。它基于 throughput-performance 配置集。它还会增加内核网络缓冲区。

它继承 latency-performancethroughput-performance 配置集,并将 energy_performance_preferencescaling_governor 属性更改为 performance 配置集。

virtual-guest

基于 throughput-performance 配置集为 Red Hat Enterprise Linux 8 虚拟机和 VMWare 客户机设计配置集,它可减少虚拟内存交换性并增加磁盘预读值。它不禁用磁盘障碍。

它继承 throughput-performance 配置集,并将 energy_performance_preferencescaling_governor 属性更改为 performance 配置集。

virtual-host

基于 throughput-performance 配置集为虚拟主机设计的配置集,除了其它任务外,还可减少虚拟内存交换性,增加磁盘预读值,并启用更积极的脏页面回写值。

它继承 throughput-performance 配置集,并将 energy_performance_preferencescaling_governor 属性更改为 performance 配置集。

oracle
基于 throughput-performance 配置文件优化的 Oracle 数据库负载配置集。它还禁用透明大内存页并修改其他与性能相关的内核参数。这个配置集由 tuned-profiles-oracle 软件包提供。
desktop
基于 balanced 配置文件为桌面优化的配置文件。它还支持调度程序自动组,以更好地响应交互式应用程序。
cpu-partitioning

cpu-partitioning 配置集将系统 CPU 划分为隔离和内务的 CPU。为减少隔离 CPU 上的 jitter 和中断,配置集清除了与用户空间进程、可移动内核线程、中断处理程序和内核计时器隔离的 CPU。

内务 CPU 可以运行所有服务、shell 进程和内核线程。

您可以在 /etc/tuned/cpu-partitioning-variables.conf 文件中配置 cpu-partitioning 配置集。配置选项为:

isolated_cores=cpu-list
列出要隔离的 CPU。隔离 CPU 的列表用逗号分开,用户可以指定范围。您可以使用破折号指定一个范围,如 3-5。此选项是必需的。此列表中缺少的任何 CPU 都会自动被视为内务 CPU。
no_balance_cores=cpu-list
列出内核在系统范围范围的进程负载均衡期间没有考虑的 CPU。此选项是可选的。这通常与 isolated_cores 列表相同。

有关 cpu-partitioning 的详情请参考 tuned-profiles-cpu-partitioning(7) man page。

optimize-serial-console

通过减少 printk 值将 I/O 活动向下调整到串行控制台的配置集。这可提高串行控制台的响应速度。这个配置集旨在用作其他配置集上的覆盖。例如:

# tuned-adm profile throughput-performance optimize-serial-console
mssql
为 Microsoft SQL Server 提供的配置集。它基于 thoguhput-performance 配置集。
intel-sst

针对具有用户定义的 Intel Speed Select Technology 配置的系统优化配置集。这个配置集旨在用作其他配置集上的覆盖。例如:

# tuned-adm profile cpu-partitioning intel-sst

2.7. RHEL 提供的实时 Tuned 配置集

实时配置集适用于运行实时内核的系统。如果没有特殊的内核构建,它们不会将系统配置为实时系统。在 RHEL 上,配置集可从其他软件仓库获得。

可用的实时配置集如下:

realtime

在裸机实时系统上使用。

tuned-profiles-realtime 软件包提供,该软件包可从 RT 或 NFV 存储库获取。

realtime-virtual-host

在配置为实时的虚拟化主机中使用.

tuned-profiles-nfv-host 软件包提供,该软件包可从 NFV 存储库中获取。

realtime-virtual-guest

在配置为实时的虚拟化 guest 中使用.

tuned-profiles-nfv-guest 软件包提供,该软件包可从 NFV 存储库中获取。

2.8. Tuned 中的静态和动态调优

本节解释 Tuned 应用的两个系统调优类别之间的区别:静态 和动态

静态调优
主要由预定义的 sysctlsysfs 设置以及几个配置工具(如 ethtool )的一次性激活组成。
动态调优

观察如何在整个系统正常运行期间使用各种系统组件。tuned 可基于该监控信息动态调整系统设置。

例如,硬盘驱动器在启动和登录期间大量使用,但在用户可能主要使用 Web 浏览器或电子邮件客户端等应用时很少使用。同样,CPU 和网络设备在不同的时间使用不同。tuned 监控这些组件的活动,并响应其使用中的变化。

默认情况下禁用动态调优。要启用它,请编辑 /etc/tuned/tuned-main.conf 文件并将 dynamic_tuning 选项改为 1tuned 随后定期分析系统统计信息,并使用它们更新您的系统调优设置。要配置这些更新之间的时间间隔,使用 update_interval 选项。

目前实施动态调优算法,试图平衡性能和 powersave,因此在性能配置集中被禁用。可以在 Tuned 配置集中启用或禁用单个插件的动态调优。

例 2.2. workstation 上的静态和动态调优

在典型的办公室工作站上,以太网网络接口大部分时间处于非活动状态。只有几封电子邮件可以进入和传出,或者可能加载一些网页。

对于这些类型的负载,网络接口不必像默认那样全速运行。tuned 具有对网络设备的监控和调优插件,可检测此低活动,然后自动降低该接口的速度,通常导致功耗降低。

如果接口上的活动在较长时间内增加,例如,下载 DVD 镜像或打开包含大附件的电子邮件,Tuned 会检测到这一点,并将接口速度设置为在活动水平较高时提供最佳性能。

此原则也用于 CPU 和磁盘的其他插件。

2.9. tuned no-daemon 模式

您可以使用 no-daemon 模式运行 Tuned,不需要任何驻留的内存。在这个模式中,Tuned 应用设置并退出。

默认情况下禁用 no-daemon 模式,因为此模式中缺少很多 Tuned 功能,包括:

  • D-Bus 支持
  • 热插拔支持
  • 对设置的回滚支持

要启用 no-daemon 模式,请在 /etc/tuned/tuned-main.conf 文件中包括以下行:

daemon = 0

2.10. 安装并启用 Tuned

此流程安装并启用 Tuned 应用程序,为您的系统安装 Tuned 配置集并预设置默认 Tuned 配置集。

流程

  1. 安装 tuned 软件包:

    # yum install tuned
  2. 启用并启动 tuned 服务:

    # systemctl enable --now tuned
  3. 另外,还可为实时系统安装 Tuned 配置集:

    # yum install tuned-profiles-realtime tuned-profiles-nfv
  4. 验证 Tuned 配置集是否活跃并应用:

    $ tuned-adm active
    
    Current active profile: balanced
    $ tuned-adm verify
    
    Verfication succeeded, current system settings match the preset profile.
    See tuned log file ('/var/log/tuned/tuned.log') for details.

2.11. 列出可用的 Tuned 配置集

此流程列出了系统中当前可用的所有 Tuned 配置集。

流程

  • 要列出系统中所有可用的 Tuned 配置集,请使用:

    $ tuned-adm list
    
    Available profiles:
    - balanced               - General non-specialized tuned profile
    - desktop                - Optimize for the desktop use-case
    - latency-performance    - Optimize for deterministic performance at the cost of increased power consumption
    - network-latency        - Optimize for deterministic performance at the cost of increased power consumption, focused on low latency network performance
    - network-throughput     - Optimize for streaming network throughput, generally only necessary on older CPUs or 40G+ networks
    - powersave              - Optimize for low power consumption
    - throughput-performance - Broadly applicable tuning that provides excellent performance across a variety of common server workloads
    - virtual-guest          - Optimize for running inside a virtual guest
    - virtual-host           - Optimize for running KVM guests
    Current active profile: balanced
  • 要只显示当前活跃的配置集,请使用:

    $ tuned-adm active
    
    Current active profile: balanced

其它资源

  • tuned-adm(8) man 手册.

2.12. 设置 Tuned 配置集

此流程激活系统中所选 Tuned 配置集。

先决条件

流程

  1. 另外,您还可以让 Tuned 建议最适合您的系统的配置集:

    # tuned-adm recommend
    
    balanced
  2. 激活配置集:

    # tuned-adm profile selected-profile

    另外,您可以激活多个配置集的组合:

    # tuned-adm profile profile1 profile2

    例 2.3. 针对低功耗优化的虚拟机

    以下示例优化了系统,使其在具有最佳性能的虚拟机中运行,并同时进行微调以实现低功耗,而低功耗则是优先级:

    # tuned-adm profile virtual-guest powersave
  3. 查看系统中当前活跃的 Tuned 配置集:

    # tuned-adm active
    
    Current active profile: selected-profile
  4. 重启系统:

    # reboot

验证步骤

  • 验证 Tuned 配置集是否活跃并应用:

    $ tuned-adm verify
    
    Verfication succeeded, current system settings match the preset profile.
    See tuned log file ('/var/log/tuned/tuned.log') for details.

其它资源

  • tuned-adm(8) man page

2.13. 禁用 Tuned

此流程禁用 Tuned,并在 Tuned 修改前将所有受影响的系统设置重置为原始状态。

流程

  • 临时禁用所有调整:

    # tuned-adm off

    调整会在 tuned 服务重启后再次应用。

  • 另外,要永久停止和禁用 tuned 服务:

    # systemctl disable --now tuned

其它资源

  • tuned-adm(8) man page

第 3 章 自定义 Tuned 配置集

您可以创建或修改 Tuned 配置集,以针对您的预期用例优化系统性能。

先决条件

3.1. tuned 配置集

对系统的详细分析可能非常耗时。tuned 提供许多预定义配置集,适用于典型的用例。您还可以创建、修改和删除配置文件。

Tuned 提供的配置集分为以下类别:

  • 节能配置集
  • 性能提升配置集

性能提升配置集包括侧重于以下方面的配置集:

  • 存储和网络的低延迟
  • 存储和网络的高吞吐量
  • 虚拟机性能
  • 虚拟化主机性能

配置集配置语法

tuned.conf 文件可以包含一个 [main] 部分,以及用于配置插件实例的其它部分。但是,所有部分都是可选的。

以 hash 符号(#)开头的行是注释。

其它资源

  • tuned.conf(5) man 手册.

3.2. 默认 Tuned 配置集

在安装过程中,系统的最佳配置集会被自动选择。目前,默认配置集会根据以下可自定义规则选择:

环境默认配置集目标

计算节点

throughput-performance

最佳吞吐量性能

虚拟机

virtual-guest

最佳性能.如果您对最佳性能不感兴趣,您可以将其改为 balancedpowersave 配置集。

其他情况

balanced

平衡性能和功耗

其它资源

  • tuned.conf(5) man 手册.

3.3. 合并 Tuned 配置集

作为实验性功能,可以同时选择更多配置集。tuned 将尝试在负载期间合并它们。

如果存在冲突,则最后一个指定的配置集中的设置具有优先权。

例 3.1. 虚拟客户机中的低功耗

以下示例优化了系统在虚拟机中运行以获得最佳性能,并同时针对低功耗进行调整,而低功耗则是优先级:

# tuned-adm profile virtual-guest powersave
警告

合并可以自动完成,无需检查生成的参数组合是否有意义。因此,这个功能可能会以相反的方式调整一些参数,这可能是计数器:例如,使用 throughput-performance 配置集设置磁盘以实现高吞吐量,并同时将磁盘降序设置为 spindown-disk 配置集的低值。

其它资源

  • tuned.conf(5) man 手册.

3.4. Tuned 配置集的位置

在以下目录中调优存储配置集

/usr/lib/tuned/
发行版相关的配置文件存储在 目录中。每个配置集都有自己的目录。该配置集由名为 tuned.conf 的主配置文件以及其他可选文件组成,如 helper 脚本。
/etc/tuned/
如果需要自定义配置集,请将配置集目录复制到用于自定义配置集的 目录中。如果同一名称有两个配置集,则使用 /etc/tuned/ 中的自定义配置集。

其它资源

  • tuned.conf(5) man 手册.

3.5. Tuned 配置集之间的继承

调优配置集可以基于其他配置集,并且只能修改其父配置文件的某些方面。

Tuned 配置集的 [main] 部分识别 include 选项:

[main]
include=parent

配置文件中的所有设置都会在此 子配置文件中加载在以下部分中,子配置集可以覆盖从 配置集继承的某些设置 ,或者添加新的设置。

您可以根据 /usr/lib/tuned/ 中预安装的配置集在 /etc/tuned/ 目录中创建自己的子配置集,只调整一些参数。

如果在 Tuned 升级后更新了父配置集,如 Tuned 升级后,这些更改会反映在子配置集中

例 3.2. 基于均衡的省电配置文件

以下是扩展 balanced 配置集的自定义配置集示例,它为所有设备设置 Aggressive Link Power Management(ALPM)。

[main]
include=balanced

[scsi_host]
alpm=min_power

其它资源

  • tuned.conf(5) man page

3.6. Tuned 中的静态和动态调优

本节解释 Tuned 应用的两个系统调优类别之间的区别:静态 和动态

静态调优
主要由预定义的 sysctlsysfs 设置以及几个配置工具(如 ethtool )的一次性激活组成。
动态调优

观察如何在整个系统正常运行期间使用各种系统组件。tuned 可基于该监控信息动态调整系统设置。

例如,硬盘驱动器在启动和登录期间大量使用,但在用户可能主要使用 Web 浏览器或电子邮件客户端等应用时很少使用。同样,CPU 和网络设备在不同的时间使用不同。tuned 监控这些组件的活动,并响应其使用中的变化。

默认情况下禁用动态调优。要启用它,请编辑 /etc/tuned/tuned-main.conf 文件并将 dynamic_tuning 选项改为 1tuned 随后定期分析系统统计信息,并使用它们更新您的系统调优设置。要配置这些更新之间的时间间隔,使用 update_interval 选项。

目前实施动态调优算法,试图平衡性能和 powersave,因此在性能配置集中被禁用。可以在 Tuned 配置集中启用或禁用单个插件的动态调优。

例 3.3. workstation 上的静态和动态调优

在典型的办公室工作站上,以太网网络接口大部分时间处于非活动状态。只有几封电子邮件可以进入和传出,或者可能加载一些网页。

对于这些类型的负载,网络接口不必像默认那样全速运行。tuned 具有对网络设备的监控和调优插件,可检测此低活动,然后自动降低该接口的速度,通常导致功耗降低。

如果接口上的活动在较长时间内增加,例如,下载 DVD 镜像或打开包含大附件的电子邮件,Tuned 会检测到这一点,并将接口速度设置为在活动水平较高时提供最佳性能。

此原则也用于 CPU 和磁盘的其他插件。

3.7. tuned 插件

插件是 Tuned 配置集中的模块,Tuned 使用这些模块来监控或优化系统上的不同设备。

tuned 使用两种插件:

监控插件

监控插件用于从正在运行的系统获取信息。监控插件的输出可通过调优插件进行动态调优。

每当启用的调优插件需要其指标时,监控插件会自动实例化。如果两个调优插件需要相同的数据,则仅创建一个监控插件实例并共享数据。

调优插件
每个调优插件对单个子系统进行调优,并取从调优配置集填充的多个参数。每个子系统可以有多个设备,如多个 CPU 或网卡,它们由调优插件的各个实例处理。也支持单个设备的特定设置。

Tuned 配置集中的插件语法

描述插件实例的部分采用以下方式格式化:

[NAME]
type=TYPE
devices=DEVICES
名称
是插件实例的名称,因为它在日志中使用。它可以是任意字符串。
类型
是调优插件的类型。
DEVICES

此插件实例处理的设备列表。

devices 行可以包含列表、通配符(*)和否定法(!)。如果没有 devices 行,则TYPE 系统中存在或更新的所有设备都由插件实例处理。这与使用 devices=* 选项相同。

例 3.4. 使用插件匹配块设备

以下示例匹配以 sd 开始的所有块设备,如 sdasdb,且不禁用它们的障碍:

[data_disk]
type=disk
devices=sd*
disable_barriers=false

以下示例与 sda1sda2 以外的所有块设备匹配:

[data_disk]
type=disk
devices=!sda1, !sda2
disable_barriers=false

如果没有指定插件实例,则该插件不会被启用。

如果插件支持更多选项,则可以在插件部分指定它们。如果没有指定 选项,且之前未在包含的插件中指定,则使用默认值。

短插件语法

如果您不需要插件实例的自定义名称,且配置文件中只有一个实例定义,Tuned 支持以下简短语法:

[TYPE]
devices=DEVICES

在这种情况下,可以省略 type 行。然后,实例使用名称引用,与类型相同。以上示例可改写为:

例 3.5. 使用简短语法匹配块设备

[disk]
devices=sdb*
disable_barriers=false

配置集中的冲突插件定义

如果使用 include 选项多次指定同一部分,则会合并设置。如果由于冲突而无法合并,最后一个冲突的定义会覆盖先前的设置。如果您不知道之前定义的内容,您可以使用 replace 布尔值选项并将其设置为 true。这会导致之前的所有定义被覆盖,且不会发生合并。

您还可以通过指定 enabled=false 选项来禁用插件。这具有与从未定义实例相同的效果。如果您要从 include 选项中重新定义之前的定义,并且不希望插件在自定义配置集中活跃,则禁用插件非常有用。

备注

tuned 包括运行任何 shell 命令,作为启用或禁用调优配置文件的一部分。这可让您使用尚未集成到 Tuned 的功能扩展 Tuned 配置集。

您可以使用 script 插件指定任意 shell 命令。

其它资源

  • tuned.conf(5) man page

3.8. 可用的 Tuned 插件

本节列出了 Tuned 中当前可用的所有监控和调优插件。

监控插件

目前,以下监控插件已被实施:

disk
获取每个设备的磁盘负载(IO 操作数)和测量间隔。
net
获取每个网卡的网络负载(传输数据包数)和测量间隔。
load
获得每个 CPU 的 CPU 负载和测量间隔。

调优插件

目前,实施以下调优插件:只有其中一部分插件实现了动态调优。还列出了插件支持的选项:

cpu

将 CPU 调控器设置为 governor 选项指定的值,并根据 CPU 负载动态更改 Power Management Quality of Service(PM QoS)CPU Direct Memory Access(DMA)延迟。

如果 CPU 负载低于 load_threshold 选项指定的值,则延迟被设置为 latency_high 选项指定的值,否则设置为 latency_low 指定的值。

您还可以强制延迟到特定值,并防止它进一步更改。要做到这一点,将 force_latency 选项设置为所需的延迟值。

eeepc_she

根据 CPU 负载动态设置前端总线(FSB)速度。

此功能可在某些工作簿中找到,也称为 ASUS Super Hybrid Engine(SHE)。

如果 CPU 负载较低或等于 load_threshold_powersave 选项指定的值,插件会将 FSB 速度设置为 she_powersave 选项指定的值。如果 CPU 负载高于或等于 load_threshold_normal 选项指定的值,它会将 FSB 速度设置为 she_normal 选项指定的值。

如果 Tuned 没有检测到此功能的硬件支持,则不支持静态调优,且插件会透明地禁用。

net
将 Wake-on-LAN 功能配置为 wake_on_lan 选项指定的值。它使用与 ethtool 工具相同的语法。它还会根据接口使用率动态更改接口速度。
sysctl

设置插件选项指定的各种 sysctl 设置。

语法是 name=value,名称 sysctl 实用程序提供的名称相同。

如果您需要更改 Tuned 中未包含的其他插件的系统设置,请使用 sysctl 插件。如果某些特定插件覆盖了设置,则首选这些插件。

usb

将 USB 设备的超时时间设置为 autosuspend 参数指定的值。

0 表示自动暂停被禁用。

vm

根据 transparent_hugepages 选项的值启用或禁用透明巨页。

transparent_hugepages 选项的有效值有:

  • "always"
  • "永不"
  • "madvise"
audio

将音频解码器的 autosuspend 超时设置为 timeout 选项指定的值。

目前,支持 snd_hda_intelsnd_ac97_codec 编码。0 表示自动暂停被禁用。您还可以通过将布尔值选项 reset_controller 设置为 true 来强制控制器重置。

disk

将磁盘电梯设置为 elevator 选项指定的值。

它还设置:

  • APM 到 apm 选项指定的值
  • 调度程序数量到 scheduler_quantum 选项指定的值
  • 磁盘减速超时到 spindown 选项指定的值
  • 磁盘读取到 readahead 参数指定的值
  • 当前磁盘读头值乘以 readahead_multiply 选项指定的常量值

此外,这个插件会根据当前的驱动器使用率动态更改驱动器的高级电源管理和降序超时设置。动态调优可以通过布尔值选项 dynamic 进行控制,并默认启用。

scsi_host

调整 SCSI 主机的选项.

它将 Aggressive Link Power Management(ALPM)设置为 alpm 选项指定的值。

mounts
根据 disable_barriers 选项的布尔值,启用或禁用挂载的障碍。
script

加载或卸载配置集时,执行外部脚本或二进制文件。您可以选择任意可执行文件。

重要

script 插件主要为与早期版本的兼容性提供。如果其他 Tuned 插件涵盖所需的功能,则首选它们。

tuned 使用以下参数之一调用可执行文件:

  • start 加载配置集时
  • stop 卸载配置集时

您需要在可执行文件中正确实现 stop 操作,并恢复您在 start 操作中更改的所有设置。否则,更改 Tuned 配置集后的回滚步骤将无法正常工作。

Bash 脚本可以导入 /usr/lib/tuned/functions Bash 库,并使用那里定义的功能。这些函数仅用于 Tuned 不原生提供的功能。如果函数名称以下划线(如 _wifi_set_power_level )开头,请考虑这个功能私有,且不要在脚本中使用它,因为它将来可能会改变。

使用插件配置中的 script 参数指定可执行文件的路径。

例 3.6. 从配置集运行 Bash 脚本

要运行位于配置集目录中名为 script.sh 的 Bash 脚本,请使用:

[script]
script=${i:PROFILE_DIR}/script.sh
sysfs

设置插件选项指定的各种 sysfs 设置。

语法是 name=value,其中name 是要使用的 sysfs 路径。

如果需要更改没有被其他插件覆盖的一些设置,请使用此插件。如果特定插件涵盖所需的设置,则首选它们。

video

在显卡上设置各种幂流级别。目前,只支持 Radeon 卡。

可以使用 radeon_powersave 选项指定 powersave 级别。支持的值有:

  • default
  • auto
  • low
  • mid
  • high
  • dynpm
  • dpm-battery
  • dpm-balanced
  • dpm-perfomance

详情请查看 http://www.x.org/wiki/RadeonFeature#KMS_Power_Management_Options。请注意,这个插件是实验性的,在以后的版本中可能会更改 选项。

bootloader

在内核命令行中添加选项。此插件只支持 GRUB 2 引导装载程序。

可以通过 grub2_cfg_file 选项指定 GRUB 2 配置文件的自定义非标准位置。

内核选项添加到当前 GRUB 配置及其模板中。需要重新引导系统才能使内核选项生效。

切换到另一个配置集或手动停止 tuned 服务会删除附加选项。如果您关闭或重启系统,内核选项会在 grub.cfg 文件中保留。

内核选项可使用以下语法指定:

cmdline=arg1 arg2 ... argN

例 3.7. 修改内核命令行

例如,要在 Tuned 配置集中添加 quiet 内核选项,请在 tuned.conf 文件中包括以下行:

[bootloader]
cmdline=quiet

以下是在内核命令行中添加 isolcpus=2 选项的自定义配置集示例:

[bootloader]
cmdline=isolcpus=2

3.9. Tuned 配置集中的变量

激活 Tuned 配置集时,变量会在运行时扩展。

使用 Tuned 变量可减少 Tuned 配置集中所需的输入量。

Tuned 配置集中没有预定义的变量。您可以通过在配置集中创建 [variables] 部分并使用以下语法来定义自己的变量:

[variables]

variable_name=value

要扩展配置集中的变量值,请使用以下语法:

${variable_name}

例 3.8. 使用变量隔离 CPU 内核

在以下示例中,${isolated_cores} 变量扩展至 1,2,因此内核使用 isolcpus=1,2 选项引导:

[variables]
isolated_cores=1,2

[bootloader]
cmdline=isolcpus=${isolated_cores}

这些变量可以在单独的文件中指定。例如,您可以在 tuned.conf 中添加以下行:

[variables]
include=/etc/tuned/my-variables.conf

[bootloader]
cmdline=isolcpus=${isolated_cores}

如果您在 /etc/tuned/my-variables.conf 文件中添加 isolated_cores=1,2 选项,内核将使用 isolcpus=1,2 选项引导。

其它资源

  • tuned.conf(5) man page

3.10. Tuned 配置集中的内置功能

当激活 Tuned 配置集时,内置功能会在运行时扩展。

您可以:

  • 将各种内置功能与 Tuned 变量一起使用
  • 在 Python 中创建自定义功能,并以插件的形式将它们添加到 Tuned

要调用函数,请使用以下语法:

${f:function_name:argument_1:argument_2}

要扩展配置集和 tuned.conf 文件所在的目录路径,请使用 PROFILE_DIR 功能,它需要特殊语法:

${i:PROFILE_DIR}

例 3.9. 使用变量和内置功能隔离 CPU 内核

在以下示例中,${non_isolated_cores} 变量扩展到 0,3-5cpulist_invert 内置函数通过 0,3-5 参数调用:

[variables]
non_isolated_cores=0,3-5

[bootloader]
cmdline=isolcpus=${f:cpulist_invert:${non_isolated_cores}}

cpulist_invert 功能会颠倒 CPU 列表。对于 6-CPU 机器,inversion 是 1,2,内核使用 isolcpus=1,2 命令行选项引导。

其它资源

  • tuned.conf(5) man page

3.11. Tuned 配置集中可用的内置功能

所有 Tuned 配置集都包括以下内置功能:

PROFILE_DIR
返回配置集和 tuned.conf 文件所在的目录路径。
exec
执行进程并返回其输出。
assertion
比较两个参数。如果不匹配,函数会记录第一个参数的文本并中止配置集加载。
assertion_non_equal
比较两个参数。如果匹配,函数会记录第一个参数的文本并加载 aborts 配置集。
kb2s
将 KB 转换为磁盘扇区.
s2kb
将磁盘扇区转换为 KB.
strip
从所有传递的参数创建字符串,并删除前导和尾随空格。
virt_check

检查 Tuned 是否在虚拟机(VM)或裸机上运行:

  • 在虚拟机内,函数返回第一个参数。
  • 在裸机上,函数会返回第二个参数,即使出现错误也是如此。
cpulist_invert
颠倒 CPU 列表,使其成为补充。例如:在一个有 4 个 CPU 的系统中,从 0 到 3,列表 0,2,3 的 inversion 是 1
cpulist2hex
将 CPU 列表转换为十六进制 CPU 掩码。
cpulist2hex_invert
将 CPU 列表转换为十六进制 CPU 掩码,并颠倒 CPU 掩码。
hex2cpulist
将十六进制 CPU 掩码转换为 CPU 列表。
cpulist_online
检查列表中的 CPU 是否在线。返回仅包含在线 CPU 的列表。
cpulist_present
检查列表中是否存在 CPU。返回仅包含现有 CPU 的列表。
cpulist_unpack
将 CPU 列表解包为 1-3,41,2,3,4
cpulist_pack
将 CPU 列表以 1,2,3,5 的形式打包到 1-3,5

3.12. 创建新的 Tuned 配置集

此流程使用自定义性能规则创建新的 Tuned 配置集。

先决条件

流程

  1. /etc/tuned/ 目录中,创建一个名为与您要创建的配置集相同的新目录:

    # mkdir /etc/tuned/my-profile
  2. 在新目录中,创建名为 tuned.conf 的文件。根据您的要求,添加 [main] 部分和其中的插件定义。

    例如,查看 balanced 配置集的配置:

    [main]
    summary=General non-specialized tuned profile
    
    [cpu]
    governor=conservative
    energy_perf_bias=normal
    
    [audio]
    timeout=10
    
    [video]
    radeon_powersave=dpm-balanced, auto
    
    [scsi_host]
    alpm=medium_power
  3. 要激活配置集,请使用:

    # tuned-adm profile my-profile
  4. 验证 Tuned 配置集是否活跃并应用系统设置:

    $ tuned-adm active
    
    Current active profile: my-profile
    $ tuned-adm verify
    
    Verfication succeeded, current system settings match the preset profile.
    See tuned log file ('/var/log/tuned/tuned.log') for details.

其它资源

  • tuned.conf(5) man page

3.13. 修改现有的 Tuned 配置集

此流程基于现有的 Tuned 配置集创建修改的子配置集。

先决条件

流程

  1. /etc/tuned/ 目录中,创建一个名为与您要创建的配置集相同的新目录:

    # mkdir /etc/tuned/modified-profile
  2. 在新目录中,创建一个名为 tuned.conf 的文件,并设置 [main] 部分,如下所示:

    [main]
    include=parent-profile

    parent-profile 替换为您要修改的配置集的名称。

  3. 包括您的配置集修改。

    例 3.10. 在 throughput-performance 配置集中降低 swappiness

    要使用 throughput-performance 配置集中的设置并将 vm.swappiness 的值改为 5,而不是默认的 10,请使用:

    [main]
    include=throughput-performance
    
    [sysctl]
    vm.swappiness=5
  4. 要激活配置集,请使用:

    # tuned-adm profile modified-profile
  5. 验证 Tuned 配置集是否活跃并应用系统设置:

    $ tuned-adm active
    
    Current active profile: my-profile
    $ tuned-adm verify
    
    Verfication succeeded, current system settings match the preset profile.
    See tuned log file ('/var/log/tuned/tuned.log') for details.

其它资源

  • tuned.conf(5) man page

3.14. 使用 Tuned 设置磁盘调度程序

此流程创建并启用 Tuned 配置集,该配置集为所选块设备设置给定磁盘调度程序。这个设置会在系统重启后保留。

在以下命令和配置中替换:

  • 带有块设备名称的设备,例如: sdf
  • 带有您要为该设备设置的磁盘调度程序的 selected-scheduler,例如 bfq

先决条件

流程

  1. 可选:选择一个您配置集将要基于的现有 Tuned 配置集。有关可用配置集列表,请参阅 RHEL 提供的 Tuned 配置集

    要查看哪个配置集当前处于活跃状态,请使用:

    $ tuned-adm active
  2. 创建一个新目录来保存您的 Tuned 配置集:

    # mkdir /etc/tuned/my-profile
  3. 查找所选块设备系统唯一标识符:

    $ udevadm info --query=property --name=/dev/device | grep -E '(WWN|SERIAL)'
    
    ID_WWN=0x5002538d00000000_
    ID_SERIAL=Generic-_SD_MMC_20120501030900000-0:0
    ID_SERIAL_SHORT=20120501030900000
    注意

    本例中的 命令将返回标识为全局名称(WWN)或与指定块设备关联的序列号的所有值。虽然最好使用 WWN,但 WWN 并不总是可用于给定设备,示例命令返回的任何值都可用作设备系统唯一 ID

  4. 创建 /etc/tuned/my-profile/tuned.conf 配置文件。在该文件中设置以下选项:

    1. 可选:包含现有配置集:

      [main]
      include=existing-profile
    2. 为与 WWN 标识符匹配的设备设置所选磁盘调度程序:

      [disk]
      devices_udev_regex=IDNAME=device system unique id
      elevator=selected-scheduler

      在这里:

      • 使用正在使用的标识符的名称替换 IDNAME (例如 ID_WWN)。
      • 将设备系统唯一 id 替换为所选标识符的值(例如 0x5002538d00000000)。

        要匹配 devices_udev_regex 选项中的多个设备,请将标识符括在括号中,并使用竖线分隔它们:

        devices_udev_regex=(ID_WWN=0x5002538d00000000)|(ID_WWN=0x1234567800000000)
  5. 启用您的配置集:

    # tuned-adm profile my-profile

验证步骤

  • 验证 Tuned 配置集是否活跃并应用:

    $ tuned-adm active
    
    Current active profile: my-profile
    $ tuned-adm verify
    
    Verification succeeded, current system settings match the preset profile.
    See tuned log file ('/var/log/tuned/tuned.log') for details.

第 4 章 使用 tuna 接口检查系统

使用 tuna 工具调整调度程序可调项、调整线程优先级、IRQ 处理程序,以及隔离 CPU 内核和套接字。Tuna 降低了执行调优任务的复杂性。

tuna 工具执行以下操作:

  • 列出系统上的 CPU
  • 列出系统上当前运行的中断请求(IRQ)
  • 更改线程的策略和优先级信息
  • 显示系统当前的策略和优先级

4.1. 安装 tuna 工具

tuna 工具设计为用于运行的系统中。这允许应用程序特定的测量工具在更改后立即查看和分析系统性能。

这个步骤描述了如何安装 tuna 工具。

流程

  • 安装 tuna 工具:

    # yum install tuna

验证步骤

  • 查看可用的 tuna CLI 选项:

    # tuna -h

其它资源

  • tuna(8) man page

4.2. 使用 tuna 工具查看系统状态

这个步骤描述了如何使用 tuna 命令行界面(CLI)工具查看系统状态。

先决条件

流程

  • 查看当前的策略和优先级:

    # tuna --show_threads
                thread
    pid   SCHED_ rtpri affinity             cmd
    1      OTHER     0      0,1            init
    2       FIFO    99        0     migration/0
    3      OTHER     0        0     ksoftirqd/0
    4       FIFO    99        0      watchdog/0
  • 查看与 PID 对应的特定线程或与命令名称匹配:

    # tuna --threads=pid_or_cmd_list --show_threads

    Thepid_or_cmd_list 参数是一个逗号分隔的 PID 或命令行模式的列表。

  • 要使用 tuna CLI 调整 CPU,请参阅使用 tuna 工具调优 CPU
  • 要使用 tuna 工具调整 IRQ,请参阅使用 tuna 工具调优 IRQ。
  • 保存更改的配置:

    # tuna --save=filename

    这个命令只保存当前运行的内核线程。未运行的进程不会被保存。

其它资源

  • tuna(8) man page

4.3. 使用 tuna 工具调优 CPU

tuna 工具命令可以针对单个 CPU。

使用 tuna 工具,您可以:

Isolate CPUs
在指定 CPU 上运行的所有任务都将移到下一个可用的 CPU。隔离 CPU 使其无法通过从所有线程的关联掩码中删除。
Include CPUs
允许任务在指定的 CPU 上运行
Restore CPUs
将指定的 CPU 恢复到之前的配置。

这个步骤描述了如何使用 tuna CLI 调整 CPU。

先决条件

流程

  • 指定要受命令影响的 CPU 列表:

    # tuna --cpus=cpu_list [command]

    cpu_list 参数是一个逗号分隔的 CPU 编号列表。例如: --cpus=0,2。CPU 列表也可以在范围中指定,例如 --cpus=”1-3,它可选择 CPU 1、2 和 3。

    要将特定的 CPU 添加到当前的 cpu_list 中,例如,使用 --cpus=+0

    将 [command] 替换为 --isolate

  • 隔离 CPU:

    # tuna --cpus=cpu_list --isolate
  • 要包括 CPU:

    # tuna --cpus=cpu_list --include
  • 要使用有四个或者多个处理器的系统,显示所有 ssh 线程在 CPU 01 上运行,以及 CPU 2 和 3 中的所有 http 线程:

    # tuna --cpus=0,1 --threads=ssh\* \
    --move --cpus=2,3 --threads=http\* --move

    这个命令按顺序执行以下操作:

    1. 选择 CPU 0 1.
    2. 选择以 ssh 开头的所有线程。
    3. 将所选线程移到所选 CPU。Tuna 将线程的关联性掩码从 ssh 开始设置为适当的 CPU。CPU 可以数字表示为 01,十六进制掩码表示为 0x3,或者二进制形式为 11。
    4. 将 CPU 列表重置为 23
    5. 选择以 http 开头的所有线程。
    6. 将所选线程移到指定的 CPU。Tuna 设置线程的关联性掩码,从 http 开始到指定的 CPU。CPU 可以通过数字方式表示为 23,以十六进制掩码表示为 0xC,或者作为 1100 的二进制代码表示。

验证步骤

  • 显示当前配置并验证更改是否已按预期执行:

    # tuna --threads=gnome-sc\* --show_threads \
    --cpus=0 --move --show_threads --cpus=1 \
    --move --show_threads --cpus=+0 --move --show_threads
    
                           thread       ctxt_switches
         pid SCHED_ rtpri affinity voluntary nonvoluntary             cmd
       3861   OTHER     0      0,1     33997           58 gnome-screensav
                           thread       ctxt_switches
         pid SCHED_ rtpri affinity voluntary nonvoluntary             cmd
       3861   OTHER     0        0     33997           58 gnome-screensav
                           thread       ctxt_switches
         pid SCHED_ rtpri affinity voluntary nonvoluntary             cmd
       3861   OTHER     0        1     33997           58 gnome-screensav
                           thread       ctxt_switches
         pid SCHED_ rtpri affinity voluntary nonvoluntary             cmd
       3861   OTHER     0      0,1     33997           58 gnome-screensav

    这个命令按顺序执行以下操作:

    1. 选择以 gnome-sc 线程开头的所有线程。
    2. 显示所选线程,使用户能够验证其关联性掩码和 RT 优先级。
    3. 选择 CPU 0
    4. gnome-sc 线程移到指定的 CPU,CPU 0
    5. 显示移动的结果。
    6. 将 CPU 列表重置为 CPU 1
    7. gnome-sc 线程移到指定的 CPU,CPU 1
    8. 显示移动结果.
    9. 将 CPU 0 添加到 CPU 列表中。
    10. gnome-sc 线程移到指定的 CPU、CPU 01
    11. 显示移动结果.

其它资源

  • /proc/cpuinfo file
  • tuna(8) man page

4.4. 使用 tuna 工具调优 IRQ

/proc/interrupts 文件记录每个 IRQ 的中断数、中断类型以及位于该 IRQ 的设备名称。

这个步骤描述了如何使用 tuna 工具调整 IRQ。

先决条件

流程

  • 查看当前的 IRQ 及其相关性:

    # tuna --show_irqs
    # users            affinity
    0 timer                   0
    1 i8042                   0
    7 parport0                0
  • 指定要受命令影响的 IRQ 列表:

    # tuna --irqs=irq_list [command]

    irq_list 参数是一个逗号分隔的 IRQ 编号或用户名模式的列表。

    将 [command] 替换为 --isolate

  • 将中断移动到指定的 CPU:

    # tuna --irqs=128 --show_irqs
       # users            affinity
     128 iwlwifi           0,1,2,3
    
    # tuna --irqs=128 --cpus=3 --move

    使用 irq_list 参数替换 128,并将 3 替换为 cpu_list 参数。

    cpu_list 参数是一个用逗号分开的 CPU 号码列表,例如 --cpus=0,2如需更多信息,请参阅使用 tuna 工具调优 CPU

验证步骤

  • 将任何中断前和之后所选 IRQ 的状态与指定 CPU 进行对比:

    # tuna --irqs=128 --show_irqs
       # users            affinity
     128 iwlwifi                 3

其它资源

  • /procs/interrupts file
  • tuna(8) man page

第 5 章 使用 RHEL 系统角色监控性能

作为系统管理员,您可以使用 metrics RHEL 系统角色和任何 Ansible Automation Platform 控制节点来监控系统的性能。

5.1. RHEL 系统角色简介

RHEL 系统角色是 Ansible 角色和模块的集合。RHEL 系统角色提供了一个配置界面,用于远程管理多个 RHEL 系统。这个界面允许在多个 RHEL 版本间管理系统配置,以及处理新的主发行版本。

在 Red Hat Enterprise Linux 8 中,该接口目前由以下角色组成:

  • kdump
  • network
  • selinux
  • storage
  • certificate
  • kernel_settings
  • logging
  • metrics
  • nbde_client 和 nbde_server
  • timesync
  • tlog

所有这些角色都由 AppStream 存储库中可用的 rhel-system-roles 软件包提供。

其它资源

5.2. RHEL 系统角色术语

您可以在本文档中找到以下术语:

系统角色术语

Ansible playbook
Playbook 是 Ansible 的配置、部署和编配语言。它们可以描述您希望远程系统强制使用的策略,或者在一般的 IT 进程中选择一组步骤。
控制节点
安装了 Ansible 的任何机器。您可以从任何控制节点运行命令和 playbook,调用 /usr/bin/ansible 或 /usr/bin/ansible-playbook。您可以使用任意安装了 Python 的计算机作为控制节点 - 笔记本电脑、共享桌面和服务器都可以运行 Ansible。但是,您不能使用 Windows 机器作为控制节点。您可以拥有多个控制节点。
清单(Inventory)
受管节点列表。清单文件有时也称为"hostfile"。您的清单可以为每个受管节点指定像 IP 地址等信息。清单也可以管理受管节点,创建并嵌套组以更轻松地进行扩展。如需了解更多有关清单的信息,请参阅使用清单一 节。
受管节点
使用 Ansible 管理的网络设备、服务器或两者。受管节点有时也称为 "hosts(主机)"。Ansible 未安装到受管节点上。

5.3. 在系统中安装 RHEL 系统角色

要使用 RHEL 系统角色,请安装所需的软件包。

先决条件

流程

  1. 在您要用作控制节点的系统中安装该 rhel-system-roles 软件包:

    # yum install rhel-system-roles

    如果您没有 Red Hat Ansible Engine 订阅,可以使用 Red Hat Enterprise Linux 订阅提供的有限版本的 Red Hat Ansible Engine。在这种情况下,请按照以下步骤操作:

    1. 启用 RHEL Ansible Engine 存储库:

      # subscription-manager refresh
      
      # subscription-manager repos --enable ansible-2-for-rhel-8-x86_64-rpms
    2. 安装 Ansible Engine:

      # yum install ansible

因此,您可以创建一个 Ansible playbook。

其它资源

5.4. 应用一个角色

以下流程描述了如何应用特定角色。

先决条件

  • 确定在您要用作控制节点的系统中安装了 rhel-system-roles 软件包:

    # yum install rhel-system-roles
  • 您需要 ansible 软件包来运行使用 RHEL 系统角色的 playbook。确保启用了 Ansible Engine 软件仓库,并在您要用作控制节点的系统中安装 ansible 软件包。

    • 如果您没有 Red Hat Ansible Engine 订阅,可以使用 Red Hat Enterprise Linux 订阅提供的有限版本的 Red Hat Ansible Engine。在这种情况下,请按照以下步骤操作:

      1. 启用 RHEL Ansible Engine 存储库:

        # subscription-manager refresh
        # subscription-manager repos --enable ansible-2-for-rhel-8-x86_64-rpms
      2. 安装 Ansible Engine:

        # yum install ansible
    • 如果您有 Red Hat Ansible Engine 订阅,请按照以下所述步骤操作 如何下载和安装 Red Hat Ansible Engine?
  • 确保您能够创建 Ansible 清单。

    清单表示主机、主机组,以及 Ansible playbook 使用的一些配置参数。

    playbook 通常为人类可读,并以 iniyamljson 和其他文件格式定义。

  • 确保您能够创建 Ansible playbook。

    Playbook 代表 Ansible 的配置、部署和编配语言。通过使用 playbook,您可以声明和管理远程机器的配置,部署多个远程机器,编配任何手动排序进程的步骤。

    playbook 是一个或多个 plays 的列表。每个 play 都可以包括 Ansible 变量、任务或角色。

    playbook 是人类可读的,使用 yaml 格式定义。

流程

  1. 创建所需的 Ansible 清单,使其包含您要管理的主机和组。以下是一个示例,它使用一组名为 webservers 的主机名为 inventory.ini 的文件:

    [webservers]
    host1
    host2
    host3
  2. 创建一个 Ansible playbook,包括所需角色。以下示例演示了如何通过 playbook 的 roles: 选项使用角色:

    以下示例演示了如何通过给定 roles: 选项使用角色 play:

    ---
    - hosts: webservers
      roles:
         - rhel-system-roles.network
         - rhel-system-roles.timesync
    注意

    每个角色都包括 README 文件,该文件记录如何使用角色和支持的参数值。您还可以在角色的文档目录中找到特定角色的示例 playbook。这些文档目录默认由 rhel-system-roles 软件包提供,并可在以下位置找到:

    /usr/share/doc/rhel-system-roles/SUBSYSTEM/

    SUBSYSTEM 替换为所需角色的名称,如 selinuxkdumpnetworktimesyncstorage

  3. 要在特定主机上执行 playbook,您必须执行以下任一操作:

    • 编辑 playbook 以使用 hosts: host1[,host2,…​]hosts: all 并执行该命令:

      # ansible-playbook name.of.the.playbook
    • 编辑清单,以确保在组中定义了您要使用的主机,并执行该命令:

      # ansible-playbook -i name.of.the.inventory name.of.the.playbook
    • 指定执行 ansible-playbook 命令时的所有主机:

      # ansible-playbook -i host1,host2,... name.of.the.playbook
      重要

      请注意,-i 标志指定了所有可用主机的清单。如果您有多个目标主机,但希望选择要针对其运行 playbook 的主机,您可以在 playbook 中添加变量,以便能够选择主机。例如:

      Ansible Playbook | example-playbook.yml:
      
      - hosts: "{{ target_host }}"
        roles:
           - rhel-system-roles.network
           - rhel-system-roles.timesync

      Playbook 执行命令:

      # ansible-playbook -i host1,..hostn -e target_host=host5 example-playbook.yml

5.5. 指标系统角色简介

RHEL 系统角色是 Ansible 角色和模块的集合,可为远程管理多个 RHEL 系统提供一致的配置界面。指标系统角色为本地系统配置性能分析服务,并选择性地包含要由本地系统监控的远程系统列表。借助 metrics 系统角色,您可以使用 pcp 来监控系统性能,而无需单独配置pcp,因为 playbook 处理 pcp 设置和部署。

表 5.1. 指标系统角色变量

角色变量描述用法示例

metrics_monitored_hosts

目标主机要分析的远程主机列表。这些主机将在目标主机上记录指标,以确保每个主机的 /var/log 中有足够的磁盘空间。

metrics_monitored_hosts: ["webserver.example.com", "database.example.com"]

metrics_retention_days

在删除前配置性能数据保留的天数。

metrics_retention_days: 14

metrics_graph_service

一个布尔值标记,允许主机设置有服务通过 pcpgrafana 进行性能数据视觉化。默认设置为 false。

metrics_graph_service: false

metrics_query_service

一个布尔值标记,允许主机设置时间序列查询服务,以便通过 redis 查询记录的 pcp 指标。默认设置为 false。

metrics_query_service: false

metrics_provider

指定要用于提供指标的指标收集器。目前, pcp 是唯一支持的指标提供程序。

metrics_provider: "pcp"

注意

有关使用的参数 metrics_connections 以及有关 metrics 系统角色的额外信息,请查看 /usr/share/ansible/roles/rhel-system-roles.metrics/README.md 文件。

5.6. 使用指标系统角色以可视化方式监控本地系统

此流程描述了如何在同时置备数据视觉化时使用 metrics RHEL 系统角色监控您的本地系统 grafana

先决条件

  • 您已在要监控的机器上安装了 Red Hat Ansible Engine。
  • 您需要在要监控的机器中安装 rhel-system-roles 软件包。

流程

  1. 通过 localhost 将以下内容添加到清单中,在 /etc/ansible/hosts Ansible 清单中配置:

    localhost ansible_connection=local
  2. 使用以下内容创建一个 Ansible playbook:

    ---
    - hosts: localhost
      vars:
        metrics_graph_service: yes
      roles:
        - rhel-system-roles.metrics
  3. 运行 Ansible playbook:

    # ansible-playbook name_of_your_playbook.yml
    注意

    因为 metrics_graph_service 布尔值被设置为 value="yes", grafana 它会被自动安装并置备并将 pcp 添加为数据源。

  4. 要查看您机器上收集的指标的视觉化,请访问 Grafana grafana Web UI 中的 Web 界面。

5.7. 使用 metrics 系统角色设置监控其自身的独立系统

此流程描述了如何使用 metrics 系统角色设置一组机器来监控其自身。

先决条件

  • 您已在要用来运行 playbook 的机器上安装了 Red Hat Ansible Engine。
  • 已安装要用来运行 playbook 的机器上的 rhel-system-roles 软件包。

流程

  1. 将您要通过 playbook 监控的机器的名称或 IP 添加到 /etc/ansible/hosts Ansible 清单文件中,并使用括号括起的标识组名称:

    [remotes]
    webserver.example.com
    database.example.com
  2. 使用以下内容创建一个 Ansible playbook:

    ---
    - hosts: remotes
      vars:
        metrics_retention_days: 0
      roles:
        - rhel-system-roles.metrics
  3. 运行 Ansible playbook:

    # ansible-playbook name_of_your_playbook.yml

5.8. 使用 metrics 系统角色通过本地机器集中监控机器的数量

此流程描述了如何使用 metrics 系统角色设置本地机器来集中监控机器数量,同时通过 grafana 进行数据视觉化,通过 redis 查询数据。

先决条件

  • 您已在要用来运行 playbook 的机器上安装了 Red Hat Ansible Engine。
  • 已安装要用来运行 playbook 的机器上的 rhel-system-roles 软件包。

流程

  1. 使用以下内容创建一个 Ansible playbook:

    ---
    - hosts: localhost
      vars:
        metrics_graph_service: yes
        metrics_query_service: yes
        metrics_retention_days: 10
        metrics_monitored_hosts: ["database.example.com", "webserver.example.com"]
      roles:
        - rhel-system-roles.metrics
  2. 运行 Ansible playbook:

    # ansible-playbook name_of_your_playbook.yml
    注意

    因为 metrics_graph_servicemetrics_query_service 被设置为 value="yes",grafana 会被自动安装,被置备为带有 pcp 作为 pcp 数据源索引到 redis,从而可以使用 pcp 查询语言对数据进行复杂的查询。

  3. 要查看机器集中收集的指标的图形表示,并查询数据,请访问 grafana Web 界面,如访问 Grafana web UI 所述。

5.9. 使用 metrics 系统角色监控系统时设置身份验证

PCP 通过 Simple Authentication Security Layer(SASL)框架支持 scram-sha-256 验证机制。metrics RHEL 系统角色使用 scram-sha-256 身份验证机制自动执行设置身份验证的步骤。这个步骤描述了如何使用 metrics RHEL 系统角色设置身份验证。

先决条件

  • 您已在要用来运行 playbook 的机器上安装了 Red Hat Ansible Engine。
  • 已安装要用来运行 playbook 的机器上的 rhel-system-roles 软件包。

流程

  1. 在您要为其设置身份验证的 Ansible playbook 中包含以下变量:

    ---
      vars:
        metrics_username: your_username
        metrics_password: your_password
  2. 运行 Ansible playbook:

    # ansible-playbook name_of_your_playbook.yml

验证步骤

  • 验证 sasl 配置:

    # pminfo -f -h "pcp://127.0.0.1?username=your_username" disk.dev.read
    Password:
    disk.dev.read
    inst [0 or "sda"] value 19540

5.10. 使用 metrics 系统角色为 SQL Server 配置和启用指标集合

这个步骤描述了如何使用 metrics RHEL 系统角色通过本地系统中的 pcp 为 Microsoft SQL Server 自动配置和启用指标集合。

先决条件

  • 您已在要监控的机器上安装了 Red Hat Ansible Engine。
  • 您需要在要监控的机器中安装 rhel-system-roles 软件包。
  • 您已安装了用于红帽企业 Linux 的 Microsoft SQL Server 并建立了与 SQL 服务器的"可信"连接。
  • 您已安装了适用于红帽企业 Linux 的 SQL Server 的 Microsoft ODBC 驱动程序。

流程

  1. 通过 localhost 将以下内容添加到清单中,在 /etc/ansible/hosts Ansible 清单中配置:

    localhost ansible_connection=local
  2. 创建一个包含以下内容的 Ansible playbook:

    ---
    - hosts: localhost
      roles:
        - role: rhel-system-roles.metrics
          vars:
            metrics_from_sql: yes
  3. 运行 Ansible playbook:

    # ansible-playbook name_of_your_playbook.yml

验证步骤

  • 使用 pcp 命令验证 SQL Server PMDA 代理(mssql)是否已加载并正在运行:

    # pcp
    platform: Linux rhel82-2.local 4.18.0-167.el8.x86_64 #1 SMP Sun Dec 15 01:24:23 UTC 2019 x86_64
     hardware: 2 cpus, 1 disk, 1 node, 2770MB RAM
     timezone: PDT+7
     services: pmcd pmproxy
         pmcd: Version 5.0.2-1, 12 agents, 4 clients
         pmda: root pmcd proc pmproxy xfs linux nfsclient mmv kvm mssql
               jbd2 dm
     pmlogger: primary logger: /var/log/pcp/pmlogger/rhel82-2.local/20200326.16.31
         pmie: primary engine: /var/log/pcp/pmie/rhel82-2.local/pmie.log


[1] 本文档会随 rhel-system-roles 软件包自动安装。

第 6 章 设置 PCP

Performance Co-Pilot(PCP)是一组用于监控、可视化、存储和分析系统级性能测量的工具、服务和库。

这部分论述了如何在您的系统上安装和启用 PCP。

6.1. PCP 概述

您可以使用 Python、Perl、C++ 和 C 接口添加性能指标。分析工具可以直接使用 Python、C++、C 客户端 API 和丰富的 Web 应用程序,使用 JSON 接口探索所有可用的性能数据。

您可以通过将实时结果与存档数据进行比较来分析数据模式。

PCP 的特性:

  • 轻量级分布式架构,在集中分析复杂系统时非常有用。
  • 它允许监控和管理实时数据。
  • 它允许记录和检索历史数据。

PCP 有以下组件:

  • Performance Metric Collector Daemon(pmcd)从已安装的性能指标(pmda)收集性能数据。PMDA 可以在系统上单独加载或卸载,并由同一主机上的 PMCD 控制。
  • 各种客户端工具,如 pminfopmstat,可以在同一个主机或网络上检索、显示、归档和处理这些数据。
  • pcp 软件包提供命令行工具和底层功能。
  • pcp-gui 软件包提供了图形应用程序。执行 yum install pcp-gui 命令安装 pcp-gui 软件包。如需更多信息,请参阅使用 PCP Charts 应用程序可视化追踪 PCP 日志归档

6.2. 安装并启用 PCP

要开始使用 PCP,请安装所有必要的软件包并启用 PCP 监控服务。

这个步骤描述了如何使用 pcp 软件包安装 PCP。如果要自动执行 PCP 安装,使用 pcp-zeroconf 软件包安装。有关使用 pcp-zeroconf 安装 PCP 的更多信息,请参阅使用 pcp-zeroconf 设置 PCP

流程

  1. 安装 pcp 软件包:

    # yum install pcp
  2. 在主机上启用并启动 pmcd 服务:

    # systemctl enable pmcd
    
    # systemctl start pmcd

验证步骤

  • 验证 pmcd 进程是否在主机上运行:

    # pcp
    
    Performance Co-Pilot configuration on workstation:
    
    platform: Linux workstation 4.18.0-80.el8.x86_64 #1 SMP Wed Mar 13 12:02:46 UTC 2019 x86_64
    hardware: 12 cpus, 2 disks, 1 node, 36023MB RAM
    timezone: CEST-2
    services: pmcd
    pmcd: Version 4.3.0-1, 8 agents
    pmda: root pmcd proc xfs linux mmv kvm jbd2

其它资源

6.3. 部署最小 PCP 设置

最小 PCP 设置收集红帽企业 Linux 的性能统计信息。设置涉及在生产系统上添加收集数据以便进一步分析所需的最少软件包数量。

您可以使用各种 PCP 工具分析生成的 tar.gz 文件和 pmlogger 输出归档,并将其与其他性能信息来源进行比较。

先决条件

流程

  1. 更新 pmlogger 配置:

    # pmlogconf -r /var/lib/pcp/config/pmlogger/config.default
  2. 启动 pmcdpmlogger 服务:

    # systemctl start pmcd.service
    
    # systemctl start pmlogger.service
  3. 执行所需的操作,以记录性能数据。
  4. 停止 pmcdpmlogger 服务:

    # systemctl stop pmcd.service
    
    # systemctl stop pmlogger.service
  5. 保存输出并将其保存到基于主机名和当前日期和时间命名的 tar.gz 文件中:

    # cd /var/log/pcp/pmlogger/
    
    # tar -czf $(hostname).$(date +%F-%Hh%M).pcp.tar.gz $(hostname)

    使用 PCP 工具提取此文件并分析数据。

其它资源

6.4. 使用 PCP 分发的系统服务

下表描述了通过 PCP 分发的各种系统服务的角色。

表 6.1. 使用 PCP 分发的系统服务的角色

名称

描述

pmcd

Performance Metric Collector Daemon(PMCD)。

pmie

性能指标参考引擎.

pmlogger

性能指标日志记录器。

pmmgr

根据零个或多个配置目录,为一组已发现的本地和远程主机管理 PCP 守护进程集合,运行 Performance Metric Collector Daemon(PMCD)。

pmproxy

Performance Metric Collector Daemon(PMCD)代理服务器。

6.5. PCP 发布的工具

下表描述了各种工具的用法,这些工具随 PCP 一起分发。

表 6.2. 使用 PCP 发布的工具

名称

描述

pcp

显示 Performance Co-Pilot 安装的当前状态。

pcp-atop

从性能角度显示最重要的硬件资源的系统级别:CPU、内存、磁盘和网络。

pcp-dstat

一次显示一个系统的指标。要显示多个系统的指标,请使用 --host 选项。

pmchart

绘制 Performance Co-Pilot 工具提供的性能指标值。

pmclient

使用性能指标应用程序编程接口(PMAPI)显示高级别系统性能指标。

pmcollectl

从实时系统或 Performance Co-Pilot 存档文件收集和显示系统级数据。

pmconfig

显示配置参数的值。

pmdbg

显示可用的 Performance Co-Pilot 调试控制标志及其值。

pmdiff

比较给定时间窗口中一个或多个存档中每个指标的平均值,以了解在搜索性能回归时可能感兴趣的更改。

pmdumplog

显示 Performance Co-Pilot 归档文件中的控制、元数据、索引和状态信息。

pmdumptext

输出实时或从 Performance Co-Pilot 归档收集的性能指标值。

pmerr

显示可用的 Performance Co-Pilot 错误代码及其对应的错误消息。

pmfind

查找网络上的 PCP 服务。

pmie

定期评估一组算术、逻辑和规则表达式的推理引擎。指标从实时系统或从 Performance Co-Pilot 归档文件收集。

pmieconf

显示或设置可配置的 pmie 变量.

pminfo

显示性能指标信息。指标从实时系统或从 Performance Co-Pilot 归档文件收集。

pmiostat

报告 SCSI 设备(默认)或设备映射器设备的 I/O 统计信息(使用 -x dm 选项)。

pmlc

以交互方式配置活跃的 pmlogger 实例。

pmlogcheck

在 Performance Co-Pilot 归档文件中识别无效的数据。

pmlogconf

创建并修改 pmlogger 配置文件。

pmloglabel

验证、修改或修复 Performance Co-Pilot 存档文件的标签。

pmlogsummary

计算 Performance Co-Pilot 存档文件中存储的性能指标的统计信息。

pmprobe

决定性能指标的可用性。

pmrep

报告所选、易于定制的性能指标值。

pmsocks

允许通过防火墙访问 Performance Co-Pilot 主机。

pmstat

定期显示系统性能的简短摘要。

pmstore

修改性能指标的值。

pmtrace

为跟踪性能指标域代理(PMDA)提供命令行界面。

pmval

显示性能指标的当前值。

第 7 章 使用 pmlogger 记录性能数据

通过 PCP 工具,您可以记录性能指标值并在以后重播。这样,您可以进行回顾性性能分析。

使用 pmlogger 工具,您可以:

  • 在系统上创建所选指标的存档日志
  • 指定在系统上记录哪些指标,以及记录的频率

7.1. 使用 pmlogconf 修改 pmlogger 配置文件

pmlogger 服务运行时,PCP 会记录主机上的一组默认指标。

使用 pmlogconf 工具检查默认配置。如果 pmlogger 配置文件不存在,pmlogconf 会使用默认指标值创建该文件。

先决条件

流程

  1. 创建或修改 pmlogger 配置文件:

    # pmlogconf -r /var/lib/pcp/config/pmlogger/config.default
  2. 按照 pmlogconf 提示,启用或禁用相关性能指标组,并控制每个启用的组的日志记录间隔。

其它资源

7.2. 手动编辑 pmlogger 配置文件

要使用特定指标和给定间隔创建定制日志配置,请手动编辑 pmlogger 配置文件。默认的 pmlogger 配置文件是 /var/lib/pcp/config/pmlogger/config.default。配置文件指定主日志记录实例记录哪些指标。

在手动配置中,您可以:

  • 记录自动配置中未列出的指标。
  • 选择自定义日志记录频率。
  • 使用应用程序指标添加 PMDA

先决条件

流程

  • 打开并编辑 /var/lib/pcp/config/pmlogger/config.default 文件以添加特定的指标:

    # It is safe to make additions from here on ...
    #
    
    log mandatory on every 5 seconds {
        xfs.write
        xfs.write_bytes
        xfs.read
        xfs.read_bytes
    }
    
    log mandatory on every 10 seconds {
        xfs.allocs
        xfs.block_map
        xfs.transactions
        xfs.log
    
    }
    
    [access]
    disallow * : all;
    allow localhost : enquire;

其它资源

7.3. 启用 pmlogger 服务

必须启动并启用 pmlogger 服务来记录本地机器上的指标值。

这个步骤描述了如何启用 pmlogger 服务。

先决条件

流程

  • 启动并启用 pmlogger 服务:

    # systemctl start pmlogger
    
    # systemctl enable pmlogger

验证步骤

  • 验证 pmlogger 服务是否已启用:

    # pcp
    
    Performance Co-Pilot configuration on workstation:
    
    platform: Linux workstation 4.18.0-80.el8.x86_64 #1 SMP Wed Mar 13 12:02:46 UTC 2019 x86_64
    hardware: 12 cpus, 2 disks, 1 node, 36023MB RAM
    timezone: CEST-2
    services: pmcd
    pmcd: Version 4.3.0-1, 8 agents, 1 client
    pmda: root pmcd proc xfs linux mmv kvm jbd2
    pmlogger: primary logger: /var/log/pcp/pmlogger/workstation/20190827.15.54

其它资源

7.4. 为指标集合设置客户端系统

这个步骤描述了如何设置客户端系统,以便中央服务器可以从运行 PCP 的客户端收集指标。

先决条件

流程

  1. 安装 pcp-system-tools 软件包:

    # yum install pcp-system-tools
  2. pmcd 配置 IP 地址:

    # echo "-i 192.168.4.62" >>/etc/pcp/pmcd/pmcd.options

    192.168.4.62 替换为 IP 地址,客户端应侦听。

    默认情况下,pmcd 正在侦听 localhost。

  3. 将防火墙配置为永久添加公共 zone

    # firewall-cmd --permanent --zone=public --add-port=44321/tcp
    success
    
    # firewall-cmd --reload
    success
  4. 设置 SELinux 布尔值:

    # setsebool -P pcp_bind_all_unreserved_ports on
  5. 启用 pmcdpmlogger 服务:

    # systemctl enable pmcd pmlogger
    # systemctl restart pmcd pmlogger

验证步骤

  • 验证 pmcd 是否正确侦听配置的 IP 地址:

    # ss -tlp | grep 44321
    LISTEN   0   5     127.0.0.1:44321   0.0.0.0:*   users:(("pmcd",pid=151595,fd=6))
    LISTEN   0   5  192.168.4.62:44321   0.0.0.0:*   users:(("pmcd",pid=151595,fd=0))
    LISTEN   0   5         [::1]:44321      [::]:*   users:(("pmcd",pid=151595,fd=7))

其它资源

7.5. 设置中央服务器以收集数据

这个步骤描述了如何创建中央服务器从运行 PCP 的客户端收集指标。

流程

  1. 安装 pcp-system-tools 软件包:

    # yum install pcp-system-tools
  2. 使用以下内容创建 /etc/pcp/pmlogger/control.d/remote 文件:

    # DO NOT REMOVE OR EDIT THE FOLLOWING LINE
    $version=1.1
    
    192.168.4.13 n n PCP_LOG_DIR/pmlogger/rhel7u4a -r -T24h10m -c config.rhel7u4a
    192.168.4.14 n n PCP_LOG_DIR/pmlogger/rhel6u10a -r -T24h10m -c config.rhel6u10a
    192.168.4.62 n n PCP_LOG_DIR/pmlogger/rhel8u1a -r -T24h10m -c config.rhel8u1a

    使用客户端 IP 地址替换 192.168.4.13192.168.4.14192.168.4.62

  3. 启用 pmcdpmlogger 服务:

    # systemctl enable pmcd pmlogger
    # systemctl restart pmcd pmlogger

验证步骤

  • 确保您可以从每个目录中访问最新的归档文件:

    # for i in /var/log/pcp/pmlogger/rhel*/*.0; do pmdumplog -L $i; done
    Log Label (Log Format Version 2)
    Performance metrics from host rhel6u10a.local
      commencing Mon Nov 25 21:55:04.851 2019
      ending     Mon Nov 25 22:06:04.874 2019
    Archive timezone: JST-9
    PID for pmlogger: 24002
    Log Label (Log Format Version 2)
    Performance metrics from host rhel7u4a
      commencing Tue Nov 26 06:49:24.954 2019
      ending     Tue Nov 26 07:06:24.979 2019
    Archive timezone: CET-1
    PID for pmlogger: 10941
    [..]

    /var/log/pcp/pmlogger/ 目录中的归档文件可用于进一步分析和图表。

其它资源

7.6. 使用 pmdumptext 回放 PCP 日志存档

记录指标数据后,您可以重播 PCP 日志存档。要将日志导出到文本文件并将其导入到电子表格中,请使用 PCP 工具,如 pmdumptextpmreppmlogsummary

使用 pmdumptext 工具,您可以:

  • 查看日志文件
  • 解析所选 PCP 日志归档并将值导出到 ASCII 表
  • 通过在命令行中指定个别指标来提取整个存档日志或仅从日志中选择指标值

先决条件

流程

  • 显示指标上的数据:

    $ pmdumptext -t 5seconds -H -a 20170605 xfs.perdev.log.writes
    
    Time local::xfs.perdev.log.writes["/dev/mapper/fedora-home"] local::xfs.perdev.log.writes["/dev/mapper/fedora-root"]
    ? 0.000 0.000
    none count / second count / second
    Mon Jun 5 12:28:45 ? ?
    Mon Jun 5 12:28:50 0.000 0.000
    Mon Jun 5 12:28:55 0.200 0.200
    Mon Jun 5 12:29:00 6.800 1.000

    以上示例显示归档中以 5 秒间隔收集的 xfs.perdev.log 指标数据,并显示所有标头。

其它资源

第 8 章 使用 Performance Co-Pilot 监控性能

Performance Co-Pilot(PCP)是一组用于监控、可视化、存储和分析系统级性能测量的工具、服务和库。

作为系统管理员,您可以使用 Red Hat Enterprise Linux 8 中的 PCP 应用程序监控系统性能。

8.1. 使用 pmda-postfix 监控 postfix

这个步骤描述了如何使用 pmda-postfix 监控 postfix 邮件服务器的性能指标。有助于检查每秒收到的电子邮件数量。

流程

  1. 安装以下软件包:

    1. 安装 pcp-system-tools

      # yum install pcp-system-tools
    2. 安装 pmda-postfix 软件包以监控 postfix

      # yum install pcp-pmda-postfix postfix
    3. 安装日志记录守护进程:

      # yum install rsyslog
    4. 安装邮件客户端进行测试:

      # yum install mutt
  2. 启用 postfixrsyslog 服务:

    # systemctl enable postfix rsyslog
    # systemctl restart postfix rsyslog
  3. 启用 SELinux 布尔值,以便 pmda-postfix 可以访问所需的日志文件:

    # setsebool -P pcp_read_generic_logs=on
  4. 安装 PMDA

    # cd /var/lib/pcp/pmdas/postfix/
    
    # ./Install
    
    Updating the Performance Metrics Name Space (PMNS) ...
    Terminate PMDA if already installed ...
    Updating the PMCD control file, and notifying PMCD ...
    Waiting for pmcd to terminate ...
    Starting pmcd ...
    Check postfix metrics have appeared ... 7 metrics and 58 values

验证步骤

  • 验证 pmda-postfix 操作:

    echo testmail | mutt root
  • 验证可用的指标:

    # pminfo postfix
    
    postfix.received
    postfix.sent
    postfix.queues.incoming
    postfix.queues.maildrop
    postfix.queues.hold
    postfix.queues.deferred
    postfix.queues.active

其它资源

8.2. 使用 PCP Charts 应用以视觉方式追踪 PCP 日志归档

记录指标数据后,您可以将 PCP 日志存档重播为图形。指标来自一个或多个实时主机,提供备选选项,以将 PCP 日志存档的指标数据用作历史数据源。要自定义 PCP Charts 应用界面来显示性能指标中的数据,您可以使用折线图表、条形图或利用率图。

使用 PCP Charts 应用程序,您可以:

  • 重播 PCP Charts 应用中的数据,并使用图表来视觉化恢复数据以及系统的实时数据。
  • 将性能指标值绘制为图形。
  • 同时显示多个图表。

先决条件

流程

  1. 从命令行启动 PCP Charts 应用程序:

    # pmchart

    图 8.1. PCP Charts 应用程序

    pmchart 已启动

    pmtime 服务器设置位于底部。通过 startpause 按钮,您可以控制:

    • PCP 轮询指标数据的时间间隔
    • 历史数据指标的日期和时间
  2. 单击 File,然后单击 New Chart,以通过指定本地计算机和远程计算机的主机名或地址从本地计算机和远程计算机选择指标。高级配置选项包括手动设置 chart 的轴值以及手动选择图表颜色的功能。
  3. 记录 PCP Charts 应用程序中创建的视图:

    以下是获取镜像或记录 PCP Charts 应用程序中创建视图的选项:

    • 单击 File,然后单击 Export 以保存当前视图的镜像。
    • 单击 Record ,然后开始记录。单击 Record,然后单击 Stop 以停止记录。停止记录后,记录的指标会被存档以供稍后查看。
  4. 可选:在 PCP Charts 应用程序中,主配置文件(称为 视图 )允许保存与一个或多个 chart 关联的元数据。这个元数据描述了所有 Chart 方面,包括使用的指标和 chart 列。单击 File,然后单击 Save View ,再加载查看配置,以保存自定义视图 配置

    以下 PCP Charts 应用视图配置文件示例描述了一个堆栈图表,其中显示了读取和写入给定 XFS 文件系统的字节总数 loop1:

    #kmchart
    version 1
    
    chart title "Filesystem Throughput /loop1" style stacking antialiasing off
        plot legend "Read rate"   metric xfs.read_bytes   instance  "loop1"
        plot legend "Write rate"  metric xfs.write_bytes  instance  "loop1"

其它资源

8.3. 使用 PCP 从 SQL 服务器收集数据

在 Red Hat Enterprise Linux 8.2 或更高版本中,SQL 服务器代理包括在 Performance Co-Pilot(PCP)中,这可帮助您监控和分析数据库性能问题。

这个步骤描述了如何通过系统中的 pcp 为 Microsoft SQL Server 收集数据。

先决条件

  • 您已安装了用于红帽企业 Linux 的 Microsoft SQL Server 并建立了与 SQL 服务器的"可信"连接。
  • 您已安装了适用于红帽企业 Linux 的 SQL Server 的 Microsoft ODBC 驱动程序。

流程

  1. 安装 PCP:

    # yum install pcp-zeroconf
  2. 安装 pyodbc 驱动程序所需的软件包:

    # yum install gcc-c++ python3-devel unixODBC-devel
    
    $ pip3 install pyodbc
  3. 安装 mssql 代理:

    1. 为 PCP 安装 Microsoft SQL Server 域代理:

      # yum install pcp-pmda-mssql
    2. 编辑 /var/lib/pcp/pmdas/mssql/mssql.conf 文件,为 mssql 代理配置 SQL 服务器帐户的用户名和密码。确保您配置的帐户具有对性能数据的访问权限。

      username: user_name
      password: user_password

      使用 SQL Server 帐户和 user_password 将 user_ name 替换为此帐户的 SQL Server 用户密码。

  4. 添加所需的权限:

    # chown root:root /var/lib/pcp/pmdas/mssql/mssql.conf
    # chmod 400 /var/lib/pcp/pmdas/mssql/mssql.conf
  5. 安装代理:

    # cd /var/lib/pcp/pmdas/mssql
    # ./Install
    Updating the Performance Metrics Name Space (PMNS) ...
    Terminate PMDA if already installed ...
    Updating the PMCD control file, and notifying PMCD ...
    Check mssql metrics have appeared ... 168 metrics and 598 values
    [...]

验证步骤

  • 使用 pcp 命令,验证 SQL Server PMDA(mssql)是否已加载并在运行:

    $ pcp
    Performance Co-Pilot configuration on rhel.local:
    
    platform: Linux rhel.local 4.18.0-167.el8.x86_64 #1 SMP Sun Dec 15 01:24:23 UTC 2019 x86_64
     hardware: 2 cpus, 1 disk, 1 node, 2770MB RAM
     timezone: PDT+7
     services: pmcd pmproxy
         pmcd: Version 5.0.2-1, 12 agents, 4 clients
         pmda: root pmcd proc pmproxy xfs linux nfsclient mmv kvm mssql
               jbd2 dm
     pmlogger: primary logger: /var/log/pcp/pmlogger/rhel.local/20200326.16.31
         pmie: primary engine: /var/log/pcp/pmie/rhel.local/pmie.log
  • 查看 PCP 可以从 SQL Server 收集的指标的完整列表:

    # pminfo mssql
  • 查看指标列表后,您可以报告事务率。例如,在 5 秒的窗口中报告每秒总交易数:

    # pmval -t 1 -T 5 mssql.databases.transactions
  • 使用 pmchart 命令查看系统中这些指标的图形图表。如需更多信息,请参阅使用 PCP Charts 应用程序可视化追踪 PCP 日志归档

其它资源

第 9 章 使用 PCP 的 XFS 的性能分析

XFS PMDA 作为 pcp 软件包的一部分提供,并在安装过程中默认启用。它用于在 Performance Co-Pilot(PCP)中收集 XFS 文件系统的性能指标数据。

这部分论述了如何使用 PCP 分析 XFS 文件系统的性能。

9.1. 手动安装 XFS PMDA

如果 pcp 配置输出中没有列出 XFS PMDA,请手动安装 PMDA 代理。

这个步骤描述了如何手动安装 PMDA 代理。

先决条件

流程

  1. 进入 xfs 目录:

    # cd /var/lib/pcp/pmdas/xfs/
  2. 手动安装 XFS PMDA:

    xfs]# ./Install
    
    You will need to choose an appropriate configuration for install of
    the “xfs” Performance Metrics Domain Agent (PMDA).
    
      collector     collect performance statistics on this system
      monitor       allow this system to monitor local and/or remote systems
      both          collector and monitor configuration for this system
    
    Please enter c(ollector) or m(onitor) or (both) [b]
    Updating the Performance Metrics Name Space (PMNS) ...
    Terminate PMDA if already installed ...
    Updating the PMCD control file, and notifying PMCD ...
    Waiting for pmcd to terminate ...
    Starting pmcd ...
    Check xfs metrics have appeared ... 149 metrics and 149 values
  3. 通过为收集器输入 c、为监控器输入 mb 来选择所需的 PMDA 角色。PMDA 安装脚本提示您指定以下 PMDA 角色之一:

    • collector 角色允许在当前系统中收集性能指标
    • monitor 角色允许系统监控本地系统、远程系统或两者

      默认选项是 collectormonitor,它允许 XFS PMDA 在大部分情况下正常工作。

验证步骤

  • 验证 pmcd 进程是否在主机上运行,并在配置中列为 enabled:

    # pcp
    
    Performance Co-Pilot configuration on workstation:
    
    platform: Linux workstation 4.18.0-80.el8.x86_64 #1 SMP Wed Mar 13 12:02:46 UTC 2019 x86_64
    hardware: 12 cpus, 2 disks, 1 node, 36023MB RAM
    timezone: CEST-2
    services: pmcd
    pmcd: Version 4.3.0-1, 8 agents
    pmda: root pmcd proc xfs linux mmv kvm jbd2

其它资源

9.2. 使用 pminfo 检查 XFS 性能指标

PCP 可让 XFS PMDA 允许为每个挂载的 XFS 文件系统报告某些 XFS 指标。这样更易于查明特定挂载的文件系统问题并评估性能。

pminfo 命令为每个挂载的 XFS 文件系统提供每个设备的 XFS 指标。

这个过程显示 XFS PMDA 提供的所有可用指标的列表。

先决条件

流程

  • 显示 XFS PMDA 提供的所有可用指标列表:

    # pminfo xfs
  • 显示单个指标的信息。以下示例使用 pminfo 工具检查特定的 XFS readwrite 指标:

    • 显示 xfs.write_bytes 指标的简短描述:

      # pminfo --oneline xfs.write_bytes
      
      xfs.write_bytes [number of bytes written in XFS file system write operations]
    • 显示 xfs.read_bytes 指标的长描述:

      # pminfo --helptext xfs.read_bytes
      
      xfs.read_bytes
      Help:
      This is the number of bytes read via read(2) system calls to files in
      XFS file systems. It can be used in conjunction with the read_calls
      count to calculate the average size of the read operations to file in
      XFS file systems.
    • 获取 xfs.read_bytes 指标的当前性能值:

      # pminfo --fetch xfs.read_bytes
      
      xfs.read_bytes
          value 4891346238
    • 使用 pminfo 获取每个设备的 XFS 指标:

      # pminfo --fetch --oneline xfs.perdev.read xfs.perdev.write
      
      xfs.perdev.read [number of XFS file system read operations]
      inst [0 or "loop1"] value 0
      inst [0 or "loop2"] value 0
      
      xfs.perdev.write [number of XFS file system write operations]
      inst [0 or "loop1"] value 86
      inst [0 or "loop2"] value 0

其它资源

9.3. 使用 pmstore 重置 XFS 性能指标

使用 PCP,您可以修改特定指标的值,特别是指标充当控制变量时,如 xfs.control.reset 指标。要修改指标值,请使用 pmstore 工具。

这个步骤描述了如何使用 pmstore 工具重置 XFS 指标。

先决条件

流程

  1. 显示指标值:

    $ pminfo -f xfs.write
    
    xfs.write
        value 325262
  2. 重置所有 XFS 指标:

    # pmstore xfs.control.reset 1
    
    xfs.control.reset old value=0 new value=1

验证步骤

  • 在重置指标后查看信息:

    $ pminfo --fetch xfs.write
    
    xfs.write
        value 0

其它资源

9.4. XFS 的 PCP 指标组

下表描述了 XFS 的可用 PCP 指标组。

表 9.1. XFS 的指标组

指标组

提供的指标

xfs.*

常规 XFS 指标,包括读取和写入操作计数、读取和写入字节计数。与计数器一起清空、群集化和群集失败次数的内节点数。

xfs.allocs.*

xfs.alloc_btree.*

有关在文件系统中分配对象的指标范围,其中包括扩展数目和块创建/释放。分配树查找,并与从 btree 中的扩展记录创建和删除进行比较。

xfs.block_map.*

xfs.bmap_tree.*

指标包括块映射读/写和块删除的数量,用于插入、删除和查找的扩展列表操作。另外,用于从 blockmap 中比较、查找、插入和删除操作的操作计数器。

xfs.dir_ops.*

XFS 文件系统中的目录操作计数器,用于创建、条目删除、"getdent"操作计数.

xfs.transactions.*

元数据事务计数器包括同步和异步交易数量计数,以及空事务的数量。

xfs.inode_ops.*

针对操作系统在索引节点缓存中查找具有不同结果的 XFS 索引节点的次数,计数器.这些计数缓存命中、缓存未命中等。

xfs.log.*

xfs.log_tail.*

通过 XFS 文件符号链接写入的日志缓冲区数量计数器包括写入到磁盘的块数。日志清空和固定数量的指标。

xfs.xstrat.*

XFS flush deamon 清除出的文件数据的字节数,以及刷新到磁盘上连续和非相邻空间的缓冲区数量。

xfs.attr.*

所有 XFS 文件系统上的属性 get、设置、删除和列出操作的数量。

xfs.quota.*

XFS 文件系统的配额操作指标包括配额重新声明数量的计数器、配额缓存未命中、缓存命中和配额数据重新声明。

xfs.buffer.*

有关 XFS 缓冲区对象的指标范围。计数器包括请求的缓冲区调用数量、成功缓冲区锁定、等待的缓冲区锁定、failure_locks、failure_retries 和 buffer hits(查找页面时)。

xfs.btree.*

有关 XFS btree 操作的指标。

xfs.control.reset

用于重置 XFS 统计的指标计数器的配置指标。控制指标通过 pmstore 工具切换。

9.5. XFS 的每设备 PCP 指标组

下表描述了 XFS 的每设备 PCP 指标组的可用情况。

表 9.2. XFS 的每设备 PCP 指标组

指标组

提供的指标

xfs.perdev.*

常规 XFS 指标,包括读取和写入操作计数、读取和写入字节计数。与计数器一起清空、群集化和群集失败次数的内节点数。

xfs.perdev.allocs.*

xfs.perdev.alloc_btree.*

有关在文件系统中分配对象的指标范围,其中包括扩展数目和块创建/释放。分配树查找,并与从 btree 中的扩展记录创建和删除进行比较。

xfs.perdev.block_map.*

xfs.perdev.bmap_tree.*

指标包括块映射读/写和块删除的数量,用于插入、删除和查找的扩展列表操作。另外,用于从 blockmap 中比较、查找、插入和删除操作的操作计数器。

xfs.perdev.dir_ops.*

XFS 文件系统的目录操作计数器,用于创建、条目删除、"getdent"操作计数.

xfs.perdev.transactions.*

元数据事务计数器包括同步和异步交易数量计数,以及空事务的数量。

xfs.perdev.inode_ops.*

针对操作系统在索引节点缓存中查找具有不同结果的 XFS 索引节点的次数,计数器.这些计数缓存命中、缓存未命中等。

xfs.perdev.log.*

xfs.perdev.log_tail.*

通过 XFS fileytems 写入日志缓冲区数量的计数器包括写入到磁盘的块数。日志清空和固定数量的指标。

xfs.perdev.xstrat.*

XFS flush deamon 清除出的文件数据的字节数,以及刷新到磁盘上连续和非相邻空间的缓冲区数量。

xfs.perdev.attr.*

所有 XFS 文件系统上的属性 get、设置、删除和列出操作的数量。

xfs.perdev.quota.*

XFS 文件系统的配额操作指标包括配额重新声明数量的计数器、配额缓存未命中、缓存命中和配额数据重新声明。

xfs.perdev.buffer.*

有关 XFS 缓冲区对象的指标范围。计数器包括请求的缓冲区调用数量、成功缓冲区锁定、等待的缓冲区锁定、failure_locks、failure_retries 和 buffer hits(查找页面时)。

xfs.perdev.btree.*

有关 XFS btree 操作的指标。

第 10 章 设置 PCP 指标的图形表示

根据 Performance Co-Pilot(PCP)收集的实时数据或数据,使用 pcpgrafanapcp redispcp bpftracepcp vector 的组合提供图形。

这部分论述了如何设置和访问 PCP 指标的图形表示。

10.1. 使用 pcp-zeroconf 设置 PCP

这个步骤描述了如何在带有 pcp-zeroconf 软件包的系统中设置 PCP。安装 pcp-zeroconf 软件包后,系统会将默认指标集记录到存档文件中。

流程

  • 安装 pcp-zeroconf 软件包:

    # yum install pcp-zeroconf

验证步骤

  • 确保 pmlogger 服务活跃,并开始归档指标:

    # pcp | grep pmlogger
     pmlogger: primary logger: /var/log/pcp/pmlogger/localhost.localdomain/20200401.00.12

其它资源

10.2. 设置 grafana-server

Grafana 生成可通过浏览器访问的图形。grafana-server 是 Grafana 仪表板的后端服务器。默认情况下,它侦听所有接口,并提供通过 Web 浏览器访问的 Web 服务。grafana-pcp 插件与后端中的 pmproxy 协议交互。

这个步骤描述了如何设置 grafana-server

流程

  1. 安装以下软件包:

    # yum install grafana grafana-pcp
  2. 重启并启用以下服务:

    # systemctl restart grafana-server
    # systemctl enable grafana-server

验证步骤

  • 确保 grafana-server 正在侦听请求并响应:

    # ss -ntlp | grep 3000
    LISTEN  0  128  *:3000  *:*  users:(("grafana-server",pid=19522,fd=7))
  • 确定安装了 grafana-pcp 插件:

    # grafana-cli plugins ls | grep performancecopilot-pcp-app
    
    performancecopilot-pcp-app @ 3.0.2

其它资源

  • pmproxy(1)grafana-server man page

10.3. 访问 Grafana Web UI

此流程描述了如何访问 Grafana Web 界面。

使用 Grafana web 界面,您可以:

  • 添加 PCP Redis、PCP bpftrace 和 PCP Vector 数据源
  • 创建仪表板
  • 查看任何有用的指标的概述
  • 在 PCP Redis 中创建警报

流程

  1. 在客户端系统中,打开浏览器并使用 grafana-server :3000 链接在端口 3000 上访问。

    192.0.2.0 替换为您的机器 IP。

  2. 若要进行第一次登录,请在 Email 或 usernamePassword 字段中输入 admin

    Grafana 会提示设置新密码以创建安全帐户。如果要稍后设置它,请点击 Skip

  3. 在菜单中,把鼠标移到 grafana gear icon Configuration 图标上,然后点击 Plugins
  4. Plugins 选项卡中,在 Search by name 或键入文本框中键入 performance co-pilot,然后单击 Performance Co-Pilot (PCP)插件。
  5. Plugins / Performance Co-Pilot 窗格中,单击 Enable
  6. 点击 Grafana grafana home page whirl icon 图标。此时会显示 Grafana Home 页面。

    图 10.1. 主仪表板

    Grafana 主页仪表板
    注意

    该屏幕的右上角有一个类似的 grafana top corner settings icon 图标,但它控制常规仪表板设置

  7. 在 Grafana Home 页面中,点 Add your first data source 添加 PCP Redis、PCP bpftrace 和 PCP Vector 数据源。有关添加数据源的更多信息,请参阅:

  8. 可选:在菜单中,把鼠标移到 admin 配置集 grafana logout option icon 图标上以更改 Preferences,包括 Edit Profile、changePasswordSign out

其它资源

  • grafana-cligrafana-server man page

10.4. 配置 PCP Redis

本节提供有关配置 PCP Redis 数据源的信息。

使用 PCP Redis 数据源来:

  • 查看数据归档
  • 使用 pmseries 语言查询时间序列
  • 分析多个主机间的数据

流程

  1. 安装 redis 软件包:

    # yum install redis
  2. 启动并启用以下服务:

    # systemctl start pmproxy redis
    # systemctl enable pmproxy redis
  3. 已安装并配置了邮件传输代理,例如 sendmailpostfix
  4. 确保 allow_loading_unsigned_plugins 参数在 grafana.ini 文件中被设置为 PCP Redis 数据库:

    # vi /etc/grafana/grafana.ini
    
    allow_loading_unsigned_plugins = pcp-redis-datasource
  5. 重启 grafana-server

    # systemctl restart grafana-server

验证步骤

  • 确保 pmproxyredis 正常工作:

    # pmseries disk.dev.read
    2eb3e58d8f1e231361fb15cf1aa26fe534b4d9df

    如果没有安装 redis 软件包,这个命令不会返回任何数据。

其它资源

  • pmseries(1) man page

10.5. 在 PCP Redis 数据源中创建面板和警报

添加 PCP Redis 数据源后,您可以使用有用的指标概述来查看仪表板,添加查询来视觉化负载图,并创建警报以帮助您在出现系统问题后查看系统问题。

先决条件

  1. 配置了 PCP Redis。如需更多信息,请参阅配置 PCP Redis
  2. grafana-server 可以访问。如需更多信息,请参阅访问 Grafana Web UI

流程

  1. 登录到 Grafana web UI。
  2. 在 Grafana Home 页面中,点 Add your first data source
  3. Add data source 窗格中,在 Filter by name 或键入文本框中键入 redis,然后单击 PCP Redis
  4. Data Sources / PCP Redis 窗格中,执行以下操作:

    1. URL 字段中添加 http://localhost:44322,然后点 Save & Test
    2. Dashboards 选项卡ImportPCP Redis: Host Overview,查看包含任何有用指标概述的仪表板。

      图 10.2. PCP Redis:主机概述

      pcp redis 主机概述
  5. 添加新面板:

    1. 在菜单中,把鼠标移到Create 图标DashboardAdd new panel 图标
    2. Query 选项卡中,从查询列表中选择 PCP Redis ,而不是选择的默认选项,在 A 的文本字段中输入 metric,例如 kernel.all.load 用于视觉化内核负载图形。
    3. 可选:添加面板标题和 描述,以及更新 Settings 中的其他选项。
    4. 单击 Save 以应用更改并保存仪表板添加仪表板名称.
    5. 单击 Apply 以应用更改,再返回到仪表板。

      图 10.3. pcp Redis 查询面板

      pcp redis 查询面板
  6. 创建警报规则:

    1. PCP Redis 查询面板中,点 redis alert icon Alert,然后点击 Create Alert
    2. 编辑 Rule 中的 Name 、Evaluate查询和 For 字段,并指定警报的条件
    3. 单击 Save 以应用更改并保存仪表板。单击 Apply 以应用更改,再返回到仪表板。

      图 10.4. 在 PCP Redis 面板中创建警报

      pcp redis 查询警报面板
    4. 可选:在同一面板中,向下滚动并点击 Delete 图标删除创建的规则。
    5. 可选:从菜单中点击 alerting bell icon Alerting 图标查看创建的具有不同警报状态的警报规则,编辑警报规则,或者从 Alert Rules 标签页中暂停现有规则。

      要为创建的警报规则添加通知频道以从 Grafana 接收警报通知,请参阅为警报添加通知频道

10.6. 为警报添加通知频道

通过添加通知频道,您可以在满足警报规则条件且系统需要进一步监控时收到来自 Grafana 的警报通知。

您可以从支持的通知列表中选择一个类型后接收这些警报,其中包括 DingDing、D iscord、电子邮件、Google Hangouts Chat、HipChatKafka REST Proxy 、LINE、Microsoft 团队、OptosGenie、PagerDuty、Prometheus Alertmanager、Pustom Alertmanager、Pensu Slack、Tlack、Thlegram、Threema Gateway、VicctorOpswebhook

先决条件

  1. grafana-server 可以访问。如需更多信息,请参阅访问 Grafana Web UI
  2. 已创建一个警报规则。如需更多信息,请参阅在 PCP Redis 数据源中创建面板和警报
  3. 配置 SMTP 并在 grafana/grafana.ini 文件中添加有效的发件人电子邮件地址:

    # vi /etc/grafana/grafana.ini
    
    [smtp]
    enabled = true
    from_address = abc@gmail.com

    使用有效的电子邮件地址替换

流程

  1. 在菜单中,把鼠标移到Alerting 图标上 点通知频道
  2. 在 Add notification channel details 窗格中,执行以下操作:

    1. Name 文本框中输入您的名称
    2. 选择通信类型,例如 Email 并输入电子邮件地址。您可以使用 ; 分隔符添加多个电子邮件地址。
    3. 可选:配置可选电子邮件设置 和通知设置
  3. Save
  4. 在警报规则中选择一个通知频道:

    1. 在菜单中,把鼠标移到 alerting bell icon Alerting 图标上,然后点击 Alert rules
    2. Alert Rules 选项卡,单击创建的警报规则。
    3. Notifications 选项卡上,从 Send to 选项选择您的通知频道名称,然后添加警报消息。
    4. 应用

10.7. 在 PCP 组件间设置身份验证

您可以使用 scram-sha-256 身份验证机制设置验证,PCP 通过简单身份验证层(SASL)框架支持这个机制。

注意

在 Red Hat Enterprise Linux 8.3 中,PCP 支持 scram-sha-256 身份验证机制。

流程

  1. scram-sha-256 身份验证机制安装 sasl 框架:

    # yum install cyrus-sasl-scram cyrus-sasl-lib
  2. 指定 pmcd.conf 文件中支持的身份验证机制和用户数据库路径:

    # vi /etc/sasl2/pmcd.conf
    
    mech_list: scram-sha-256
    
    sasldb_path: /etc/pcp/passwd.db
  3. 创建一个新用户:

    # useradd -r metrics

    使用您的用户名替换指标

  4. 在用户数据库中添加创建的用户:

    # saslpasswd2 -a pmcd metrics
    
    Password:
    Again (for verification):

    要添加创建的用户,您需要输入指标帐户密码

  5. 设置用户数据库的权限:

    # chown root:pcp /etc/pcp/passwd.db
    # chmod 640 /etc/pcp/passwd.db
  6. 重启 pmcd 服务:

    # systemctl restart pmcd

验证步骤

  • 验证 sasl 配置:

    # pminfo -f -h "pcp://127.0.0.1?username=metrics" disk.dev.read
    Password:
    disk.dev.read
    inst [0 or "sda"] value 19540

10.8. 安装 PCP bpftrace

安装 PCP bpftrace 代理来内省系统并从内核和用户空间追踪点收集指标。

bpftrace 代理使用 bpftrace 脚本来收集指标数据。bpftrace 脚本使用增强的 Berkeley Packet 过滤器(eBPF)。

这个步骤描述了如何安装 pcp bpftrace

先决条件

  1. 配置了 PCP。如需更多信息,请参阅使用 pcp-zeroconf 设置 PCP
  2. grafana-server 已配置。如需更多信息,请参阅设置 grafana-server
  3. 配置了 scram-sha-256 身份验证机制。如需更多信息,请参阅在 PCP 组件间设置身份验证

流程

  1. 安装 pcp-pmda-bpftrace 软件包:

    # yum install pcp-pmda-bpftrace
  2. 编辑 bpftrace.conf 文件并添加您在 {setting-up-authentication-betwe between-pcp-components} 中创建的用户:

    # vi /var/lib/pcp/pmdas/bpftrace/bpftrace.conf
    
    [dynamic_scripts]
    enabled = true
    auth_enabled = true
    allowed_users = root,metrics

    使用您的用户名替换指标

  3. 安装 bpftrace PMDA:

    # cd /var/lib/pcp/pmdas/bpftrace/
    # ./Install
    Updating the Performance Metrics Name Space (PMNS) ...
    Terminate PMDA if already installed ...
    Updating the PMCD control file, and notifying PMCD ...
    Check bpftrace metrics have appeared ... 7 metrics and 6 values

    pmda-bpftrace 现已安装,且只能在验证您的用户后使用。如需更多信息,请参阅查看 PCP bpftrace 系统分析仪表板

其它资源

  • pmdabpftrace(1)bpftrace man page

10.9. 查看 PCP bpftrace 系统分析仪表板

使用 PCP bpftrace 数据源,您可以从 pmlogger 或存档中不提供常规数据的源访问实时数据

在 PCP bpftrace 数据源中,您可以使用有用的指标概述来查看仪表板。

先决条件

  1. 已安装 PCP bpftrace。如需更多信息,请参阅安装 PCP bpftrace
  2. grafana-server 可以访问。如需更多信息,请参阅访问 Grafana Web UI

流程

  1. 登录到 Grafana web UI。
  2. 在 Grafana Home 页面中,点 Add your first data source
  3. Add data source 窗格中,在 Filter by name 中键入 bpftrace,或者键入文本框,然后单击 PCP bpftrace
  4. Data Sources / PCP bpftrace 窗格中,执行以下操作:

    1. URL 字段中添加 http://localhost:44322
    2. 切换 Basic Auth 选项,并在 UserPassword 字段中添加创建的用户凭据
    3. 点击 Save & Test

      图 10.5. 在数据源中添加 PCP bpftrace

      bpftrace auth
    4. Dashboards 选项卡ImportPCP bpftrace: System Analysis,以查看包含任何有用指标概述的仪表板。

      图 10.6. pcp bpftrace: 系统分析

      pcp bpftrace bpftrace 系统分析

10.10. 安装 PCP 向量

这个步骤描述了如何安装 pcp vector

流程

  1. 安装 pcp-pmda-bcc 软件包:

    # yum install pcp-pmda-bcc
  2. 安装 bcc PMDA:

    # cd /var/lib/pcp/pmdas/bcc
    # ./Install
    [Wed Apr  1 00:27:48] pmdabcc(22341) Info: Initializing, currently in 'notready' state.
    [Wed Apr  1 00:27:48] pmdabcc(22341) Info: Enabled modules:
    [Wed Apr  1 00:27:48] pmdabcc(22341) Info: ['biolatency', 'sysfork',
    [...]
    Updating the Performance Metrics Name Space (PMNS) ...
    Terminate PMDA if already installed ...
    Updating the PMCD control file, and notifying PMCD ...
    Check bcc metrics have appeared ... 1 warnings, 1 metrics and 0 values

其它资源

  • pmdabcc(1) man page

10.11. 查看 PCP 向量检查列表

PCP Vector 数据源显示实时指标数据,并使用 pcp 指标。它分析各个主机的数据。

添加 PCP Vector 数据源后,您可以使用有用的指标概述来查看仪表板,并查看清单中的相关故障排除或参考链接。

先决条件

  1. 已安装 PCP Vector。如需更多信息,请参阅安装 PCP Vector
  2. grafana-server 可以访问。如需更多信息,请参阅访问 Grafana Web UI

流程

  1. 登录到 Grafana web UI。
  2. 在 Grafana Home 页面中,点 Add your first data source
  3. Add data source 窗格中,键入 Filter by name 或键入文本框中的向量,然后点击 PCP Vector
  4. Data Sources / PCP Vector 窗格中,执行以下操作:

    1. URL 字段中添加 http://localhost:44322,然后点 Save & Test
    2. Dashboards 选项卡ImportPCP Vector: Host Overview 查看包含任何有用指标概述的仪表板。

      图 10.7. pcp 向量:主机概述

      PCP 向量主机概述
  5. 从菜单中,把鼠标悬停在 pcp plugin in grafana Performance Co-Pilot 插件上,然后单击 PCP Vector Checklist

    在 PCP 清单中,点击 pcp vector checklist troubleshooting doc 帮助或 pcp vector checklist warning 警告图标查看相关的故障排除或参考链接。

    图 10.8. Performance Co-Pilot / PCP Vector Checklist

    PCP 向量清单

第 11 章 使用 web 控制台优化系统性能

了解如何在 RHEL 8 web 控制台中设置性能配置集,以便为所选任务优化系统性能。

11.1. Web 控制台中的性能调优选项

Red Hat Enterprise Linux 8 提供几个根据以下任务优化系统的性能配置集:

  • 使用桌面的系统
  • 吞吐性能
  • 延迟性能
  • 网络性能
  • 低电源消耗
  • 虚拟机

tuned 服务优化系统选项以匹配所选配置集。

在 Web 控制台中,您可以设置系统使用的哪个性能配置集。

其它资源

11.2. 在 Web 控制台中设置性能配置集

此流程使用 Web 控制台优化所选任务的系统性能。

先决条件

流程

  1. 登录到 RHEL 8 web 控制台。详情请参阅 Web 控制台的日志记录
  2. Overview
  3. Performance Profile 字段中点击当前的性能配置集。

    cockpit performance profile pf4

  4. 如果需要,在 Change Performance Profile 对话框中修改配置集。
  5. Change Profile

    cockpit performance profile change pf4

验证步骤

  • 概述标签现在显示所选的性能配置集。

11.3. 使用 Web 控制台监控性能

红帽的 Web 控制台使用 Utilization Saturation and Errors(USE)方法进行故障排除。新的性能指标页面具有按时间顺序组织的最新数据的历史视图。

您可以在此处查看事件、错误和图形表示,以了解资源利用率和饱和度。

先决条件

  1. 确保 Web 控制台已安装并可以访问。详情请参阅 安装 Web 控制台
  2. 安装 cockpit-pcp 软件包,它将启用收集性能指标:

    # yum install cockpit-pcp

流程

  1. 登录到 RHEL 8 web 控制台。详情请参阅 Web 控制台的日志记录
  2. Overview

    Web console Overview

  3. 点击 View details 和 history 查看 Performance Metrics

    View details and history

    Performance metrics in Web console

第 12 章 设置磁盘调度程序

磁盘调度程序负责订购提交至存储设备的 I/O 请求。

您可以通过几种不同方式配置调度程序:

注意

在 Red Hat Enterprise Linux 8 中,块设备只支持多队列调度。这可让块层性能针对使用快速固态驱动器(SSD)和多核系统进行正常扩展。

Red Hat Enterprise Linux 7 及更早版本中提供的传统的单队列调度程序已被删除。

12.1. 可用磁盘调度程序

Red Hat Enterprise Linux 8 支持以下多队列磁盘调度程序:

none
实施一向先出(FIFO)调度算法。它通过简单的最后一个缓存合并通用块层的请求。
mq-deadline

尝试从请求到达调度程序时起为请求提供保证的延迟。

mq-deadline 调度程序将排队的 I/O 请求排序为读或写批处理,然后调度它们以增加逻辑块寻址(LBA)顺序来执行。默认情况下,读取批处理优先于写入批处理,因为应用更有可能阻止读取 I/O 操作。mq-deadline 处理批处理后,它会检查处理器时间不足的时间,并根据情况调度下一个读取或写入批处理。

此调度程序适用于大多数用例,特别是写操作大部分异步的情况。

bfq

以桌面系统和互动任务为目标。

bfq 调度程序确保单个应用程序永远不会使用所有带宽。实际上,存储设备总是像它们处于闲置时一样进行响应。在默认配置中,bfq 着重提供最低延迟,而不是实现最大吞吐量。

bfq 基于 cfq 代码。它不会为每个进程分配一个固定时间片段的磁盘,而是以扇区数为进程分配一个预算

此调度程序适合用于复制大型文件,在这种情况下,系统也不会变得无响应。

kyber

调度程序通过计算提交至块 I/O 层的每个 I/O 请求的延迟来调整自身以达到延迟目标。如果出现缓存缺少和同步写入请求,您可以为读取配置目标延迟。

这个调度程序适合快速设备,如 NVMe、SSD 或其他低延迟设备。

12.2. 不同用例的不同磁盘调度程序

根据您的系统执行的任务,在分析和调整任务之前,建议使用以下磁盘调度程序作为基准:

表 12.1. 适用于不同用例的磁盘调度程序

使用案例磁盘调度程序

传统的使用 SCSI 接口的 HDD

使用 mq-deadlinebfq

高性能 SSD 或具有快速存储的 CPU 绑定系统

使用 none,特别是在运行企业级应用程序时。另外,还可使用 kyber

桌面或互动任务

使用 bfq

虚拟客户端

使用 mq-deadline。对于支持多队列的主机总线适配器(HBA)驱动程序,请使用 none

12.3. 默认磁盘调度程序

块设备使用默认磁盘调度程序,除非您指定了另一个调度程序。

注意

对于 non-volatile Memory Express (NVMe) 块设备,默认调度程序是 none,红帽建议不要更改它。

内核根据设备类型选择默认磁盘调度程序。自动选择的调度程序通常是最佳设置。如果您需要不同的调度程序,红帽建议使用 udev 规则或 Tuned 应用程序进行配置。匹配所选设备并只为那些设备切换调度程序。

12.4. 确定活跃磁盘调度程序

此流程决定了哪个磁盘调度程序目前在给定块设备中活跃。

流程

  • 阅读 /sys/block/device/queue/scheduler 文件的内容:

    # cat /sys/block/device/queue/scheduler
    
    [mq-deadline] kyber bfq none

    在文件名中,使用块设备名称替换 device,例如 sdc

    活跃调度程序列在方括号([ ])中。

12.5. 使用 Tuned 设置磁盘调度程序

此流程创建并启用 Tuned 配置集,该配置集为所选块设备设置给定磁盘调度程序。这个设置会在系统重启后保留。

在以下命令和配置中替换:

  • 带有块设备名称的设备,例如: sdf
  • 带有您要为该设备设置的磁盘调度程序的 selected-scheduler,例如 bfq

先决条件

流程

  1. 可选:选择一个您配置集将要基于的现有 Tuned 配置集。有关可用配置集列表,请参阅 RHEL 提供的 Tuned 配置集

    要查看哪个配置集当前处于活跃状态,请使用:

    $ tuned-adm active
  2. 创建一个新目录来保存您的 Tuned 配置集:

    # mkdir /etc/tuned/my-profile
  3. 查找所选块设备系统唯一标识符:

    $ udevadm info --query=property --name=/dev/device | grep -E '(WWN|SERIAL)'
    
    ID_WWN=0x5002538d00000000_
    ID_SERIAL=Generic-_SD_MMC_20120501030900000-0:0
    ID_SERIAL_SHORT=20120501030900000
    注意

    本例中的 命令将返回标识为全局名称(WWN)或与指定块设备关联的序列号的所有值。虽然最好使用 WWN,但 WWN 并不总是可用于给定设备,示例命令返回的任何值都可用作设备系统唯一 ID

  4. 创建 /etc/tuned/my-profile/tuned.conf 配置文件。在该文件中设置以下选项:

    1. 可选:包含现有配置集:

      [main]
      include=existing-profile
    2. 为与 WWN 标识符匹配的设备设置所选磁盘调度程序:

      [disk]
      devices_udev_regex=IDNAME=device system unique id
      elevator=selected-scheduler

      在这里:

      • 使用正在使用的标识符的名称替换 IDNAME (例如 ID_WWN)。
      • 将设备系统唯一 id 替换为所选标识符的值(例如 0x5002538d00000000)。

        要匹配 devices_udev_regex 选项中的多个设备,请将标识符括在括号中,并使用竖线分隔它们:

        devices_udev_regex=(ID_WWN=0x5002538d00000000)|(ID_WWN=0x1234567800000000)
  5. 启用您的配置集:

    # tuned-adm profile my-profile

验证步骤

  • 验证 Tuned 配置集是否活跃并应用:

    $ tuned-adm active
    
    Current active profile: my-profile
    $ tuned-adm verify
    
    Verification succeeded, current system settings match the preset profile.
    See tuned log file ('/var/log/tuned/tuned.log') for details.

12.6. 使用 udev 规则设置磁盘调度程序

此流程使用 udev 规则为特定块设备设置给定磁盘调度程序。这个设置会在系统重启后保留。

在以下命令和配置中替换:

  • 带有块设备名称的设备,例如: sdf
  • 带有您要为该设备设置的磁盘调度程序的 selected-scheduler,例如 bfq

流程

  1. 查找块设备系统唯一标识符:

    $ udevadm info --name=/dev/device | grep -E '(WWN|SERIAL)'
    E: ID_WWN=0x5002538d00000000
    E: ID_SERIAL=Generic-_SD_MMC_20120501030900000-0:0
    E: ID_SERIAL_SHORT=20120501030900000
    注意

    本例中的 命令将返回标识为全局名称(WWN)或与指定块设备关联的序列号的所有值。虽然最好使用 WWN,但 WWN 并不总是可用于给定设备,示例命令返回的任何值都可用作设备系统唯一 ID

  2. 配置 udev 规则。使用以下内容创建 /etc/udev/rules.d/99-scheduler.rules 文件:

    ACTION=="add|change", SUBSYSTEM=="block", ENV{IDNAME}=="device system unique id", ATTR{queue/scheduler}="selected-scheduler"

    在这里:

    • 使用正在使用的标识符的名称替换 IDNAME (例如 ID_WWN)。
    • 将设备系统唯一 id 替换为所选标识符的值(例如 0x5002538d00000000)。
  3. 重新载入 udev 规则:

    # udevadm control --reload-rules
  4. 应用调度程序配置:

    # udevadm trigger --type=devices --action=change

验证步骤

  • 验证活跃的调度程序:

    # cat /sys/block/device/queue/scheduler

12.7. 为特定磁盘临时设置调度程序

此流程为特定块设备设置给定磁盘调度程序。系统重启后该设置不会保留。

流程

  • 将所选调度程序的名称写入 /sys/block/device/queue/scheduler 文件:

    # echo selected-scheduler > /sys/block/device/queue/scheduler

    在文件名中,使用块设备名称替换 device,例如 sdc

验证步骤

  • 验证调度程序是否在该设备中活跃:

    # cat /sys/block/device/queue/scheduler

第 13 章 调整 Samba 服务器的性能

本章论述了在某些情况下,什么设置可以提高 Samba 的性能,以及哪些设置可能会对性能造成负面影响。

本节的部分内容来自在 Samba Wiki 中发布的 Performance Tuning 文档。许可证: CC BY 4.0。作者和贡献者:请参阅 Wiki 页面上的历史记录选项卡

先决条件

13.1. 设置 SMB 协议版本

每个新的 SMB 版本都会添加功能并提高协议的性能。最新的 Windows 和 Windows 服务器操作系统始终支持最新的协议版本。如果 Samba 还使用最新的协议版本,则连接 Samba 的 Windows 客户端可从性能改进中受益。在 Samba 中,服务器 max 协议的默认值被设置为最新支持的 stable SMB 协议版本。

注意

要总是启用最新的 stable SMB 协议版本,请不要设置 server max protocol 参数。如果手动设置 参数,则需要修改 SMB 协议的每个新版本的设置,以启用最新的协议版本。

以下流程解释了如何使用 server max protocol 参数中的默认值。

流程

  1. /etc/samba/smb.conf 文件中的 [global] 部分删除 server max protocol 参数。
  2. 重新载入 Samba 配置

    # smbcontrol all reload-config

13.2. 与包含大量文件的目录调整共享

Linux 支持区分大小写的文件名。因此,Samba 在搜索或访问文件时需要扫描大写和小写文件名的目录。您可以将共享配置为仅以小写或大写创建新文件,这可以提高性能。

先决条件

  • Samba 配置为文件服务器

流程

  1. 将共享上的所有文件重命名为小写。

    注意

    使用这个过程中的设置,名称不为小写的文件将不再显示。

  2. 在共享部分中设置以下参数:

    case sensitive = true
    default case = lower
    preserve case = no
    short preserve case = no

    有关参数的详情,请参考 smb.conf(5) man page 中的描述。

  3. 验证 /etc/samba/smb.conf 文件:

    # testparm
  4. 重新载入 Samba 配置:

    # smbcontrol all reload-config

应用这些设置后,此共享上所有新建文件的名称都使用小写。由于这些设置,Samba 不再需要扫描大写和小写的 目录,这样可以提高性能。

13.3. 可能会对性能造成负面影响的设置

默认情况下,Red Hat Enterprise Linux 中的内核会根据高网络性能进行了微调。例如,内核对缓冲区大小使用自动轮询机制。在 /etc/samba/smb.conf 文件中设置 socket options 参数会覆盖这些内核设置。因此,设置此参数会在大多数情况下降低 Samba 网络性能。

要使用内核中优化的设置,从 /etc/samba/smb.conf[global] 部分中删除 socket options 参数。

第 14 章 优化虚拟机性能

与主机相比,虚拟机的性能总会有所降低。以下小节解释了导致这个问题的原因,并提供了有关如何在 RHEL 8 中最小化虚拟化性能影响的说明,以便您的硬件基础架构资源能尽可能高效地使用。

14.1. 影响虚拟机性能的因素

虚拟机作为用户空间进程在主机上运行。因此管理程序需要转换主机的系统资源,以便虚拟机可使用它们。因此,部分资源会被转换消耗,因此虚拟机无法获得与主机相同的性能效率。

虚拟化对系统性能的影响

体虚拟机性能损失的原因包括:

  • 虚拟 CPU(vCPU)是主机上的线,,由 Linux 调度程序处理。
  • VM 不会自动继承主机内核的优化功能,比如 NUMA 或巨页。
  • 主机的磁盘和网络 I/O 设置可能会对虚拟机有显著的性能影响。
  • 网络流量通常通过基于软件的网桥到达虚拟机。
  • 根据主机设备及其模型,模拟特定硬件可能会产生大量开销。

虚拟化对虚拟机性能的影响严重程度受到各种因素的影响,具体包括:

  • 并行运行的虚拟机数量。
  • 每个虚拟机使用的虚拟设备数量。
  • 虚拟机使用的设备类型。

降低虚拟机性能损失

RHEL 8 提供很多功能,可用于降低虚拟化的负面影响。值得注意的是:

重要

调整虚拟机性能会对其他虚拟化功能造成负面影响。例如,它可以使迁移修改过的虚拟机更为困难。

14.2. 使用 tuned 优化虚拟机性能

tuned 工具是一种调优配置集交付机制,可根据特定工作负载特性进行调整,如 CPU 密集型任务的要求或存储网络吞吐量响应能力。它提供很多预先配置的调优配置文件,以便在多个特定用例中增强性能并降低功耗。您可以编辑这些配置集,或创建新配置集来创建适合您的环境的性能解决方案,包括虚拟环境。

红帽建议在 RHEL 8 中使用以下配置集:

  • 对于 RHEL 8 虚拟机,使用 virtual-guest 配置集。它基于 throughput-performance 配置集,但也会降低虚拟内存的交换性。
  • 对于 RHEL 8 虚拟化主机,请使用 virtual-host 配置集。这可提高脏内存页面的主动回写,这有助于主机性能。

先决条件

流程

启用特定的 tuned 配置集:

  1. 列出可用的 tuned 配置集。

    # tuned-adm list
    
    Available profiles:
    - balanced             - General non-specialized tuned profile
    - desktop              - Optimize for the desktop use-case
    [...]
    - virtual-guest        - Optimize for running inside a virtual guest
    - virtual-host         - Optimize for running KVM guests
    Current active profile: balanced
  2. 可选: 创建新 tuned 配置集或编辑现有的 tuned 配置集。

    如需更多信息,请参阅自定义 tuned 配置集

  3. 激活 tuned 配置集。

    # tuned-adm profile selected-profile
    • 要优化虚拟化主机,请使用 virtual-host 配置集。

      # tuned-adm profile virtual-host
    • 在 RHEL 虚拟机操作系统中,使用 virtual-guest 配置集。

      # tuned-adm profile virtual-guest

其它资源

14.3. 配置虚拟机内存

要提高虚拟机(VM)的性能,您可以为虚拟机分配额外的主机 RAM。类似地,您可以减少分配给虚拟机的内存量,从而使主机内存可以分配给其他虚拟机或任务。

要执行这些操作,您可以使用 Web 控制台或 命令行界面

14.3.1. 使用 web 控制台添加和删除虚拟机内存

要提高虚拟机(VM)的性能或释放它使用的主机资源,您可以使用 Web 控制台调整分配给虚拟机的内存量。

先决条件

  • 客户端操作系统正在运行内存 balloon 驱动程序。请执行以下命令校验:

    1. 确定虚拟机的配置包含 memballoon 设备:

      # virsh dumpxml testguest | grep memballoon
      <memballoon model='virtio'>
          </memballoon>

      如果这个命令显示了输出结果,且模型没有设置为 none,则代表 memballoon 设备存在。

    2. 确定 ballon 驱动程序正在客户端操作系统中运行。

  • 要使用 Web 控制台管理虚拟机,请安装 Web 控制台虚拟机插件

流程

  1. 可选:包含有关虚拟机最大内存和当前使用的内存的信息。这将作为您更改的基准,并进行验证。

    # virsh dominfo testguest
    Max memory:     2097152 KiB
    Used memory:    2097152 KiB
  2. 虚拟机接口中,点包含您要查看和调整分配的内存的虚拟机名称的一行。

    行会展开,以显示 Overview 窗格中有关所选虚拟机的基本信息。

  3. 点击 Overview 窗格中的 Memory 行值。

    此时会出现 Memory Adjustment 对话框。

    virt 内存 cockpit
  4. 为所选虚拟机配置虚拟 CPU。

    • 最大分配 - 设置虚拟机可用于其进程的最大主机内存量。增加这个值可以提高虚拟机的性能风险,降低这个值会降低虚拟机在主机上的性能占用空间。

      只有在关闭虚拟机上才能调整最大内存分配。

    • 当前分配 - 设置分配给虚拟机的实际内存量。您可以调整值,以规范虚拟机为其进程可用的内存。这个值不能超过最大分配值。
  5. Save

    调整了虚拟机的内存分配。

其它资源

14.3.2. 使用命令行界面添加和删除虚拟机内存

若要提高虚拟机(VM)的性能或释放其使用的主机资源,您可以使用 CLI 调整分配给虚拟机的内存量。

先决条件

  • 客户端操作系统正在运行内存 balloon 驱动程序。请执行以下命令校验:

    1. 确定虚拟机的配置包含 memballoon 设备:

      # virsh dumpxml testguest | grep memballoon
      <memballoon model='virtio'>
          </memballoon>

      如果这个命令显示了输出结果,且模型没有设置为 none,则代表 memballoon 设备存在。

    2. 确定 ballon 驱动程序正在客户端操作系统中运行。

流程

  1. 可选:包含有关虚拟机最大内存和当前使用的内存的信息。这将作为您更改的基准,并进行验证。

    # virsh dominfo testguest
    Max memory:     2097152 KiB
    Used memory:    2097152 KiB
  2. 调整分配给虚拟机的最大内存。增加这个值可以提高虚拟机的性能风险,降低这个值会降低虚拟机在主机上的性能占用空间。请注意,此更改只能在关闭虚拟机上执行,因此调整正在运行的虚拟机需要重新引导才能生效。

    例如,将 testguest 虚拟机可以使用的最大内存更改为 4096 MiB:

    # virt-xml testguest --edit --memory memory=4096,currentMemory=4096
    Domain 'testguest' defined successfully.
    Changes will take effect after the domain is fully powered off.
  1. 可选: 您还可以调整虚拟机当前使用的内存,最多不超过最大分配数。这限制了虚拟机在主机上的内存负载,直到下一次重启为止,而不更改虚拟机的最大分配。

    # virsh setmem testguest --current 2048

验证

  1. 确认虚拟机使用的内存已更新:

    # virsh dominfo testguest
    Max memory:     4194304 KiB
    Used memory:    2097152 KiB
  2. 可选:如果您调整了当前虚拟机内存,您可以获取虚拟机的内存 balloon 统计,以评估它如何有效地控制其内存使用量。

     # virsh domstats --balloon testguest
    Domain: 'testguest'
      balloon.current=365624
      balloon.maximum=4194304
      balloon.swap_in=0
      balloon.swap_out=0
      balloon.major_fault=306
      balloon.minor_fault=156117
      balloon.unused=3834448
      balloon.available=4035008
      balloon.usable=3746340
      balloon.last-update=1587971682
      balloon.disk_caches=75444
      balloon.hugetlb_pgalloc=0
      balloon.hugetlb_pgfail=0
      balloon.rss=1005456

其它资源

14.3.3. 其它资源

  • 要增加正在运行的虚拟机的最大内存,您可以将内存设备附加到虚拟机。这也被称为内存热插拔。详情请查看 将设备附加到虚拟机

    请注意,在 RHEL 8 中不支持从虚拟机中删除内存设备,也称为内存热拔。红帽强烈建议不要使用它。

14.4. 优化虚拟机 I/O 性能

虚拟机(VM)的输入和输出(I/O)功能可能会显著限制虚拟机的整体效率。要解决这个问题,您可以通过配置块 I/O 参数来优化虚拟机的 I/O。

14.4.1. 在虚拟机中调整块 I/O

当一个或多个虚拟机正在使用多个块设备时,可能需要通过修改虚拟设备的 I/O 优先级来调整虚拟设备的 I/O 权重

增加设备的 I/O 权重会增加设备的 I/O 带宽的优先级,从而为它提供更多主机资源。同样的,降低设备的权重可使其消耗较少的主机资源。

注意

每个设备的 weight 值都必须在 1001000 范围内。或者,该值可以是 0,它从每个设备列表中删除该设备。

流程

显示和设置虚拟机的块 I/O 参数:

  1. 显示虚拟机的当前 <blkio> 参数:

    # virsh dumpxml VM-name

    <domain>
      [...]
      <blkiotune>
        <weight>800</weight>
        <device>
          <path>/dev/sda</path>
          <weight>1000</weight>
        </device>
        <device>
          <path>/dev/sdb</path>
          <weight>500</weight>
        </device>
      </blkiotune>
      [...]
    </domain>
  2. 编辑指定设备的 I/O 加权:

    # virsh blkiotune VM-name --device-weights device, I/O-weight

    例如:以下将 liftrul 虚拟机中的 /dev/sda 设备的权重改为 500。

    # virsh blkiotune liftbrul --device-weights /dev/sda, 500

14.4.2. 虚拟机中的磁盘 I/O 节流

当多个虚拟机同时运行时,它们可能会通过使用过量磁盘 I/O 来干扰系统性能。KVM 虚拟化中的磁盘 I/O 节流使得能够对从虚拟机发送至主机的磁盘 I/O 请求设定限制。这可以防止虚拟机过度利用共享资源并影响其他虚拟机的性能。

要启用磁盘 I/O 节流,请对从附加到虚拟机到主机计算机的每个块设备发送的磁盘 I/O 请求设置限制。

流程

  1. 使用 virsh domblklist 命令列出指定虚拟机中的所有磁盘设备名称。

    # virsh domblklist rollin-coal
    Target     Source
    ------------------------------------------------
    vda        /var/lib/libvirt/images/rollin-coal.qcow2
    sda        -
    sdb        /home/horridly-demanding-processes.iso
  2. 找到您要节流的虚拟磁盘挂载的主机块设备。

    例如:如果要从上一步中节流 sdb 虚拟磁盘,以下输出显示磁盘被挂载到 /dev/nvme0n1p3 分区中。

    $ lsblk
    NAME                                          MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
    zram0                                         252:0    0     4G  0 disk  [SWAP]
    nvme0n1                                       259:0    0 238.5G  0 disk
    ├─nvme0n1p1                                   259:1    0   600M  0 part  /boot/efi
    ├─nvme0n1p2                                   259:2    0     1G  0 part  /boot
    └─nvme0n1p3                                   259:3    0 236.9G  0 part
      └─luks-a1123911-6f37-463c-b4eb-fxzy1ac12fea 253:0    0 236.9G  0 crypt /home
  3. 使用 virsh blkiotune 命令为块设备设置 I/O 限值。

    # virsh blkiotune VM-name --parameter device,limit

    以下示例将 rollin-coal 虚拟机上的 sdb 磁盘限制为每秒 1000 个读写 I/O 操作,每秒读写 I/O 操作吞吐量 50 MB。

    # virsh blkiotune rollin-coal --device-read-iops-sec /dev/nvme0n1p3,1000 --device-write-iops-sec /dev/nvme0n1p3,1000 --device-write-bytes-sec /dev/nvme0n1p3,52428800 --device-read-bytes-sec /dev/nvme0n1p3,52428800

附加信息

  • 磁盘 I/O 节流可用于各种情况,例如,属于不同客户的虚拟机在同一主机上运行,或者为不同的虚拟机提供服务质量保障时。磁盘 I/O 节流还可用来模拟较慢的磁盘。
  • I/O 节流可以独立于附加到虚拟机的每个块设备应用,并支持吞吐量和 I/O 操作的限制。
  • 红帽不支持使用 virsh blkdeviotune 命令在虚拟机中配置 I/O 节流。有关使用 RHEL 8 作为虚拟机主机时不支持的功能的更多信息,请参阅 RHEL 8 虚拟化中的不受支持的功能

14.4.3. 启用多队列 virtio-scsi

当在虚拟机(VM)中使用 virtio-scsi 存储设备时,多队列 virtio-scsi 功能可提高存储性能和可扩展性。它允许每个虚拟 CPU(vCPU)拥有单独的队列和中断,而不影响其他 vCPU。

流程

  • 要为特定虚拟机启用多队列 virtio-scsi 支持,请在虚拟机的 XML 配置中添加以下内容,其中 N 是 vCPU 队列的总数:

    <controller type='scsi' index='0' model='virtio-scsi'>
       <driver queues='N' />
    </controller>

14.5. 优化虚拟机 CPU 性能

与主机计算机中的物理 CPU 非常相似,vCPU 对虚拟机(VM)性能至关重要。因此,优化 vCPU 会对虚拟机的资源效率产生重大影响。优化 vCPU:

  1. 调整分配给虚拟机的主机 CPU 数。您可以使用 CLIWeb 控制台进行此操作。
  2. 确保 vCPU 模型与主机的 CPU 型号一致。例如,将 testguest1 虚拟机设置为使用主机的 CPU 型号:

    # virt-xml testguest1 --edit --cpu host-model
  3. 取消激活内核同页合并(KSM)。
  4. 如果您的主机使用非统一内存访问 (NUMA),您也可以为其虚拟机配置 NUMA。这会尽可能将主机的 CPU 和内存进程映射到虚拟机的 CPU 和内存进程上。实际上,NUMA 调优为 vCPU 提供了对分配给虚拟机的系统内存的更精简访问,这可以提高 vCPU 处理效率。

    详情请查看 第 14.5.3 节 “在虚拟机中配置 NUMA”第 14.5.4 节 “vCPU 性能调整场景示例”

14.5.1. 使用命令行界面添加和删除虚拟 CPU

要提高或优化虚拟机(VM)的 CPU 性能,您可以添加或删除分配给虚拟机的虚拟 CPU(vCPU)。

当在运行的虚拟机上执行时,这也被称为 vCPU 热插和热拔。但请注意,RHEL 8 不支持 vCPU 热拔,红帽不建议使用它。

先决条件

  • 可选:查看目标虚拟机中的 vCPU 的当前状态。例如,显示 testguest 虚拟机上的 vCPU 数量:

    # virsh vcpucount testguest
    maximum      config         4
    maximum      live           2
    current      config         2
    current      live           1

    此输出显示 testguest 目前使用 1 个 vCPU,另外 1 个 vCPu 可以热插入以提高虚拟机性能。但是,重新引导后,vCPU testguest 使用的数量会改为 2,而且能够热插 2 个 vCPU。

流程

  1. 调整可以附加到虚拟机的最大 vCPU 数量,这在虚拟机下次引导时生效。

    例如,要将 testguest 虚拟机的最大 vCPU 数量增加到 8:

    # virsh setvcpus testguest 8 --maximum --config

    请注意,最大值可能受 CPU 拓扑、主机硬件、系统管理程序和其他因素的限制。

  2. 将当前附加到虚拟机的 vCPU 数量调整到上一步中配置的最大值。例如:

    • 将附加到正在运行的 testguest 虚拟机的 vCPU 数量增加到 4:

      # virsh setvcpus testguest 4 --live

      这会增加虚拟机的性能和主机的 testguest 负载占用,直到虚拟机下次引导为止。

    • 将附加到 testguest 虚拟机的 vCPU 数量永久减少至 1:

      # virsh setvcpus testguest 1 --config

      这会降低虚拟机的性能和 testguest 的主机负载占用。但是,如果需要可热插入虚拟机以暂时提高性能。

验证

  • 确认虚拟机的 vCPU 的当前状态反映了您的更改。

    # virsh vcpucount testguest
    maximum      config         8
    maximum      live           4
    current      config         1
    current      live           4

其它资源

14.5.2. 使用 Web 控制台管理虚拟 CPU

使用 RHEL 8 web 控制台,您可以查看并配置 web 控制台连接的虚拟机使用的虚拟 CPU。

流程

  1. Virtual Machines 界面中,单击带有您要查看和配置虚拟 CPU 参数的虚拟机名称的行。

    行扩展以显示 Overview 窗格,其中包含有关所选虚拟机的基本信息,包括虚拟 CPU 数量,以及用于关闭和删除虚拟机的控件。

  2. 点击 Overview 窗格中的 vCPU 数量。

    此时会出现 vCPU 详情对话框。

    Cockpit 配置 vCPU
    注意

    只有在更改虚拟 CPU 设置后,vCPU 详情对话框中的警告会出现。

  3. 为所选虚拟机配置虚拟 CPU。

    • vCPU 数量 - 当前正在使用的 vCPU 数量。

      注意

      vCPU 数量不能超过 vCPU 的最大值。

    • vCPU 最大 - 可为虚拟机配置的最大虚拟 CPU 数。如果这个值大于 vCPU Count,可以为虚拟机附加额外的 vCPU。
    • 插槽 - 向虚拟机公开的插槽数量。
    • 每个插槽的内核数 - 向虚拟机公开的每个插槽的内核数。
    • 每个内核的线程数 - 向虚拟机公开的每个内核的线程数。

      请注意, 插槽每个插槽的内核数每个内核的线程数选项调整了虚拟机的 CPU 拓扑。这可能对 vCPU 性能有用,可能会影响客户机操作系统中某些软件的功能。如果您的部署不需要不同的设置,红帽建议保留默认值。

  4. 应用

    配置了虚拟机的虚拟 CPU。

    注意

    对虚拟 CPU 设置的更改仅在重启虚拟机后生效。

其他资源:

14.5.3. 在虚拟机中配置 NUMA

以下方法可用于在 RHEL 8 主机上配置虚拟机(VM)的非一致性内存访问(NUMA)设置。

先决条件

  • 主机是一个与 NUMA 兼容的机器。要检测是否是这种情况,使用 virsh nodeinfo 命令并查看 NUMA cell(s) 行:

    # virsh nodeinfo
    CPU model:           x86_64
    CPU(s):              48
    CPU frequency:       1200 MHz
    CPU socket(s):       1
    Core(s) per socket:  12
    Thread(s) per core:  2
    NUMA cell(s):        2
    Memory size:         67012964 KiB

    如果行的值为 2 或更高,则主机与 NUMA 兼容。

流程

为便于使用,您可以使用自动化实用程序和服务设置虚拟机的 NUMA 配置。但是,手动 NUMA 设置可能会显著提高性能。

自动方法

  • 将虚拟机的 NUMA 策略设置为 Preferred。例如,对于 testguest5 虚拟机要这样做:

    # virt-xml testguest5 --edit --vcpus placement=auto
    # virt-xml testguest5 --edit --numatune mode=preferred
  • 在主机上启用自动 NUMA 均衡:

    # echo 1 > /proc/sys/kernel/numa_balancing
  • 使用 numad 命令自动将虚拟机 CPU 与内存资源匹配。

    # numad

手动方法

  1. 将特定 vCPU 线程固定到特定主机 CPU 或者 CPU 范围。在非 NUMA 主机和虚拟机上也可以这样做,我们推荐您使用一种安全的方法来提高 vCPU 性能。

    例如,以下命令将 testguest6 虚拟机的 vCPU 线程 0 到 5 分别固定到主机 CPU 1、3、5、7、9 和 11:

    # virsh vcpupin testguest6 0 1
    # virsh vcpupin testguest6 1 3
    # virsh vcpupin testguest6 2 5
    # virsh vcpupin testguest6 3 7
    # virsh vcpupin testguest6 4 9
    # virsh vcpupin testguest6 5 11

    之后,您可以验证操作是否成功:

    # virsh vcpupin testguest6
    VCPU   CPU Affinity
    ----------------------
    0      1
    1      3
    2      5
    3      7
    4      9
    5      11
  2. 固定 vCPU 线程后,您还可以将与指定虚拟机关联的 QEMU 进程线程固定到特定的主机 CPU 或 CPU 范围。例如:以下命令将 testguest6 的 QEMU 进程线程 固定到 CPU 13 和 15,确认成功:

    # virsh emulatorpin testguest6 13,15
    # virsh emulatorpin testguest6
    emulator: CPU Affinity
    ----------------------------------
           *: 13,15
  3. 最后,您也可以指定将哪些主机 NUMA 节点专门分配给特定的虚拟机。这可提高虚拟机 vCPU 的主机内存用量。例如,以下命令将 testguest6 设置为使用主机 NUMA 节点 3 到 5,确认成功:

    # virsh numatune testguest6 --nodeset 3-5
    # virsh numatune testguest6

其它资源

14.5.4. vCPU 性能调整场景示例

要获得最佳 vCPU 性能,红帽建议您手动 vcpupinemulatorpinnumatune 设置,如以下场景中所示。

起始场景

  • 您的主机有以下与硬件相关的信息:

    • 2 个 NUMA 节点
    • 每个节点上的 3 个 CPU 内核
    • 每个内核有 2 个线程

    这类机器的 virsh nodeinfo 的输出类似于:

    # virsh nodeinfo
    CPU model:           x86_64
    CPU(s):              12
    CPU frequency:       3661 MHz
    CPU socket(s):       2
    Core(s) per socket:  3
    Thread(s) per core:  2
    NUMA cell(s):        2
    Memory size:         31248692 KiB
  • 您打算将现有虚拟机修改为具有 8 个 vCPU,这意味着它不适用于单个 NUMA 节点。

    因此,您应该在每个 NUMA 节点上分发 4 个 vCPU,并使 vCPU 拓扑尽可能与主机拓扑相似。这意味着,作为给定物理 CPU 的同级线程运行的 vCPU 应该固定到同一内核中的主机线程。详情请查看以下解决方案:

解决方案

  1. 获取主机拓扑的信息:

    # virsh capabilities

    输出应包含类似如下的部分:

    <topology>
      <cells num="2">
        <cell id="0">
          <memory unit="KiB">15624346</memory>
          <pages unit="KiB" size="4">3906086</pages>
          <pages unit="KiB" size="2048">0</pages>
          <pages unit="KiB" size="1048576">0</pages>
          <distances>
            <sibling id="0" value="10" />
            <sibling id="1" value="21" />
          </distances>
          <cpus num="6">
            <cpu id="0" socket_id="0" core_id="0" siblings="0,3" />
            <cpu id="1" socket_id="0" core_id="1" siblings="1,4" />
            <cpu id="2" socket_id="0" core_id="2" siblings="2,5" />
            <cpu id="3" socket_id="0" core_id="0" siblings="0,3" />
            <cpu id="4" socket_id="0" core_id="1" siblings="1,4" />
            <cpu id="5" socket_id="0" core_id="2" siblings="2,5" />
          </cpus>
        </cell>
        <cell id="1">
          <memory unit="KiB">15624346</memory>
          <pages unit="KiB" size="4">3906086</pages>
          <pages unit="KiB" size="2048">0</pages>
          <pages unit="KiB" size="1048576">0</pages>
          <distances>
            <sibling id="0" value="21" />
            <sibling id="1" value="10" />
          </distances>
          <cpus num="6">
            <cpu id="6" socket_id="1" core_id="3" siblings="6,9" />
            <cpu id="7" socket_id="1" core_id="4" siblings="7,10" />
            <cpu id="8" socket_id="1" core_id="5" siblings="8,11" />
            <cpu id="9" socket_id="1" core_id="3" siblings="6,9" />
            <cpu id="10" socket_id="1" core_id="4" siblings="7,10" />
            <cpu id="11" socket_id="1" core_id="5" siblings="8,11" />
          </cpus>
        </cell>
      </cells>
    </topology>
  2. 可选:使用 ??? 适用的工具和实用程序测试虚拟机的性能
  3. 在主机上设置并挂载 1 GiB 巨页:

    1. 在主机的内核命令行中添加以下行:

      default_hugepagesz=1G hugepagesz=1G
    2. 使用以下内容创建 /etc/systemd/system/hugetlb-gigantic-pages.service 文件:

      [Unit]
      Description=HugeTLB Gigantic Pages Reservation
      DefaultDependencies=no
      Before=dev-hugepages.mount
      ConditionPathExists=/sys/devices/system/node
      ConditionKernelCommandLine=hugepagesz=1G
      
      [Service]
      Type=oneshot
      RemainAfterExit=yes
      ExecStart=/etc/systemd/hugetlb-reserve-pages.sh
      
      [Install]
      WantedBy=sysinit.target
    3. 使用以下内容创建 /etc/systemd/hugetlb-reserve-pages.sh 文件:

      #!/bin/sh
      
      nodes_path=/sys/devices/system/node/
      if [ ! -d $nodes_path ]; then
      	echo "ERROR: $nodes_path does not exist"
      	exit 1
      fi
      
      reserve_pages()
      {
      	echo $1 > $nodes_path/$2/hugepages/hugepages-1048576kB/nr_hugepages
      }
      
      reserve_pages 4 node1
      reserve_pages 4 node2

      这会从 node1 保留 4 个 1GiB 巨页,并在 node2 中保留 4 个 1GiB 巨页。

    4. 使在上一步中创建的脚本可执行:

      # chmod +x /etc/systemd/hugetlb-reserve-pages.sh
    5. 在引导时启用巨页保留:

      # systemctl enable hugetlb-gigantic-pages
  4. 使用 virsh edit 命令编辑您要优化的虚拟机的 XML 配置,在这个示例中 super-VM

    # virsh edit super-vm
  5. 用以下方法调整虚拟机的 XML 配置:

    1. 将虚拟机设置为使用 8 个静态 vCPU。使用 <vcpu/> 项进行此操作。
    2. 将每个 vCPU 线程固定到拓扑中镜像的对应主机 CPU 线程。要做到这一点,使用 <cputune> 部分中的 <vcpupin/> 项。

      请注意,如上面的 virsh capabilities 工具所示,主机 CPU 线程不会在它们对应的内核中按顺序排序。此外,vCPU 线程应固定到同一 NUMA 节点上提供的最高可用主机核心集合。有关表插图,请参见下面的附加资源部分

      步骤 a. 和 b. 的 XML 配置类似:

      <cputune>
        <vcpupin vcpu='0' cpuset='1'/>
        <vcpupin vcpu='1' cpuset='4'/>
        <vcpupin vcpu='2' cpuset='2'/>
        <vcpupin vcpu='3' cpuset='5'/>
        <vcpupin vcpu='4' cpuset='7'/>
        <vcpupin vcpu='5' cpuset='10'/>
        <vcpupin vcpu='6' cpuset='8'/>
        <vcpupin vcpu='7' cpuset='11'/>
        <emulatorpin cpuset='6,9'/>
      </cputune>
    3. 将虚拟机设置为使用 1 GiB 巨页:

      <memoryBacking>
        <hugepages>
          <page size='1' unit='GiB'/>
        </hugepages>
      </memoryBacking>
    4. 配置虚拟机的 NUMA 节点,使其使用主机上对应的 NUMA 节点的内存。要做到这一点,使用 <numatune/> 部分中的 <memnode/> 元素:

      <numatune>
        <memory mode="preferred" nodeset="1"/>
        <memnode cellid="0" mode="strict" nodeset="0"/>
        <memnode cellid="1" mode="strict" nodeset="1"/>
      </numatune>
    5. 确保 CPU 模式被设置为 host-passthrough,且 CPU 在 passthrough 模式中使用缓存:

      <cpu mode="host-passthrough">
        <topology sockets="2" cores="2" threads="2"/>
        <cache mode="passthrough"/>
  6. 虚拟机的 XML 配置应该包括以下部分:

    [...]
      <memoryBacking>
        <hugepages>
          <page size='1' unit='GiB'/>
        </hugepages>
      </memoryBacking>
      <vcpu placement='static'>8</vcpu>
      <cputune>
        <vcpupin vcpu='0' cpuset='1'/>
        <vcpupin vcpu='1' cpuset='4'/>
        <vcpupin vcpu='2' cpuset='2'/>
        <vcpupin vcpu='3' cpuset='5'/>
        <vcpupin vcpu='4' cpuset='7'/>
        <vcpupin vcpu='5' cpuset='10'/>
        <vcpupin vcpu='6' cpuset='8'/>
        <vcpupin vcpu='7' cpuset='11'/>
        <emulatorpin cpuset='6,9'/>
      </cputune>
      <numatune>
        <memory mode="preferred" nodeset="1"/>
        <memnode cellid="0" mode="strict" nodeset="0"/>
        <memnode cellid="1" mode="strict" nodeset="1"/>
      </numatune>
      <cpu mode="host-passthrough">
        <topology sockets="2" cores="2" threads="2"/>
        <cache mode="passthrough"/>
        <numa>
          <cell id="0" cpus="0-3" memory="2" unit="GiB">
            <distances>
              <sibling id="0" value="10"/>
              <sibling id="1" value="21"/>
            </distances>
          </cell>
          <cell id="1" cpus="4-7" memory="2" unit="GiB">
            <distances>
              <sibling id="0" value="21"/>
              <sibling id="1" value="10"/>
            </distances>
          </cell>
        </numa>
      </cpu>
    </domain>
  7. 可选:使用 ??? 适用的工具和实用程序测试虚拟机的性能,以评估虚拟机优化的影响。

其它资源

  • 下表演示了 vCPU 和主机 CPU 之间的连接:

    表 14.1. 主机拓扑

    CPU 线程

    0

    3

    1

    4

    2

    5

    6

    9

    7

    10

    8

    11

    内核

    0

    1

    2

    3

    4

    5

    插槽

    0

    1

    NUMA 节点

    0

    1

    表 14.2. VM 拓扑

    vCPU 线程

    0

    1

    2

    3

    4

    5

    6

    7

    内核

    0

    1

    2

    3

    插槽

    0

    1

    NUMA 节点

    0

    1

    表 14.3. 合并主机和虚拟机拓扑

    vCPU 线程

     

    0

    1

    2

    3

     

    4

    5

    6

    7

    主机 CPU 线程

    0

    3

    1

    4

    2

    5

    6

    9

    7

    10

    8

    11

    内核

    0

    1

    2

    3

    4

    5

    插槽

    0

    1

    NUMA 节点

    0

    1

    在这种情况下,有 2 个 NUMA 节点和 8 个 vCPU。因此,应该为每个节点固定 4 个 vCPU 线程。

    另外,红帽建议在每个节点中保留至少一个 CPU 线程用于主机系统操作。

    因为在这个示例中,每个 NUMA 节点都包含 3 个内核,每个内核都有 2 个主机 CPU 线程,所以节点 0 的设置转换如下:

    <vcpupin vcpu='0' cpuset='1'/>
    <vcpupin vcpu='1' cpuset='4'/>
    <vcpupin vcpu='2' cpuset='2'/>
    <vcpupin vcpu='3' cpuset='5'/>

14.5.5. 取消激活内核相同页面合并

虽然内核相同页面合并(KSM)提高了内存密度,但它会增加 CPU 利用率,并且可能会根据工作负载对整体性能造成负面影响。在这种情况下,您可以通过停用 KSM 来提高虚拟机(VM)性能。

根据您的要求,可以为单个会话取消激活 KSM,也可以永久停用。

流程

  • 要在一个会话中取消激活 KSM,请使用 systemctl 工具停止 ksmksmtuned 服务。

    # systemctl stop ksm
    
    # systemctl stop ksmtuned
  • 要永久取消激活 KSM,使用 systemctl 工具禁用 ksmksmtuned 服务。

    # systemctl disable ksm
    Removed /etc/systemd/system/multi-user.target.wants/ksm.service.
    # systemctl disable ksmtuned
    Removed /etc/systemd/system/multi-user.target.wants/ksmtuned.service.
注意

取消激活 KSM 前在虚拟机间共享的内存页将保持共享。要停止共享,使用以下命令删除系统中的所有 PageKSM 页面:

# echo 2 > /sys/kernel/mm/ksm/run

在匿名页面替换了 KSM 页面后,khugepaged 内核服务将在虚拟机物理内存上重建透明巨页。

14.6. 优化虚拟机网络性能

由于虚拟机的网络接口卡(NIC)的虚拟性质,虚拟机会丢失其分配的主机网络带宽的一部分,这样可以降低虚拟机的整体工作负载效率。以下提示可最大程度降低虚拟化对虚拟 NIC(vNIC)吞吐量的负面影响。

流程

使用以下任一方法并观察它是否对虚拟机网络性能有帮助:

启用 vhost_net 模块

在主机上,确定启用了 vhost_net 内核功能:

# lsmod | grep vhost
vhost_net              32768  1
vhost                  53248  1 vhost_net
tap                    24576  1 vhost_net
tun                    57344  6 vhost_net

如果这个命令的输出为空白,启用 vhost_net 内核模块:

# modprobe vhost_net
设置多队列 virtio-net

要为虚拟机设置 多队列 virtio-net 功能,使用 virsh edit 命令编辑虚拟机的 XML 配置。在 XML 中,将以下内容添加到 <devices> 部分,并使用虚拟机中的 vCPU 数量替换 N,最多为 16:

<interface type='network'>
      <source network='default'/>
      <model type='virtio'/>
      <driver name='vhost' queues='N'/>
</interface>

如果虚拟机正在运行,重启它以使更改生效。

批量网络数据包

在具有长传输路径的 Linux VM 配置中,在将数据包提交到内核之前进行批处理可以提高缓存利用率。要设置数据包批处理,请在主机上使用以下命令,并将 tap0 替换为虚拟机使用的网络接口名称:

# ethtool -C tap0 rx-frames 128
SR-IOV
如果您的主机 NIC 支持 SR-IOV,请为您的 vNIC 使用 SR-IOV 设备分配。如需更多信息,请参阅管理 SR-IOV 设备

14.7. 虚拟机性能监控工具

要确定哪些消耗了最多 VM 资源以及虚拟机性能需要优化的哪一方面,可以使用一般诊断工具和特定于虚拟机的工具。

默认操作系统性能监控工具

要进行标准性能评估,您可以使用主机和客户机操作系统默认提供的工具:

  • 在 RHEL 8 主机上,以 root 用户身份使用 top 实用程序或 系统监控应用程序,并在输出中查找 qemuvirt。这显示了您的虚拟机消耗的主机系统资源量。

    • 如果监控工具显示任何 qemuvirt 进程消耗大量主机 CPU 或内存容量,请使用 perf 工具程序进行调查。详情请查看以下信息。
    • 另外,如果名为 examplevhost_net-1234vhost_net 线程进程显示为消耗过多的主机 CPU 容量,请考虑使用虚拟网络优化功能,如 multi-queue virtio-net
  • 在客户机操作系统上,使用系统上可用的性能实用程序和应用程序来评估哪些进程消耗最多的系统资源。

    • 在 Linux 系统中,您可以使用 top 工具。
    • 在 Windows 系统中,您可以使用 Task Manager 应用程序。

perf kvm

您可以使用 perf 实用程序收集有关 RHEL 8 主机性能的特定虚拟化统计。要做到这一点:

  1. 在主机上安装 perf 软件包:

    # yum install perf
  2. 使用 perf kvm stat 命令之一显示虚拟化主机的 perf 统计:

    • 对于虚拟机监控程序的实时监控,请使用 perf kvm stat live 命令。
    • 要记录虚拟机监控程序的 perf 数据,请使用 perf kvm stat record 命令激活日志。取消或中断命令后,数据保存在 perf.data.guest 文件中,该文件可使用 perf kvm stat report 命令分析。
  3. 分析 VM-EXIT 事件类型及其分布的 perf 输出。例如,PAUSE_INSTRUCTION 事件应该不频繁,但在以下输出中,此事件的频繁发生意味着主机 CPU 没有正确处理正在运行的 vCPU。在这种情况下,请考虑关闭部分活动虚拟机,从这些虚拟机中删除 vCPU,或调优 vCPU 的性能

    # perf kvm stat report
    
    Analyze events for all VMs, all VCPUs:
    
    
                 VM-EXIT    Samples  Samples%     Time%    Min Time    Max Time         Avg time
    
      EXTERNAL_INTERRUPT     365634    31.59%    18.04%      0.42us  58780.59us    204.08us ( +-   0.99% )
               MSR_WRITE     293428    25.35%     0.13%      0.59us  17873.02us      1.80us ( +-   4.63% )
        PREEMPTION_TIMER     276162    23.86%     0.23%      0.51us  21396.03us      3.38us ( +-   5.19% )
       PAUSE_INSTRUCTION     189375    16.36%    11.75%      0.72us  29655.25us    256.77us ( +-   0.70% )
                     HLT      20440     1.77%    69.83%      0.62us  79319.41us  14134.56us ( +-   0.79% )
                  VMCALL      12426     1.07%     0.03%      1.02us   5416.25us      8.77us ( +-   7.36% )
           EXCEPTION_NMI         27     0.00%     0.00%      0.69us      1.34us      0.98us ( +-   3.50% )
           EPT_MISCONFIG          5     0.00%     0.00%      5.15us     10.85us      7.88us ( +-  11.67% )
    
    Total Samples:1157497, Total events handled time:413728274.66us.

    perf kvm stat 输出中可能会信号问题的其他事件类型包括:

有关使用 perf 监控虚拟化性能的详情请参考 perf-kvm man page。

numastat

要查看系统的当前 NUMA 配置,您可以使用 numastat 工具程序,通过安装 numactl 软件包来提供该工具。

以下显示了一个有 4 个运行虚拟机的主机,各自从多个 NUMA 节点获取内存。这不是 vCPU 性能的最佳方案,并保证调整

# numastat -c qemu-kvm

Per-node process memory usage (in MBs)
PID              Node 0 Node 1 Node 2 Node 3 Node 4 Node 5 Node 6 Node 7 Total
---------------  ------ ------ ------ ------ ------ ------ ------ ------ -----
51722 (qemu-kvm)     68     16    357   6936      2      3    147    598  8128
51747 (qemu-kvm)    245     11      5     18   5172   2532      1     92  8076
53736 (qemu-kvm)     62    432   1661    506   4851    136     22    445  8116
53773 (qemu-kvm)   1393      3      1      2     12      0      0   6702  8114
---------------  ------ ------ ------ ------ ------ ------ ------ ------ -----
Total              1769    463   2024   7462  10037   2672    169   7837 32434

相反,以下显示单个节点为每个虚拟机提供内存,这效率显著提高。

# numastat -c qemu-kvm

Per-node process memory usage (in MBs)
PID              Node 0 Node 1 Node 2 Node 3 Node 4 Node 5 Node 6 Node 7 Total
---------------  ------ ------ ------ ------ ------ ------ ------ ------ -----
51747 (qemu-kvm)      0      0      7      0   8072      0      1      0  8080
53736 (qemu-kvm)      0      0      7      0      0      0   8113      0  8120
53773 (qemu-kvm)      0      0      7      0      0      0      1   8110  8118
59065 (qemu-kvm)      0      0   8050      0      0      0      0      0  8051
---------------  ------ ------ ------ ------ ------ ------ ------ ------ -----
Total                 0      0   8072      0   8072      0   8114   8110 32368

第 15 章 使用 PowerTOP 管理功耗

作为系统管理员,您可以使用PowerTOP 工具来分析和管理功耗。

15.1. PowerTOP 的目的

powertop 是一个诊断与功耗相关的问题的程序,并提供了有关如何延长电池生命周期的建议。

PowerTOP 工具可提供系统总耗估算,以及每个进程、设备、内核工作程序、计时器和中断处理程序的单独电源使用情况。该工具还可以识别经常唤醒 CPU 的内核和用户空间应用程序的特定组件。

Red Hat Enterprise Linux 8 使用PowerTOP 版本 2.x。

15.2. 使用 PowerTOP

先决条件

  • 要可以使用PowerTOP,请确保已在您的系统中安装了 powertop 软件包:

    # yum install powertop

15.2.1. 启动 PowerTOP

流程

  • 要运行PowerTOP,请使用以下命令:

    # powertop
重要

运行 powertop 命令时,笔记本电脑应在电池电源中运行。

15.2.2. calibrating PowerTOP

流程

  1. 在笔记本电脑中,您可以通过运行以下命令来校准电源估算引擎:

    # powertop --calibrate
  2. 使校准完成而无需在安装过程中与计算机交互。

    校准需要时间,因为进程会执行各种测试,通过亮度级别进行循环,以及打开和关闭交换机设备。

  3. 完成 calibration 过程后,PowerTOP 会正常启动。让它运行大约一小时来收集数据。

    收集到足够的数据后,输出表的第一列将显示电源估算数据。

注意

请注意,powertop --calibrate 只能在笔记本电脑中使用。

15.2.3. 设置测量间隔

默认情况下,PowerTOP 以 20 秒间隔进行测量。

如果要更改这个测量频率,请使用以下步骤:

流程

  • 使用 --time 选项运行 powertop 命令:

    # powertop --time=time in seconds

15.3. powertop 统计

在运行期间,PowerTOP 从系统中收集统计信息。

powertop的输出会提供多个标签页:

  • Overview
  • Idle stats
  • Frequency stats
  • Device stats
  • Tunables

您可以使用 TabShift+Tab 键循环这些标签页。

15.3.1. Overview 选项卡

Overview 标签页中,您可以查看向 CPU 发送唤醒的组件列表,或者最多消耗最多的组件。Overview 选项卡中的项目(包括进程、中断、设备和其他资源)按照使用情况进行排序。

Overview 标签页中的相邻列提供了以下信息:

使用
对资源使用情况的电源估算.
events/s
每秒 Wakeups.每秒唤醒次数表示内核的服务或设备和驱动程序的效率如何。更少的唤醒意味着消耗的功率更少。组件按照其功耗可优化程度排序。
类别
组件的分类,如流程、设备或计时器。
描述
组件的描述。

如果正确校准,也会显示第一列中列出的每个项目的功耗估算。

此外,Overview 标签还包括带有汇总统计的行,例如:

  • 总功耗
  • 剩余电池寿命(仅适用于)
  • 每秒唤醒总数、每秒 GPU 操作数和虚拟文件系统操作摘要

15.3.2. Idle stats 选项卡

Idle stats 标签显示所有处理器和内核的 C-states 使用情况,而 Frequency stats 标签则显示 P-states 的使用情况,包括 Turbo 模式(如果适用)用于所有处理器和内核。C- 或 P-states 的时间代表 CPU 使用率优化程度。CPU 处于更高 C- 或 P-states 的时间越长(例如,C4 高于 C3),CPU 使用率优化越好。理想情况下,当系统空闲时,驻留在最高 C- 或 P-state 中是 90% 或 P-state。

15.3.3. 设备统计数据选项卡

Device stats 标签提供与 Overview 标签类似的信息,但只适用于设备。

15.3.4. Tunables 选项卡

Tunables 标签包含用于优化系统以降低功耗的PowerTOP建议。

使用 updown 键完成建议,使用 enter 键切换或关闭建议。

图 15.1. powertop 输出

powertop 输出 n

其它资源

有关PowerTOP的详情,请参阅 PowerTOP 的主页

15.4. 生成 HTML 输出

除了终端中的 powertop’s 输出外,您还可以生成 HTML 报告。

流程

  • 使用 --html 选项运行 powertop 命令:

    # powertop --html=htmlfile.html

    htmlfile.html 参数替换为输出文件所需的名称。

15.5. 优化功耗

要优化功耗,您可以使用 powertop 服务或 powertop2tuned 工具。

15.5.1. 使用 powertop 服务优化功耗

您可以使用 powertop 服务从引导的 Tunables 标签页中自动启用所有PowerTOP建议:

流程

  • 启用 powertop 服务:

    # systemctl enable powertop

15.5.2. powertop2tuned 工具

powertop2tuned 工具允许您根据PowerTOP 建议创建自定义Tuned 配置集。

默认情况下,powertop2tuned/etc/tuned/ 目录中创建配置集,并在当前选择的Tuned 配置集中基于自定义配置集。出于安全考虑,新的配置集首先禁用所有PowerTOP 调优。

要启用调优,您可以:

  • /etc/tuned/profile_name/tuned.conf file 中取消注释学员。
  • 使用 --enable-e 选项生成一个新配置集,启用PowerTOP 建议的大多数调优。

    某些潜在问题调优(如 USB 自动暂停)默认禁用,需要手动取消注释。

15.5.3. 使用 powertop2tuned 工具优化功耗

先决条件

  • powertop2tuned 工具安装在系统中:

    # yum install tuned-utils

流程

  1. 创建自定义配置集:

    # powertop2tuned new_profile_name
  2. 激活新配置集:

    # tuned-adm profile new_profile_name

附加信息

  • 如需 powertop2tuned 支持的完整选项列表,请使用:

    $ powertop2tuned --help

15.5.4. powertop.service 和 powertop2tuned 的比较

使用 powertop2tuned 优化功耗优先于 powertop.service,理由如下:

  • powertop2tuned 工具代表PowerTOP集成到 Tuned 中,它可受益于这两个工具的优势。
  • powertop2tuned 工具允许对启用的调整进行精细控制。
  • 使用 powertop2tuned 时,潜在的危险调优不会自动启用。
  • 使用 powertop2tuned 时,可以在不重启的情况下回滚。

第 16 章 perf 入门

作为系统管理员,您可以使用 perf 工具来收集并分析系统的性能数据。

16.1. perf 简介

perf 用户空间工具与基于内核的 Linux 子系统性能计数器 (PCL)接口。perf 是一个强大的工具,使用性能监控单元(PMU)来测量、记录和监控各种硬件和软件事件。perf 还支持追踪点、kprobes 和 uprobes。

16.2. 安装 perf

这个过程安装 perf 用户空间工具。

流程

  • 安装 perf 工具:

    # yum install perf

16.3. 常见的 perf 命令

本节概述了常用的 perf 命令。

通常使用 perf 命令

perf stat
此命令提供常见性能事件的整体统计信息,包括执行的指令和消耗的时钟周期。选项允许选择默认测量事件以外的事件。
perf record
这个命令将性能数据记录到文件 perf.data 中,以后可以使用 perf report 命令分析这些文件。
perf report
这个命令从 perf record 创建的 perf.data 文件中读取并显示性能数据。
perf list
此命令会列出特定计算机上可用的事件。这些事件将根据系统的性能监控硬件和软件配置而有所不同。
perf top
这个命令执行与 top 工具类似的功能。它实时生成并显示性能计数器配置文件。
perf trace
这个命令执行与 strace 工具类似的功能。它监控指定线程或进程使用的系统调用,以及该应用收到的所有信号。
perf help
这个命令显示 perf 命令的完整列表。

其它资源

  • 在子命令中添加 --help 选项以打开 man page。

第 17 章 使用 perf top 实时分析 CPU 使用情况

您可以使用 perf top 命令实时测量不同功能的 CPU 使用情况。

先决条件

17.1. perf top 的目的

perf top 命令用于实时系统性能分析,功能与 top 工具类似。但是,top 工具通常显示给定进程或线程使用的 CPU 时间,perf top 显示每个特定功能使用的 CPU 时间。在默认状态下,perf top 告知您用户空间和内核空间的所有 CPU 中使用的功能。要使用 perf top,您需要 root 访问权限。

17.2. 使用 perf top 分析 CPU 使用率

此流程实时激活 perf top 和配置集 CPU 使用情况。

先决条件

流程

  • 启动 perf top 监控接口:

    # perf top

    监控接口类似如下:

    --------------------------------------------------------------------
    PerfTop:   20806 irqs/sec  kernel:57.3%  exact: 100.0% lost: 0/0 drop: 0/0 [4000Hz cycles],  (all, 8 CPUs)
    ---------------------------------------------------------------------
    Overhead  Shared Object       Symbol
       2.20%  [kernel]            [k] do_syscall_64
       2.17%  [kernel]            [k] module_get_kallsym
       1.49%  [kernel]            [k] copy_user_enhanced_fast_string
       1.37%  libpthread-2.29.so  [.] pthread_mutex_lock 1.31% [unknown] [.] 0000000000000000 1.07% [kernel] [k] psi_task_change 1.04% [kernel] [k] switch_mm_irqs_off 0.94% [kernel] [k] fget
       0.74%  [kernel]            [k] entry_SYSCALL_64
       0.69%  [kernel]            [k] syscall_return_via_sysret
       0.69%  libxul.so           [.] 0x000000000113f9b0
       0.67%  [kernel]            [k] kallsyms_expand_symbol.constprop.0
       0.65%  firefox             [.] moz_xmalloc
       0.65%  libpthread-2.29.so  [.] __pthread_mutex_unlock_usercnt
       0.60%  firefox             [.] free
       0.60%  libxul.so           [.] 0x000000000241d1cd
       0.60%  [kernel]            [k] do_sys_poll
       0.58%  [kernel]            [k] menu_select
       0.56%  [kernel]            [k] _raw_spin_lock_irqsave
       0.55%  perf                [.] 0x00000000002ae0f3

    在这个示例中,内核功能 do_syscall_64 使用最多 CPU 时间。

其它资源

  • perf-top(1) man page

17.3. perf 最高输出的解读

perf top 监控界面在几个列中显示数据:

"Overhead"列
显示给定功能正在使用的 CPU 百分比。
"共享对象"列
显示使用 函数的程序或库的名称。
"Symbol"列
显示函数名称或符号。内核空间中执行的功能由 [k] 标识,用户空间执行的功能由 [.] 标识。

17.4. 为什么 perf 显示一些功能名称作为原始函数地址

对于内核函数,perf 使用 /proc/kallsyms 文件中的信息将示例映射到对应的功能名称或符号。但是,对于在用户空间中执行的功能,您可能会看到原始功能地址,因为二进制已被剥离。

必须安装可执行文件的 debuginfo 软件包,如果可执行文件是本地开发的应用程序,则必须编译应用程序并打开调试信息(GCC 中的 -g 选项)以显示在这种情况下的功能名称或符号。

注意

安装与可执行文件关联的 debuginfo 后,不需要重新运行 perf record 命令。只需重新运行 perf report 命令。

17.5. 启用 debug 和源存储库

Red Hat Enterprise Linux 的标准安装不会启用 debug 和源存储库。这些存储库包含调试系统组件和衡量其性能所需的信息。

流程

  • 启用源和调试信息软件包频道:

    # subscription-manager repos --enable rhel-8-for-$(uname -i)-baseos-debug-rpms
    # subscription-manager repos --enable rhel-8-for-$(uname -i)-baseos-source-rpms
    # subscription-manager repos --enable rhel-8-for-$(uname -i)-appstream-debug-rpms
    # subscription-manager repos --enable rhel-8-for-$(uname -i)-appstream-source-rpms

    $(uname -i) 部分自动替换为您的系统构架的匹配值:

    架构名称

    64 位 Intel 和 AMD

    x86_64

    64-bit ARM

    aarch64

    IBM POWER

    ppc64le

    64-bit IBM Z

    s390x

17.6. 使用 GDB 为应用程序或库获取 debuginfo 软件包

调试信息需要调试信息。对于从软件包安装的代码,GNU Debugger(GDB)会自动识别缺少的调试信息,解决软件包名称并提供了有关如何获取软件包的具体建议。

先决条件

  • 您要调试的应用程序或库必须安装在系统上。
  • GDB 和 debuginfo-install 工具必须安装在系统中。详情请查看 设置调试应用程序
  • 在系统中必须配置并启用提供 debuginfodebugsource 软件包的频道。

流程

  1. 启动附加到您要调试的应用程序或库的 GDB。GDB 自动识别缺少的调试信息,并建议运行 命令。

    $ gdb -q /bin/ls
    Reading symbols from /bin/ls...Reading symbols from .gnu_debugdata for /usr/bin/ls...(no debugging symbols found)...done.
    (no debugging symbols found)...done.
    Missing separate debuginfos, use: dnf debuginfo-install coreutils-8.30-6.el8.x86_64
    (gdb)
  2. 退出 GDB: 键入 q,然后使用 Enter 进行确认

    (gdb) q
  3. 运行 GDB 建议的命令安装所需的 debuginfo 软件包:

    # dnf debuginfo-install coreutils-8.30-6.el8.x86_64

    dnf 软件包管理工具提供更改概述,询问确认,下载并安装所有必要的文件。

  4. 如果 GDB 无法推荐 debuginfo 软件包,请按照手动为应用程序或库获取 debuginfo 软件包的步骤进行操作

第 18 章 使用 perf stat 计算进程执行期间的事件

您可以使用 perf stat 命令在进程执行过程中统计硬件和软件事件。

先决条件

18.1. perf stat 的目的

perf stat 命令执行指定的命令,在命令执行过程中保留正在运行的硬件和软件事件计数,并生成这些计数的统计信息。如果您没有指定任何事件,则 perf stat 计算一组常见的硬件和软件事件。

18.2. 使用 perf stat 计算事件

您可以使用 perf stat 统计命令执行过程中出现的硬件和软件事件,并生成这些计数的统计信息。默认情况下,perf stat 在每个线程模式下运行。

先决条件

流程

  • 计算事件数。

    • 在没有 root 访问权限的情况下运行 perf stat 命令只会统计用户空间中发生的事件:

      $ perf stat ls

      例 18.1. perf stat 的输出在没有 root 访问权限的情况下运行

      Desktop  Documents  Downloads  Music  Pictures  Public  Templates  Videos
      
       Performance counter stats for 'ls':
      
                    1.28 msec task-clock:u               #    0.165 CPUs utilized
                       0      context-switches:u         #    0.000 M/sec
                       0      cpu-migrations:u           #    0.000 K/sec
                     104      page-faults:u              #    0.081 M/sec
               1,054,302      cycles:u                   #    0.823 GHz
               1,136,989      instructions:u             #    1.08  insn per cycle
                 228,531      branches:u                 #  178.447 M/sec
                  11,331      branch-misses:u            #    4.96% of all branches
      
             0.007754312 seconds time elapsed
      
             0.000000000 seconds user
             0.007717000 seconds sys

      如上例中所示,当 perf stat 在没有 root 的情况下运行时,事件名称后面会跟着 :u,这表示这些事件只在用户空间中计数。

    • 要同时计算用户空间和内核空间事件,您必须在运行 perf stat 时具有 root 访问权限:

      # perf stat ls

      例 18.2. perf stat 的输出使用 root 访问权限运行

      Desktop  Documents  Downloads  Music  Pictures  Public  Templates  Videos
      
       Performance counter stats for 'ls':
      
                    3.09 msec task-clock                #    0.119 CPUs utilized
                      18      context-switches          #    0.006 M/sec
                       3      cpu-migrations            #    0.969 K/sec
                     108      page-faults               #    0.035 M/sec
               6,576,004      cycles                    #    2.125 GHz
               5,694,223      instructions              #    0.87  insn per cycle
               1,092,372      branches                  #  352.960 M/sec
                  31,515      branch-misses             #    2.89% of all branches
      
             0.026020043 seconds time elapsed
      
             0.000000000 seconds user
             0.014061000 seconds sys
      • 默认情况下,perf stat 在每个线程模式下运行。要改为 CPU 范围的事件计数,将 -a 选项传递给 perf stat。要计算 CPU 范围的事件,您需要 root 访问权限:

        # perf stat -a ls

其它资源

  • perf-stat(1) man page

18.3. perf stat 输出的解读

perf stat 执行命令期间执行指定命令并计算发生的事件,并在三列中显示这些计数的统计信息:

  1. 给定事件的出现次数
  2. 所计算的事件的名称
  3. 当相关指标可用时,最右侧列中的 hash 符号(#)后会显示一个比率或百分比。

    例如,当以默认模式运行时,perf stat 计算周期和指令,因此在最右侧列中计算并显示每个周期的说明。您可以看到与分支缺少相关的类似行为,因为默认情况下这两个事件都被计算为两个分支的百分比。

18.4. 将 perf stat 附加到正在运行的进程

您可以将 perf stat 附加到正在运行的进程。这将指示 perf stat 计算命令执行期间仅在指定进程中发生的事件。

先决条件

流程

  • perf stat 附加到正在运行的进程:

    $ perf stat -p ID1,ID2 sleep seconds

    前面的示例计算 ID 为 ID1ID2 的进程中的事件,时间为 seconds 秒,这由 sleep 命令指定。

其它资源

  • perf-stat(1) man page

第 19 章 使用 perf 记录和分析性能配置集

perf 工具允许您记录性能数据并稍后进行分析。

先决条件

19.1. perf 记录的目的

perf record 命令对性能数据进行样本,并将其保存在文件 perf.data 中,该文件可与其他 perf 命令读取和视觉化。perf.data 是在当前目录中生成的,可以在以后访问,可能在其他计算机上访问。

如果您没有为 perf record 指定在安装过程中记录的命令,它将记录,直到您通过按 Ctrl+C 手动停止该进程为止。您可以将 perf record 附加到特定进程,方法是传递 -p 选项后跟一个或多个进程 ID。您可以在没有 root 访问权限的情况下运行 perf record,但是这样做只会在用户空间中示例性能数据。在默认模式中,perf record 将 CPU 周期用作抽样事件,并在启用了继承模式的每线程模式中运行。

19.2. 在没有 root 访问权限的情况下记录性能配置集

您可以在没有 root 访问权限的情况下使用 perf record,只用于用户空间中的示例和记录性能数据。

先决条件

流程

  • 示例并记录性能数据:

    $ perf record command

    使用您要在其中示例数据的命令替换 command。如果您没有指定命令,则 perf record Ctrl+C

附加资源

  • perf-record(1) man page

19.3. 使用 root 访问权限记录性能配置集

您可以在 root 访问权限中使用 perf record 来同时在用户空间和内核空间中对性能数据进行抽样和记录。

先决条件

流程

  • 示例并记录性能数据:

    # perf record command

    使用您要在其中示例数据的命令替换 command。如果您没有指定命令,则 perf record Ctrl+C

附加资源

  • perf-record(1) man page

19.4. 以每个 CPU 模式记录性能配置集

您可以在被监控 CPU 上的所有线程中同时使用 perf record 在每个 CPU 模式中对用户空间和内核空间的性能数据进行抽样和记录。默认情况下,按 CPU 模式监控所有在线 CPU。

先决条件

流程

  • 示例并记录性能数据:

    # perf record -a command

    使用您要在其中示例数据的命令替换 command。如果您没有指定命令,则 perf record Ctrl+C

其它资源

  • perf-record(1) man page

19.5. 使用 perf 记录捕获调用图形数据

您可以配置 perf record 工具,以便记录哪些功能在性能配置集中调用其他功能。这有助于识别多个进程调用同一功能时的瓶颈。

先决条件

流程

  • 使用 --call-graph 选项的示例和记录性能数据:

    $ perf record --call-graph method command
    • 使用您要在其中示例数据的命令替换 command。如果您没有指定命令,则 perf record Ctrl+C
    • 使用以下解压缩方法之一替换方法

      fp
      使用帧指针方法。根据编译器优化,比如使用 GCC 选项 --fomit-frame-pointer 构建的二进制文件,这可能无法取消堆栈。
      dwarf
      使用 DWARF 调用信息来取消堆栈。
      lbr
      在 Intel 处理器上使用最后一个分支记录硬件。

其它资源

  • perf-record(1) man page

19.6. 使用 perf 报告分析 perf.data

您可以使用 perf report 显示和分析 perf.data 文件。

先决条件

  • 已安装 perf 用户空间工具。如需更多信息,请参阅安装 perf
  • 当前目录中有一个 perf.data 文件。
  • 如果 perf.data 文件是使用 root 访问权限创建的,则需要同时使用 root 访问权限运行 perf report

流程

  • 显示 perf.data 文件的内容以进行进一步分析:

    # perf report

    这个命令会显示类似如下的输出:

    Samples: 2K of event 'cycles', Event count (approx.): 235462960
    Overhead  Command          Shared Object                     Symbol
       2.36%  kswapd0          [kernel.kallsyms]                 [k] page_vma_mapped_walk
       2.13%  sssd_kcm         libc-2.28.so                      [.] memset_avx2_erms 2.13% perf [kernel.kallsyms] [k] smp_call_function_single 1.53% gnome-shell libc-2.28.so [.] strcmp_avx2
       1.17%  gnome-shell      libglib-2.0.so.0.5600.4           [.] g_hash_table_lookup
       0.93%  Xorg             libc-2.28.so                      [.] memmove_avx_unaligned_erms 0.89% gnome-shell libgobject-2.0.so.0.5600.4 [.] g_object_unref 0.87% kswapd0 [kernel.kallsyms] [k] page_referenced_one 0.86% gnome-shell libc-2.28.so [.] memmove_avx_unaligned_erms
       0.83%  Xorg             [kernel.kallsyms]                 [k] alloc_vmap_area
       0.63%  gnome-shell      libglib-2.0.so.0.5600.4           [.] g_slice_alloc
       0.53%  gnome-shell      libgirepository-1.0.so.1.0.0      [.] g_base_info_unref
       0.53%  gnome-shell      ld-2.28.so                        [.] _dl_find_dso_for_object
       0.49%  kswapd0          [kernel.kallsyms]                 [k] vma_interval_tree_iter_next
       0.48%  gnome-shell      libpthread-2.28.so                [.] pthread_getspecific 0.47% gnome-shell libgirepository-1.0.so.1.0.0 [.] 0x0000000000013b1d 0.45% gnome-shell libglib-2.0.so.0.5600.4 [.] g_slice_free1 0.45% gnome-shell libgobject-2.0.so.0.5600.4 [.] g_type_check_instance_is_fundamentally_a 0.44% gnome-shell libc-2.28.so [.] malloc 0.41% swapper [kernel.kallsyms] [k] apic_timer_interrupt 0.40% gnome-shell ld-2.28.so [.] _dl_lookup_symbol_x 0.39% kswapd0 [kernel.kallsyms] [k] raw_callee_save___pv_queued_spin_unlock

附加资源

  • perf-report(1) man page

19.7. perf 报告输出的解读

运行 perf report 命令显示的表将数据分为几个列:

'Overhead' 列
指明在该特定功能中收集总样本的百分比。
'Command' 列
告诉您从哪个进程收集样本。
"共享对象"列
显示样本来自的 ELF 镜像的名称(样本来自内核时使用名称 [kernel.kallsyms])。
'Symbol' 列
显示函数名称或符号。

在默认模式中,函数按照降序排列,其开销最先显示。

19.8. 生成可在不同设备中读取的 perf.data 文件

您可以使用 perf 工具将性能数据记录到要在不同设备中分析的 perf.data 文件中。

先决条件

流程

  1. 捕获您有兴趣进一步调查的性能数据:

    # perf record -a --call-graph fp sleep seconds

    这个示例将在整个系统中根据 sleep 命令的规定在 seconds 秒内生成 perf.data。它还将使用帧指针方法捕获调用图形数据。

  2. 生成包含记录数据的调试符号的归档文件:

    # perf archive

验证步骤

  • 验证归档文件是否已在当前活跃目录中生成:

    # ls perf.data*

    输出将显示当前目录中以 perf.data 开头的每个文件。归档文件将命名为:

    perf.data.tar.gz

    或者

    perf data.tar.bz2

19.9. 分析在不同设备中创建的 perf.data 文件

您可以使用 perf 工具分析在不同设备中生成的 perf.data 文件。

先决条件

流程

  1. perf.data 文件和归档文件复制到您当前的活跃目录中。
  2. 将存档文件提取到 ~/.debug

    # mkdir -p ~/.debug
    # tar xf perf.data.tar.bz2 -C ~/.debug
    注意

    归档文件也可能命名为 perf.data.tar.gz

  3. 打开 perf.data 文件进行进一步分析:

    # perf report

19.10. 为什么 perf 显示一些功能名称作为原始函数地址

对于内核函数,perf 使用 /proc/kallsyms 文件中的信息将示例映射到对应的功能名称或符号。但是,对于在用户空间中执行的功能,您可能会看到原始功能地址,因为二进制已被剥离。

必须安装可执行文件的 debuginfo 软件包,如果可执行文件是本地开发的应用程序,则必须编译应用程序并打开调试信息(GCC 中的 -g 选项)以显示在这种情况下的功能名称或符号。

注意

安装与可执行文件关联的 debuginfo 后,不需要重新运行 perf record 命令。只需重新运行 perf report 命令。

19.11. 启用 debug 和源存储库

Red Hat Enterprise Linux 的标准安装不会启用 debug 和源存储库。这些存储库包含调试系统组件和衡量其性能所需的信息。

流程

  • 启用源和调试信息软件包频道:

    # subscription-manager repos --enable rhel-8-for-$(uname -i)-baseos-debug-rpms
    # subscription-manager repos --enable rhel-8-for-$(uname -i)-baseos-source-rpms
    # subscription-manager repos --enable rhel-8-for-$(uname -i)-appstream-debug-rpms
    # subscription-manager repos --enable rhel-8-for-$(uname -i)-appstream-source-rpms

    $(uname -i) 部分自动替换为您的系统构架的匹配值:

    架构名称

    64 位 Intel 和 AMD

    x86_64

    64-bit ARM

    aarch64

    IBM POWER

    ppc64le

    64-bit IBM Z

    s390x

19.12. 使用 GDB 为应用程序或库获取 debuginfo 软件包

调试信息需要调试信息。对于从软件包安装的代码,GNU Debugger(GDB)会自动识别缺少的调试信息,解决软件包名称并提供了有关如何获取软件包的具体建议。

先决条件

  • 您要调试的应用程序或库必须安装在系统上。
  • GDB 和 debuginfo-install 工具必须安装在系统中。详情请查看 设置调试应用程序
  • 在系统中必须配置并启用提供 debuginfodebugsource 软件包的频道。

流程

  1. 启动附加到您要调试的应用程序或库的 GDB。GDB 自动识别缺少的调试信息,并建议运行 命令。

    $ gdb -q /bin/ls
    Reading symbols from /bin/ls...Reading symbols from .gnu_debugdata for /usr/bin/ls...(no debugging symbols found)...done.
    (no debugging symbols found)...done.
    Missing separate debuginfos, use: dnf debuginfo-install coreutils-8.30-6.el8.x86_64
    (gdb)
  2. 退出 GDB: 键入 q,然后使用 Enter 进行确认

    (gdb) q
  3. 运行 GDB 建议的命令安装所需的 debuginfo 软件包:

    # dnf debuginfo-install coreutils-8.30-6.el8.x86_64

    dnf 软件包管理工具提供更改概述,询问确认,下载并安装所有必要的文件。

  4. 如果 GDB 无法推荐 debuginfo 软件包,请按照手动为应用程序或库获取 debuginfo 软件包的步骤进行操作

第 20 章 使用 perf 调查忙碌 CPU

在调查系统中的性能问题时,您可以使用 perf 工具来识别和监控忙碌 CPU,以便专注于工作。

20.1. 使用 perf stat 显示在哪些 CPU 事件计数

您可以使用 perf stat 来通过禁用 CPU 计数聚合来显示哪些 CPU 事件计数。您必须使用 -a 标记计算系统范围模式中的事件,才能使用此功能。

先决条件

流程

  • 计数禁用 CPU 数量聚合的事件:

    # perf stat -a -A sleep seconds

    前面的示例显示在 seconds 秒的时间段记录的一组默认通用硬件和软件事件的计数,这由使用 sleep 命令以升序排列的每个 CPU 指定的,从 CPU0 开始。因此,指定周期等事件可能会很有用:

    # perf stat -a -A -e cycles sleep seconds

20.2. 显示使用 perf 报告进行的 CPU 样本

perf record 命令对性能数据进行样本,并将这些数据保存在可以使用 perf report 命令读取的 perf.data 文件中。perf record 命令始终记录获取的 CPU 样本。您可以配置 perf report 来显示此信息。

先决条件

  • 您已安装了 perf 用户空间工具,如安装 perf 所述。
  • 当前目录中使用 perf record 创建了一个 perf.data 文件。如果 perf.data 文件是使用 root 访问权限创建的,则需要同时使用 root 访问权限运行 perf report

流程

  • 在按 CPU 排序时显示 perf.data 文件的内容以进行进一步分析:

    # perf report --sort cpu
    • 您可以按 CPU 和命令排序,以显示 CPU 时间所花位置的更多详细信息:

      # perf report --sort cpu,comm

      本示例将列出所有受监控 CPU 的命令,按开销使用量降序排列所有受监控 CPU 的命令,并确定运行命令所针对的 CPU。

20.3. 在使用 perf top 分析时显示特定的 CPU

您可以将 perf top 配置为在实时分析系统时显示特定 CPU 及其相对使用情况。

先决条件

流程

  • 在按 CPU 排序时启动 perf top 接口:

    # perf top --sort cpu

    本示例将实时按开销使用量降序列出 CPU 及其对应的开销。

    • 您可以按 CPU 和命令排序,以获取有关 CPU 时间所花位置的更多详细信息:

      # perf top --sort cpu,comm

      本示例将按开销使用量降序排列命令列出命令,并确定实时执行该命令的 CPU。

20.4. 使用 perf 记录和 perf 报告监控特定 CPU

您可以将 perf record 配置为仅抽样相关特定 CPU,并使用 perf report 分析生成的 perf.data 文件,以便进一步分析。

先决条件

流程

  1. 示例并在特定 CPU 中记录性能数据,生成 perf.data 文件:

    • 使用以逗号分隔的 CPU 列表:

      # perf record -C 0,1 sleep seconds

      前面的示例在 CPU 0 和 1 中记录数据,时间为 seconds 秒,具体取决于使用 sleep 命令的规定。

    • 使用一组 CPU:

      # perf record -C 0-2 sleep seconds

      前面的示例示例并记录 CPU 0 到 2 中所有 CPU 中的数据,时间为 seconds 秒(根据使用 sleep 命令的规定)。

  2. 显示 perf.data 文件的内容以进行进一步分析:

    # perf report

    这个示例将显示 perf.data 的内容。如果您正在监控多个 CPU,并想了解哪个 CPU 数据被抽样,请参阅 显示使用 perf 报告进行的 CPU 样本

第 21 章 使用 perf 监控应用程序性能

本节论述了如何使用 perf 工具监控应用程序性能。

21.1. 将 perf 记录附加到正在运行的进程

您可以将 perf record 附加到正在运行的进程。这将指示 perf record 仅对指定进程中的性能数据进行抽样和记录。

先决条件

流程

  • perf record 附加到正在运行的进程:

    $ perf record -p ID1,ID2 sleep seconds

    前面的示例示例并记录了带有进程 ID ID1ID2 的进程的性能数据,时间跨度为 seconds 秒,使用 sleep 命令指定。您还可以配置 perf 以记录特定线程中的事件:

    $ perf record -t ID1,ID2 sleep seconds
    注意

    当使用 -t 标志并强制处理线程 ID 时,perf 默认禁用继承。您可以通过添加 --inherit 选项来启用继承。

21.2. 使用 perf 记录捕获调用图形数据

您可以配置 perf record 工具,以便记录哪些功能在性能配置集中调用其他功能。这有助于识别多个进程调用同一功能时的瓶颈。

先决条件

流程

  • 使用 --call-graph 选项的示例和记录性能数据:

    $ perf record --call-graph method command
    • 使用您要在其中示例数据的命令替换 command。如果您没有指定命令,则 perf record Ctrl+C
    • 使用以下解压缩方法之一替换方法

      fp
      使用帧指针方法。根据编译器优化,比如使用 GCC 选项 --fomit-frame-pointer 构建的二进制文件,这可能无法取消堆栈。
      dwarf
      使用 DWARF 调用信息来取消堆栈。
      lbr
      在 Intel 处理器上使用最后一个分支记录硬件。

其它资源

  • perf-record(1) man page

21.3. 使用 perf 报告分析 perf.data

您可以使用 perf report 显示和分析 perf.data 文件。

先决条件

  • 已安装 perf 用户空间工具。如需更多信息,请参阅安装 perf
  • 当前目录中有一个 perf.data 文件。
  • 如果 perf.data 文件是使用 root 访问权限创建的,则需要同时使用 root 访问权限运行 perf report

流程

  • 显示 perf.data 文件的内容以进行进一步分析:

    # perf report

    这个命令会显示类似如下的输出:

    Samples: 2K of event 'cycles', Event count (approx.): 235462960
    Overhead  Command          Shared Object                     Symbol
       2.36%  kswapd0          [kernel.kallsyms]                 [k] page_vma_mapped_walk
       2.13%  sssd_kcm         libc-2.28.so                      [.] memset_avx2_erms 2.13% perf [kernel.kallsyms] [k] smp_call_function_single 1.53% gnome-shell libc-2.28.so [.] strcmp_avx2
       1.17%  gnome-shell      libglib-2.0.so.0.5600.4           [.] g_hash_table_lookup
       0.93%  Xorg             libc-2.28.so                      [.] memmove_avx_unaligned_erms 0.89% gnome-shell libgobject-2.0.so.0.5600.4 [.] g_object_unref 0.87% kswapd0 [kernel.kallsyms] [k] page_referenced_one 0.86% gnome-shell libc-2.28.so [.] memmove_avx_unaligned_erms
       0.83%  Xorg             [kernel.kallsyms]                 [k] alloc_vmap_area
       0.63%  gnome-shell      libglib-2.0.so.0.5600.4           [.] g_slice_alloc
       0.53%  gnome-shell      libgirepository-1.0.so.1.0.0      [.] g_base_info_unref
       0.53%  gnome-shell      ld-2.28.so                        [.] _dl_find_dso_for_object
       0.49%  kswapd0          [kernel.kallsyms]                 [k] vma_interval_tree_iter_next
       0.48%  gnome-shell      libpthread-2.28.so                [.] pthread_getspecific 0.47% gnome-shell libgirepository-1.0.so.1.0.0 [.] 0x0000000000013b1d 0.45% gnome-shell libglib-2.0.so.0.5600.4 [.] g_slice_free1 0.45% gnome-shell libgobject-2.0.so.0.5600.4 [.] g_type_check_instance_is_fundamentally_a 0.44% gnome-shell libc-2.28.so [.] malloc 0.41% swapper [kernel.kallsyms] [k] apic_timer_interrupt 0.40% gnome-shell ld-2.28.so [.] _dl_lookup_symbol_x 0.39% kswapd0 [kernel.kallsyms] [k] raw_callee_save___pv_queued_spin_unlock

附加资源

  • perf-report(1) man page

第 22 章 使用 perf mem 分析内存访问

您可以使用 perf mem 命令示例系统中的内存访问。

22.1. perf mem 的目的

perf 工具的 mem 子命令允许对内存访问进行抽样(负载和存储)。perf mem 命令提供有关内存延迟、内存访问类型、导致缓存命中和丢失的功能的信息,并通过记录数据符号,记录这些命中和丢失的内存位置。

22.2. 使用 perf mem 对内存进行抽样访问

这个步骤描述了如何使用 perf mem 命令对系统中内存访问进行示例。命令采用与 perf recordperf report 相同的选项,以及专用于 mem 子命令的一些选项。记录的数据保存在当前目录中的 perf.data 文件中,以便稍后进行分析。

先决条件

流程

  1. 内存访问示例:

    # perf mem record -a sleep seconds

    这个示例根据 sleep 命令的规定,在所有 CPU 间访问内存时长为秒。您可以为要示例内存访问数据的任何命令替换 sleep 命令。默认情况下,perf mem 对内存负载和存储的示例。您只能使用 -t 选项选择一个内存操作,并在 perf memrecord 之间指定 "load" 或 "store"。对于负载,捕获内存层次结构级别的信息、TLB 内存访问、总线侦听和内存锁定。

  2. 打开 perf.data 文件进行分析:

    # perf mem report

    如果您使用了示例命令,输出为:

    Available samples
    35k cpu/mem-loads,ldlat=30/P
    54k cpu/mem-stores/P

    cpu/mem-loads,ldlat=30/P 行表示通过内存负载收集的数据,cpu/mem-stores/P 行表示通过内存存储收集的数据。突出显示相关类别并按 Enter 查看数据:

    Samples: 35K of event 'cpu/mem-loads,ldlat=30/P', Event count (approx.): 4067062
    Overhead       Samples  Local Weight  Memory access             Symbol                                                                 Shared Object                 Data Symbol                                                     Data Object                            Snoop         TLB access              Locked
       0.07%            29  98            L1 or L1 hit              [.] 0x000000000000a255                                                 libspeexdsp.so.1.5.0          [.] 0x00007f697a3cd0f0                                          anon                                   None          L1 or L2 hit            No
       0.06%            26  97            L1 or L1 hit              [.] 0x000000000000a255                                                 libspeexdsp.so.1.5.0          [.] 0x00007f697a3cd0f0                                          anon                                   None          L1 or L2 hit            No
       0.06%            25  96            L1 or L1 hit              [.] 0x000000000000a255                                                 libspeexdsp.so.1.5.0          [.] 0x00007f697a3cd0f0                                          anon                                   None          L1 or L2 hit            No
       0.06%             1  2325          Uncached or N/A hit       [k] pci_azx_readl                                                      [kernel.kallsyms]             [k] 0xffffb092c06e9084                                          [kernel.kallsyms]                      None          L1 or L2 hit            No
       0.06%             1  2247          Uncached or N/A hit       [k] pci_azx_readl                                                      [kernel.kallsyms]             [k] 0xffffb092c06e8164                                          [kernel.kallsyms]                      None          L1 or L2 hit            No
       0.05%             1  2166          L1 or L1 hit              [.] 0x00000000038140d6                                                 libxul.so                     [.] 0x00007ffd7b84b4a8                                          [stack]                                None          L1 or L2 hit            No
       0.05%             1  2117          Uncached or N/A hit       [k] check_for_unclaimed_mmio                                           [kernel.kallsyms]             [k] 0xffffb092c1842300                                          [kernel.kallsyms]                      None          L1 or L2 hit            No
       0.05%            22  95            L1 or L1 hit              [.] 0x000000000000a255                                                 libspeexdsp.so.1.5.0          [.] 0x00007f697a3cd0f0                                          anon                                   None          L1 or L2 hit            No
       0.05%             1  1898          L1 or L1 hit              [.] 0x0000000002a30e07                                                 libxul.so                     [.] 0x00007f610422e0e0                                          anon                                   None          L1 or L2 hit            No
       0.05%             1  1878          Uncached or N/A hit       [k] pci_azx_readl                                                      [kernel.kallsyms]             [k] 0xffffb092c06e8164                                          [kernel.kallsyms]                      None          L2 miss                 No
       0.04%            18  94            L1 or L1 hit              [.] 0x000000000000a255                                                 libspeexdsp.so.1.5.0          [.] 0x00007f697a3cd0f0                                          anon                                   None          L1 or L2 hit            No
       0.04%             1  1593          Local RAM or RAM hit      [.] 0x00000000026f907d                                                 libxul.so                     [.] 0x00007f3336d50a80                                          anon                                   Hit           L2 miss                 No
       0.03%             1  1399          L1 or L1 hit              [.] 0x00000000037cb5f1                                                 libxul.so                     [.] 0x00007fbe81ef5d78                                          libxul.so                              None          L1 or L2 hit            No
       0.03%             1  1229          LFB or LFB hit            [.] 0x0000000002962aad                                                 libxul.so                     [.] 0x00007fb6f1be2b28                                          anon                                   None          L2 miss                 No
       0.03%             1  1202          LFB or LFB hit            [.] __pthread_mutex_lock                                               libpthread-2.29.so            [.] 0x00007fb75583ef20                                          anon                                   None          L1 or L2 hit            No
       0.03%             1  1193          Uncached or N/A hit       [k] pci_azx_readl                                                      [kernel.kallsyms]             [k] 0xffffb092c06e9164                                          [kernel.kallsyms]                      None          L2 miss                 No
       0.03%             1  1191          L1 or L1 hit              [k] azx_get_delay_from_lpib                                            [kernel.kallsyms]             [k] 0xffffb092ca7efcf0                                          [kernel.kallsyms]                      None          L1 or L2 hit            No

    或者,您可以对结果进行排序,以调查显示数据时感兴趣的不同方面。例如,要按抽样期间发生的内存访问类型对内存负载进行排序,请按它们所考虑的开销降序排列:

    # perf mem -t load report --sort=mem

    例如,输出可以是:

    Samples: 35K of event 'cpu/mem-loads,ldlat=30/P', Event count (approx.): 40670
    Overhead       Samples  Memory access
      31.53%          9725  LFB or LFB hit
      29.70%         12201  L1 or L1 hit
      23.03%          9725  L3 or L3 hit
      12.91%          2316  Local RAM or RAM hit
       2.37%           743  L2 or L2 hit
       0.34%             9  Uncached or N/A hit
       0.10%            69  I/O or N/A hit
       0.02%           825  L3 miss

其它资源

  • perf-mem(1) man 手册.

22.3. perf mem 报告输出的解读

运行不带修饰符的 perf mem report 命令显示的表,可将数据分为几个列:

'Overhead' 列
表示特定功能中收集的整体样本的百分比。
'Samples' 列
显示按该行划分的示例数量。
'Local Weight' 列
显示处理器核心周期的访问延迟。
'Memory Access' 列
显示发生的内存访问类型。
'Symbol' 列
显示函数名称或符号。
"共享对象"列
显示样本来自的 ELF 镜像的名称(样本来自内核时使用名称 [kernel.kallsyms])。
"Data Symbol"列
显示所在行所针对的内存位置的地址。
重要

通常,由于被访问的内存或堆栈内存的动态分配,"数据 Symbol"列将显示原始地址。

"Snoop"列
显示总线事务.
'TLB Access' 列
显示 TLB 内存访问。
'Locked' 列
指示函数是否已被锁定或未锁定内存。

在默认模式中,函数按照降序排列,其开销最先显示。

第 23 章 检测错误共享

当对称多处理(SMP)系统上的处理器核心修改同一缓存行上供其他处理器用于访问处理器之间未共享的其他数据项时,就会进行错误共享。

这种初始修改要求使用缓存行的其他处理器将其副本失效并请求更新的处理器,尽管处理器不需要,甚至不必访问更新后的数据项版本。

您可以使用 perf c2c 命令检测错误共享。

23.1. perf c2c 的目的

perf 工具的 c2c 子命令启用共享数据缓存到缓存(C2C)分析。您可以使用 perf c2c 命令检查缓存行争用来检测真实和错误共享。

当单对称多进程(SMP)系统上的处理器核心修改其他处理器所使用的同一缓存行上的数据项时,就会发生缓存行争。所有其他使用此缓存行的处理器都必须将其副本失效并请求更新的副本。这会导致性能下降。

perf c2c 命令提供以下信息:

  • 检测到竞争的缓存行
  • 进程读取和写入数据
  • 导致竞争的指令
  • 争用中的非一致性内存访问(NUMA)节点

23.2. 使用 perf c2c 检测缓存行竞争

使用 perf c2c 命令检测系统中的缓存行争用。

perf c2c 命令支持与 perf record 相同的选项,也支持专用于 c2c 子命令的一些选项。记录的数据保存在当前目录中的 perf.data 文件中,以便稍后进行分析。

先决条件

流程

  • 使用 perf c2c 检测缓存行争用:

    # perf c2c record -a sleep seconds

    这个示例示例按照 sleep 命令的规定,在所有 CPU 的 seconds 周期内对所有 CPU 的缓存线性争用数据进行抽样和记录。您可以使用您要通过收集缓存线争用数据的任何命令替换 sleep 命令。

其它资源

  • perf-c2c(1) man page

23.3. 视觉化使用 perf c2c 记录记录的 perf.data 文件

这个步骤描述了如何视觉化 perf.data 文件,该文件使用 perf c2c 命令记录。

先决条件

流程

  1. 打开 perf.data 文件进行进一步分析:

    # perf c2c report --stdio

    这个命令将 perf.data 文件视觉化为终端中的几个图形:

    =================================================
               Trace Event Information
    =================================================
     Total records                     :     329219
     Locked Load/Store Operations      :      14654
     Load Operations                   :      69679
     Loads - uncacheable               :          0
     Loads - IO                        :          0
     Loads - Miss                      :       3972
     Loads - no mapping                :          0
     Load Fill Buffer Hit              :      11958
     Load L1D hit                      :      17235
     Load L2D hit                      :         21
     Load LLC hit                      :      14219
     Load Local HITM                   :       3402
     Load Remote HITM                  :      12757
     Load Remote HIT                   :       5295
     Load Local DRAM                   :        976
     Load Remote DRAM                  :       3246
     Load MESI State Exclusive         :       4222
     Load MESI State Shared            :          0
     Load LLC Misses                   :      22274
     LLC Misses to Local DRAM          :        4.4%
     LLC Misses to Remote DRAM         :       14.6%
     LLC Misses to Remote cache (HIT)  :       23.8%
     LLC Misses to Remote cache (HITM) :       57.3%
     Store Operations                  :     259539
     Store - uncacheable               :          0
     Store - no mapping                :         11
     Store L1D Hit                     :     256696
     Store L1D Miss                    :       2832
     No Page Map Rejects               :       2376
     Unable to parse data source       :          1
    
    =================================================
       Global Shared Cache Line Event Information
    =================================================
     Total Shared Cache Lines          :         55
     Load HITs on shared lines         :      55454
     Fill Buffer Hits on shared lines  :      10635
     L1D hits on shared lines          :      16415
     L2D hits on shared lines          :          0
     LLC hits on shared lines          :       8501
     Locked Access on shared lines     :      14351
     Store HITs on shared lines        :     109953
     Store L1D hits on shared lines    :     109449
     Total Merged records              :     126112
    
    =================================================
                     c2c details
    =================================================
     Events                            : cpu/mem-loads,ldlat=30/P
    	                                    : cpu/mem-stores/P
     Cachelines sort on                : Remote HITMs
     Cacheline data groupping          : offset,pid,iaddr
    
    =================================================
    	   Shared Data Cache Line Table
    =================================================
    #
    #                              Total      Rmt  ----- LLC Load Hitm -----  ---- Store Reference ----  --- Load Dram ----      LLC    Total  ----- Core Load Hit -----  -- LLC Load Hit --
    # Index           Cacheline  records     Hitm    Total      Lcl      Rmt    Total    L1Hit   L1Miss       Lcl       Rmt  Ld Miss    Loads       FB       L1       L2       Llc       Rmt
    # .....  ..................  .......  .......  .......  .......  .......  .......  .......  .......  ........  ........  .......  .......  .......  .......  .......  ........  ........
    #
          0            0x602180   149904   77.09%    12103     2269     9834   109504   109036      468       727      2657    13747    40400     5355    16154        0      2875       529
          1            0x602100    12128   22.20%     3951     1119     2832        0        0        0        65       200     3749    12128     5096      108        0      2056       652
          2  0xffff883ffb6a7e80      260    0.09%       15        3       12      161      161        0         1         1       15       99       25       50        0         6         1
          3  0xffffffff81aec000      157    0.07%        9        0        9        1        0        1         0         7       20      156       50       59        0        27         4
          4  0xffffffff81e3f540      179    0.06%        9        1        8      117       97       20         0        10       25       62       11        1        0        24         7
    
    =================================================
          Shared Cache Line Distribution Pareto
    =================================================
    #
    #        ----- HITM -----  -- Store Refs --        Data address                               ---------- cycles ----------       cpu                                     Shared
    #   Num      Rmt      Lcl   L1 Hit  L1 Miss              Offset      Pid        Code address  rmt hitm  lcl hitm      load       cnt               Symbol                Object                  Source:Line  Node{cpu list}
    # .....  .......  .......  .......  .......  ..................  .......  ..................  ........  ........  ........  ........  ...................  ....................  ...........................  ....
    #
      -------------------------------------------------------------
          0     9834     2269   109036      468            0x602180
      -------------------------------------------------------------
              65.51%   55.88%   75.20%    0.00%                 0x0    14604            0x400b4f     27161     26039     26017         9  [.] read_write_func  no_false_sharing.exe  false_sharing_example.c:144   0{0-1,4}  1{24-25,120}  2{48,54}  3{169}
    	   0.41%    0.35%    0.00%    0.00%                 0x0    14604            0x400b56     18088     12601     26671         9  [.] read_write_func  no_false_sharing.exe  false_sharing_example.c:145   0{0-1,4}  1{24-25,120}  2{48,54}  3{169}
    	   0.00%    0.00%   24.80%  100.00%                 0x0    14604            0x400b61         0         0         0         9  [.] read_write_func  no_false_sharing.exe  false_sharing_example.c:145   0{0-1,4}  1{24-25,120}  2{48,54}  3{169}
    	   7.50%    9.92%    0.00%    0.00%                0x20    14604            0x400ba7      2470      1729      1897         2  [.] read_write_func  no_false_sharing.exe  false_sharing_example.c:154   1{122}  2{144}
    	  17.61%   20.89%    0.00%    0.00%                0x28    14604            0x400bc1      2294      1575      1649         2  [.] read_write_func  no_false_sharing.exe  false_sharing_example.c:158   2{53}  3{170}
    	   8.97%   12.96%    0.00%    0.00%                0x30    14604            0x400bdb      2325      1897      1828         2  [.] read_write_func  no_false_sharing.exe  false_sharing_example.c:162   0{96}  3{171}
    
      -------------------------------------------------------------
          1     2832     1119        0        0            0x602100
      -------------------------------------------------------------
    	  29.13%   36.19%    0.00%    0.00%                0x20    14604            0x400bb3      1964      1230      1788         2  [.] read_write_func  no_false_sharing.exe  false_sharing_example.c:155   1{122}  2{144}
    	  43.68%   34.41%    0.00%    0.00%                0x28    14604            0x400bcd      2274      1566      1793         2  [.] read_write_func  no_false_sharing.exe  false_sharing_example.c:159   2{53}  3{170}
    	  27.19%   29.40%    0.00%    0.00%                0x30    14604            0x400be7      2045      1247      2011         2  [.] read_write_func  no_false_sharing.exe  false_sharing_example.c:163   0{96}  3{171}

23.4. perf c2c 报告输出的解读

本节论述了如何解释 perf c2c report 命令的输出。

运行 perf c2c report --stdio 命令显示的视觉化将数据排序为多个表:

Trace Events Information
这个表提供了 perf c2c record 命令收集的所有负载和存储样本的高级概述。
Global Shared Cache Line Event Information
此表提供有关共享缓存行的统计信息。
c2c Details
这个表格提供有关哪些事件被抽样的信息,以及 perf c2c report 数据如何在视觉化中组织的信息。
Shared Data Cache Line Table
此表为热门缓存行提供一个行摘要,其中检测到假共享,按照默认情况下每个缓存行检测到的远程 Hitm 数量来排列。
Shared Cache Line Distribution Pareto

这个表提供有关每个缓存行遇到争用的各种信息:

  • 0 开始,缓存行在 NUM 列中编号。
  • 每个缓存行的虚拟地址都包含在 Data address Offset 列中,随后会在发生不同访问的缓存行中偏移。
  • Pid 列中包含进程 ID。
  • Code Address 列中包含指令指针代码地址。
  • 周期标签下的列显示平均负载延迟
  • cpu cnt 列显示来自多少个不同的 CPU 样本(基本而言,在该给定位置上等待索引的数据的不同 CPU 数量)。
  • Symbol 列显示函数名或符号
  • Shared Object 列显示样本来自的 ELF 镜像的名称(样本来自内核时使用名称 [kernel.kallsyms])。
  • Source:Line 列显示源文件和行号。
  • Node{cpu list} 列中显示每个节点来自哪些特定 CPU 样本。

23.5. 使用 perf c2c 检测错误共享

这个步骤描述了如何使用 perf c2c 命令检测假共享。

先决条件

流程

  1. 打开 perf.data 文件进行进一步分析:

    # perf c2c report --stdio

    这会在终端中打开 perf.data 文件。

  2. 在"Trace Event Information"表中,找到包含 LLC Misses to Remote Cache(HITM) 值的行:

    LLC Misses to Remote Cache(HITM) 行的值列中的百分比代表了修改的缓存行中 NUMA 节点之间发生 LLC 丢失的百分比。

    =================================================
                Trace Event Information
    =================================================
      Total records                     :     329219
      Locked Load/Store Operations      :      14654
      Load Operations                   :      69679
      Loads - uncacheable               :          0
      Loads - IO                        :          0
      Loads - Miss                      :       3972
      Loads - no mapping                :          0
      Load Fill Buffer Hit              :      11958
      Load L1D hit                      :      17235
      Load L2D hit                      :         21
      Load LLC hit                      :      14219
      Load Local HITM                   :       3402
      Load Remote HITM                  :      12757
      Load Remote HIT                   :       5295
      Load Local DRAM                   :        976
      Load Remote DRAM                  :       3246
      Load MESI State Exclusive         :       4222
      Load MESI State Shared            :          0
      Load LLC Misses                   :      22274
      LLC Misses to Local DRAM          :        4.4%
      LLC Misses to Remote DRAM         :       14.6%
      LLC Misses to Remote cache (HIT)  :       23.8%
      LLC Misses to Remote cache (HITM) : 57.3%
      Store Operations                  :     259539
      Store - uncacheable               :          0
      Store - no mapping                :         11
      Store L1D Hit                     :     256696
      Store L1D Miss                    :       2832
      No Page Map Rejects               :       2376
      Unable to parse data source       :          1
  3. 检查共享数据缓存表的 LLC Load Hitm 字段的 Rmt 列:

      =================================================
                 Shared Data Cache Line Table
      =================================================
      #
      #                              Total      Rmt  ----- LLC Load Hitm -----  ---- Store Reference ----  --- Load Dram ----      LLC    Total  ----- Core Load Hit -----  -- LLC Load Hit --
      # Index           Cacheline  records     Hitm    Total      Lcl      Rmt    Total    L1Hit   L1Miss       Lcl       Rmt  Ld Miss    Loads       FB       L1       L2       Llc       Rmt
      # .....  ..................  .......  .......  .......  .......  .......  .......  .......  .......  ........  ........  .......  .......  .......  .......  .......  ........  ........
      #
            0            0x602180   149904   77.09%    12103     2269     9834   109504   109036      468       727      2657    13747    40400     5355    16154        0      2875       529
            1            0x602100    12128   22.20%     3951     1119     2832        0        0        0        65       200     3749    12128     5096      108        0      2056       652
            2  0xffff883ffb6a7e80      260    0.09%       15        3       12      161      161        0         1         1       15       99       25       50        0         6         1
            3  0xffffffff81aec000      157    0.07%        9        0        9        1        0        1         0         7       20      156       50       59        0        27         4
            4  0xffffffff81e3f540      179    0.06%        9        1        8      117       97       20         0        10       25       62       11        1        0        24         7

    这个表按照每个缓存行检测到的远程 Hitm 数量按降序排列。LLC Load Hitm 部分的 Rmt 列中有一个高数字表示共享错误,并且需要进一步检查发生错误共享活动的缓存行。

第 24 章 flamegraphs 入门

作为系统管理员,您可以使用 flamegraphs 创建使用 perf 工具记录的系统性能数据的视觉化呈现。作为软件开发商,您可以使用 flamegraphs 创建使用 perf 工具记录的应用程序性能数据的视觉化呈现。

sampling stack traces 是使用 perf 工具分析 CPU 性能的常用技术。遗憾的是,使用 perf 分析堆栈踪迹的结果可能非常详细,且需要分析大量劳动力。flamegraphs 视觉化从使用 perf 记录的数据创建,以便更快速、轻松地识别热代码路径。

24.1. 安装 flamegraphs

要开始使用 flamegraphs,请安装所需的软件包。

流程

  • 安装 flamegraphs 软件包:

    # yum install js-d3-flame-graph

24.2. 在整个系统中创建 flamegraphs

这个步骤描述了如何使用 flamegraphs 视觉化在整个系统中记录的性能数据。

先决条件

流程

  • 记录数据并创建视觉化:

    # perf script flamegraph -a -F 99 sleep 60

    这个命令在 60 秒内对整个系统的性能数据进行抽样并记录,因为使用 sleep 命令,然后构建将存储在当前活跃目录中的视觉化呈现为 flamegraph.html。默认情况下,命令示例 call-graph 数据,并使用与 perf 工具相同的参数,在这种情况下:

    -a
    强制记录整个系统中的数据。
    -F
    设置每秒抽样频率:

验证步骤

  • 为了进行分析,请查看生成的视觉化:

    # xdg-open flamegraph.html

    这个命令在默认浏览器中打开视觉化:

    flamegraph allcpus

24.3. 在特定进程上创建 flamegraphs

您可以使用 flamegraphs 视觉化通过特定运行的进程记录的性能数据。

先决条件

流程

  • 记录数据并创建视觉化:

    # perf script flamegraph -a -F 99 -p ID1,ID2 sleep 60

    这个命令在 60 秒内对进程 ID 为 ID1ID2 的进程的性能数据进行抽样并记录,通过使用 sleep 命令可以生成视觉化,然后以 flamegraph.html 形式存储在当前活动目录中。默认情况下,命令示例 call-graph 数据,并使用与 perf 工具相同的参数,在这种情况下:

    -a
    强制记录整个系统中的数据。
    -F
    设置每秒抽样频率:
    -p
    对特定进程 ID 进行抽样并记录数据的步骤:

验证步骤

  • 为了进行分析,请查看生成的视觉化:

    # xdg-open flamegraph.html

    这个命令在默认浏览器中打开视觉化:

    flamegraph

24.4. 解释 flamegraphs

Flangraph 中的每个方框表示堆栈中的不同功能。y-xis 显示了堆栈的深度,每个堆栈中最顶层框是实际运行在 CPU 上的功能,其下方的所有内容都处于就绪状态。x-axis 显示示例调用-graph 数据的填充。

给定行中的堆栈子级显示基于每个相应函数按照 x-axis 降序获取的示例数量;x-axis 并不代表时间传递。个人盒越宽,在数据被采样时,它越常发生 CPU 或 CPU ancestry 的一部分。

流程

  • 显示之前可能未显示的功能名称,并进一步调查 flamegraph 中的框以放大到给定位置的堆栈中:

    zoomed in flamegraph

  • 要返回 flamegraph 的默认视图,点 Reset Zoom
重要

代表用户空间函数的框可以在 flamegraphs 中标记为 Unknown,因为该功能的二进制被剥离。必须安装可执行文件的 debuginfo 软件包,如果可执行文件是本地开发的应用程序,则必须使用调试信息编译应用程序。使用 GCC 中的 -g 选项显示在这种情况下的功能名称或符号。

flamegraph

第 25 章 使用 perf 循环缓冲区监控性能瓶颈的进程

您可以使用 perf 工具创建特定于事件的数据快照,以便监控系统中运行的特定进程或应用程序部分的性能瓶颈。在这种情况下,perf 只将数据写入 perf.data 文件,以便在检测到指定事件时稍后进行分析。

25.1. 使用 perf 循环缓冲区和特定于事件的快照

当使用 perf 调查进程或应用程序中性能问题时,可能经济实惠或不适合在发生特定感兴趣的事件前几小时内记录数据。在这种情况下,您可以使用 perf record 创建自定义循环缓冲区,在特定事件后生成快照。

--overwrite 选项使 perf record 将所有数据存储在可写的循环缓冲区中。当缓冲区已满时,perf record 会自动覆盖最旧的记录,因此永远不会写入 perf.data 文件中。

--overwrite--switch-output-event 选项一起使用配置一个循环缓冲,它会持续记录和转储数据,直到检测到 --switch-output-event 触发器事件为止。触发事件信号 perf record,用户感兴趣的事情已经发生,并在循环缓冲中将数据写入 perf.data 文件中。这会收集您感兴趣的特定数据,同时通过不写入您不想的 perf.data 文件来降低运行 perf 进程的开销。

25.2. 使用 perf 循环缓冲区收集特定数据来监控性能瓶颈

使用 perf 工具,您可以创建由您指定的事件触发的循环缓冲,以便只收集您感兴趣的数据。要创建循环缓冲区来收集事件特定数据,请使用 perf--overwrite--switch-output-event 选项。

先决条件

  • 已安装 perf 用户空间工具。如需更多信息,请参阅安装 perf
  • 您已在进程或应用程序中想要监控的进程或应用程序中对应位置设置了一个优良:

    # perf probe -x /path/to/executable -a function
    Added new event:
      probe_executable:function   (on function in /path/to/executable)
    
    You can now use it in all perf tools, such as:
    
            perf record -e probe_executable:function -aR sleep 1

流程

  • 使用 uprobe 创建循环缓冲作为触发器事件:

    # perf record --overwrite -e cycles --switch-output-event probe_executable:function ./executable
    [ perf record: dump data: Woken up 1 times ]
    [ perf record: Dump perf.data.2021021012231959 ]
    [ perf record: dump data: Woken up 1 times ]
    [ perf record: Dump perf.data.2021021012232008 ]
    ^C[ perf record: dump data: Woken up 1 times ]
    [ perf record: Dump perf.data.2021021012232082 ]
    [ perf record: Captured and wrote 5.621 MB perf.data.<timestamp> ]

    这个示例启动可执行文件并收集在 -e 选项后指定的 cpu 周期,直到 perf 检测到 uprobe,在 --switch-output-event 选项后指定的触发器事件。此时,perf 会获取循环缓冲区中所有数据的快照,并将其存储在由时间戳标识的唯一 perf.data 文件中。这个示例生成了总计 2 个快照,最后的 perf.data 文件是通过按 Ctrl+c 强制的。

第 26 章 从正在运行的 perf 收集器添加和删除追踪点,而不停止或重启 perf

通过使用控制管道界面在运行的 perf 收集器中启用和禁用不同的追踪点,您可以动态调整要收集的数据,而无需停止或重启 perf。这样可确保您不会丢失原本会在停止或重启过程中记录的性能数据。

26.1. 在运行的 perf 收集器中添加追踪点,而不停止或重启 perf

使用控制管道接口为正在运行的 perf 收集器添加追踪点,以调整您记录的数据,而无需停止 perf 并丢失性能数据。

先决条件

流程

  1. 配置控制管道接口:

    # mkfifo control ack perf.pipe
  2. 使用控制文件设置和您要启用的事件运行 perf record

    # perf record --control=fifo:control,ack -D -1 --no-buffering -e 'sched:*' -o - > perf.pipe

    在本例中,在 -e 选项后声明 'sched:*' 使用调度程序事件启动 perf record

  3. 在第二个终端中,启动控制管道的读取端:

    # cat perf.pipe | perf --no-pager script -i -

    启动控制管道读取端会在第一个终端中触发以下信息:

    Events disabled
  4. 在第三个终端中,使用控制文件启用追踪点:

    # echo 'enable sched:sched_process_fork' > control

    这个命令会触发 perf 扫描控制文件中声明的事件列表。如果存在该事件,则会启用追踪点,并在第一个终端中显示以下信息:

    event sched:sched_process_fork enabled

    启用追踪点后,第二个终端会显示来自检测追踪点的 perf 的输出:

    bash 33349 [034] 149587.674295: sched:sched_process_fork: comm=bash pid=33349 child_comm=bash child_pid=34056

26.2. 从正在运行的 perf 收集器中删除追踪点,而不停止或重启 perf

使用控制管道接口从正在运行的 perf 收集器中删除追踪点,以减少您收集的数据范围,而无需停止 perf 并丢失性能数据。

先决条件

流程

  • 删除追踪点:

    # echo 'disable sched:sched_process_fork' > control
    注意

    这个示例假设您之前已将调度程序事件加载到控制文件中并启用了追踪点 sched:sched_process_fork

    这个命令会触发 perf 扫描控制文件中声明的事件列表。如果存在该事件,则禁用追踪点,并在用来配置控制管道的终端中显示以下消息:

    event sched:sched_process_fork disabled

第 27 章 使用 numastat 分析内存分配

使用 numastat 工具,您可以显示系统中内存分配的统计数据。

numastat 工具单独显示每个 NUMA 节点的数据。您可以使用这些信息来调查系统的内存性能或系统中不同内存策略的有效性。

27.1. 默认 numastat 统计

默认情况下,numastat 工具显示每个 NUMA 节点的这些类别的数据的统计信息:

numa_hit
成功分配给此节点的页面数。
numa_miss
由于预期节点上的内存不足,在此节点上分配的页面数量。每个 numa_miss 事件在另一个节点上都有对应的 numa_foreign 事件。
numa_foreign
最初用于此节点的页面数量改为分配给另一节点。每个 numa_foreign 事件在另一个节点上都有对应的 numa_miss 事件。
interleave_hit
成功分配给此节点的 interleave 策略页面数量。
local_node
此节点上的进程在此节点上成功分配的页面数。
other_node
另外一个节点上的进程在此节点上分配的页面数量。
注意

numa_hit 值和低 numa_miss 值(相互相对)代表最佳的性能。

27.2. 使用 numastat 查看内存分配

您可以使用 numastat 工具查看系统的内存分配。

先决条件

  • 安装 numactl 软件包:

    # yum install numactl

流程

  • 查看系统的内存分配:

    $ numastat
                                 node0         node1
    numa_hit                  76557759      92126519
    numa_miss                 30772308      30827638
    numa_foreign              30827638      30772308
    interleave_hit              106507        103832
    local_node                76502227      92086995
    other_node                30827840      30867162

其它资源

  • numastat(8) man page

第 28 章 配置操作系统以优化 CPU 使用率

这部分论述了如何配置操作系统以优化其工作负载中的 CPU 利用率。

28.1. 监控和诊断处理器问题的工具

以下是 Red Hat Enterprise Linux 8 中用来监控和诊断处理器相关性能问题的工具:

  • turbostat 工具以指定间隔打印计数器结果,以帮助管理员发现服务器中的意外行为,如过度使用电源、未能进入深度睡眠状态或不必要的系统管理中断(SMI)。
  • numactl 实用程序提供了多个选项来管理处理器和内存关联。numactl 软件包包括 libnuma 库,它为内核支持的 NUMA 策略提供了一个简单的编程接口,并可用于比 numactl 应用程序进行更精细的调整。
  • numastat 工具显示操作系统及其进程的每 NUMA 节点内存统计信息,并显示管理员进程内存是分散到系统中还是集中到特定的节点上。这个工具由 numactl 软件包提供。
  • numad 是自动 NUMA 关联性管理守护进程。它监控系统中 NUMA 拓扑和资源使用情况,以便动态改进 NUMA 资源的分配和管理。
  • /proc/interrupts 文件显示中断请求(IRQ)编号、系统中各个处理器处理的类似中断请求数、发送中断的类型,以及响应所列中断请求的设备列表。
  • pqos 工具程序包括在 intel-cmt-cat 软件包中。它监控最近 Intel 处理器上的 CPU 缓存和内存带宽。它监控:

    • 每个周期(IPC)的说明。
    • 最后一个级别缓存 MISSES 的数量。
    • 程序在 LLC 中给定 CPU 占用空间中执行的 KB 大小。
    • 到本地内存的带宽(MBL)。
    • 到远程内存的带宽(MBR)。
  • x86_energy_perf_policy 管理员可利用工具定义性能和能源效率的相对重要性。当处理器选择在性能和能源效率之间取舍的选择时,可以利用这些信息来影响支持此功能的处理器。
  • taskset 工具由 util-linux 软件包提供。它允许管理员检索和设置正在运行的进程的处理器关联,或者启动具有指定处理器相关性的进程。

其它资源

  • turbostat(8)numactl(8)numastat(8)numa(7)numad(8)pqos(8)x86_energy_perf_policy(8)taskset(1) man page

28.2. 系统拓扑类型

在现代计算中,CPU 的概念令人困惑,因为大多数现代系统都有多个处理器。系统拓扑是这些处理器互相连接和其他系统资源的方式。这会影响系统和应用程序的性能,以及系统的调优注意事项。

以下是现代计算中使用的两种主要拓扑类型:

Symmetric Multi-Processor (SMP) topology
SMP 拓扑允许所有处理器在相同的时间里访问内存。但是,由于共享和相等内存访问本质上会强制从所有 CPU 进行序列化内存访问,因此 SMP 系统扩展限制现在通常被视为不可接受。因此,实际上,所有现代服务器系统都是 NUMA 计算机。
Non-Uniform Memory Access (NUMA) topology

NUMA 拓扑的开发时间比 SMP 拓扑更近。在 NUMA 系统中,一个套接字上对多个处理器进行物理分组。每个套接字都有一个专用的内存和处理器区域,其对该内存具有本地访问权限,它们统称为节点。位于同一节点上的处理器能够快速访问该节点的内存数据库,而且对不在节点的内存库的访问速度也较慢。

因此,访问非本地内存时性能会受到影响。因此,具有 NUMA 拓扑的系统上对性能敏感的应用应该访问与执行应用的处理器位于同一节点上的内存,并尽可能避免访问远程内存。

对性能敏感的多线程应用或许能够配置为在特定 NUMA 节点上执行,而非特定的处理器。这是否适合取决于您的系统以及应用程序的要求。如果多个应用程序线程访问相同的缓存数据,则可能适合将这些线程配置为在同一处理器上执行。但是,如果访问和缓存同一处理器中执行的不同数据的多个线程可能会驱除以前的线程访问的缓存数据。这意味着每个线程"缺少"缓存并浪费执行时间从内存中获取数据并将其替换缓存中。使用 perf 工具检查太多缓存未命中。

28.2.1. 显示系统拓扑

许多命令可帮助理解系统的拓扑。这个步骤描述了如何确定系统拓扑。

流程

  • 显示您的系统拓扑概述:

    $ numactl --hardware
    available: 4 nodes (0-3)
    node 0 cpus: 0 4 8 12 16 20 24 28 32 36
    node 0 size: 65415 MB
    node 0 free: 43971 MB
    [...]
  • 要收集 CPU 架构的信息,如 CPU、线程、内核、插槽和 NUMA 节点的数量:

    $ lscpu
    Architecture:          x86_64
    CPU op-mode(s):        32-bit, 64-bit
    Byte Order:            Little Endian
    CPU(s):                40
    On-line CPU(s) list:   0-39
    Thread(s) per core:    1
    Core(s) per socket:    10
    Socket(s):             4
    NUMA node(s):          4
    Vendor ID:             GenuineIntel
    CPU family:            6
    Model:                 47
    Model name:            Intel(R) Xeon(R) CPU E7- 4870  @ 2.40GHz
    Stepping:              2
    CPU MHz:               2394.204
    BogoMIPS:              4787.85
    Virtualization:        VT-x
    L1d cache:             32K
    L1i cache:             32K
    L2 cache:              256K
    L3 cache:              30720K
    NUMA node0 CPU(s):     0,4,8,12,16,20,24,28,32,36
    NUMA node1 CPU(s):     2,6,10,14,18,22,26,30,34,38
    NUMA node2 CPU(s):     1,5,9,13,17,21,25,29,33,37
    NUMA node3 CPU(s):     3,7,11,15,19,23,27,31,35,39
  • 查看您系统的图形表示:

    # yum install hwloc-gui
    # lstopo

    图 28.1. lstopo 输出

    lstopo
  • 查看详细的文本输出:

    # yum install hwloc
    # lstopo-no-graphics
    Machine (15GB)
      Package L#0 + L3 L#0 (8192KB)
        L2 L#0 (256KB) + L1d L#0 (32KB) + L1i L#0 (32KB) + Core L#0
            PU L#0 (P#0)
            PU L#1 (P#4)
           HostBridge L#0
        PCI 8086:5917
            GPU L#0 "renderD128"
            GPU L#1 "controlD64"
            GPU L#2 "card0"
        PCIBridge
            PCI 8086:24fd
              Net L#3 "wlp61s0"
        PCIBridge
            PCI 8086:f1a6
        PCI 8086:15d7
            Net L#4 "enp0s31f6"

其它资源

  • numactl(8)lscpu(1)lstopo(1) man page

28.3. 配置内核绑定时间

默认情况下,Red Hat Enterprise Linux 8 使用无空循环内核,它不会中断空闲 CPU 以降低功耗并允许新处理器利用深层次的睡眠状态。

Red Hat Enterprise Linux 8 还提供了动态无循环选项,对于对延迟敏感的工作负载(如高性能计算或实时计算)非常有用。默认情况下,动态无循环选项被禁用。红帽建议使用 cpu-partitioning Tuned 配置集为指定为 isolated_cores 的内核启用动态无循环选项。

这个步骤描述了如何手动启用动态无循环行为。

流程

  1. 要在特定内核中启用动态无循环行为,请使用 nohz_full 参数在内核命令行中指定这些内核。在 16 个内核系统中,将此参数附加到 /etc/default/grub 文件中的 GRUB_CMDLINE_LINUX 选项中:

    nohz_full=1-15

    这启用了内核 115 的动态无引号行为,将所有计时操作移至唯一未指定的内核(核心 0)。

  2. 要永久启用动态无循环行为,请使用编辑后的默认 文件重新生成 GRUB2 配置。在带有 BIOS 固件的系统中,执行以下命令:

    # grub2-mkconfig -o /etc/grub2.cfg

    在带有 UEFI 固件的系统中,执行以下命令:

    # grub2-mkconfig -o /etc/grub2-efi.cfg
  3. 当系统引导时,手动将 rcu 线程移到非延迟的内核中,在本例中为 core 0

    # for i in `pgrep rcu[^c]` ; do taskset -pc 0 $i ; done
  4. 可选: 使用内核命令行中的 isolcpus 参数将某些内核与用户空间任务隔离。
  5. 可选:将内核的 write-back bdi-flush 线程的 CPU 关联性设置为 housekeeping 内核:

    echo 1 > /sys/bus/workqueue/devices/writeback/cpumask

验证步骤

  • 系统重启后,验证 dynticks 是否启用:

    # journalctl -xe | grep dynticks
    Mar 15 18:34:54 rhel-server kernel: NO_HZ: Full dynticks CPUs: 1-15.
  • 验证动态无循环配置是否正常工作:

    # perf stat -C 1 -e irq_vectors:local_timer_entry taskset -c 1 sleep 3

    该命令测量 CPU 1 上的粘滞,同时指示 CPU 1 休眠 3 秒。

  • 默认内核计时器配置会在常规 CPU 上显示大约 3100 号:

    # perf stat -C 0 -e irq_vectors:local_timer_entry taskset -c 0 sleep 3
    
     Performance counter stats for 'CPU(s) 0':
    
                 3,107      irq_vectors:local_timer_entry
    
           3.001342790 seconds time elapsed
  • 配置动态无空循环内核后,您应该会看到大约 4 ticks:

    # perf stat -C 1 -e irq_vectors:local_timer_entry taskset -c 1 sleep 3
    
     Performance counter stats for 'CPU(s) 1':
    
                     4      irq_vectors:local_timer_entry
    
           3.001544078 seconds time elapsed

28.4. 中断请求概述

中断请求或 IRQ 是从硬件部分向处理器发送立即关注的信号。系统中的每个设备都会被分配一个或多个 IRQ 号,以允许它发送唯一中断。启用中断时,接收中断请求的处理器会立即暂停当前应用线程的执行,以解决中断请求。

由于中断停止正常操作,高中断率可能会严重降低系统性能。可以通过配置中断关联或在批处理中发送多个较低优先级中断(联合多个中断)来减少中断所花费的时间。

中断请求具有关联的关联性属性 smp_affinity,它定义处理中断请求的处理器。若要提高应用性能,可将中断关联和进程相关性分配到同一处理器或同一核心上的处理器。这允许指定的中断和应用程序线程共享缓存行。

在支持中断的系统中,修改中断请求的 smp_affinity 属性会设置硬件,以便在没有内核干预的情况下在硬件级别决定使用特定处理器提供中断。

28.4.1. 手动平衡中断

如果您的 BIOS 导出其 NUMA 拓扑,irqbalance 服务可自动在节点中为本地硬件请求服务提供中断请求。

流程

  1. 检查哪些设备与您要配置的中断请求对应。
  2. 查找您的平台的硬件规格。检查系统上的芯片组是否支持分发中断。

    1. 如果存在,您可以按照以下步骤中所述配置中断交付。此外,检查您的芯片组用于平衡中断的算法。某些 BIOS 拥有配置中断发送的选项。
    2. 如果没有,您的芯片组总是将所有中断路由到单个静态 CPU。您无法配置使用哪个 CPU。
  3. 检查您的系统上使用哪个 Advanced Programmable Interrupt Controller(APIC)模式:

    $ journalctl --dmesg | grep APIC

    在这里,

    • 如果您的系统使用 flat 以外的模式,您可以看到与 Setting APIC routing to physical flat 类似的行。
    • 如果没有看到这样的信息,您的系统将使用 flat 模式。

      如果您的系统使用 x2apic 模式,您可以通过在 bootloader 配置的内核命令行中添加 nox2apic 选项来禁用它。

      只有非物理扁平模式(flat)支持将中断分发到多个 CPU。这个模式只适用于有最多 8 CPU 的系统。

  4. 计算 smp_affinity mask。有关如何计算 smp_affinity mask 的更多信息,请参阅设置 smp_affinity 掩码

其它资源

  • journalctl(1)taskset(1) man page

28.4.2. 设置 smp_affinity 掩码

smp_affinity 值保存为代表系统中所有处理器的十六进制位掩码。每个位配置一个不同的 CPU。最不重要的位是 CPU 0。

掩码的默认值是 f,这意味着中断请求可以在系统中的任何处理器中处理。将此值设置为 1 表示只有处理器 0 可以处理中断。

流程

  1. 在二进制中,将值 1 用于处理中断的 CPU。例如:要设置 CPU 0 和 CPU 7 来处理中断,使用 0000000010000001 作为二进制代码:

    表 28.1. CPU 的二进制 Bit

    CPU

    15

    14

    13

    12

    11

    10

    9

    8

    7

    6

    5

    4

    3

    2

    1

    0

    二进制

    0

    0

    0

    0

    0

    0

    0

    0

    1

    0

    0

    0

    0

    0

    0

    1

  2. 将二进制代码转换为十六进制:

    例如,使用 Python 转换二进制代码:

    >>> hex(int('0000000010000001', 2))
    
    '0x81'

    在超过 32 个处理器的系统中,您必须为离散 32 位组分隔 smp_affinity 值。例如:如果您只希望 64 处理器系统的前 32 个处理器为中断请求提供服务,请使用 0xffffffff,00000000

  3. 特定中断请求的中断关联性值存储在关联的 /proc/irq/irq_number/smp_affinity 文件中。在此文件中设置 smp_affinity 掩码:

    # echo mask > /proc/irq/irq_number/smp_affinity

其它资源

  • journalctl(1)irqbalance(1)taskset(1) man page

第 29 章 调整调度策略

在 Red Hat Enterprise Linux 中,最小的进程执行单元称为线程。系统调度程序决定哪个处理器运行线程,以及线程运行的时间。但是,由于调度程序的主要顾虑是保持系统处于忙碌状态,因此可能无法最佳地为应用程序性能调度线程。

例如,当 Node B 上的处理器可用时,NUMA 系统上的应用程序在节点 A 上运行。为了让节点 B 处于忙碌状态,调度程序将一个应用程序的线程移到 Node B。但是,应用程序线程仍然需要访问节点 A 上的内存。但是,此内存需要更长的时间来访问,因为线程现在在 Node B 上运行,并且 Node A 内存不再对线程而言是本地的。因此,线程在节点 B 上运行可能需要更长的时间,需要等待节点 A 上的处理器变得可用,然后在具有本地内存访问权限的原始节点上执行线程。

29.1. 调度策略的类别

对性能敏感的应用通常得益于设计人员或管理员确定线程的运行位置。Linux 调度程序实施许多调度策略,这些策略决定线程运行的位置和运行时间。

以下是两个主要类别的调度策略:

Normal policies
普通线程用于普通优先级的任务。
Realtime policies

实时策略用于必须在不中断的情况下完成的时间敏感任务。实时线程不受时间分片的影响。这意味着线程会一直运行,直到它们阻断、退出、自愿生成,或者被更高优先级的线程抢占。

最低优先级实时线程排在采用正常策略的任何线程之前调度。如需更多信息,请参阅使用 SCHED_FIFO 的静态优先级调度,并使用 SCHED_RR 进行循环优先级调度

其它资源

  • sched(7)sched_setaffinity(2)sched_getaffinity(2)sched_setscheduler(2)sched_getscheduler(2) man page

29.2. 使用 SCHED_FIFO 进行静态优先级调度

SCHED_FIFO 也称为静态优先级调度,是一个实时策略,为每个线程定义固定优先级。此策略允许管理员缩短事件响应时间并缩短延迟。对于时间敏感任务,建议不要在较长时间内执行此策略。

SCHED_FIFO 处于使用状态时,调度程序会按照优先级顺序扫描所有 SCHED_FIFO 线程列表,并调度就绪运行的最高优先级线程列表。SCHED_FIFO 线程的优先级级别可以是从 199 的任何整数,其中 99 被视为最高优先级。红帽建议从较低数量开始,只有在您发现延迟问题时才会增加优先级。

警告

因为实时线程不受时间片的限制,因此红帽不推荐将优先级设置为 99。这会使您的进程处于与迁移和 watchdog 线程相同的优先级级别;如果您的线程进入计算循环,并且这些线程已被阻止,它们将无法运行。具有单一处理器的系统最终会挂起。

管理员可以限制 SCHED_FIFO 带宽,以防止实时应用程序程序员启动将处理器推崇的实时任务。

以下是此策略中使用的一些参数:

/proc/sys/kernel/sched_rt_period_us
此参数定义时间周期,以微秒为单位,被视为处理器带宽的 10%。默认值为 1000000 μs1 second
/proc/sys/kernel/sched_rt_runtime_us
此参数定义专用于运行实时线程的时间周期,以微秒为单位。默认值为 950000 μs0.95 seconds

29.3. 使用 SCHED_RR 进行循环优先级调度

SCHED_RRSCHED_FIFO 的循环变体。当多个线程需要以同一优先级级别运行时,此策略很有用。

SCHED_FIFO 类似,SCHED_RR 是一个实时策略,为每个线程定义固定的优先级。调度程序按照优先级顺序扫描所有 SCHED_RR 线程的列表,并调度就绪运行的最高优先级线程。但是,与 SCHED_FIFO 不同,具有相同优先级的线程在特定时间片段中以轮循方式调度。

您可以使用 /proc/sys/kernel/sched_rr_timeslice_ms 文件中的 sched_rr_timeslice_ms 内核参数以毫秒为单位设置这个时间片段的值。最低的值是 1 millisecond

29.4. 使用 SCHED_OTHER 进行常规调度

SCHED_OTHER 是 Red Hat Enterprise Linux 8 中的默认调度策略。此策略使用完全公平调度程序(CFS)来允许对使用此策略调度的所有线程进行公平处理器访问。当有大量线程或者数据吞吐量具有优先权时,此策略最有用,因为它允许更有效地调度线程。

使用此策略时,调度程序会根据每个进程线程的 niceness 值部分创建动态优先级列表。管理员可以更改进程的 nice 值,但不能直接更改调度程序的动态优先级列表。

29.5. 设置调度程序策略

使用 chrt 命令行工具检查并调整调度程序策略和优先级。它可以启动具有所需属性的新进程,或者更改正在运行的进程的属性。它还可用于在运行时设置策略。

流程

  1. 查看活跃进程的进程 ID(PID):

    # ps

    ps 命令中使用 --pid-p 选项来查看特定 PID 的详情。

  2. 检查特定进程的调度策略、PID 和优先级:

    # chrt -p 468
    pid 468's current scheduling policy: SCHED_FIFO
    pid 468's current scheduling priority: 85
    
    # chrt -p 476
    pid 476's current scheduling policy: SCHED_OTHER
    pid 476's current scheduling priority: 0

    在这里,468476 是进程的 PID。

  3. 设置进程的调度策略:

    1. 例如,将 PID 为 1000 的进程设置为 SCHED_FIFO,优先级为 50

      # chrt -f -p 50 1000
    2. 例如,将 PID 为 1000 的进程设置为 SCHED_OTHER,优先级为 0

      # chrt -o -p 0 1000
    3. 例如,将 PID 为 1000 的进程设置为 SCHED_RR,其优先级为 10

      # chrt -r -p 10 1000
    4. 要使用特定的策略和优先级启动新应用程序,请指定应用程序的名称:

      # chrt -f 36 /bin/my-app

29.6. chrt 命令的策略选项

使用 chrt 命令,您可以查看和设置进程的调度策略。

下表描述了适当的策略选项,可用于设置进程的调度策略。

表 29.1. chrt 命令的策略选项

短选项长选项描述

-f

--fifo

将调度设置为 SCHED_FIFO

-o

--other

将调度设置为 SCHED_OTHER

-r

--rr

将调度设置为 SCHED_RR

29.7. 在引导过程中更改服务的优先级

使用 systemd 服务,可以为引导过程中启动的服务设置实时优先级。单元配置指令用于在启动过程中更改服务的优先级

引导过程优先级更改通过使用 service 部分中的以下指令来完成:

CPUSchedulingPolicy=
为已执行的进程设置 CPU 调度策略。它用于设置 otherfiforr 策略。
CPUSchedulingPriority=
为已执行的进程设置 CPU 调度优先级。可用的优先级范围取决于所选 CPU 调度策略。对于实时调度策略,可以使用 1 (最低优先级)和 99 (最高优先级)之间的整数。

以下流程描述了如何在引导过程中使用 mcelog 服务更改服务的优先级。

先决条件

  1. 安装 tuned 软件包:

    # yum install tuned
  2. 启用并启动 tuned 服务:

    # systemctl enable --now tuned

流程

  1. 查看正在运行的线程的调度优先级:

    # tuna --show_threads
                          thread       ctxt_switches
        pid SCHED_ rtpri affinity voluntary nonvoluntary             cmd
      1      OTHER     0     0xff      3181          292         systemd
      2      OTHER     0     0xff       254            0        kthreadd
      3      OTHER     0     0xff         2            0          rcu_gp
      4      OTHER     0     0xff         2            0      rcu_par_gp
      6      OTHER     0        0         9            0 kworker/0:0H-kblockd
      7      OTHER     0     0xff      1301            1 kworker/u16:0-events_unbound
      8      OTHER     0     0xff         2            0    mm_percpu_wq
      9      OTHER     0        0       266            0     ksoftirqd/0
    [...]
  2. 创建补充的 mcelog 服务配置文件,并在该文件中插入策略名称和优先级:

    # cat <<-EOF > /etc/systemd/system/mcelog.system.d/priority.conf
    
    >
    [SERVICE]
    CPUSchedulingPolicy=_fifo_
    CPUSchedulingPriority=_20_
    EOF
  3. 重新载入 systemd 脚本配置:

    # systemctl daemon-reload
  4. 重启 mcelog 服务:

    # systemctl restart mcelog

验证步骤

  • 显示由 systemd 问题设置的 mcelog 优先级:

    # tuna -t mcelog -P
    thread       ctxt_switches
      pid SCHED_ rtpri affinity voluntary nonvoluntary             cmd
    826     FIFO    20  0,1,2,3        13            0          mcelog

其它资源

29.8. 优先级映射

优先级按组定义,某些组专用于某些内核功能。对于实时调度策略,可以使用 1 (最低优先级)和 99 (最高优先级)之间的整数。

下表描述了优先级范围,可用于设置进程的调度策略。

表 29.2. 优先级范围的描述

优先级线程描述

1

低优先级内核线程

这个优先级通常为只需要 SCHED_OTHER 以上的任务保留。

2 - 49

可供使用

用于典型应用优先级的范围。

50

默认 hard-IRQ 值

 

51 - 98

高优先级线程

将此范围用于定期执行的线程,且必须具有快速响应时间。不要将此范围用于 CPU 绑定线程,因为您将造成中断。

99

watchdogs 和迁移

必须以最高优先级运行的系统线程。

29.9. CPU-partitioning 配置文件

cpu-partitioning 配置集用于将 CPU 与系统级别中断隔离。隔离这些 CPU 后,您可以为特定的应用程序分配它们。这在低延迟环境或您想要从硬件中提取最高性能的环境中非常有用。

此配置集还允许您指定内务处理 CPU。内务操作 CPU 用于运行所有服务、守护进程、shell 进程和内核线程。

您可以使用以下配置选项在 /etc/tuned/cpu-partitioning-variables.conf 文件中配置 cpu-partitioning 配置集:

isolated_cores=cpu-list
列出要隔离的 CPU。隔离 CPU 列表用逗号分开,您可以使用短划线来指定范围,如 3-5。此选项是必需的。此列表中缺少的任何 CPU 都会自动被视为内务 CPU。
no_balance_cores=cpu-list
列出内核在系统范围范围的进程负载均衡期间没有考虑的 CPU。此选项是可选的。这通常与 isolated_cores 列表相同。

其它资源

  • tuned-profiles-cpu-partitioning(7) man page

第 30 章 影响 I/O 和文件系统性能的因素

存储和文件系统性能的适当设置高度依赖于存储用途。

I/O 和文件系统性能可能会受到以下任何因素的影响:

  • 数据写入或读取模式
  • 连续或随机
  • 缓冲或直接 IO
  • 与底层几metry 的数据一致
  • 块大小
  • 文件系统大小
  • 日志大小和位置
  • 记录访问时间
  • 确保数据可靠性
  • 预获取数据
  • 预分配磁盘空间
  • 文件碎片
  • 资源争用

30.1. 用于监控和诊断 I/O 和文件系统问题的工具

Red Hat Enterprise Linux 8 中提供了以下工具来监控系统性能,并诊断与 I/O、文件系统及其配置相关的性能问题:

  • vmstat 工具报告整个系统中进程、内存、分页、块 I/O、中断和 CPU 活动。它可以帮助管理员确定 I/O 子系统是否负责处理任何性能问题。如果使用 vmstat 分析显示 I/O 子系统负责降低性能,管理员可以使用 iostat 工具确定负责的 I/O 设备。
  • iostat 报告系统中的 I/O 设备负载。它由 sysstat 软件包提供。
  • blktrace 提供如何花费在 I/O 子系统中时间的详细信息。配套实用程序 blkparseblktrace 读取原始输出,并生成由 blktrace 记录的输入和输出操作人类可读概述。
  • btt 分析 blktrace 输出并显示 I/O 堆栈的每个区域中数据花费的时间,以便更容易发现 I/O 子系统中的瓶颈。这个工具作为 blktrace 软件包的一部分提供。由 blktrace 机制跟踪并由 btt 分析的一些重要事件有:

    • I/O 事件排队(Q)
    • 将 I/O 分配给驱动程序事件(D)
    • I/O 事件(C)
  • iowatcher 可以使用 blktrace 输出来图形 I/O。它侧重于磁盘 I/O 的逻辑块地址(LBA)、每秒吞吐量(以 MB 为单位)、每秒请求数和 I/O 操作数。这有助于识别何时达到设备的操作数秒限制。
  • BPF Compiler Collection(BCC)是一个库,它有助于创建扩展的 Berkeley Packet Filter(eBPF)程序。eBPF 程序在事件中触发,如磁盘 I/O、TCP 连接和进程创建。BCC 工具安装在 /usr/share/bcc/tools/ 目录中。以下 bcc-tools 有助于分析性能:

    • biolatency 总结了直方图中的块设备 I/O(磁盘 I/O)中的延迟。这允许研究发行版,包括两种设备缓存命中和缓存未命中模式,以及延迟延迟延迟。
    • biosnoop 是用于显示每个 I/O 事件以及发布进程 ID 和 I/O 延迟的基本块 I/O 跟踪工具。使用这个工具,您可以调查磁盘 I/O 性能问题。
    • biotop 用于内核中的块 i/o 操作。
    • filelife 工具跟踪 stat() 系统调用。
    • fileslower 跟踪较慢的同步文件读写。
    • filetop 可按进程显示文件的读取和写入.
    • ext4slowernfsslowerxfsslower 是显示文件系统操作比特定阈值慢的工具,其默认值为 10ms

      如需更多信息,请参阅使用 BPF Compiler Collection 分析系统性能

  • bpftaceeBPF 的追踪语言,用于分析性能问题。它还提供跟踪实用程序(如 BCC)进行系统观察,这对于调查 I/O 性能问题非常有用。
  • 以下 SystemTap 脚本在诊断存储或文件系统性能问题时可能有用:

    • disktop.stp: 检查每 5 秒读取或写入磁盘的状态,并输出该期间内前 10 个条目。
    • iotime.stp:打印读取和写入操作所需的时间,以及读取和写入的字节数。
    • traceio.stp:根据观察到的累计 I/O 流量打印前十个可执行文件,每秒.
    • traceio2.stp: 会在发生对指定设备的读取和写入时打印可执行名称和进程标识符。
    • Inodewatch.stp:每次对指定主设备或次要设备上的指定索引节点发生读或写时,打印可执行名称和进程标识符。
    • inodewatch2.stp:每次在指定主设备或次要设备上的指定索引节点上更改属性时,打印可执行名称、进程标识符和属性。

其它资源

30.2. 用于格式化文件系统的可用调整选项

在设备格式化后,无法更改一些文件系统配置决策。

以下是格式化存储设备前可用的选项:

Size
为您的工作负载创建适当大小的文件系统。较小的文件系统需要较少的时间和内存进行文件系统检查。但是,如果文件系统太小,其性能会受到高碎片影响。
Block size

块是文件系统的工作单元。块大小决定了单个块中可以存储多少数据,因此一次写入或读取的最小数据量。

默认块大小适用于大多数用例。但是,如果块大小或多个块的大小与通常一次读取或写入的数据量相同或略大,则文件系统性能更好,并且存储数据效率更高。个小文件仍然使用整个 块。文件可以分散到多个块中,但这会产生额外的运行时开销。

此外,某些文件系统仅限于特定数量的块,进而限制文件系统的最大大小。使用 mkfs 命令格式化设备时,块大小作为文件系统选项的一部分指定。指定块大小的参数因文件系统而异。

Geometry

文件系统 geometry 涉及文件系统中数据的分布。如果您的系统使用分条存储(如 RAID),您可以在格式化该设备时将数据和元数据与底层存储几兆对齐来提高性能。

许多设备会导出建议的 geometry,然后在设备使用特定文件系统格式化时自动设置。如果您的设备没有导出以上建议,或者您想要更改推荐的设置,那么当使用 mkfs 命令格式化该设备时,您必须手动指定 geometry。

指定文件系统地理位置的参数因文件系统而异。

External journals
日志文件系统记录了在执行操作之前,日志文件中写入操作期间将要进行的更改。这降低了存储设备在系统崩溃或电源故障时损坏的可能性,并加快恢复过程。
注意

红帽不推荐使用外部日志选项。

元数据密集型工作负载涉及非常频繁的日志更新。较大的日志使用更多的内存,但会降低写入操作的频率。此外,您可以通过将其日志放在专用存储中,使其与主存储快或快于主存储,从而缩短具有元数据密集型工作负载的设备的搜索时间。

警告

确保外部日志可靠。丢失外部日志设备会导致文件系统损坏。必须在格式时创建外部日志,并在挂载时指定日志设备。

其它资源

30.3. 用于挂载文件系统的可用调整选项

以下是大多数文件系统可用的选项,可指定为该设备:

Access Time

每次读取文件时,都会使用发生访问时更新其元数据(atime)。这涉及额外的写入 I/O。relatime 是大多数文件系统的默认 atime 设置。

但是,如果更新这个元数据非常耗时,且不需要准确的访问时间数据,您可以使用 noatime 挂载选项挂载文件系统。这会在文件读取时禁用对元数据的更新。它还启用 nodiratime 行为,它会在读取目录时禁用对元数据的更新。

注意

使用 noatime mount 选项禁用 atime 更新可能会破坏依赖它们的应用程序,例如备份程序。

Read-ahead

Read-ahead 行为通过预先抓取可能需要的数据并将其加载到页面缓存中来加快文件访问速度,其中的检索速度可以快于磁盘上。读-ad-head 值越大,系统预填充数据前面是另一个。

Red Hat Enterprise Linux 尝试根据它检测到的文件系统设置适当的读号值。但是,准确检测并不总是被允许。例如,如果存储阵列作为单个 LUN 向系统显示自己,则系统会检测到单个 LUN,且不会为阵列设置适当的读-ahead 值。

涉及大量流传输顺序 I/O 的工作负载通常得益于高读头值。红帽企业 Linux 提供的与存储相关的调优配置集提高了读头值,与使用 LVM 条带一样,这些调整并非始终足以满足所有工作负载的需要。

其它资源

  • mount(8)xfs(5)ext4(5) man page

30.4. 丢弃未使用块的类型

对于固态磁盘和精简置备的存储,建议定期丢弃文件系统未使用的块。

以下是丢弃未使用的块的两种方法:

Batch discard
这个丢弃是 fstrim 命令的一部分。它丢弃文件系统中的所有未使用块,这些块符合管理员指定的标准。Red Hat Enterprise Linux 8 支持在支持物理丢弃操作的 XFS 和 ext4 格式的设备上进行批量丢弃。
Online discard

这种丢弃操作在挂载时通过 discard 选项进行配置,并在用户不干预的情况下实时运行。但是,它只丢弃从已使用到空闲的块。Red Hat Enterprise Linux 8 支持在 XFS 和 ext4 格式的设备上进行在线丢弃。

红帽建议批量丢弃,除非需要在线丢弃才能保持性能,或者在系统工作负载无法使用批量丢弃的情况下。

预分配将磁盘空间标记为分配给文件,而不将任何数据写入该空间。这可用于限制数据碎片和读性能差。Red Hat Enterprise Linux 8 支持在 XFS、ext4 和 GFS2 文件系统上预分配空间。应用程序也可以从使用 fallocate(2) glibc 调用预先分配空间中受益。

其它资源

  • mount(8)fallocate(2) man page

30.5. 固态磁盘调优注意事项

固态磁盘(SSD)使用 NAND 闪存芯片,而不是旋转磁带来存储持久数据。SSD 为整个逻辑块地址范围内的数据提供恒定访问时间,而且不会像其对应人员那样产生可观的搜索成本。它们每 GB 存储空间的成本更高,存储密度也更低,但它们的延迟和吞吐量也比 HDD 更低。

性能通常降级为 SSD 上使用的块,即磁盘容量。降级程度因供应商而异,但所有设备在这种情况下都会出现降级情况。启用丢弃行为有助于缓解这种降级。如需更多信息,请参阅丢弃未使用的块的类型

默认 I/O 调度程序和虚拟内存选项适合用于 SSD。在配置可影响 SSD 性能的设置时,请考虑以下因素:

I/O Scheduler

大多数 SSD 预期任何 I/O 调度程序都能正常工作。但是,与任何其他存储类型一样,红帽建议采用基准测试来确定给定工作负载的最佳配置。在使用 SSD 时,红帽建议仅更改 I/O 调度程序以测试特定工作负载。有关如何在 I/O 调度程序间切换的说明,请参考 /usr/share/doc/kernel-version/Documentation/block/switching-sched.txt 文件。

对于单队列 HBA,默认 I/O 调度程序是 deadline。对于多个队列 HBA,默认的 I/O 调度程序是 none。有关如何设置 I/O 调度程序的详情,请参考 设置磁盘调度程序

Virtual Memory
与 I/O 调度程序一样,虚拟内存(VM)子系统不需要特殊调优。鉴于 SSD 上 I/O 的快速性质,请尝试关闭 vm_dirty_background_ratiovm_dirty_ratio 设置,因为增加的写入活动通常不会对磁盘中其他操作的延迟造成负面影响。不过,这种调优可能会产生更多整体 I/O,因此在未进行特定于工作负载的测试的情况下,通常不建议这样做。
Swap
SSD 也可以用作交换设备,并且可能会生成良好的 page-out 和 page-in 性能。

30.6. 通用块设备调优参数

本节中列出的通用调优参数包括在 /sys/block/sdX/queue/ 目录中。

以下列出的调优参数与 I/O 调度程序调整分开,并适用于所有 I/O 调度程序:

add_random
一些 I/O 事件对 /dev/random 的熵池贡献贡献。如果这些贡献的开销可以相当长,则可以将此参数设置为 0
iostats

默认情况下启用 iostats,默认值为 1。将 iostats 值设置为 0 可禁用为该设备收集 I/O 统计,这会删除 I/O 路径的少量开销。将 iostats 设置为 0 可能会稍为提高非常高性能设备的性能,比如某些 NVMe 固态存储设备。建议不要启用 iostats,除非厂商为给定的存储模型另有指定。

如果您禁用 iostats,该设备的 I/O 统计信息将不再出现在 /proc/diskstats 文件中。/sys/diskstats 文件的内容是监控 I/O 工具的 I/O 信息来源,如 sariostats。因此,如果您为设备禁用 iostats 参数,则 I/O 监控工具输出中不再存在该设备。

max_sectors_kb

以 KB 为单位指定 I/O 请求的最大大小。默认值为 512 KB。此参数的最小值由存储设备的逻辑块大小决定。这个参数的最大值由 max_hw_sectors_kb 的值决定。

红帽建议 max_sectors_kb 始终是最佳 I/O 大小的倍数,以及内部纠删块大小。如果参数为零或者未由存储设备指定,则为任一参数使用 logical_block_size 值。

nomerges
大多数工作负载均可从请求合并中受益。但是,禁用合并对于调试很有用。默认情况下,nomerges 参数被设置为 0,这将启用合并。要禁用简单的一次性合并,将 nomerges 设置为 1。要禁用所有类型的合并,将 nomerges 设置为 2
nr_requests
它是已排队 I/O 的最大允许数。如果当前的 I/O 调度程序是 none,则这个数字只能减少,否则可以增加或减少这个数量。
optimal_io_size
有些存储设备通过此参数报告最佳 I/O 大小。如果报告这个值,红帽建议应用程序尽可能在最佳 I/O 大小的倍数中与 I/O 一致。
read_ahead_kb

定义操作系统可在后续读取操作期间提前读取的最大 KB 数。因此,下一个顺序读取的内核页面缓存中已存在必要的信息,这提高了读取 I/O 性能。

设备映射器通常受益于高 read_ahead_kb 值。128 每个设备映射的 KB 都是一个不错的起点,但将 read_ahead_kb 值增加到请求队列的 max_sectors_kb 可能会改进在进行连续读取大型文件的应用程序环境中的性能。

rotational
有些固态磁盘无法正确公布其固态状态,而是作为传统旋转磁盘挂载。手动将 rotational 值设置为 0,以禁用调度程序中不必要的搜索尝试逻辑。
rq_affinity
rq_affinity 的默认值是 1。它在一个 cpu 核心上完成 I/O 操作,它位于发布的 cpu 核心的同一个 cpu 组中。要只在发出 I/O 请求的处理器中执行完成,将 rq_affinity 设置为 2。要禁用上述两个能力,请将其设置为 0
scheduler
要为特定存储设备设置调度程序或调度程序首选顺序,编辑 /sys/block/devname/queue/scheduler 文件,其中 devname 是您要配置的设备的名称。

第 31 章 配置操作系统以优化对网络资源的访问

本节论述了如何配置操作系统以显示对工作负载中网络资源的优化访问。网络性能问题有时是硬件故障或基础架构故障造成的。解决这些问题超出了本文档的范围。

Tuned 服务提供了多个不同的配置集来提高多个特定用例的性能:

  • latency-performance
  • network-latency
  • network-throughput

31.1. 监控和诊断性能问题的工具

以下是 Red Hat Enterprise Linux 8 中可用的工具,用于监控系统性能并诊断与网络子系统相关的性能问题:

  • ss 实用程序打印有关套接字的统计信息,使管理员能够随着时间的推移评估设备性能。默认情况下,ss 显示已建立连接的开放非监听 TCP 套接字。利用命令行选项,管理员可以过滤掉有关特定套接字的统计信息。红帽建议使用 ss 替代 Red Hat Enterprise Linux 中已弃用的 netstat
  • ip 借助 实用程序,管理员可以管理和监控路由、设备、路由策略和隧道。ip 监控命令可以持续监控设备、地址和路由的状态。使用 -j 选项以 JSON 格式显示输出,该格式可进一步提供给其他实用程序以自动处理信息。
  • dropwatch 是一个交互式工具,由 dropwatch 软件包提供。它监控并记录内核丢弃的数据包。
  • ethtool 实用程序使管理员能够查看和编辑网络接口卡设置。使用此工具观察某些设备的统计信息,如该设备丢弃的数据包数量。使用 ethtool -S device name 命令,查看指定设备计数器的状态。
  • /proc/net/snmp 文件显示 snmp 代理用于 IP、ICMP、TCP 和 UDP 监控和管理的数据。定期检查此文件可帮助管理员识别异常值,从而识别潜在的性能问题。例如,在 /proc/net/snmp 文件中增加 UDP 输入错误(InErrors)可能表示套接字接收队列中存在瓶颈。
  • nstat 工具监控内核 SNMP 和网络接口统计信息.这个工具从 /proc/net/snmp 文件中读取数据,并以人类可读格式打印信息。
  • 默认情况下,由 systemtap-client 软件包提供的 SystemTap 脚本安装在 /usr/share/systemtap/examples/network 目录中:

    • nettop.stp: 脚本每 5 秒显示一个进程(进程标识符和命令)列表,其中包含发送和接收的数据包数,以及进程在该间隔期间发送和接收的数据量。
    • socket-trace.stp: 划分 Linux 内核的 net/socket.c 文件中的每个功能,并显示 trace 数据。
    • dropwatch.stp:每 5 秒,脚本会显示释放在内核中位置的套接字缓冲区数量。使用 --all-modules 选项查看符号名称。
    • latencytap.stp:此脚本记录了不同类型的延迟对一个或多个进程的影响。它每 30 秒打印延迟类型列表,按进程或进程等待的总时间降序排列。这可用于识别存储和网络延迟的原因。

    红帽建议在该脚本中使用 --all-modules 选项来更好地映射延迟事件。默认情况下,该脚本安装在 /usr/share/systemtap/examples/profiling 目录中。

  • BPF Compiler Collection(BCC)是一个库,它有助于创建扩展的 Berkeley Packet Filter(eBPF)程序。eBPF 程序的主要工具是分析操作系统性能和网络性能,而不会出现开销或安全问题。

其它资源

31.2. 数据包接收中的瓶颈

虽然网络堆栈在很大程度上是自我优化的,但网络数据包处理期间存在多个点,它们可能会成为瓶颈并降低性能。

以下是可能导致瓶颈的问题:

The buffer or ring buffer of the network card
如果内核丢弃大量数据包,硬件缓冲区可能会成为瓶颈。使用 ethtool 工具监控丢弃的数据包的系统。
The hardware or software interrupt queues
中断可能会增加延迟和处理器争用。有关处理器如何处理中断的详情,请参阅中断请求概述、手动 Balancing 中断和 设置 smp_affinity 掩码
The socket receive queue of the application
许多未复制的数据包或者 /proc/net/snmp 文件中的 UDP 输入错误(InErrors)增加,表示应用程序的接收队列存在瓶颈。

如果硬件缓冲丢弃了大量数据包,则以下是一些可能的解决方案:

Slow the input traffic
过滤传入流量,减少加入的多播组数量,或者减少广播流量以降低队列填充的速度。
Resize the hardware buffer queue

调整硬件缓冲区队列的大小:通过增大队列的大小来减少丢弃的数据包数量,使其不会像容易那样轻松地溢出。您可以使用 ethtool 命令修改网络设备的 rx/tx 参数:

ethtool --set-ring device-name value

Change the drain rate of the queue
  • 通过在到达队列前过滤或丢弃数据包,或通过降低设备的权重来降低队列填充的速度。过滤传入流量或降低网络接口卡的设备权重,以减慢传入的流量速度。

    设备权重指的是设备在单个调度处理器访问中一次可接收的数据包数量。您可以通过增加由 dev_weight 内核设置控制的设备权重来提高队列排空的速率。要临时更改此参数,请更改 /proc/sys/net/core/dev_weight 文件的内容,或者永久更改,使用 procps-ng 软件包提供的 sysctl 命令。

  • 增加应用的套接字队列的长度:这通常是提高套接字队列排空率的最简单方法,但不太可能是长期解决方案。如果套接字队列接收的突发流量有限,增加套接字队列的深度以匹配突发流量的大小可能会阻止数据包被丢弃。要增大队列的深度,请通过以下更改之一增加套接字接收缓冲的大小:

    • 增加 /proc/sys/net/core/rmem_default 参数的值:此参数控制套接字使用的接收缓冲的默认大小。这个值必须小于或等于 proc/sys/net/core/rmem_max 参数的值。
    • 使用 setsockopt 配置更大的 SO_RCVBUF 值: 这个参数控制套接字接收缓冲的最大字节大小。使用 getsockopt 系统调用来确定缓冲区的当前值。

更改队列的排空率通常是降低网络性能的最简单方法。但是,增加设备一次接收的数据包数量会使用额外的处理器时间,在此期间无法调度其他进程,因此可能会导致其他性能问题。

其它资源

  • ss(8)socket(7)ethtool(8) man page
  • /proc/net/snmp file

31.3. 忙碌轮询

如果分析揭示了高延迟,则您的系统可能会从基于轮询的数据包接收中受益,而非基于中断的数据包接收。

繁忙的轮询有助于减少网络接收路径的延迟,允许套接字层代码轮询网络设备的接收队列,并禁用网络中断。这删除了中断和结果上下文切换造成的延迟。不过,它也会增加 CPU 利用率。忙碌轮询也会阻止 CPU 休眠,这可能会产生额外的功耗。所有设备驱动程序都支持忙碌轮询行为。

其它资源

31.3.1. 启用忙碌轮询

默认情况下,禁用忙碌轮询。这个步骤描述了如何启用繁忙的轮询。

流程

  1. 确定启用了 CONFIG_NET_RX_BUSY_POLL 编译选项:

    # cat /boot/config-$(uname -r) | grep CONFIG_NET_RX_BUSY_POLL
    CONFIG_NET_RX_BUSY_POLL=y
  2. 启用忙碌轮询

    1. 要在特定套接字上启用忙碌轮询,请将 sysctl.net.core.busy_poll 内核值设置为 0 以外的值:

      # echo "net.core.busy_poll=50" > /etc/sysctl.d/95-enable-busy-polling-for-sockets.conf
      # sysctl -p /etc/sysctl.d/95-enable-busy-polling-for-sockets.conf

      这个参数控制在套接字轮询中等待数据包的微秒数并选择 syscalls。红帽建议使用 50 值。

    2. 在套接字中添加 SO_BUSY_POLL 套接字选项。
    3. 要在全局范围内启用忙碌轮询,请将 sysctl.net.core.busy_read 设置为 0 以外的值:

      # echo "net.core.busy_read=50" > /etc/sysctl.d/95-enable-busy-polling-globally.conf
      # sysctl -p /etc/sysctl.d/95-enable-busy-polling-globally.conf

      net.core.busy_read 参数控制在设备队列中等待套接字读取数据包的微秒数。它还设置 SO_BUSY_POLL 选项的默认值。红帽建议为少量套接字使用 50 值,对于大量套接字,值为 100。对于非常大的插槽,例如超过数百个,使用 epoll 系统调用。

验证步骤

  • 验证是否启用了忙碌轮询

    # ethtool -k device | grep "busy-poll"
    busy-poll: on [fixed]
    
    # cat /proc/sys/net/core/busy_read
    50

其它资源

31.4. 接收扩展

接收扩展(RSS)(也称为多队列接收)可在多个基于硬件的接收队列之间分发网络接收处理,允许多个 CPU 处理入站网络流量。RSS 可用于减轻因单个 CPU 过载导致的接收中断处理方面的瓶颈,并降低网络延迟。默认情况下启用 RSS。

在适当的网络设备驱动程序中配置应处理 RSS 网络活动的队列数量或 CPU 数量:

  • 对于 bnx2x 驱动程序,它在 num_queues 参数中配置。
  • 对于 sfc 驱动程序,它在 rss_cpus 参数中配置。

不管如何,它通常在 /sys/class/net/device/queues/rx-queue/ 目录中配置,其中 device 是网络设备的名称(如 enp1s0)和rx-queue 是相应接收队列的名称。

irqbalance 守护进程可与 RSS 结合使用,以减少跨节点内存传输和缓存行重新使用的可能性。这降低了处理网络数据包的延迟。

31.4.1. 查看中断请求队列

在配置接收扩展(RSS)时,红帽建议将队列数量限制为每个物理 CPU 内核一个队列。超线程通常在分析工具中作为单独的核心来表示,但为所有核心(如超线程)配置队列并不对网络性能有用。

启用后,RSS 根据每个 CPU 的处理量在可用 CPU 之间均匀分配网络处理。但是,使用 ethtool 工具的 --show-rxfh-indir--set-rxfh-indir 参数,修改 RHEL 分发网络活动的方式,并平衡某些类型的网络活动的重要性。

这个步骤描述了如何查看中断请求队列。

流程

  • 要确定您的网络接口卡是否支持 RSS,检查多个中断请求队列是否与 /proc/interrupts 中的接口关联:

    # egrep 'CPU|p1p1' /proc/interrupts
     CPU0    CPU1    CPU2    CPU3    CPU4    CPU5
    89:   40187       0       0       0       0       0   IR-PCI-MSI-edge   p1p1-0
    90:       0     790       0       0       0       0   IR-PCI-MSI-edge   p1p1-1
    91:       0       0     959       0       0       0   IR-PCI-MSI-edge   p1p1-2
    92:       0       0       0    3310       0       0   IR-PCI-MSI-edge   p1p1-3
    93:       0       0       0       0     622       0   IR-PCI-MSI-edge   p1p1-4
    94:       0       0       0       0       0    2475   IR-PCI-MSI-edge   p1p1-5

    输出显示 NIC 驱动程序为 p1p1 接口(p1p1-0p1p1-5)创建了 6 个接收队列。它还显示每个队列处理了多少个中断,以及服务中断的 CPU。在这种情况下,有 6 个队列,因为默认情况下,这个特定 NIC 驱动程序会为每个 CPU 创建一个队列,此系统具有 6 个 CPU。在 NIC 驱动程序中,这是相当常见的模式。

  • 使用地址 0000:01:00.0 列出 PCI 设备的中断请求队列:

    # ls -1 /sys/devices/*/*/0000:01:00.0/msi_irqs
    101
    102
    103
    104
    105
    106
    107
    108
    109

31.5. 接收数据包表

接收数据包声明(RPS)与接收侧边扩展(RSS)类似,因为它用于将数据包定向到特定 CPU 进行处理。但是,RPS 在软件级别上实施,有助于防止单个网络接口卡的硬件队列成为网络流量的瓶颈。

与基于硬件的 RSS 相比,RPS 具有几个优点:

  • RPS 可以和任何网络接口卡一起使用。
  • 可以在 RPS 中添加软件过滤器,以处理新协议。
  • RPS 不会增加网络设备的硬件中断率。然而,它确实引入了处理器间中断。

RPS 根据网络设备和接收队列配置,在 /sys/class/net/device/queues/rx-queue/rps_cpus 文件中,其中 device 是网络设备的名称,如 enp1s0 andrx-queue 是相应接收队列的名称,如 rx-0。

rps_cpus 文件的默认值为 0。这会禁用 RPS,CPU 处理网络中断并处理数据包。要启用 RPS,使用应处理指定网络设备数据包并接收队列的 CPU 配置适当的 rps_cpus 文件。

rps_cpus 文件使用以逗号分隔的 CPU 位映射。因此,要允许 CPU 处理接口上接收队列的中断,请将它们在位图中的位置值设置为 1。例如,若要使用 CPU 0123 处理中断,可将 rps_cpus 的值设置为 f,这是 15 的十六进制值。在二进制表示中,1500001111 (1+2+4+8)

对于具有单传输队列的网络设备,可以通过将 RPS 配置为使用同一内存域中的 CPU 来实现最佳性能。在非 NUMA 系统上,这意味着可以使用所有可用的 CPU。如果网络中断率非常高,除处理网络中断的 CPU 外,也可以提高性能。

对于有多个队列的网络设备,配置 RPS 和 RSS 时通常没有好处,因为 RSS 被配置为默认将 CPU 映射到每个接收队列。但是,如果硬件队列比 CPU 少,并且 RPS 配置为在同一内存域中使用 CPU,则 RPS 仍然很有用。

31.6. 接收流畅

接收流速(RFS)扩展接收数据包定位(RPS)行为,以提高 CPU 缓存命中率,从而减少网络延迟。当 RPS 仅根据队列长度转发数据包时,RFS 使用 RPS 后端来计算最合适的 CPU,然后根据使用数据包的应用程序的位置转发数据包。这提高了 CPU 缓存效率。

从单个发送器接收的数据不会发送到多个 CPU。如果单个发送方收到的数据量大于单个 CPU 可处理的数据量,请配置更大的帧大小以减少中断数量,从而减少 CPU 处理工作的数量。或者,考虑 NIC 卸载选项或更快的 CPU。

考虑将 numactltaskset 与 RFS 结合使用,将应用程序固定到特定的内核、套接字或 NUMA 节点。这有助于防止数据包被不按顺序处理。

31.6.1. 启用接收流(接收流)

默认情况下禁用接收流(RFS)。这个步骤描述了如何启用 RFS。

流程

  1. net.core.rps_sock_flow_entries 内核值的值设置为预期的并发活跃连接的最大数量:

    # echo "net.core.rps_sock_flow_entries=32768" > /etc/sysctl.d/95-enable-rps.conf
    注意

    红帽建议为中等服务器负载使用 32768 值。输入的所有值在实际中都被舍入到 2 最接近的容量。

  2. 永久设置 net.core.rps_sock_flow_entries

    # sysctl -p /etc/sysctl.d/95-enable-rps.conf
  3. sys/class/net/device/queues/rx-queue/rps_flow_cnt 文件的值临时设置为(rps_sock_flow_entries/N)的值,其中 N 是设备中的接收队列数:

    # echo 2048 > /sys/class/net/device/queues/rx-queue/rps_flow_cnt

    使用您要配置的网络设备的名称替换 device(例如,enp1s0),并将rx-queue 替换为您要配置的接收队列(例如:rx-0)。

    使用配置的接收队列数量替换 N。例如,如果 rps_flow_entries 被设置为 32768,并且有 16 配置的接收队列,则 rps_flow_cnt = 32786/16= 2048 (即 rps_flow_cnt = rps_flow_enties/N )。

    对于单队列设备,rps_flow_cnt 的值与 rps_sock_flow_entries 值相同。

  4. 在所有网络设备中永久启用 RFS,创建 /etc/udev/rules.d/99-persistent-net.rules 文件并添加以下内容:

    SUBSYSTEM=="net", ACTION=="add", RUN{program}+="/bin/bash -c 'for x in /sys/$DEVPATH/queues/rx-*; do echo 2048 > $x/rps_flow_cnt;  done'"
  5. 可选:在特定网络设备中启用 RPS:

    SUBSYSTEM=="net", ACTION=="move", NAME="device name" RUN{program}+="/bin/bash -c 'for x in /sys/$DEVPATH/queues/rx-*; do echo 2048 > $x/rps_flow_cnt; done'"

    使用实际网络设备名称替换设备名称

验证步骤

  • 验证是否启用了 RFS:

    # cat /proc/sys/net/core/rps_sock_flow_entries
    32768
    
    # cat /sys/class/net/device/queues/rx-queue/rps_flow_cnt
    2048

其它资源

  • sysctl(8) man page

31.7. 加速的 RFS

通过添加硬件辅助功能,加速 RFS 提升了接收流(RFS)的速度。与 RFS 一样,数据包根据使用数据包的应用程序的位置进行转发。

但是,与传统的 RFS 不同,数据包直接发送到使用数据的线程的本地 CPU:

  • 执行应用的 CPU
  • 或者缓存层次结构中该 CPU 本地的 CPU

只有满足以下条件时,加速的 RFS 才可用:

  • NIC 必须支持加速的 RFS。导出 ndo_rx_flow_steer() 功能的卡支持加速 RFS。net_device检查 NIC 的数据表,以确保是否支持此功能。
  • ntuple 必须启用过滤。有关如何启用这些过滤器的详情,请参考 启用 ntuple 过滤器

满足这些条件后,根据传统的 RFS 配置自动停用 CPU 到队列映射。也就是说,CPU 到队列映射将根据驱动程序为每个接收队列配置的 IRQ 影响而降低。有关启用传统 RFS 的更多信息,请参阅启用接收流域

31.7.1. 启用 ntuple 过滤器

必须启用 ntuple 过滤。使用 ethtool -k 命令启用 ntuple 过滤器。

流程

  1. 显示 ntuple 过滤器的当前状态:

    # ethtool -k enp1s0 | grep ntuple-filters
    
    ntuple-filters: off
  2. 启用 ntuple 过滤器:

    # ethtool -k enp1s0 ntuple on
注意

如果输出是 ntuple-filters: off [fixed],则禁用 ntuple 过滤,且您无法配置它:

# ethtool -k enp1s0 | grep ntuple-filters
ntuple-filters: off [fixed]

验证步骤

  • 如果启用了 ntuple 过滤器:

    # ethtool -k enp1s0 | grep ntuple-filters
    ntuple-filters: on

其它资源

  • ethtool(8) man page

第 32 章 配置操作系统以优化内存访问

这部分论述了如何配置操作系统以优化工作负载的内存访问,以及用于这样做的工具。

32.1. 用于监控和诊断系统内存问题的工具

Red Hat Enterprise Linux 8 中提供了以下工具来监控系统性能并诊断与系统内存相关的性能问题:

  • vmstat procps-ng 软件包提供的工具显示系统进程、内存、分页、块 I/O、陷阱、磁盘和 CPU 活动的报告。它提供自计算机上次打开或上次报告之后平均这些事件的即时报告。
  • valgrind 框架为用户空间二进制文件提供了工具。使用 yum install valgrind 命令安装这个工具。它包含很多工具,您可以使用它们来分析和分析程序性能,例如:

    • memcheck 选项是默认的 valgrind 工具。它检测并报告一些难以检测和诊断的内存错误,例如:

      • 不应发生的内存访问
      • 未定义或未初始化值使用
      • 释放堆内存不正确
      • 指针重叠
      • 内存泄漏

        注意

        memcheck 只能报告这些错误,它无法阻止它们发生。但是,memcheck 在出错前立即记录错误消息。

    • cachegrind 选项模拟应用程序与系统的缓存层次结构和分支预测器的交互。它在应用执行期间收集统计信息,并将摘要输出到控制台。
    • massif 选项测量指定应用使用的堆空间。它测量有用的空间和分配用于预订和调整的其他空间。

其它资源

  • vmstat(8)valgrind(1) man page
  • /usr/share/doc/valgrind-version/valgrind_manual.pdf file

32.2. 系统内存概述

Linux 内核旨在最大限度地提高系统内存资源(RAM)的利用率。由于这些设计特征,根据工作负载的内存要求,系统部分内存正在内核中使用,代表工作负载使用,而内存的一小部分是空闲的。此可用内存保留给特殊系统分配,用于其他低优先级或高优先级系统服务。

系统内存的其余部分专用于工作负载本身,并分为以下两个类别:

File memory

在此类别中添加的页面代表永久存储中文件的一部分。这些页面可以从页面缓存中映射或取消映射应用的地址空格。您可以使用应用程序使用 mmap 系统调用将文件映射到其地址空间中,或者通过缓冲的 I/O 读写系统调用处理文件。

缓冲的 I/O 系统调用以及直接映射页面的应用程序可以重新利用未映射的页面。因此,这些页面由内核存储在缓存中,特别是在系统没有运行任何内存密集型任务时,以避免在同一组页面上重新发出昂贵的 I/O 操作。

Anonymous memory
此类别中的页面由动态分配的进程使用,或者与永久存储中的文件无关。这组页面备份每个任务的内存中控制结构,如应用堆栈和堆区域。

图 32.1. 内存用量模式

RHEL 内存使用模式

32.3. 虚拟内存参数

虚拟内存参数在 /proc/sys/vm 目录中列出。

以下是可用的虚拟内存参数:

vm.dirty_ratio
是百分比值。当修改系统内存总量的百分比时,系统开始使用 pdflush 操作写入磁盘修改。默认值为 20 %。
vm.dirty_background_ratio
百分比值.修改系统内存总量的百分比时,系统开始在后台将修改写入磁盘。默认值为 10 %。
vm.overcommit_memory

定义确定大型内存请求是接受还是拒绝的条件。默认值是 0

默认情况下,内核通过估算可用内存量和失败的请求量来执行启发式内存过量使用处理。但是,由于内存是使用启发式而不是精确算法来分配的,因此此设置可能会造成内存过载。

设置 overcommit_memory 参数的值:

  • 当将此参数设置为 1 时,内核不会执行内存过量使用处理。这增加了内存过载的可能性,但提高了内存密集型任务的性能。
  • 当将此参数设置为 2 时,内核会拒绝等于或大于可用交换空间总和 overcommit_ratio 中指定的物理 RAM 百分比的内存请求。这降低了过量使用内存的风险,但建议仅用于交换区域大于物理内存的系统。
vm.overcommit_ratio
指定 overcommit_memory 设置为 2 时考虑的物理 RAM 百分比。默认值为 50
vm.max_map_count
定义进程可以使用的最大内存映射区域数。默认值为 65530。如果您的应用程序需要更多内存映射区域,请提高这个值。
vm.min_free_kbytes

设置保留可用页面池的大小。它还负责设置管理 Linux 内核页面重新声明算法行为的 min_pagelow_pagehigh_page 阈值。它还指定了在系统中保持可用最小 KB 的数量。这会为每个低内存区域计算一个特定值,每个区按照其大小分配一组保留的可用页面。

设置 vm.min_free_kbytes 参数的值:

  • 增加参数值可有效减少应用程序的工作集合的可用内存。因此,您可能只将它用于由内核驱动的工作负载,其中驱动程序缓冲区需要在原子环境中分配。
  • 如果内存在系统中面临大量争用,则减少参数值可能会导致内核无法服务系统请求。

    警告

    极端值可能会影响系统的性能。将 vm.min_free_kbytes 设置为非常低的值可防止系统有效地回收内存,这会导致系统崩溃并导致服务中断或其他内核服务失败。但是,设置 vm.min_free_kbytes 过高会显著增加系统重新声明活动,从而导致错误直接重新声明状态导致分配延迟。这可能会导致系统立即输入内存不足状态。

    vm.min_free_kbytes 参数还设置一个页重新声明水位线,名为 min_pages。在决定控制页面回收算法的其他两个内存水位线 low_pageshigh_pages 时,这个水位线被用作因素。

/proc/PID/oom_adj

如果系统内存不足,且 panic_on_oom 参数被设置为 0oom_killer 功能会终止进程,从具有最高 oom_score 的进程开始,直到系统恢复为止。

oom_adj 参数决定进程的 oom_score。这个参数是为每个进程标识符设置的。-17 的值会禁用该进程的 oom_killer。其他有效值范围从 -1615

注意

由调整后的进程创建的进程将继承该进程的 oom_score

vm.swappiness

交换性值(范围从 0100 )控制系统首选从匿名内存池或页面缓存内存池回收内存的程度。

设置 swappiness 参数的值:

  • 更高的值优先是文件映射驱动的工作负载,而交换出不太活跃访问的进程的 RAM 映射内存。这可用于文件服务器或流应用程序,这些应用程序依赖存储中的文件(来自存储中的文件)驻留在内存中,以减少服务请求的 I/O 延迟。
  • 低值优先使用匿名映射的工作负载,同时回收页面缓存(文件映射内存)。此设置对于不大量依赖于文件系统信息、大量使用动态分配和私有内存的应用程序(如数学和编号阻塞应用程序)以及很少的硬件虚拟化管理器(如 QEMU)非常有用。

    vm.swappiness 参数的默认值是 30

    警告

    vm.swappiness 设置为 0 会积极避免将匿名内存交换到磁盘中,这会增加内存或 I/O 密集型工作负载时被 oom_killer 功能终止的风险。

其它资源

32.4. 文件系统参数

文件系统参数在 /proc/sys/fs 目录中列出。以下是可用文件系统参数:

aio-max-nr
定义所有活跃的异步输入/输出上下文中允许的最大事件数。默认值为 65536,修改这个值不会预先分配或调整任何内核数据结构的大小。
file-max

确定整个系统处理的最大文件数。Red Hat Enterprise Linux 8 中的默认值是 8192,或者内核启动时可用的内存页面中有一个,以更长的时间为准。

增加这个值可解决缺少可用文件 handle 导致的错误。

其它资源

  • sysctl(8) man page

32.5. 内核参数

内核参数的默认值位于 /proc/sys/kernel/ 目录中。这些值会在启动时由内核计算,具体取决于可用的系统资源。

以下是用来为 msg*shm* System V IPC(sysvipc)系统调用设置限制的可用内核参数:

msgmax
定义消息队列中任何单个消息允许的最大允许大小,以字节为单位。这个值不能超过队列(msgmnb)的大小。使用 sysctl msgmax 命令确定您系统中的当前 msgmax 值。
msgmnb
定义单个消息队列的最大字节大小。使用 sysctl msgmnb 命令确定您系统中的当前 msgmnb 值。
msgmni
定义消息队列标识符的最大数量,以及队列的最大数量。使用 sysctl msgmni 命令确定您系统中的当前 msgmni 值。
shmall
定义一次系统上可以使用的共享内存页面总量。例如:AMD64 和 Intel 64 架构中的 4096 字节是 字节。使用 sysctl shmall 命令确定您系统中的当前 shmall 值。
shmmax
定义内核允许的单个共享内存段的最大字节大小。使用 sysctl shmmax 命令确定您系统中的当前 shmmax 值。
shmmni
定义系统范围的最大共享内存片段数。默认值为所有系统中的 4096

其它资源

  • sysvipc(7)sysctl(8) man page

第 33 章 配置巨页

物理内存在固定大小的块(称为页面)中进行管理。在 Red Hat Enterprise Linux 8 支持的 x86_64 构架中,内存页面的默认大小为 4 KB。此默认页面大小已证明适合通用操作系统,如支持多种不同工作负载的 Red Hat Enterprise Linux。

然而,在某些情况下,特定应用程序可能会因使用更大的页面大小而受益。例如:使用 4 KB 页面时,处理大量且相对固定的数百兆字节甚至几十兆字节的数据的应用程序可能会有性能问题。此类数据集可能需要大量 4 KB 页面,这可能会导致操作系统和 CPU 开销。

这部分提供有关 Red Hat Enterprise Linux 8 中的巨页以及如何配置它们的信息。

33.1. 可用的巨页功能

使用 Red Hat Enterprise Linux 8 时,您可以将巨页用于处理大数据集的应用程序,并改进此类应用程序的性能。

以下是 Red Hat Enterprise Linux 8 支持的巨页方法:

HugeTLB pages

HugeTLB 页面也称为静态巨页。保留 HugeTLB 页面的方法有两种:

Transparent HugePages (THP)

使用 THP 时,内核会自动为进程分配巨页,因此不需要手动保留静态大页面。以下是 THP 中的两种操作模式:

  • system-wide: 在这里,内核会尝试在可能分配大页面时为进程分配大页面,该进程正在使用很大的连续虚拟内存区域。
  • per-process: 在这里,内核只为您可以使用 madvise()系统调用指定的单独进程的内存区域分配巨页。

    注意

    THP 功能只支持 2 MB 页面。

    有关启用和禁用 THP 的详情,请参考 启用透明大页并禁用透明大页

33.2. 在引导时保留 HugeTLB 页面的参数

在引导时,使用以下参数来影响 HugeTLB 页面行为:

表 33.1. 用于在引导时配置 HugeTLB 页面的参数

参数描述默认值

hugepages

定义在启动时在内核中配置的持久大页面数量。

在 NUMA 系统中,定义了此参数的巨页在节点间平均分配。

您可以通过更改 /sys/devices/system/node/node_id/hugepages/hugepages-size/nr_hugepages 文件中的节点值,在运行时为特定节点分配巨页。

默认值为 0

要在引导时更新这个值,请在 /proc/sys/vm/nr_hugepages 文件中更改此参数的值。

hugepagesz

定义在启动时在内核中配置的持久大页面大小。

有效值为 2 MB1 GB。默认值为 2 MB

default_hugepagesz

定义在启动时在内核中配置的持久性巨页的默认大小。

有效值为 2 MB1 GB。默认值为 2 MB

33.3. 在引导时配置 HugeTLB

HugeTLB 子系统支持的页面大小取决于架构。x86_64 架构支持 2 MB 巨页和 1 GB 巨页。

这个步骤描述了如何在引导时保留 1 GB 页面。

流程

  1. 通过以 root 用户身份在 /etc/default/grub 文件中的内核命令行选项中附加以下行,为 1 GB 页面创建一个 HugeTLB 池:

    default_hugepagesz=1G hugepagesz=1G
  2. 使用编辑的默认文件重新生成 GRUB2 配置:

    1. 如果您的系统使用 BIOS 固件,请执行以下命令:

      # grub2-mkconfig -o /boot/grub2/grub.cfg
    2. 如果您的系统使用 UEFI 框架,请执行以下命令:

      # grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg
  3. /usr/lib/systemd/system/ 目录中创建一个名为 hugetlb-gigantic-pages.service 的新文件并添加以下内容:

    [Unit]
    Description=HugeTLB Gigantic Pages Reservation
    DefaultDependencies=no
    Before=dev-hugepages.mount
    ConditionPathExists=/sys/devices/system/node
    ConditionKernelCommandLine=hugepagesz=1G
    
    [Service]
    Type=oneshot
    RemainAfterExit=yes
    ExecStart=/usr/lib/systemd/hugetlb-reserve-pages.sh
    
    [Install]
    WantedBy=sysinit.target
  4. /usr/lib/systemd/ 目录中创建一个名为 hugetlb-reserve-pages.sh 的新文件并添加以下内容:

    在添加以下内容时,将 number_of_pages 替换为您要保留的 1GB 页面数,并使用要保留这些页面的节点名称替换 node。

    #!/bin/sh
    
    nodes_path=/sys/devices/system/node/
    if [ ! -d $nodes_path ]; then
        echo "ERROR: $nodes_path does not exist"
        exit 1
    fi
    
    reserve_pages()
    {
        echo $1 > $nodes_path/$2/hugepages/hugepages-1048576kB/nr_hugepages
    }
    
    reserve_pages number_of_pages node

    例如:要在 node0 上保留两个 1 GB 页面,在 node 1 上保留 1 个 1GB 页面,将 number_of_pages 替换为 2 用于 node0,1 用于 node1

    reserve_pages 2 node0
    reserve_pages 1 node1
  5. 创建可执行脚本:

    # chmod +x /usr/lib/systemd/hugetlb-reserve-pages.sh
  6. 启用早期引导保留:

    # systemctl enable hugetlb-gigantic-pages
注意
  • 您可以通过随时写入 nr_hugepages,尝试在运行时保留更多 1GB 页面。但是,由于内存碎片,此类保留可能会失败。保留 1 GB 页面的最可靠方法是使用这个 hugetlb-reserve-pages.sh 脚本,该脚本会在引导过程早期运行。
  • 保留静态大页面可以有效地减少系统可用的内存量,并阻止它正确使用内存容量。虽然正确大小的保留大页面池对于使用大页面的应用程序很有用,但保留巨页池的大小过大或未使用的剩余大页面最终将阻碍整体系统性能。在设置保留的巨页池时,请确保系统可以正确利用其完整内存容量。

其它资源

  • systemd.service(5) man page
  • /usr/share/doc/kernel-doc-kernel_version/Documentation/vm/hugetlbpage.txt file

33.4. 在运行时保留 HugeTLB 页面的参数

在运行时,使用以下参数来影响 HugeTLB 页面行为。

表 33.2. 在运行时配置 HugeTLB 页面的参数

参数描述文件名

nr_hugepages

定义分配给指定 NUMA 节点的指定大小的巨页数量。

/sys/devices/system/node/node_id/hugepages/hugepages-size/nr_hugepages

nr_overcommit_hugepages

定义系统可以通过过量使用内存来创建和使用的额外巨页的最大数量。

将任何非零值写入该文件表示系统会从内核的普通页面池中获取巨页的数量(如果持久的大页面池已耗尽)。当这些大页面变得未使用后,它们会被释放并返回到内核的普通页面池。

/proc/sys/vm/nr_overcommit_hugepages

33.5. 在运行时配置 HugeTLB

这个步骤描述了如何向 node2 添加 2048 kB 巨页。

要根据您的要求保留页面,请替换:

  • 20 以及您要保留的巨页数量,
  • 2048KB,带有巨页大小,
  • node2 带有您要保留页面的节点。

流程

  1. 显示内存统计信息:

    # numastat -cm | egrep 'Node|Huge'
                     Node 0 Node 1 Node 2 Node 3  Total add
    AnonHugePages         0      2      0      8     10
    HugePages_Total       0      0      0      0      0
    HugePages_Free        0      0      0      0      0
    HugePages_Surp        0      0      0      0      0
  2. 将指定大小的巨页数量添加到节点:

    # echo 20 > /sys/devices/system/node/node2/hugepages/hugepages-2048kB/nr_hugepages

验证步骤

  • 确保添加了巨页数量:

    # numastat -cm | egrep 'Node|Huge'
                     Node 0 Node 1 Node 2 Node 3  Total
    AnonHugePages         0      2      0      8     10
    HugePages_Total       0      0     40      0     40
    HugePages_Free        0      0     40      0     40
    HugePages_Surp        0      0      0      0      0

其它资源

  • numastat(8) man page

33.6. 启用透明大页

在 Red Hat Enterprise Linux 8 中默认启用 THP。但是,您可以启用或禁用 THP。

这个步骤描述了如何启用 THP。

流程

  1. 检查 THP 的当前状态:

    # cat /sys/kernel/mm/transparent_hugepage/enabled
  2. 启用 THP:

    # echo always > /sys/kernel/mm/transparent_hugepage/enabled
  3. 要防止应用程序分配超过必要数量的内存资源,请禁用系统范围的透明巨页,并只为通过 madvise 明确请求它的应用程序启用它们:

    # echo madvise > /sys/kernel/mm/transparent_hugepage/enabled
注意

有时,为短期的分配提供低延迟的优先级高于立即通过长期分配实现最佳性能。在这种情况下,您可以在启用 THP 的同时禁用直接紧凑。

直接紧凑是在巨页分配期间异步内存紧凑。禁用直接紧凑不保证保存内存,但可以降低频繁页面错误时出现较高延迟的风险。请注意,如果工作负载显著受益于 THP,性能会降低。禁用直接压缩:

# echo madvise > /sys/kernel/mm/transparent_hugepage/defrag

其它资源

33.7. 禁用透明大页

在 Red Hat Enterprise Linux 8 中默认启用 THP。但是,您可以启用或禁用 THP。

这个步骤描述了如何禁用 THP。

流程

  1. 检查 THP 的当前状态:

    # cat /sys/kernel/mm/transparent_hugepage/enabled
  2. 禁用 THP:

    # echo never > /sys/kernel/mm/transparent_hugepage/enabled

33.8. 对转换前缓冲大小的影响

从页表中读取地址映射非常耗时且耗费资源,因此 CPU 构建时会使用最近使用的地址的缓存,称为 Translation Lookaside Buffer(TLB)。但是,默认 TLB 只能缓存一定数量的地址映射。

如果请求的地址映射不在 TLB 中(称为 TLB miss),则系统仍需要读取页表以确定物理地址到虚拟地址映射。由于应用程序内存要求和用于缓存地址映射的页面大小之间的关系,具有大型内存要求的应用程序更有可能遭受 TLB 未命中性能下降的问题,而不是内存要求最低的应用程序。因此,尽可能避免 TLB 未命中非常重要。

HugeTLB 和 Transparent Huge Page 功能允许应用程序使用大于 4 KB 的页面。这允许 TLB 中存储的地址引用更多内存,这可减少 TLB 未命中并提高应用性能。

第 34 章 SystemTap 入门

作为系统管理员,您可以使用 SystemTap 识别运行 Linux 系统上出现错误或性能问题的底层原因。

作为应用开发人员,您可以使用 SystemTap 详细监控应用程序在 Linux 系统中的行为。

34.1. SystemTap 的目的

SystemTap 是一款跟踪和探测工具,可用于详细研究和监控操作系统(特别是内核)的活动。SystemTap 提供的信息类似于 netstatpstopiostat 等工具的输出。但是,SystemTap 为收集的信息提供更多过滤和分析选项。在 SystemTap 脚本中,您可以指定 SystemTap 收集的信息。

SystemTap 旨在通过为用户提供相应的基础架构来跟踪内核活动并将此功能与两个属性相结合,以此补充现有的 Linux 监控工具套件:

灵活性
SystemTap 框架允许您开发用于调查和监控内核空间中各种内核功能、系统调用和其他事件的简单脚本。因此,SystemTap 不再只是一个工具,它是一个可让您开发特定于内核的取证和监控工具的系统。
易于使用
SystemTap 允许您监控内核活动,而无需重新编译内核或重新引导系统。

34.2. Installing SystemTap

要开始使用 SystemTap,请安装必要的软件包。要在多个系统安装了多个内核的内核中使用 SystemTap,请为每个内核版本安装对应的内核软件包

先决条件

流程

  1. 安装所需的 SystemTap 软件包:

    # yum install systemtap
  2. 安装所需的内核软件包:

    1. 使用 stap-prep:

      # stap-prep
    2. 如果 stap-prep 无法工作,请手动安装所需的内核软件包:

      # yum install kernel-debuginfo-$(uname -r) kernel-debuginfo-common-$(uname -i)-$(uname -r) kernel-devel-$(uname -r)

      $(uname -i) 会自动替换为系统的硬件平台,$(uname -r) 会自动替换为正在运行的内核版本。

验证步骤

  • 如果要使用 SystemTap 探测的内核当前正在使用,测试您的安装是否成功:

    # stap -v -e 'probe kernel.function("vfs_read") {printf("read performed\n"); exit()}'

    成功部署 SystemTap 时会出现类似如下的输出:

    Pass 1: parsed user script and 45 library script(s) in 340usr/0sys/358real ms.
    Pass 2: analyzed script: 1 probe(s), 1 function(s), 0 embed(s), 0 global(s) in 290usr/260sys/568real ms.
    Pass 3: translated to C into "/tmp/stapiArgLX/stap_e5886fa50499994e6a87aacdc43cd392_399.c" in 490usr/430sys/938real ms.
    Pass 4: compiled C into "stap_e5886fa50499994e6a87aacdc43cd392_399.ko" in 3310usr/430sys/3714real ms.
    Pass 5: starting run. 1
    read performed 2
    Pass 5: run completed in 10usr/40sys/73real ms. 3

    输出的最后三行(使用 Pass 5的示例)表示:

    1
    SystemTap 成功创建了探测内核并运行检测的工具。
    2
    SystemTap 检测到指定的事件(本例中为 A VFS 读取)。
    3
    SystemTap 执行了一个有效的处理程序(打印文本,然后在不出现错误的情况下将其关闭)。

34.3. 运行 SystemTap 的特权

运行 SystemTap 脚本需要升级的系统特权,但在某些情况下,非特权用户可能需要在其计算机上运行 SystemTap 检测。

要允许用户在没有 root 访问权限的情况下运行 SystemTap,请将用户添加到这两个用户组中

stapdev

这个组的成员可以使用 stap 运行 SystemTap 脚本,或者 staprun 运行 SystemTap 检测模块。

运行 stap 涉及将 SystemTap 脚本编译到内核模块中,并将它们加载到内核中。这需要提高系统的权限,系统会授予 stapdev 成员的权限。不幸的是,这些权限也授予 stapdev 成员的有效 root 访问权限。因此,只为可信任 root 访问权限的用户授予 stapdev 组成员资格。

stapusr
这个组的成员只能使用 staprun 运行 SystemTap 检测模块。另外,他们只能从 /lib/modules/kernel_version/systemtap/ 目录中运行这些模块。该目录只能归 root 用户所有,并且只能由 root 用户写入。

34.4. 运行 SystemTap 脚本

您可以从标准输入或文件运行 SystemTap 脚本。

/usr/share/systemtap/examples 目录中可以找到随 SystemTap 安装一起分发的示例脚本。

先决条件

  1. SystemTap 和相关所需的内核软件包安装如安装 Systemtap 中所述
  2. 要以普通用户身份运行 SystemTap 脚本,请将用户添加到 SystemTap 组:

    # usermod --append --groups
    stapdev,stapusr user-name

流程

  • 运行 SystemTap 脚本:

    • 从标准输入中输入:

      # echo "probe timer.s(1) {exit()}" | stap -

      这个命令指示 stap 运行 echo 传递给标准输入的脚本。要添加 stap 选项,在 - 字符前面插入它们。例如,要使这个命令的结果更加详细,该命令为:

      # echo "probe timer.s(1) {exit()}" | stap -v -
    • 在一个文件中:

      # stap file_name

第 35 章 交叉检测 SystemTap

交叉检测 SystemTap 正在从一个系统上使用的 SystemTap 脚本创建 SystemTap 检测模块,脚本可在未完全部署 SystemTap 的另一个系统上使用。

35.1. SystemTap 交叉检测

运行 SystemTap 脚本时,从该脚本中构建一个内核模块。然后,SystemTap 将模块加载到内核中。

通常,SystemTap 脚本只能在部署 SystemTap 的系统上运行。要在十个系统上运行 SystemTap,需要在所有这些系统上部署 SystemTap。在某些情况下,这可能无法实现,也不需要。例如,企业策略可能会阻止您在特定计算机上安装提供编译器或调试信息的软件包,这将阻止 SystemTap 部署。

要临时解决这个问题,请使用交叉检测。交叉检测是从一个系统上要使用的 SystemTap 脚本生成 SystemTap 检测模块的过程。这个过程提供以下优点:

  • 可以将各种计算机的内核信息包安装到单一主机计算机上。
小心

内核打包错误可能会阻止此操作。在这种情况下,主机系统 和目标系统的 kernel-debuginfokernel-devel 软件包必须匹配。如果发生了这种情况,请向 https://bugzilla.redhat.com/ 报告这个错误。

  • 每一目标计算机只需要安装一个软件包即可使用生成的 SystemTap 检测模块: systemtap-runtime
重要

主机系统必须架构相同 ,并且运行与目标系统相同的 Linux 发行版,以便构建的检测模块正常工作

术语
检测模块
从 SystemTap 脚本构建的内核模块;SystemTap 模块构建在主机系统上 ,并将加载到目标系统的目标内核中
主机系统
编译检测模块的系统(来自 SystemTap 脚本),以加载到目标系统上
目标系统
正在构建检测模块的系统 (从 SystemTap 脚本)。
目标内核
目标系统的内核这是加载并运行检测模块的内核

35.2. 初始化 SystemTap 的交叉检测

初始化对 SystemTap 的交叉检测,从一个系统上的 SystemTap 脚本构建 SystemTap 检测模块,并在未完全部署 SystemTap 的另一系统上使用这些模块。

先决条件

小心

内核打包程序错误可能会阻止在一个系统中安装多个 kernel-debuginfokernel-devel 软件包。在这种情况下,主机系统 和目标系统的次要版本必须匹配。如果发生了这种情况,请向 https://bugzilla.redhat.com/ 报告这个错误。

流程

  1. 确定在每个目标系统中运行的内核

    $ uname -r

    对每个目标系统重复此步骤

  2. 在主机系统上,使用安装 Systemtap 的方法为每个目标系统安装 目标 内核和相关软件包
  3. 在主机系统中构建检测模块,将此模块复制到 目标系统中并在目标系统上运行此模块

    1. 使用远程实现:

      # stap --remote target_system script

      此命令在目标系统上远程实施指定的脚本您必须确保可以从主机系统到 目标系统进行 SSH 连接,才能成功。

    2. 手动:

      1. 在主机系统中构建检测模块

        # stap -r kernel_version script -m module_name -p 4

        在这里,kernel_version 是指在第 1 步中确定的目标内核版本脚本引用要转换为检测 模块的脚本,而 module_name 是检测模块的所需名称-p4 选项告诉 SystemTap 不加载并运行编译的模块。

      2. 编译检测模块后,将其复制到目标系统中并使用以下命令载入它:

        # staprun module_name.ko

第 36 章 使用 BPF Compiler Collection 分析系统性能

作为系统管理员,您可以使用 BPF Compiler Collection(BCC)库创建用于分析 Linux 操作系统性能和收集信息的工具,这些信息可能难以通过其他接口获得。

36.1. BCC 介绍

BPF Compiler Collection(BCC)是一个库,可帮助创建扩展的 Berkeley Packet Filter(eBPF)程序。eBPF 程序的主要工具是在不需要额外的开销或存在安全问题的情况下,分析操作系统性能和网络性能。

BCC 不再需要用户了解 eBPF 的技术详情,并提供了许多开箱即用的起点,如预先创建的 eBPF 程序的 bcc-tools 软件包。

注意

eBPF 程序在事件中触发,如磁盘 I/O、TCP 连接以及进程创建。程序不太可能导致内核崩溃、循环或者变得无响应,因为它们在内核的安全性虚拟机中运行。

36.2. 安装 bcc-tools 软件包

本节论述了如何安装 bcc-tools 软件包,该软件包还会将 BPF Compiler Collection(BCC)库作为依赖性安装。

先决条件

流程

  1. 安装 bcc-tools:

    # yum install bcc-tools

    BCC 工具安装在 /usr/share/bcc/tools/ 目录中。

  2. (可选)检查工具:

    # ll /usr/share/bcc/tools/
    ...
    -rwxr-xr-x. 1 root root  4198 Dec 14 17:53 dcsnoop
    -rwxr-xr-x. 1 root root  3931 Dec 14 17:53 dcstat
    -rwxr-xr-x. 1 root root 20040 Dec 14 17:53 deadlock_detector
    -rw-r--r--. 1 root root  7105 Dec 14 17:53 deadlock_detector.c
    drwxr-xr-x. 3 root root  8192 Mar 11 10:28 doc
    -rwxr-xr-x. 1 root root  7588 Dec 14 17:53 execsnoop
    -rwxr-xr-x. 1 root root  6373 Dec 14 17:53 ext4dist
    -rwxr-xr-x. 1 root root 10401 Dec 14 17:53 ext4slower
    ...

    上表中的 doc 目录包括了每个工具的文档。

36.3. 使用所选 bcc-tools 进行性能调整

这部分论述了如何使用 BPF Compiler Collection(BCC)库中某些预先创建的程序来高效且安全地分析每个事件的系统性能。BCC 库中预创建的程序集可作为创建其他程序的示例。

先决条件

使用 execsnoop 检查系统进程

  1. 在一个终端中执行 execsnoop 程序:

    # /usr/share/bcc/tools/execsnoop
  2. 在另一个终端执行中,例如:

    $ ls /usr/share/bcc/tools/doc/

    以上会为 ls 命令创建了一个简短运行的进程。

  3. 终端运行 execsnoop 显示类似如下的输出:

    PCOMM	PID    PPID   RET ARGS
    ls   	8382   8287     0 /usr/bin/ls --color=auto /usr/share/bcc/tools/doc/
    sed 	8385   8383     0 /usr/bin/sed s/^ *[0-9]\+ *//
    ...

    execsnoop 程序为每个消耗系统资源的新进程输出一行。它甚至会检测很快运行的程序(如 ls )的进程,大多数监控工具都不会注册它们。

    execsnoop 输出显示以下字段:

    • PCOMM - 父进程名称。(ls)
    • PID - 进程 ID。(8382)
    • PPID - 上级进程 ID。(8287)
    • RET - exec() 系统调用(0)的返回值,它会将程序代码加载到新进程中。
    • ARGS - 使用参数启动的程序的位置。

要查看 execsnoop 的详情、示例和选项,请参阅 /usr/share/bcc/tools/doc/execsnoop_example.txt 文件。

有关 exec() 的详情请参考 exec(3) 手册页。

使用 opensnoop 跟踪命令打开的文件

  1. 在一个终端中执行 opensnoop 程序:

    # /usr/share/bcc/tools/opensnoop -n uname

    以上列出了文件的输出结果,这些文件只由 uname 命令的进程打开。

  2. 在另一个终端中执行:

    $ uname

    以上命令会打开某些在下一步中捕获的文件。

  3. 终端运行 opensnoop 显示类似如下的输出:

    PID    COMM 	FD ERR PATH
    8596   uname 	3  0   /etc/ld.so.cache
    8596   uname 	3  0   /lib64/libc.so.6
    8596   uname 	3  0   /usr/lib/locale/locale-archive
    ...

    opensnoop 程序监视整个系统的 open() 系统调用,并为每个 uname 试图按方法打开的文件输出一行。

    opensnoop 输出显示以下字段:

    • PID - 进程 ID。(8596)
    • COMM - 进程名称。(uname)
    • FD - 文件描述符 - open() 返回引用打开文件的值。(3)
    • ERR - 任何错误。
    • PATH - open() 试图打开的文件位置。

      如果命令尝试读取不存在的文件,则 FD 列返回 -1ERR 列显示与相关错误对应的值。因此,opensnoop 可以帮助您识别行为不正确的应用程序。

要查看 opensnoop 的详情、示例和选项,请参阅 /usr/share/bcc/tools/doc/opensnoop_example.txt 文件。

有关 open() 的详情请参考 open(2) 手册页。

使用技术检查磁盘上的 I/O 操作

  1. 在一个终端中执行 biotop 程序:

    # /usr/share/bcc/tools/biotop 30

    该命令可让您监控在磁盘中执行 I/O 操作的主要进程。参数确保命令生成 30 秒概述。

    注意

    如果未提供任何参数,则默认情况下输出屏幕会每 1 秒刷新一次。

  2. 在另一个终端中执行,例如:

    # dd if=/dev/vda of=/dev/zero

    以上命令从本地硬盘设备中读取内容,并将输出写入 /dev/zero 文件中。此步骤生成特定的 I/O 流量来演示 biotop

  3. 终端运行 biotop 显示类似如下的输出:

    PID    COMM             D MAJ MIN DISK       I/O  Kbytes     AVGms
    9568   dd               R 252 0   vda      16294 14440636.0  3.69
    48     kswapd0          W 252 0   vda       1763 120696.0    1.65
    7571   gnome-shell      R 252 0   vda        834 83612.0     0.33
    1891   gnome-shell      R 252 0   vda       1379 19792.0     0.15
    7515   Xorg             R 252 0   vda        280  9940.0     0.28
    7579   llvmpipe-1       R 252 0   vda        228  6928.0     0.19
    9515   gnome-control-c  R 252 0   vda         62  6444.0     0.43
    8112   gnome-terminal-  R 252 0   vda         67  2572.0     1.54
    7807   gnome-software   R 252 0   vda         31  2336.0     0.73
    9578   awk              R 252 0   vda         17  2228.0     0.66
    7578   llvmpipe-0       R 252 0   vda        156  2204.0     0.07
    9581   pgrep            R 252 0   vda         58  1748.0     0.42
    7531   InputThread      R 252 0   vda         30  1200.0     0.48
    7504   gdbus            R 252 0   vda          3  1164.0     0.30
    1983   llvmpipe-1       R 252 0   vda         39   724.0     0.08
    1982   llvmpipe-0       R 252 0   vda         36   652.0     0.06
    ...

    biotop 输出显示以下字段:

    • PID - 进程 ID。(9568)
    • COMM - 进程名称。(dd)
    • DISK - 执行读取操作的磁盘。(vda)
    • I/O - 执行读取操作的数量。(16294)
    • Kbytes - 读操作达到的 K 字节。(14,440,636)
    • AVGms - 读操作的平均 I/O 时间。(3.69)

要查看 biotop 的详情、示例和选项,请参阅 /usr/share/bcc/tools/doc/biotop_example.txt 文件。

有关 dd 的详情请参考 dd(1) 手册页。

使用 xfsslower 来公开意料外的慢文件系统操作

  1. 在一个终端中执行 xfsslower 程序:

    # /usr/share/bcc/tools/xfsslower 1

    以上命令测量 XFS 文件系统执行读取、写入、打开或同步(fsync)操作的时间。1 参数确保程序只显示比 1 ms 慢的操作。

    注意

    如果没有提供参数,xfsslower 默认会显示比 10 ms 慢的操作。

  2. 在另一个终端中执行,例如:

    $ vim text

    以上命令在 vim 编辑器中创建了一个文本文件,用于启动与 XFS 文件系统的某些互动。

  3. 运行 xfsslower 的终端显示在保存上一步中的文件时:

    TIME     COMM           PID    T BYTES   OFF_KB   LAT(ms) FILENAME
    13:07:14 b'bash'        4754   R 256     0           7.11 b'vim'
    13:07:14 b'vim'         4754   R 832     0           4.03 b'libgpm.so.2.1.0'
    13:07:14 b'vim'         4754   R 32      20          1.04 b'libgpm.so.2.1.0'
    13:07:14 b'vim'         4754   R 1982    0           2.30 b'vimrc'
    13:07:14 b'vim'         4754   R 1393    0           2.52 b'getscriptPlugin.vim'
    13:07:45 b'vim'         4754   S 0       0           6.71 b'text'
    13:07:45 b'pool'        2588   R 16      0           5.58 b'text'
    ...

    上面的每一行代表文件系统中的一个操作,其用时超过特定阈值。xfsslower 对于公开可能的文件系统问题非常有用,这些问题可能会意外地减慢操作速度。

    xfsslower 输出显示以下字段:

    • COMM - 进程名称。(b’bash')
    • T - 操作类型。R

      • Read
      • Write
      • Sync
    • OFF_KB - KB 中的文件偏移。(0)
    • FILENAME - 被读取、写入或者同步的文件。

要查看 xfsslower 的详情、示例和选项,请参阅 /usr/share/bcc/tools/doc/xfsslower_example.txt 文件。

有关 fsync 的详情请参考 fsync(2) 手册页。

法律通告

Copyright © 2021 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, the Red Hat logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.