Linux 性能调优之内核可调参数优化

对每个人而言,真正的职责只有一个:找到自我。然后在心中坚守其一生,全心全意,永不停息。所有其它的路都是不完整的,是人的逃避方式,是对大众理想的懦弱回归,是随波逐流,是对内心的恐惧 ——赫尔曼·黑塞《德米安》

写在前面


  • 考试整理相关笔记
  • 博文内容没有涉及具体应该调整哪些内核参数
  • 简单介绍了调整内核参数的方式,procsys 的简单说明
  • 理解不足小伙伴帮忙指正

对每个人而言,真正的职责只有一个:找到自我。然后在心中坚守其一生,全心全意,永不停息。所有其它的路都是不完整的,是人的逃避方式,是对大众理想的懦弱回归,是随波逐流,是对内心的恐惧 ——赫尔曼·黑塞《德米安》


Linux 中 内核可调参数允许系统管理员和用户根据系统需求和特定的使用场景来调整内核的行为和性能,进行资源管理和性能优化,提高系统安全和稳定性

/proc 文件系统

/proc 文件系统是一个伪文件系统,通过proc 可以查看进程内核数据结构的一个接口,内核在启动时将进程文件系统挂载到 proc 文件系统/proc静态文件为只读文件,内核可调参数文件proc/sys具备可写权限,但是只针对与 root 来讲。

目录中的部分文件

CPU 信息存放位置

1
2
3
┌──[root@liruilongs.github.io]-[/]
└─$ll proc/cpuinfo
-r--r--r--. 1 root root 0 Sep 17 03:10 proc/cpuinfo

内存信息存放位置

1
2
3
┌──[root@liruilongs.github.io]-[/]
└─$ll proc/meminfo
-r--r--r--. 1 root root 0 Sep 17 03:09 proc/meminfo

交换分区信息

1
2
3
┌──[root@liruilongs.github.io]-[/]
└─$ll proc/swaps
-r--r--r--. 1 root root 0 Sep 16 10:38 proc/swaps

最近一次启动内核参数

1
2
3
4
5
┌──[root@liruilongs.github.io]-[/proc/1]
└─$cat /proc/cmdline
BOOT_IMAGE=(hd0,msdos1)/vmlinuz-4.18.0-193.el8.x86_64 root=UUID=893bf4a5-f929-4a4f-9bb3-f1694d8ad757 ro resume=UUID=56504db0-34ca-458f-970b-1591a6af18bb rhgb quiet rd.shell=0
┌──[root@liruilongs.github.io]-[/proc/1]
└─$

网卡设备信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

┌──[root@liruilongs.github.io]-[/proc/1]
└─$ls /proc/net/dev
/proc/net/dev
┌──[root@liruilongs.github.io]-[/proc/1]
└─$cat /proc/net/dev
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
privbr1-nic: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
vnet2: 619644 3619 0 0 0 0 0 0 6737397 11605 0 0 0 0 0 0
privbr0: 531527 2916 0 0 0 0 0 0 340658 4082 0 0 0 0 0 0
virbr1: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ens160: 2692846 27276 0 74 0 0 0 5754 28082733 56656 0 0 0 0 0 0
virbr0-nic: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
vnet1: 1203 11 0 0 0 0 0 0 7517 79 0 0 0 0 0 0
br1-nic: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
privbr1: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
lo: 246059 2971 0 0 0 0 0 0 246059 2971 0 0 0 0 0 0
br0: 2808686 34649 0 0 0 0 0 0 34462873 58892 0 0 0 0 0 0
vnet4: 60737 862 0 0 0 0 0 0 6283662 1979 0 0 0 0 0 0
vnet0: 6775163 8259 0 0 0 0 0 0 7832674 13302 0 0 0 0 0 0
virbr1-nic: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
privbr2: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
virbr0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
privbr2-nic: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
vnet3: 6046921 784 0 0 0 0 0 0 423092 7725 0 0 0 0 0 0
br1: 1049 11 0 0 0 0 0 0 2717 30 0 0 0 0 0 0
privbr0-nic: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

