﻿# tuned / tuned-adm —— 一键套用内核调优配置集

## 这个工具是做什么的

> 生产环境真正做性能调优时，最烦的不是"不知道怎么改"，而是"改了东忘了西"——`sysctl` 改了一行、`/sys` 改了三个文件、GRUB 加了个 `isolcpus`、`ethtool` 调了中断合并…散落各处、换台机器又得重新来。**tuned** 就是为解决这个痛点设计的：它把**一组系统级调优参数打包成一个叫 profile 的配置集**，`tuned-adm profile <name>` 一条命令全部套用，切 profile 时还能自动回滚旧设定。

## 可以回答什么问题

| 问题 | 怎么用 |
|------|--------|
| 当前用的什么调优方案？ | `tuned-adm active` |
| 有哪些现成的调优方案可选？ | `tuned-adm list` |
| 想把服务器设成"通用高吞吐"模式？ | `tuned-adm profile throughput-performance` |
| 数据库低延迟怎么一键配置？ | `tuned-adm profile latency-performance` |
| 云虚拟机默认 profile 可能没开 performance governor？ | `tuned-adm active` 如果是 `virtual-guest`，切掉 |
| 想基于已有 profile 微调几个参数？ | 写自定义 profile，`include=throughput-performance` 继承 |
| 怎么验证 tuned 到底改了哪些参数？ | `tuned-adm profile_info <name>` |


> 相关：[kernel-tuning.md](/tools/proc/kernel-tuning.md) 讲了所有内核配置入口（sysctl/sysfs/GRUB/ethtool/ulimit），tuned 本质是把这些入口的参数**批量编排**起来；具体参数的语境散见 [../memory/free.md](/tools/memory/free.md)、[../../concepts/cache/tlb.md](/concepts/cache/tlb.md)、[../../concepts/process/thread-affinity.md](/concepts/process/thread-affinity.md) 等。

## 零、一句话定位

**tuned 是一个 daemon（`tuned`）+ 命令行管理工具（`tuned-adm`），它按"场景"（低延迟/高吞吐/虚拟化/省电…）预设好成套的内核参数，一条命令切过去，不用手动翻十几个文件。** 适合"我知道这个机器要跑什么类型的负载，但不记得每个参数该设多少"的场景。

## 一、核心概念：profile 就是一组规则的集合

每个 profile 是一个**目录**（通常在 `/usr/lib/tuned/<profile-name>/`），里面最重要的文件是 **`tuned.conf`**——它声明了这个 profile 会动哪些参数，以什么方式动：

```plantuml
@startuml
skinparam shadowing false
skinparam rectangle {
  BackgroundColor<<p>> #E3F2FD
  BorderColor<<p>> #1976D2
  BackgroundColor<<r>> #C8E6C9
  BorderColor<<r>> #388E3C
}
rectangle "tuned profile\n(例: latency-performance)" <<p>> as P
rectangle "[sysctl]\nvm.swappiness=10\nkernel.sched_min_granularity_ns=…" <<r>> as S
rectangle "[sysfs]\n/sys/.../scaling_governor=performance" <<r>> as F
rectangle "[bootloader]\ncmdline_spectre_v2=off" <<r>> as B
rectangle "[script]\n自定义 shell 脚本" <<r>> as C
rectangle "[cpu]\nenergy_perf_bias=performance" <<r>> as U
rectangle "…更多插件" <<r>> as X
P -down-> S
P -down-> F
P -down-> B
P -down-> C
P -down-> U
P -down-> X
note right of P : tuned-adm profile XXX\n一条命令激活全部
@enduml
```

**切换 profile 时**：tuned daemon 先回滚旧 profile 的所有修改，再应用新 profile——**不会残留脏配置**。

## 二、常用命令速查

```bash
# 查看当前激活的 profile
tuned-adm active
# 列出所有可用的 profile（内置 + 自定义）
tuned-adm list
# 查看某个 profile 的详细内容
tuned-adm profile_info latency-performance
# 切换到一个 profile（即时生效、重启后仍生效）
tuned-adm profile throughput-performance
# 让 tuned 自动检测系统类型并推荐一个合适的 profile
tuned-adm recommend
# 一键应用推荐
tuned-adm auto_profile
# 关闭 tuned（卸载所有 profile 修改，恢复出厂状态）
tuned-adm off
# 检查 tuned 服务状态
systemctl status tuned
```

