Linux 进程调度器:CFS 原理与调优

概述 进程调度器是操作系统内核的核心组件,它决定了哪个进程在哪个 CPU 上运行、运行多长时间。Linux 自 2.6.23 起采用 CFS(Completely Fair Scheduler)作为默认调度器,经过多年演进,在 6.6 内核中又引入了 EEVDF(Earliest Eligible Virtual Deadline First)替代 CFS。本文深入理解 CFS 的工作原理、nice/cgroup CPU 控制、实时调度、CPU 亲和性等核心主题,并分享生产环境的调优经验。 CFS 调度器原理 设计哲学 CFS 的核心目标是"完全公平"——每个进程按照其权重比例获得 CPU 时间。与传统调度器基于时间片不同,CFS 使用"虚拟运行时间"(vruntime)来跟踪每个进程的 CPU 消耗: vruntime = 实际运行时间 × (NICE_0_LOAD / 进程权重) nice 值为 0 的进程权重为 1024(NICE_0_LOAD) nice 值越低,权重越大,vruntime 增长越慢,获得更多 CPU 时间 CFS 始终选择 vruntime 最小的进程运行 红黑树与调度队列 CFS 使用红黑树维护运行队列,按 vruntime 排序: [vruntime=50] / \ [vruntime=20] [vruntime=80] / \ [vruntime=10] [vruntime=35] 最左节点(vruntime 最小)是下一个被调度的进程 进程运行后 vruntime 增加,被重新插入红黑树 查找、插入、删除均为 O(log N) 调度周期与最小粒度 # 调度周期(目标延迟):所有进程在这段时间内至少运行一次 $ sysctl kernel....

May 29, 2024 · 7 分钟 · 1330 字 · 徐保金

Linux 内存管理机制与调优实战

概述 内存是 Linux 系统中最宝贵的资源之一。理解内核如何管理内存,不仅能帮助你定位 OOM、内存泄漏等线上故障,还能在容量规划和性能调优时做出更准确的决策。从虚拟内存模型出发,覆盖 Page Cache、Swap 策略、OOM Killer 原理、cgroup v2 内存限制、slab/shmem 调优等核心主题,并附带多个生产环境实战案例。 虚拟内存模型 地址空间分层 Linux 采用虚拟内存机制,每个进程拥有独立的虚拟地址空间: 层级 说明 用户态可见 用户空间 0x000000000000 ~ 0x00007FFFFFFFFFFF 是 非规范区 0x0000800000000000 ~ 0xFFFF7FFFFFFFFFFF 否(空洞) 内核空间 0xFFFF800000000000 ~ 0xFFFFFFFFFFFFFFFF 否 64 位系统下,用户空间理论上有 128TB(47 位地址),内核空间同样 128TB。实际可用受 TASK_SIZE 和 mm_struct 限制。 内存_zone 划分 内核将物理内存划分为多个 zone,不同 zone 有不同用途: $ cat /proc/zoneinfo | grep -E "^Node|pages free|high|normal|DMA" Zone 用途 典型场景 DMA 16MB 以下,旧 ISA 设备 DMA 几乎不用 DMA32 4GB 以下,32 位 DMA 设备 老硬件 Normal 4GB 以上,大多数内存分配 主要使用 Movable 可迁移页面,支持内存热插拔 虚拟化/大页 当 Normal zone 内存耗尽时,内核会从 DMA32 zone 借用页面(watermark 机制),但频繁借用会导致性能下降。...

May 9, 2024 · 8 分钟 · 1594 字 · 徐保金

Linux 启动流程详解:从固件到用户空间