对应的进程信息,相关的进程信息通过 进程ID 目录直接查看

1
2
┌──[root@liruilongs.github.io]-[/]
└─$cd proc/1

进程相关的文件信息,proc 文件系统 主要用于提取进程信息访问接口,所以它提供了一个以进程为基础的文件和目录结构,可以通过 文件具体的内容获取 进程状态,命令行参数,内存映射等。

与我们下文提到的 /sys 略有不同,/sys主要用于提供对内核数据结构设备信息的访问接口。它公开了内核中的各种参数、配置和设备信息,如内核参数、设备驱动程序、总线、设备和硬件拓扑等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
┌──[root@liruilongs.github.io]-[/proc/1]
└─$ll
total 0
dr-xr-xr-x. 2 root root 0 Sep 17 05:58 attr # 进程属性的目录
-rw-r--r--. 1 root root 0 Sep 17 05:58 autogroup # 自动分组相关文件
-r--------. 1 root root 0 Sep 17 05:58 auxv # 进程的辅助向量信息
-r--r--r--. 1 root root 0 Sep 17 03:12 cgroup # 进程所属的 cgroup 信息
--w-------. 1 root root 0 Sep 17 05:58 clear_refs # 清除页引用位的文件
-r--r--r--. 1 root root 0 Sep 17 03:10 cmdline # 进程的命令行参数信息
-rw-r--r--. 1 root root 0 Sep 17 03:12 comm # 进程的命令名
-rw-r--r--. 1 root root 0 Sep 17 05:58 coredump_filter # 核心转储的过滤器设置
-r--r--r--. 1 root root 0 Sep 17 05:58 cpuset # 进程所属的 cpuset 信息
lrwxrwxrwx. 1 root root 0 Sep 17 05:58 cwd -> / # 进程的当前工作目录的符号链接
-r--------. 1 root root 0 Sep 17 03:12 environ # 进程的环境变量信息
lrwxrwxrwx. 1 root root 0 Sep 17 03:12 exe -> /usr/lib/systemd/systemd # 进程的可执行文件的符号链接
dr-x------. 2 root root 0 Sep 17 03:12 fd # 进程打开的文件描述符目录
dr-x------. 2 root root 0 Sep 17 05:58 fdinfo # 进程打开的文件描述符的信息目录
-rw-r--r--. 1 root root 0 Sep 17 05:58 gid_map # 进程 GID 映射信息
-r--------. 1 root root 0 Sep 17 05:58 io # 进程的 IO 统计信息
-r--r--r--. 1 root root 0 Sep 17 05:58 limits # 进程的资源限制信息
-rw-r--r--. 1 root root 0 Sep 17 03:12 loginuid # 包含登录用户 ID 的文件
dr-x------. 2 root root 0 Sep 17 05:58 map_files # 进程映射的文件目录
-r--r--r--. 1 root root 0 Sep 17 05:58 maps # 进程的内存映射信息
-rw-------. 1 root root 0 Sep 17 05:58 mem # 进程的内存内容
-r--r--r--. 1 root root 0 Sep 16 10:38 mountinfo # 进程所属的挂载点信息
-r--r--r--. 1 root root 0 Sep 17 05:58 mounts # 进程所属的挂载信息
-r--------. 1 root root 0 Sep 17 05:58 mountstats # 挂载统计信息
dr-xr-xr-x. 6 root root 0 Sep 17 05:58 net # 进程的网络相关信息目录
dr-x--x--x. 2 root root 0 Sep 17 05:58 ns # 进程的命名空间目录
-r--r--r--. 1 root root 0 Sep 17 05:58 numa_maps # 进程的 NUMA 内存映射信息
-rw-r--r--. 1 root root 0 Sep 17 05:58 oom_adj # 进程的 OOM 调整值
-r--r--r--. 1 root root 0 Sep 17 05:58 oom_score # 进程的 OOM 分数
-rw-r--r--. 1 root root 0 Sep 17 05:58 oom_score_adj # 进程的OOM分数调整值
-r--------. 1 root root 0 Sep 17 05:58 pagemap # 进程的页面映射信息
-r--------. 1 root root 0 Sep 17 05:58 patch_state # 内核补丁状态信息
-r--------. 1 root root 0 Sep 17 05:58 personality # 进程的人格特征设置
-rw-r--r--. 1 root root 0 Sep 17 05:58 projid_map # 进程的项目ID映射信息
lrwxrwxrwx. 1 root root 0 Sep 17 03:12 root -> / # 进程的根目录的符号链接
-rw-r--r--. 1 root root 0 Sep 17 03:12 sched # 进程的调度策略信息
-r--r--r--. 1 root root 0 Sep 17 05:58 schedstat # 进程的调度统计信息
-r--r--r--. 1 root root 0 Sep 17 03:12 sessionid # 会话ID信息
-rw-r--r--. 1 root root 0 Sep 17 05:58 setgroups # 进程的附加组信息
-r--r--r--. 1 root root 0 Sep 17 05:58 smaps # 进程的内存映射统计信息
-r--r--r--. 1 root root 0 Sep 17 05:58 smaps_rollup # 进程的内存映射统计信息汇总
-r--------. 1 root root 0 Sep 17 05:58 stack # 进程的内核栈信息
-r--r--r--. 1 root root 0 Sep 17 03:10 stat # 进程状态信息
-r--r--r--. 1 root root 0 Sep 17 05:58 statm # 进程的内存状态信息
-r--r--r--. 1 root root 0 Sep 17 03:10 status # 进程状态信息
-r--------. 1 root root 0 Sep 17 05:58 syscall # 进程的系统调用信息
dr-xr-xr-x. 3 root root 0 Sep 17 05:58 task # 进程的任务目录
-r--r--r--. 1 root root 0 Sep 17 05:58 timers # 进程的定时器信息
-rw-rw-rw-. 1 root root 0 Sep 17 05:58 timerslack_ns # 进程的定时器间隔
-rw-r--r--. 1 root root 0 Sep 17 05:58 uid_map # 进程的UID映射信息
-r--r--r--. 1 root root 0 Sep 17 05:58 wchan # 进程的等待通道信息
┌──[root@liruilongs.github.io]-[/proc/1]
└─$