> **注意**：`tuned-adm off` 不是停 daemon，而是把当前 profile 卸载、恢复默认。要彻底停掉 daemon 用 `systemctl stop tuned`。

## 三、内置 profile 速查表

发行版自带约 10~15 个常用 profile，以下是性能分析最相关的：

| Profile 名 | 目标场景 | 会动什么（典型改动） |
|-----------|---------|---------------------|
| **`throughput-performance`** | **通用高吞吐**——大多数服务器的默认推荐 | CPU governor=`performance`、`vm.swappiness=10`、`vm.dirty_ratio` 调低、网络 buffer 调大、IO 调度器=`mq-deadline`/`none` |
| **`latency-performance`** | **低延迟**——交易/实时/数据库核心 | 在 `throughput-performance` 基础上叠加：CPUIDLE 禁用深睡眠 C-state、`kernel.sched_min_granularity_ns` 调小（减少调度延迟）、`transparent_hugepages=never`（关 THP）、CPU 能量偏好=`performance` |
| **`network-throughput`** | 网络高吞吐——网关/Nginx/CDN | 重点调大网络 buffer（`rmem_max/wmem_max`、backlog）、关掉部分网卡 offload |
| **`network-latency`** | 网络低延迟——消息中间件 | 调低网络 buffer、关掉网卡中断合并（coalescing）、优先网卡中断处理 |
| **`virtual-guest`** | 虚拟机里的 guest | 针对虚拟化环境（virtio 驱动、关 swap、调 VM 感知参数） |
| **`virtual-host`** | 跑 KVM 的物理机 | 针对宿主机的 VM 调度、大页、IOMMU 相关参数 |
| **`oracle`** | Oracle 数据库 | 大页、共享内存、异步 IO、THP=never 等数据库专用组合 |
| **`mssql`** | SQL Server | 类似 oracle 但针对 mssql 的特定参数 |
| **`desktop`** | 桌面/笔记本 | 偏向省电、交互响应——不是服务器用 |
| **`powersave`** | 极致省电 | CPU governor=`powersave`、各种省电开关——性能测试**严禁**使用 |
| **`balanced`** | 桌面平衡模式 | 性能和功耗折中，同样不适合服务器 |
| **`realtime`** | 极致的硬实时 | `isolcpus` 隔离 CPU、rcu_nocbs、关中断——需要配合启动参数 |

```bash
# 查看某个 profile 到底改了哪些参数
tuned-adm profile_info throughput-performance
# 输出会列出 [sysctl]/[sysfs]/[bootloader]/[script] 各段落的实际配置
```

> **重要教训**：云服务器/虚拟机的默认 profile 往往是 `virtual-guest`，它**不会**设 CPU governor=`performance`。如果你在虚拟机里跑数据库/交易系统，忘了切 profile，CPU 可能一直在省电模式，性能损失 30%+。

## 四、自定义 profile

如果内置 profile 不满足需求（比如你的 OLTP 数据库想用 `throughput-performance` 加 THP 关闭、再加特定网络参数），可以创建自定义 profile：

### 4.1 最小示例

```bash
# 1) 创建 profile 目录
mkdir /etc/tuned/my-oltp
# 2) 写 tuned.conf
cat > /etc/tuned/my-oltp/tuned.conf << 'EOF'
[main]
# 从现有 profile 继承，在此基础上叠加修改
include=throughput-performance
summary=Custom OLTP database tuning
[sysctl]
# 关 THP——数据库常见优化
vm.transparent_hugepage_enabled=never
# 网络积压
net.core.netdev_max_backlog=65535
[sysfs]
# CPU 定频
/sys/devices/system/cpu/cpu*/cpufreq/scaling_governor=performance
[bootloader]
# 注意：修改 GRUB 后 tuned 会提示需要重启
# cmdline_isolcpus=2-5
EOF
# 3) 激活
tuned-adm profile my-oltp
```

### 4.2 两种方式：继承 vs 从零写

| 方式 | 写法 | 适用场景 |
|------|------|---------|
| **继承** | `include=throughput-performance`（开头一行） | 基于已有 profile 微调，覆盖自己关心的参数即可 |
| **从零写** | 不写 `include` | 完全掌控所有参数——但得自己补全系统基础调优 |

> **推荐继承**：你大概率不需要从头造轮子。基于 `throughput-performance` 或 `latency-performance` 继承，只写你关心的差异项。