概述 Linux 系统的启动是一个精密编排的多阶段过程,从固件加电自检到内核加载、再到用户空间服务启动,每个阶段都有其特定职责。理解完整的启动流程不仅有助于排查启动故障,还能进行启动性能优化。从固件层出发,逐层解析 BIOS/UEFI、GRUB2、initramfs、内核初始化、systemd 启动流程,并覆盖启动优化和内核崩溃恢复。 启动流程概览 [电源开启] │ ▼ [1. 固件阶段] BIOS / UEFI │ POST (加电自检) │ 硬件初始化 │ 查找启动设备 ▼ [2. 引导阶段] GRUB2 │ 加载 GRUB 到内存 │ 读取 grub.cfg │ 加载内核和 initramfs ▼ [3. 内核阶段] Linux Kernel │ 内核解压并初始化 │ 硬件检测和驱动加载 │ 挂载 initramfs │ 启动 init (systemd) ▼ [4. 用户空间阶段] systemd │ 读取 default.target │ 按依赖顺序启动服务 │ 启动登录服务 ▼ [5. 登录阶段] │ getty / display-manager │ 用户认证 │ Shell 启动 ▼ [系统就绪] BIOS 与 UEFI BIOS vs UEFI 特性 BIOS UEFI 启动模式 Legacy UEFI 固件接口 16位 32/64位 分区表 MBR (≤2TB) GPT (>2TB) 启动代码 512字节MBR EFI分区 启动速度 慢 快 网络功能 无 有(PXE/HTTP启动) 安全启动 不支持 支持 分辨率 文本模式 图形模式 BIOS 启动流程 1....

May 3, 2024 · 13 分钟 · 2586 字 · 徐保金

Linux 软件包管理:apt/yum/dnf 与包构建

概述 软件包管理是 Linux 系统运维的基础。Debian 系使用 apt/dpkg,Red Hat 系使用 yum/dnf/rpm。理解两套包管理体系的原理和用法,掌握仓库管理、依赖解析、包构建、版本锁定和离线安装,是高效运维的前提。本文系统对比两大体系,并深入实践包构建和镜像源优化。 apt/dpkg 体系 体系架构 apt (高级前端) │ ├── apt-get → 包安装/卸载/更新 ├── apt-cache → 包查询/搜索 └── apt → 综合命令(交互友好) │ dpkg (底层工具) │ ├── dpkg → .deb 包安装/卸载 ├── dpkg-deb → .deb 包操作 └── dpkg-query → 包查询 │ aptitude (替代前端,可选) apt vs apt-get # apt 是 apt-get 和 apt-cache 的综合,输出更友好 # 常用对照: # 安装 $ apt install nginx # 新(推荐交互使用) $ apt-get install nginx # 旧(推荐脚本使用) # 搜索 $ apt search nginx $ apt-cache search nginx # 查看包信息 $ apt show nginx $ apt-cache show nginx # 更新索引 $ apt update $ apt-get update # 升级 $ apt upgrade # 升级已安装的包(不删除) $ apt full-upgrade # 升级(可删除包以解决依赖) $ apt-get dist-upgrade # 等同 full-upgrade 在脚本中建议使用 apt-get/apt-cache,因为其输出格式稳定;交互操作使用 apt 更友好。...

April 26, 2024 · 15 分钟 · 3112 字 · 徐保金

磁盘 I/O 性能诊断与优化

前言 磁盘 I/O 往往是系统性能链条中最慢的一环。一次机械磁盘寻道约 10ms,而内存访问仅约 100ns——两者相差 10 万倍。当业务出现延迟抖动、响应变慢,排查方向总会指向 I/O 子系统。从指标体系出发,结合工具实战与生产案例,建立一套可复用的 I/O 诊断方法论。 I/O 性能指标体系 在动手之前,必须搞清楚四个核心指标的含义及其相互关系。 指标 单位 含义 典型参考值 IOPS 次/秒 每秒完成的 I/O 读写次数 HDD ~100,SATA SSD ~10 万,NVMe SSD ~50 万+ 吞吐量 MB/s 每秒传输的数据量 HDD ~150 MB/s,SATA SSD ~550 MB/s,NVMe SSD ~3000 MB/s+ 延迟 ms/μs 单次 I/O 从提交到完成的耗时 HDD 5-15ms,SSD 0.1-1ms,NVMe 0.02-0.1ms 队列深度 个 等待处理的 I/O 请求数 建议值 NVMe 32-256,SSD 8-32 这四个指标之间存在关键约束关系: 小块随机读写场景下,瓶颈是 IOPS(如数据库 OLTP 4KB 随机写) 大块顺序读写场景下,瓶颈是吞吐量(如日志追加、视频流媒体) 延迟是最终用户感知的指标,即使 IOPS 和吞吐量充足,单次延迟过高仍会导致卡顿 队列深度提升能增加并发,但也意味着单请求等待时间变长 一个重要认知:IOPS × 块大小 ≈ 吞吐量。例如 4KB 块、100 IOPS,吞吐量约 0....