内核可调整参数

proc/sysroot是可写的,通过改变该目录下的文件,可以调节 Linux 内核的行为,达到调优目的

1
2
3
┌──[root@liruilongs.github.io]-[/proc/1]
└─$ls /proc/sys
abi crypto debug dev fs kernel net sunrpc user vm
  • /proc/sys/dev : 包括一些系统设备的调优文件,如: RAID,SCSI 或其他设备
  • /proc/sys/fs文件系统相关的调优,如:配额之类的参数
  • /proc/sys/kerneLinux 内核的参数,如: 共享内存的设置
  • /proc/sys/net:包括网络相关的调优参数,如: 发送和接受的缓存大小
  • /proc/sys/vm:包含内核虚拟内存管理的调优参数,如: 大页内存参数

需要说明的是,内核可调参数并不是调整就是优化,存在危险性(不恰当的调整,也可能带来危险)

如果将 /proc/sys/kernel/threads-max 的值修改为 1,计算机将无法启动超过 1 个并发进程,只能重启计算机了!

1
2
3
4
5
6
┌──[root@liruilongs.github.io]-[/proc]
└─$ cat /proc/sys/kernel/threads-max
33651
┌──[root@liruilongs.github.io]-[/proc]
└─$

再比如,增加内核分配的 TCP 缓冲区大小可以提高网络吞叶量,但是,这也就需要占用更多的内存,大量的网络连接,系统消耗更多的内存,限制了用户空间程序可用的内存容量。