### 4.3 检查语法

```bash
# 检查自定义 profile 是否正确加载
tuned-adm profile_info my-oltp
# 如果 profile 有问题，systemd journal 会有日志
journalctl -u tuned -f
```

## 五、tuned 的插件机制

tuned.conf 中的每个 `[section]` 实际上对应一个**插件**（plugin），运行时 daemon 逐个调用：

| 插件名 / section | 能力 | 典型内容 |
|-----------------|------|---------|
| `[sysctl]` | 改 sysctl 参数 | `vm.swappiness=10` |
| `[sysfs]` | 写 `/sys` 下的文件 | `/sys/.../scaling_governor=performance` |
| `[bootloader]` | 修改 GRUB 启动参数 | `cmdline_isolcpus=2-5`（改完提示重启） |
| `[cpu]` | CPU 能量偏好/CPUIDLE | `energy_perf_bias=performance`、停用深睡眠 C-state |
| `[disk]` | 磁盘预读/调度器 | `readahead=4096`、`scheduler=none` |
| `[script]` | 执行任意脚本（shell/Python） | profile 激活/回滚时自动跑 |
| `[net]` | 网卡/网络缓冲 | `nf_conntrack_hashsize`、网卡中断合并 |
| `[vm]` | 透明大页（THP） | `transparent_hugepages=never` |
| `[scheduler]` | 调度域/isolcpus 发现 | 自动感知 `isolcpus=` 的内核参数 |
| `[monitor]` | 监控规则（新版本） | 运行时检测条件，动态切参数 |

> **核心理解**：`tuned.conf` 的每个 section 就是对一个插件的配置。自定义 profile 时不需要理解所有插件——把你关心的 section 写上，其余用 `include` 继承。

## 六、实际使用场景

### 6.1 低延迟交易系统

```bash
# 切到低延迟 profile
tuned-adm profile latency-performance
# 检查关键参数是否到位
sysctl kernel.sched_min_granularity_ns
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor  # 应为 performance
cat /sys/kernel/mm/transparent_hugepage/enabled            # 应为 never
```

### 6.2 数据库服务器（通用物理机）

```bash
# 先看推荐
tuned-adm recommend             # 通常返回 throughput-performance
# 如果不满足，自定义
mkdir /etc/tuned/my-db
cat > /etc/tuned/my-db/tuned.conf << 'EOF'
[main]
include=throughput-performance
summary=Database server with THP off
[vm]
transparent_hugepages=never
[sysctl]
vm.dirty_background_ratio=5
EOF
tuned-adm profile my-db
```

### 6.3 云虚拟机里跑 MySQL

```bash
# 云 VM 默认通常是 virtual-guest——不设 CPU governor
tuned-adm active  # 如果是 virtual-guest，赶紧切掉！
# 改为 throughput-performance 或自定义
tuned-adm profile throughput-performance
# 验证 CPU governor
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# 如果仍然是 powersave/ondemand，说明当前内核没装 cpufreq 驱动
# 不受 tuned 控制，这是虚拟化环境的常见情况，不是 tuned 的问题
```

### 6.4 批量生产部署

```bash
# 把自定义 profile 打成包分发（tuned profile 就是目录）
scp -r /etc/tuned/my-db target-host:/etc/tuned/
ssh target-host "tuned-adm profile my-db"
# 或通过配置管理工具（Ansible/Puppet）统一部署
```

## 七、和手动调优的对比

| 维度 | 手动（`echo` / `sysctl -w`） | tuned |
|------|---------------------------|-------|
| 改一个参数 | 快（一行命令） | 重（要写 profile） |
| 改一套参数（10+ 个） | 容易漏、改错、忘回滚 | 一条命令、自动回滚 |
| 多台机器统一 | 每台手动操作，极易不一致 | profile 目录分发，一致性强 |
| 切场景（白天跑 OLTP、晚上跑批处理） | 手动改完、晚上再改回来…噩梦 | `tuned-adm profile` 随时切 |
| 回滚 | 得自己记改前值 | 自动回滚 —— 切 profile 或 `off` |
| 持久化 | `sysctl.conf` + GRUB + udev 规则散落 | 全在 profile 目录里，一目了然 |
| 学习成本 | 要懂每个参数的含义和入口 | 先用内置 profile，再参考着改 |

> **推荐策略**：开发/测试环境手动改 OK（快），生产环境用 tuned 管理（稳）。如果只有一个参数要调，手动改就行；如果你调了 ≥3 个不同位置的参数，就该上 tuned。