March 27, 2024 · 4 分钟 · 841 字 · 徐保金

定时任务管理:cron 与 systemd timer 对比

概述 定时任务是运维自动化的基础组件——日志轮转、数据备份、证书续期、健康检查、报表生成,几乎每个运维场景都离不开定时执行。大多数人对定时任务的认知停留在 crontab -e 加一行 0 2 * * * /path/to/script.sh,但这在生产环境中远远不够:任务失败了谁通知?执行超时了谁处理?多台机器上的任务怎么协调?从 cron 到 systemd timer 到分布式调度,逐步梳理定时任务的管理实践。 参考来源:cron Wikipedia、systemd.timer 官方文档 一、cron 语法与局限 1.1 cron 表达式 cron 表达式由 5 个字段组成: ┌──────── 分钟 (0-59) │ ┌────── 小时 (0-23) │ │ ┌──── 日 (1-31) │ │ │ ┌── 月 (1-12) │ │ │ │ ┌ 星期 (0-7, 0和7都是周日) │ │ │ │ │ * * * * * command 表达式 含义 0 2 * * * 每天凌晨 2:00 */15 * * * * 每 15 分钟 0 */6 * * * 每 6 小时 0 0 * * 0 每周日 0:00 0 0 1 * * 每月 1 号 0:00 30 3-5 * * * 3:30, 4:30, 5:30 0 0 1 1,4,7,10 * 每季度首月 1 号 @reboot 系统启动时 @daily / @midnight 每天 0:00 @weekly 每周日 0:00 @monthly 每月 1 号 0:00 @yearly / @annually 每年 1 月 1 日 0:00 1....

March 18, 2024 · 15 分钟 · 3009 字 · 徐保金

Linux 日志管理:journald 与日志轮转

概述 日志是系统运维的眼睛。从内核消息到应用日志、从安全审计到性能分析,日志贯穿了故障排查的每个环节。现代 Linux 采用 journald 作为系统日志守护进程,配合 logrotate 进行日志轮转,构成了完整的日志管理基础设施。本文深入 journald 的原理与配置、journalctl 的高级查询技巧、日志轮转策略、远程日志收集方案以及实战分析案例。 journald 原理 架构概览 journald 是 systemd 的系统日志组件,取代了传统的 syslog(rsyslog)。它接收来自内核、系统服务和应用程序的日志,统一存储为结构化的二进制格式。 [内核日志] [systemd 服务] [应用程序] │ │ │ ▼ ▼ ▼ [kmsg] [sd_journal_print] [syslog()/stdout] │ │ │ └──────────┬───────┴──────────┬───────┘ ▼ ▼ [journald] [/dev/log] │ ┌──────────┼──────────┐ ▼ ▼ ▼ [持久日志] [运行时日志] [转发到 syslog] /var/log/ /run/log/ /var/log/ journal/ journal/ messages 日志存储模式 # 查看当前存储模式 $ cat /etc/systemd/journald.conf | grep Storage #Storage=auto # 三种模式: # auto(默认): /var/log/journal 存在则持久化,否则仅内存 # persistent: 强制持久化(自动创建 /var/log/journal) # volatile: 仅内存(/run/log/journal) 模式 存储位置 重启后保留 适用场景 persistent /var/log/journal 是 生产环境 auto /var/log/journal 或 /run/log/journal 取决于目录 默认 volatile /run/log/journal 否 临时系统/安全要求 日志大小控制 # /etc/systemd/journald....