1
2
3
4
5
6
7
8
┌──[root@liruilongs.github.io]-[/proc]
└─$ sysctl net.ipv4.tcp_wmem
net.ipv4.tcp_wmem = 4096 16384 4194304
┌──[root@liruilongs.github.io]-[/proc]
└─$ sysctl net.ipv4.tcp_rmem
net.ipv4.tcp_rmem = 4096 87380 6291456
┌──[root@liruilongs.github.io]-[/proc]
└─$

其中,min_wmemmin_rmem 是发送和接收缓冲区的最小大小,default_wmemdefault_rmem是默认大小,max_wmemmax_rmem是最大大小。可以根据需要调整这些值。

1
2
$ sudo sysctl -w net.ipv4.tcp_wmem="min_wmem default_wmem max_wmem"
$ sudo sysctl -w net.ipv4.tcp_rmem="min_rmem default_rmem max_rmem"

修改内核可调参数的方法

  • 重定向直接修改/proc/sys 目录中的文件[临时有效,重启无效]
  • 通过 sysctl -w 命令修改[临时有效,重启无效]
  • 修改/etc/sysctl.conf 文件或/etc/sysctl.d/目录重创建配置文件,永久有效

查看内核可调参数的列表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
┌──[root@liruilongs.github.io]-[/proc/sys]
└─$ll
total 0
dr-xr-xr-x. 1 root root 0 Oct 1 11:53 abi
dr-xr-xr-x. 1 root root 0 Sep 27 09:03 crypto
dr-xr-xr-x. 1 root root 0 Oct 1 11:53 debug
dr-xr-xr-x. 1 root root 0 Oct 1 11:53 dev
dr-xr-xr-x. 1 root root 0 Sep 27 09:03 fs
dr-xr-xr-x. 1 root root 0 Sep 27 09:03 kernel
dr-xr-xr-x. 1 root root 0 Sep 27 09:03 net
dr-xr-xr-x. 1 root root 0 Oct 1 11:53 sunrpc
dr-xr-xr-x. 1 root root 0 Oct 1 11:53 user
dr-xr-xr-x. 1 root root 0 Sep 27 09:03 vm
┌──[root@liruilongs.github.io]-[/proc/sys]
└─$

各分类的内核参数简单描述

  1. abi: 用于处理二进制接口兼容性的内核参数。
  2. crypto: 用于配置和管理加密算法密码学模块的内核参数。
  3. debug: 内核调试和跟踪相关的内核参数。
  4. dev: 设备驱动程序设备管理相关的内核参数。
  5. fs: 文件系统相关的内核参数。
  6. kernel: 配置内核的各个方面的内核参数。
  7. net: 网络配置和网络协议相关的内核参数。
  8. sunrpc: 远程过程调用(RPC)相关的内核参数。
  9. user: 用户空间内核之间的交互和权限管理相关的内核参数。
  10. vm: 虚拟内存管理和页面置换相关的内核参数。

常见的内核参数配置:

通过 echo 直接修改内核参数

ICMP 包禁用,在 Linux 中,尤其是云上的机器,处于安全考虑,会把 icmp 协议禁调,即不通通过 ping 命令来测试 IP 对应的机器是否网络互通。 一般可以通过 firewall 添加 ICPM 的相关的规则,配置处理策略,直接丢弃还是不可达。

这里我们也可以通过内核参数来配置,是否响应 ICMP 协议的发包。

1
2
3
4
5
6
7
8
9
10
11
12
13
┌──[root@liruilongs.github.io]-[/proc/sys]
└─$cat /proc/sys/net/ipv4/icmp_echo_ignore_all
0
┌──[root@liruilongs.github.io]-[/proc/sys]
└─$ping -c3 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.055 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.075 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.132 ms

--- 127.0.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 72ms
rtt min/avg/max/mdev = 0.055/0.087/0.132/0.033 ms
  • 设置为 0 内核会响应 ICMP 包
  • 设置为 1 内核会忽略 ICMP 包

简单测试:

1
2
3
4
5
6
7
8
9
10
11
┌──[root@liruilongs.github.io]-[/proc/sys]
└─$echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
┌──[root@liruilongs.github.io]-[/proc/sys]
└─$ping -c3 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.