## 八、Profile 选择与验证

### 8.1 快速决策

```bash
tuned-adm active → 当前 profile 是什么
  → virtual-guest → 云主机默认，不会设 CPU governor → 切掉
  → powersave → 省电模式，性能测试大忌
  → balanced → 桌面用，不适合服务器
tuned-adm recommend → 让 tuned 推荐
  → throughput-performance → 通用服务器推荐
  → latency-performance → 低延迟场景
```

### 8.2 profile 效果验证

| 切到哪类 profile | 验证什么 | 用什么工具 |
|-----------------|---------|-----------|
| throughput-performance / latency-performance | CPU governor 是否 `performance` | `cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor` |
| latency-performance | THP 是否关闭 | `cat /sys/kernel/mm/transparent_hugepage/enabled` |
| network-throughput | 网络 buffer 是否调大 | `sysctl net.core.rmem_max net.core.wmem_max` |
| 自定义 profile | 所有改动是否生效 | `tuned-adm profile_info <name>` 逐行比对 |
| 任何 profile | 整体效果 | `mpstat` / `iostat` / `free` 看 before/after 对比 |

## 九、常见坑

1. **虚拟机里设 `performance` governor 不生效**：如果宿主机没暴露 cpufreq 接口，客户机看不到 governor 文件，`latency-performance` 的这部分改动静默失败（无害但不生效）。遇到这种情况要么用宿主机的 tuned 管，要么忽略。
2. **`tuned-adm off` 不持久**：机器重启后 tuned 仍然会激活上次的 profile。`off` 只对当前运行期有效。要持久关闭：`systemctl disable tuned`。
3. **自定义 profile 没出现在 `tuned-adm list` 中**：检查目录名是否和 `tuned.conf` 匹配、文件权限是否可读。`journalctl -u tuned` 看错误日志。
4. **和 Ansible/Puppet 冲突**：配置管理工具也在写 `/etc/sysctl.d/` 和 `/sys`，可能与 tuned 互相覆盖。要么只让 tuned 管，要么只让配置管理管，别两边同时改同一批参数。
5. **`include` 找不到父 profile**：父 profile 必须在 `/usr/lib/tuned/` 或 `/etc/tuned/` 下存在。自定义 profile 放 `/etc/tuned/`、内置 profile 在 `/usr/lib/tuned/`，路径对就行。

## 十、与本仓库其他文档的关系

- **内核配置入口全貌**：[kernel-tuning.md](/tools/proc/kernel-tuning.md) —— tuned 本质上是对 sysctl + sysfs + GRUB + ethtool 这些入口的**编排层**，先读懂入口再学 tuned 才不会"开了 tuned 却不知它在改什么"。
- **具体参数的语境**：[../memory/free.md](/tools/memory/free.md)（swappiness）、[../../concepts/cache/tlb.md](/concepts/cache/tlb.md)（THP/大页）、[../../concepts/process/thread-affinity.md](/concepts/process/thread-affinity.md)（isolcpus/绑核）、[../../concepts/process/irq-affinity.md](/concepts/process/irq-affinity.md)（中断亲和）、[../disk/iostat.md](/tools/disk/iostat.md)（IO 调度器）。
- **验证工具**：[mpstat](/tools/cpu/mpstat.md)（CPU governor 验证）、[free](/tools/memory/free.md)（内存参数验证）、[iostat](/tools/disk/iostat.md)（IO scheduler 验证）、[ss](/tools/network/ss.md)（网络参数验证）。
- **数据源**：[procfs.md](/tools/proc/procfs.md) —— tuned 改的参数大多从 `/proc` 和 `/sys` 可读可验证。
- **启动参数**：[kernel-tuning.md](/tools/proc/kernel-tuning.md) §三 —— tuned 的 `[bootloader]` 插件本质是在帮你改 GRUB。

## 十一、一句话总结

> **tuned 是内核调优的"一键部署"工具——`tuned-adm profile <name>` 把 sysctl、sysfs、GRUB、网卡参数等散布各处的配置打包成 profile，一条命令全局切换，切错还能自动回滚。生产环境优先用内置 `throughput-performance`/`latency-performance`，不满足就 `include` 继承后微调。手动改 ≥3 个不同入口的参数就该考虑上 tuned，散落的手改难以复现和维护。**