February 14, 2024 · 10 分钟 · 2022 字 · 徐保金

systemd 服务管理深度指南

systemd 架构概述 systemd 是现代 Linux 发行版的事实标准 init 系统,从 2015 年起已取代 SysVinit 成为绝大多数主流发行版的默认 init。它不只是"启动服务的工具",而是一个完整的系统和服务管理器。 核心 unit 类型 systemd 通过 unit(单元)来管理系统资源,每种 unit 类型对应一种资源: unit 类型 扩展名 作用 service .service 系统服务(守护进程) socket .socket IPC 套接字(支持套接字激活) timer .timer 定时任务(替代 cron) target .target 服务组(类似传统 runlevel) mount .mount 文件系统挂载点 device .device 内核设备 path .path 文件路径监控(文件出现时触发服务) slice .slice cgroup 资源分配层级 target 与传统 runlevel 的映射 # 查看当前默认 target systemctl get-default # 通常输出: multi-user.target(对应 runlevel 3,多用户命令行模式) # 切换到图形界面(对应 runlevel 5) sudo systemctl isolate graphical....

February 13, 2024 · 5 分钟 · 935 字 · 徐保金

Linux 性能诊断工具集:从 top 到 perf

概述 性能诊断是 SRE 的核心技能。Linux 提供了丰富的性能分析工具,从简单的 top 到强大的 perf/eBPF,每个工具都有其适用场景。掌握这些工具的使用时机和方法,是快速定位性能瓶颈的关键。本文按 CPU、内存、IO、网络和综合工具五大维度,逐步梳理 Linux 性能诊断工具集,并提供使用场景速查表和实战案例。 负载监控工具 top:经典进程监控 $ top # 顶部摘要信息 top - 15:30:00 up 30 days, 3:21, 3 users, load average: 1.23, 0.98, 0.85 Tasks: 234 total, 1 running, 233 sleeping, 0 stopped, 0 zombie %Cpu(s): 12.3 us, 3.4 sy, 0.0 ni, 83.3 id, 0.5 wa, 0.0 hi, 0.5 si, 0.0 st MiB Mem : 32000.0 total, 5000.0 free, 15000.0 used, 12000.0 buff/cache MiB Swap: 4096....

January 19, 2024 · 14 分钟 · 2833 字 · 徐保金

Shell脚本自动化运维实战技巧

前言 Shell 脚本是运维工程师最常用的自动化工具。本文记录几个实战中常用的脚本模式。 日志定期清理 服务器日志堆积是常见问题,以下脚本按保留天数自动清理: #!/bin/bash # clean_logs.sh - 日志清理脚本 LOG_DIR="/var/log/app" KEEP_DAYS=30 find "$LOG_DIR" -name "*.log" -type f -mtime +${KEEP_DAYS} -exec gzip {} \; find "$LOG_DIR" -name "*.gz" -type f -mtime +${KEEP_DAYS} -delete echo "$(date): 日志清理完成,保留 ${KEEP_DAYS} 天" 配合 crontab 每天执行: 0 2 * * * /opt/scripts/clean_logs.sh >> /var/log/clean_logs.log 2>&1 批量主机健康检查 通过 SSH 批量检查多台服务器状态: #!/bin/bash # health_check.sh - 批量健康检查 HOSTS=("web-01" "web-02" "db-01" "cache-01") THRESHOLD=80 for host in "${HOSTS[@]}"; do echo "--- ${host} ---" ssh "$host" " echo \"CPU: \$(top -bn1 | grep 'Cpu' | awk '{print \$2}')%\" echo \"MEM: \$(free | awk '/Mem/{printf \"%....

January 11, 2024 · 2 分钟 · 246 字 · 徐保金