--- 127.0.0.1 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 60ms

┌──[root@liruilongs.github.io]-[/proc/sys]
└─$

有些调优参数会涉及到多个值,类似上面的 调整 TCP 缓存区大小,也可以通过 echo 直接修改

网卡接收数据的缓存大小,最小值,默认值,最大值

1
2
3
4
5
6
7
8
9
10
┌──[root@liruilongs.github.io]-[~]
└─$cat /proc/sys/net/ipv4/tcp_rmem
4096 87380 6291456
┌──[root@liruilongs.github.io]-[~]
└─$echo "8192 87380 6291456" > /proc/sys/net/ipv4/tcp_rmem
┌──[root@liruilongs.github.io]-[~]
└─$cat /proc/sys/net/ipv4/tcp_rmem
8192 87380 6291456
┌──[root@liruilongs.github.io]-[~]
└─$

临时修改除了上面的方式,还可以通过 sysctl 命令行的方式

通过 sysctl 命令修改内核参数

sysctl -a 可以查看全部的内核参数

1
2
3
4
5
6
7
8
9
┌──[root@liruilongs.github.io]-[~]
└─$sysctl -a | head -n 5
abi.vsyscall32 = 1
crypto.fips_enabled = 0
debug.exception-trace = 1
debug.kprobes-optimization = 1
dev.cdrom.autoclose = 1
┌──[root@liruilongs.github.io]-[~]
└─$

查看指定的内核参数

1
2
3
┌──[root@liruilongs.github.io]-[~]
└─$sysctl -n vm.swappiness
30

修改内核参数用过 -w 来修改,以 k=v 的形式

1
2
3
4
5
6
7
8
9
10
11
┌──[root@liruilongs.github.io]-[~]
└─$sysctl -w net.ipv4.icmp_echo_ignore_all=1
net.ipv4.icmp_echo_ignore_all = 1
┌──[root@liruilongs.github.io]-[~]
└─$sysctl -w vm.swappiness=10
vm.swappiness = 10
┌──[root@liruilongs.github.io]-[~]
└─$sysctl -n vm.swappiness
10
┌──[root@liruilongs.github.io]-[~]
└─$

可以发现,内核参数的命名和对应的参数目录是一致的

上面的方式都是临时写入内核参数,如果希望永久的写入内核参数,就需要 写到持久化文件

通过 写入 /etc/sysctl.conf 的方式

永久修改内核参数,在机器启动的时候,内核会重下面的目录加载内核参数

  • /etc/sysctl.conf
  • /etc/sysctld/*conf
  • /run/sysctl.d/.conf
  • /usr/lib/sysctld/conf

可以在注释信息中看到说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
┌──[root@liruilongs.github.io]-[~]
└─$cat /etc/sysctl.conf
# sysctl settings are defined through files in
# /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
#
# Vendors settings live in /usr/lib/sysctl.d/.
# To override a whole file, create a new file with the same in
# /etc/sysctl.d/ and put new settings there. To override
# only specific settings, add a file with a lexically later
# name in /etc/sysctl.d/ and put new settings there.
#
# For more information, see sysctl.conf(5) and sysctl.d(5).
┌──[root@liruilongs.github.io]-[~]
└─$ls /etc/sysctl.d/
99-sysctl.conf

需要注意的是,内核参数的文件名字必须以 conf 结尾

修改交换分区的使用频率

1
2
3
4
5
6
7
8
9
10
11
┌──[root@liruilongs.github.io]-[/proc/sys]
└─$cat /proc/sys/vm/swappiness
10
┌──[root@liruilongs.github.io]-[/proc/sys]
└─$echo 'vm.swappiness=5' >> /etc/sysctl.d/vm.swappiness.conf
┌──[root@liruilongs.github.io]-[/proc/sys]
└─$sysctl -p /etc/sysctl.d/vm.swappiness.conf
vm.swappiness = 5
┌──[root@liruilongs.github.io]-[/proc/sys]
└─$cat /proc/sys/vm/swappiness
5

/sys 文件系统

sys 文件系统也是一个伪文件系统,挂载在 /sys 目录下,/sys 提供了设备,文件系统(Cgroup)和内核模块的信息.

sysfs 曾经是 /proc 的一部分,目前独立为单独的文件系统以增加内核稳定性

1
2
3
4
5
┌──[root@liruilongs.github.io]-[/run]
└─$cd /sys/
┌──[root@liruilongs.github.io]-[/sys]
└─$ls
block bus class dev devices firmware fs hypervisor kernel module power
1
2
3
4
5
6
7
8
9
10
11
12
13
14
┌──[root@liruilongs.github.io]-[/sys]
└─$ll /sys/
total 0
drwxr-xr-x. 2 root root 0 Sep 17 03:09 block # 与块设备相关的信息和配置
drwxr-xr-x. 34 root root 0 Sep 17 03:10 bus # 总线系统的信息和配置
drwxr-xr-x. 58 root root 0 Sep 17 03:09 class # 与设备类相关的信息和配置
drwxr-xr-x. 4 root root 0 Sep 17 03:40 dev # 设备驱动程序的信息和配置
drwxr-xr-x. 15 root root 0 Sep 16 10:38 devices # 系统中检测到的设备的信息和配置
drwxr-xr-x. 6 root root 0 Sep 17 05:29 firmware # 固件相关的信息和配置
drwxr-xr-x. 9 root root 0 Sep 16 10:38 fs # 文件系统的信息和配置
drwxr-xr-x. 2 root root 0 Sep 17 06:53 hypervisor # 虚拟化平台的信息和配置
drwxr-xr-x. 14 root root 0 Sep 16 10:38 kernel # 内核相关的信息和配置
drwxr-xr-x. 192 root root 0 Sep 17 05:58 module # 已加载的内核模块的信息和配置
drwxr-xr-x. 2 root root 0 Sep 17 06:53 power # 电源管理的信息和配置

Linux 内核模块

Linux 中,内核模板 被以模块化的方式编译,可以根据用户的实际需要加载或者卸载模块,内核模块也可以在被需要时自动加载。

部分的内核模块也带有参数,可以被修改,通过安装 fernel-doc 软件包,可以找到特定的模块有哪些参数。

获取模块信息可以通过 modinfo 命令实现,通过 lsmod 可以查看当前内核加载的模块,数据有点多,通常结合 grep 使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
┌──[root@liruilongs.github.io]-[/sys]
└─$lsmod
Module Size Used by
binfmt_misc 20480 1
vfat 20480 0
msdos 20480 0
fat 81920 2 msdos,vfat
ext4 749568 0
mbcache 16384 1 ext4
jbd2 122880 1 ext4
dm_mod 151552 0
fuse 131072 3
rfcomm 86016 6
rpcsec_gss_krb5 40960 0
vhost_net 28672 5
vhost 49152 1 vhost_net
tap 28672 1 vhost_net
xt_CHECKSUM 16384 1
ipt_MASQUERADE 16384 1
xt_conntrack 16384 1
ip6t_REJECT 16384 1
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
scsi_transport_spi 40960 1 mptspi
libahci 40960 1 ahci
ata_piix 36864 0
mptscsih 45056 1 mptspi
drm 536576 10 vmwgfx,drm_kms_helper,ttm
libata 270336 4 ata_piix,libahci,ahci,ata_generic
serio_raw 16384 0
vmxnet3 61440 0
mptbase 98304 2 mptspi,mptscsih
┌──[root@liruilongs.github.io]-[/sys]
└─$

内核模块的文件位置

1
2
3
4
5
6
┌──[root@liruilongs.github.io]-[/sys]
└─$ls /usr/lib/modules/4.18.0-1
4.18.0-187.el8.x86_64/ 4.18.0-193.el8.x86_64/
┌──[root@liruilongs.github.io]-[/sys]
└─$ls /usr/lib/modules/4.18.0-193.el8.x86_64/kernel/
arch crypto drivers fs kernel lib mm net sound virt

通过 modinfo 可以查看特定模块的基本信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
┌──[root@liruilongs.github.io]-[/sys]
└─$modinfo nf_tables
filename: /lib/modules/4.18.0-193.el8.x86_64/kernel/net/netfilter/nf_tables.ko.xz
alias: nfnetlink-subsys-10
author: Patrick McHardy <kaber@trash.net>
license: GPL
rhelversion: 8.2
srcversion: 761D4E24BD503B4824C892B
depends: nfnetlink
intree: Y
name: nf_tables
vermagic: 4.18.0-193.el8.x86_64 SMP mod_unload modversions
sig_id: PKCS#7
signer: Red Hat Enterprise Linux kernel signing key
sig_key: 42:A4:B8:EB:D4:F1:21:1D:CA:0B:B6:66:62:38:61:FA:0B:90:31:59
sig_hashalgo: sha256
signature: 59:4F:B4:D9:0A:2B:7C:E2:29:AA:0D:7E:67:DA:CF:35:1D:26:2A:21:
D4:FE:7A:63:5D:AF:A7:FA:7D:1D:41:35:85:DC:CF:11:DE:D1:F4:88:
80:51:08:B8:E9:88:E9:B7:C8:92:E1:2F:19:0E:C9:43:F7:42:6F:39:
F3:12:C9:CA:FD:6A:5E:9E:4C:4F:6C:3B:9D:7A:CE:88:0F:64:94:FE:
。。。。。。。。。。
┌──[root@liruilongs.github.io]-[/sys]
└─$

通过 -p 命令可以仅显示模块涉及的参数。

1
2
3
4
5
6
7
8
┌──[root@liruilongs.github.io]-[/sys]
└─$modinfo -p usb_storage
option_zero_cd:ZeroCD mode (1=Force Modem (default), 2=Allow CD-Rom (uint)
swi_tru_install:TRU-Install mode (1=Full Logic (def), 2=Force CD-Rom, 3=Force Modem) (uint)
delay_use:seconds to delay before using a new device (uint)
quirks:supplemental list of device IDs and their quirks (string)
┌──[root@liruilongs.github.io]-[/sys]
└─$

通过 /sys/module/模块名称/parameters/参数名称,可以修改内核模块参数,如:

加载模块

1
2
┌──[root@liruilongs.github.io]-[/sys]
└─$modprobe usb_storage

查看模块参数, USB 存储模块的延迟使用参数。默认情况下,该参数的值为 1。

1
2
3
┌──[root@liruilongs.github.io]-[/sys]
└─$cat /sys/module/usb_storage/parameters/delay_use
1

如果文件有可写权限,可以通过 echo 命令修改文件参数的值

查看 delay_use 文件的权限和属性信息

1
2
3
┌──[root@liruilongs.github.io]-[/sys]
└─$ll /sys/module/usb_storage/parameters/delay_use
-rw-r--r--. 1 root root 4096 Sep 17 07:01 /sys/module/usb_storage/parameters/delay_use

将值 3 写入 delay_use 文件,更改 USB 存储模块的延迟使用参数

1
2
3
4
5
┌──[root@liruilongs.github.io]-[/sys]
└─$echo '3' > /sys/module/usb_storage/parameters/delay_use
┌──[root@liruilongs.github.io]-[/sys]
└─$cat /sys/module/usb_storage/parameters/delay_use
3

如果没有可写权限,或者需要永久修改参数的值,可以通过在 /etc/modprobe.d/ 目录写配置文件,文件名必须以 conf 结尾。

需要注意内核模块的的参数设置和内核参数略有不同 options usb_storage delay_use=5

1
2
3
4
5
┌──[root@liruilongs.github.io]-[/sys]
└─$echo "options usb_storage delay_use=5" > /etc/modprobe.d/myprobe.conf
┌──[root@liruilongs.github.io]-[/sys]
└─$cat /sys/module/usb_storage/parameters/delay_use
3

通过配置文件的方式修改,修改之前后需要卸载模块重新加载一下,才会生效

1
2
3
4
5
6
7
┌──[root@liruilongs.github.io]-[/sys]
└─$rmmod usb_storage
┌──[root@liruilongs.github.io]-[/sys]
└─$modprobe usb_storage
┌──[root@liruilongs.github.io]-[/sys]
└─$cat /sys/module/usb_storage/parameters/delay_use
5

也可以在加载模块的时候直接指定内核模块参数

1
2
3
4
5
6
7
8
9
┌──[root@liruilongs.github.io]-[/sys]
└─$rmmod usb_storage
┌──[root@liruilongs.github.io]-[/sys]
└─$modprobe usb_storage delay_use=7
┌──[root@liruilongs.github.io]-[/sys]
└─$modprobe usb_storage delay_use=5
┌──[root@liruilongs.github.io]-[/sys]
└─$cat /sys/module/usb_storage/parameters/delay_use
7

可以看到,多个加载会只有第一次加载添加的内核模块才会生效,如果需要修改需要卸载后重新安装

1
2
3
4
5
6
7
8
9
10
11
┌──[root@liruilongs.github.io]-[/sys]
└─$rmmod usb_storage
┌──[root@liruilongs.github.io]-[/sys]
└─$echo "options usb_storage delay_use=5" > /etc/modprobe.d/myprobe.conf
┌──[root@liruilongs.github.io]-[/sys]
└─$modprobe usb_storage
┌──[root@liruilongs.github.io]-[/sys]
└─$cat /sys/module/usb_storage/parameters/delay_use
5
┌──[root@liruilongs.github.io]-[/sys]
└─$

对于内核模块的参数修改的帮助文档,需要安装 kernel-doc 软件包。

1
2
3
4
5
6
7
8
[root@workstation ~]# yum -y install kernel-doc
[root@workstation ~]# rpm -qd kernel-doc | head -n 5
/usr/share/doc/kernel-doc-4.18.0/Documentation/00-INDEX
/usr/share/doc/kernel-doc-4.18.0/Documentation/ABI/README
/usr/share/doc/kernel-doc-4.18.0/Documentation/ABI/obsolete/sysfs-bus-usb
/usr/share/doc/kernel-doc-4.18.0/Documentation/ABI/obsolete/sysfs-class-typec
/usr/share/doc/kernel-doc-4.18.0/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-arvo
[root@workstation ~]#

一个修改内核模块参数的 Demo

磁盘预读

盘读的性能,可以通过提高提前预读的量,增加读磁盘的效率。预读可以有效的减少磁盘的寻道次数应用程序的I/O等待时间,是改进磁盘读I/O性能的重要优化手段之一。

内核文件 /sys/block/设备名/queue/read_ahead_kb 记录了磁盘预读的数据量.单位是 KiB

1
2
3
4
5
┌──[root@liruilongs.github.io]-[/usr/lib/tuned]
└─$cat /sys/block/sda/queue/read_ahead_kb
128
┌──[root@liruilongs.github.io]-[/usr/lib/tuned]
└─$

通过 blockdev 命令也可以查看或设置磁盘预读参数

1
2
3
4
5
6
7
8
┌──[root@liruilongs.github.io]-[/usr/lib/tuned]
└─$blockdev --getra /dev/sda
256
┌──[root@liruilongs.github.io]-[/usr/lib/tuned]
└─$echo 256*512/1024 | bc
128
┌──[root@liruilongs.github.io]-[/usr/lib/tuned]
└─$

不同于 read_ahead_kb 文件,输出的单位是 sectors(扇区),一个扇区是 512bytes

博文部分内容参考

© 文中涉及参考链接内容版权归原作者所有,如有侵权请告知,这是一个开源项目,如果你认可它,不要吝啬星星哦 :)


《 Red Hat Performance Tuning 442 》


© 2018-至今 liruilonger@gmail.com, All rights reserved. 保持署名-非商用-相同方式共享(CC BY-NC-SA 4.0)

发布于

2023-11-09

更新于

2024-11-22

许可协议

评论
Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×