登录 用户中心() [退出] 后台管理 注册
   
您的位置: 首页 >> SoftHub关联区 >> 主题: sysctl命令用于运行时配置内核参数     [回主站]     [分站链接]
sysctl命令用于运行时配置内核参数
clq
浏览(433) - 2022-10-19 15:05:00 发表 编辑

关键字:

[2022-10-19 16:33:43 最后更新]
Linux系统中sysctl命令详解
1、介绍

sysctl命令用于运行时配置内核参数,这些参数位于/proc/sys目录下。
sysctl配置与显示在/proc/sys目录中的内核参数。
可以用sysctl来设置或重新设置联网功能,如IP转发、IP碎片去除以及源路由检查等。
用户只需要编辑/etc/sysctl.conf文件,即可手工或自动执行由sysctl控制的功能。

--------------------------------------------------------
https://blog.csdn.net/xidianzxm/article/details/104205504


Linux系统中sysctl命令详解
1、介绍

sysctl命令用于运行时配置内核参数,这些参数位于/proc/sys目录下。
sysctl配置与显示在/proc/sys目录中的内核参数。
可以用sysctl来设置或重新设置联网功能,如IP转发、IP碎片去除以及源路由检查等。
用户只需要编辑/etc/sysctl.conf文件,即可手工或自动执行由sysctl控制的功能。
2、命令格式:

sysctl [-n] [-e] -w variable=value

sysctl [-n] [-e] -p (default /etc/sysctl.conf)

sysctl [-n] [-e] -a

3、常用参数的意义:

-w 临时改变某个指定参数的值,如

sysctl -w net.ipv4.ip_forward=1

-a 显示所有的系统参数

-p 从指定的文件加载系统参数,如不指定即从/etc/sysctl.conf中加载

4、临时改变值

如果仅仅是想临时改变某个系统参数的值,可以用两种方法来实现,例如想启用IP路由转发功能:

1) #echo 1 > /proc/sys/net/ipv4/ip_forward

2) #sysctl -w net.ipv4.ip_forward=1

以上两种方法都可能立即开启路由功能,但如果系统重启,或执行了 service network restart命令,所设置的值即会丢失,
5、永久改变值

如果想永久保留配置,可以修改/etc/sysctl.conf文件

将 net.ipv4.ip_forward=0改为net.ipv4.ip_forward=1
6、重新加载系统参数

sysctl -p


clq  2022-10-19 15:27:21 发表 编辑


上面三种方式都是临时释放缓存的方法,要想永久释放缓存,需要在/etc/sysctl.conf文件中配置:vm.drop_caches=1/2/3,然后sysctl -p生效即可!

clq  2022-10-19 15:33:24 发表 编辑


第一点很容易理解,尽量让每次IO操作都命中页缓存,这比操作磁盘会快很多,第二点提到的系统api主要是read和write,由于系统调用会从用户态进入内核态,并且有些还伴随这内存数据的拷贝,因此在有些场景下减少系统调用也会提高性能

readahead

readahead是一种非阻塞的系统调用,它会触发操作系统将文件内容预读到页缓存中,并且立马返回,函数原型如下

ssize_t readahead(int fd, off64_t offset, size_t count);

在通常情况下,调用readahead后立马调用read并不会提高读取速度,我们通常在批量读取或在读取之前一段时间调用readahead,假设如下场景,我们需要连续读取1000个1M的文件,有如下两个方案,伪代码如下

直接调用read函数

char* buf = (char*)malloc(10*1024*1024);

for (int i = 0; i < 1000; ++i)

{

int fd = open_file();

int size = stat_file_size();

read(fd, buf, size);

// do something with buf

close(fd);

}

先批量调用readahead再调用read

int* fds = (int*)malloc(sizeof(int)*1000);

int* fd_size = (int*)malloc(sizeof(int)*1000);

for (int i = 0; i < 1000; ++i)

{

int fd = open_file();

int size = stat_file_size();

readahead(fd, 0, size);

fds[i] = fd;

fd_size[i] = size;

}

char* buf = (char*)malloc(10*1024*1024);

for (int i = 0; i < 1000; ++i)

{

read(fds[i], buf, fd_size[i]);

// do something with buf

close(fds[i]);

}

感兴趣的可以写代码实际测试一下,需要注意的是在测试前必须先回写脏页和清空页缓存,执行如下命令

sync && sudo sysctl -w vm.drop_caches=3

可通过查看/proc/meminfo中的Cached及Dirty项确认是否生效

通过测试发现,第二种方法比第一种读取速度大约提高10%-20%,这种场景下是批量执行readahead后立马执行read,优化空间有限,如果有一种场景可以在read之前一段时间调用readahead,那将大大提高read本身的读取速度

clq  2022-10-19 15:40:48 发表 编辑


Linux系统清除缓存的方法总结
发布于2020-10-22 11:11:19阅读 4.8K0

1)缓存机制介绍

在Linux系统中,为了提高文件系统性能,内核利用一部分物理内存分配出缓冲区,用于缓存系统操作和数据文件,当内核收到读写的请求时,内核先去缓存区找是否有请求的数据,有就直接返回,如果没有则通过驱动程序直接操作磁盘。
缓存机制优点:减少系统调用次数,降低CPU上下文切换和磁盘访问频率。

CPU上下文切换:CPU给每个进程一定的服务时间,当时间片用完后,内核从正在运行的进程中收回处理器,同时把进程当前运行状态保存下来,然后加载下一个任务,这个过程叫做上下文切换。实质上就是被终止运行进程与待运行进程的进程切换。

2)查看缓存区及内存使用情况

[root@localhost ~]# free -m
total used free shared buffers cached
Mem: 7866 7725 141 19 74 6897
-/+ buffers/cache: 752 7113
Swap: 16382 32 16350

从上面的命令结果显示中可以看出:内存总共8G,已使用7725M,剩余141M,不少的人都是这么看的。
但其实这样并不能作为实际的使用率。因为有了缓存机制,具体算法如下:

空闲内存=free(141)+buffers(74)+cached(6897)

已用内存=total(7866)-空闲内存

由此算出空闲内存是7112M,已用内存754M,这才是真正的使用率,也可参考-/+ buffers/cache这行信息也是内存正确使用率。

3)缓存区分buffers和cached区别

内核在保证系统能正常使用物理内存和数据量读写情况下来分配缓冲区大小。

buffers用来缓存metadata及pages,可以理解为系统缓存,例如,vi打开一个文件。

cached是用来给文件做缓存,可以理解为数据块缓存,例如,dd if=/dev/zero of=/tmp/test count=1 bs=1G 测试写入一个文件,就会被缓存到缓冲区中,当下一次再执行这个测试命令时,写入速度会明显很快。

4)Swap用途

Swap意思是交换分区,通常我们说的虚拟内存,是从硬盘中划分出的一个分区。当物理内存不够用的时候,内核就会释放缓存区(buffers/cache)里一些长时间不用的程序,然后将这些程序临时放到Swap中,也就是说如果物理内存和缓存区内存不够用的时候,才会用到Swap。

swap清理:

swapoff -a && swapon -a

注意:这样清理有个前提条件,空闲的内存必须比已经使用的swap空间大

5)释放缓存区内存的方法


a)清理pagecache(页面缓存)

# echo 1 > /proc/sys/vm/drop_caches 或者 # sysctl -w vm.drop_caches=1

b)清理dentries(目录缓存)和inodes

# echo 2 > /proc/sys/vm/drop_caches 或者 # sysctl -w vm.drop_caches=2

c)清理pagecache、dentries和inodes

# echo 3 > /proc/sys/vm/drop_caches 或者 # sysctl -w vm.drop_caches=3

上面三种方式都是临时释放缓存的方法,要想永久释放缓存,需要在/etc/sysctl.conf文件中配置:vm.drop_caches=1/2/3,然后sysctl -p生效即可!

另外,可以使用sync命令来清理文件系统缓存,还会清理僵尸(zombie)对象和它们占用的内存

# sync

上面操作在大多数情况下都不会对系统造成伤害,只会有助于释放不用的内存。

但是如果在执行这些操作时正在写数据,那么实际上在数据到达磁盘之前就将它从文件缓存中清除掉了,这可能会造成很不好的影响。那么如果避免这种事情发生呢?

因此,这里不得不提一下/proc/sys/vm/vfs_cache_pressure这个文件,告诉内核,当清理inoe/dentry缓存时应该用什么样的优先级。

vfs_cache_pressure=100 这个是默认值,内核会尝试重新声明dentries和inodes,并采用一种相对于页面缓存和交换缓存比较”合理”的比例。
减少vfs_cache_pressure的值,会导致内核倾向于保留dentry和inode缓存。
增加vfs_cache_pressure的值,(即超过100时),则会导致内核倾向于重新声明dentries和inodes
总之,vfs_cache_pressure的值:
小于100的值不会导致缓存的大量减少
超过100的值则会告诉内核你希望以高优先级来清理缓存。
其实无论vfs_cache_pressure的值采用什么值,内核清理缓存的速度都是比较低的。
如果将此值设置为10000,系统将会将缓存减少到一个合理的水平。


释放内存前先使用sync命令做同步,以确保文件系统的完整性,将所有未写的系统缓冲区写到磁盘中,包含已修改的 i-node、已延迟的块 I/O 和读写映射文件。否则在释放缓存的过程中,可能会丢失未保存的文件。

/proc是一个虚拟文件系统,可以通过对它的读写操作作为与kernel实体间进行通信的一种手段。也就是说可以通过修改/proc中的文件,来对当前kernel的行为做出调整。也就是说我们可以通过调整/proc/sys/vm/drop_caches来释放内存。

drop_caches的值可以是0-3之间的数字,代表不同的含义:

0:不释放(系统默认值)
1:释放页缓存
2:释放dentries和inodes
3:释放所有缓存


clq  2022-10-19 15:45:13 发表 编辑


Linux cache参数调优
小耸
小耸

xiaosong.fun 二线城市中的轻文艺程序员

缓存机制(cache)是保证Linux环境下对硬盘/flash操作效率的有效方式。cache建立在内存中,它缓存了硬盘/flash的数据,当脏数据到达一定水限时,再异步地将数据刷入硬盘。这可以加速进程的文件系统访问操作。但是也有风险,当数据未写入硬盘前设备重启,存在数据丢失的风险。

如果缓存相关参数设置得不好,对系统的运行反而会有不良的影响。如果cache过大,当需要把cache中的巨量数据刷入硬盘时,会让系统显得卡顿,甚至无法调度线程。

Linux提供的接口,以支持修改cache容量。
参数说明
cache中脏数据相关参数

sysctl -a | grep dirty可以看到一组相关的内核参数

$ sysctl -a | grep dirty
vm.dirty_background_bytes = 0
vm.dirty_background_ratio = 5
vm.dirty_bytes = 0
vm.dirty_expire_centisecs = 600
vm.dirty_ratio = 10
vm.dirty_writeback_centisecs = 100

vm.dirty_background_bytes:脏数据量达到此门限后,系统会开始把脏数据写入外存。此时脏数据可能仍然继续写入内存。vm.dirty_ratio:脏数据量达到此门限后,系统会阻塞式地将脏数据写入外存,新的数据将被阻塞,无法写入cache。vm.dirty_background_bytes与vm.dirty_bytes:与vm.dirty_background_bytes/vm.dirty_ratio类似,差异仅仅是门限的计数单位,不是内存总量的百分比,而是bytes。注意_ratio与_bytes,有且仅有一个组能生效,如果一组被设置了非0值,另一组就应该被置0。vm.dirty_writeback_centisecs:表示间隔多长时间,系统去检查一次cache中的数据量是否超过门限值,以百分之一秒为单位。vm.dirty_expire_centisecs:表示数据在cache中允许被缓存多长时间。以百分之一秒为单位。

drop cache相关参数与操作

使用top命令,可以查看当前系统中cache的大小。

# top
top - 16:50:19 up 4 days, 7:00, 22 users, load average: 25.06, 24.12, 23.14
Tasks: 493 total, 7 running, 486 sleeping, 0 stopped, 0 zombie
%Cpu(s): 37.1 us, 18.9 sy, 0.0 ni, 42.3 id, 0.0 wa, 0.0 hi, 1.7 si, 0.0 st
KiB Mem : 65622752 total, 30293032 free, 29879144 used, 5450576 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 31415264 avail Mem

使用echo 3 > /proc/sys/vm/drop_caches可以手动清理cache。但这并不是一个好主意。cache有它存在的必要。假设一台网页服务器,在drop_cache之后,所有用户访问的数据都将从硬盘中读出,这会显著地影响用户访问网站的体验。

如果发现cache确实过大,我们应该尽量使用系统提供的参数来调优,不采用主动drop_cache的方式。

vm.vfs_cache_pressure:表示系统清理cache的“努力程度”。默认值为100。越大则表示内核会越频繁地回收cache。

参数建议

在一台内存为64G,硬盘读写量长期保持在500KB/s的服务器上,在未调优前,经常发生因系统回收cache导致的系统挂起。因此,我们考虑修改参数,提高flush dirty和cache回收的频率,避免脏数据与cache累积过多,一次性回收导致的系统挂起无响应。

以下参数作参考:

vm.dirty_background_bytes = 0
vm.dirty_background_ratio = 5
vm.dirty_bytes = 0
vm.dirty_expire_centisecs = 600
vm.dirty_ratio = 10
vm.dirty_writeback_centisecs = 100
vm.vfs_cache_pressure = 500

发布于 2020-04-25 17:34
缓存
系统缓存
Linux
写评论 | 你和作者最近都关注了 设计 话题

1 条评论
默认
最新
哟 有趣有趣
哟 有趣有趣

vm.vfs_cache_pressure = 500

这个参数不是在100-200之间吗?配置成500不是直接不生效?
07-26

clq  2022-10-19 16:15:47 发表 编辑

"
如果您不希望绝对限制,而只是向内核施加压力以更快地冲走缓冲区,则应查看 vm.vfs_cache_pressure

该变量控制着内核回收用于缓存VFS缓存的内存的趋势,而不是页面缓存和交换。增大此值将增加回收VFS缓存的速率。

范围从0到200。将其移向200可获得更高的压力。默认设置为100。您还可以使用以下slabtop命令分析内存使用情况。您的情况下,dentry和*_inode_cache值必须很高。

如果您想要一个绝对限制,则应该向上看cgroups。将Ceph OSD服务器放置在cgroup内,并通过memory.limit_in_bytes为cgroup 设置参数来限制它可以使用的最大内存。

memory.memsw.limit_in_bytes设置内存和交换使用之和的最大数量。如果未指定单位,则该值将解释为字节。但是,可以使用后缀来表示较大的单位-k或K表示千字节,m或M表示兆字节,g或G表示千兆字节。


"

clq  2022-10-19 16:27:18 发表 编辑

https://www.163.com/dy/article/FR03UUA30511FQO9.html


物理内存充足,但是为什么用代码总申请不到内存呢?
2020-11-09 11:07:44 来源: CSDN


作者 | 牧原

来源 | 程序猿石头(ID:tangleithu)

头图 | CSDN 下载自东方IC

本文作者:杨牧原(花名牧原),阿里云技术专家,多年操作系统和应用调试经验,理论功底深厚,实践经验丰富。目前专注Linux性能调优,容器集群和系统网络。

背景

某次遇到一个客户尝试用 Java (其实跟具体用什么语言没关系)申请使用 4G 的内存申请,机器(ECS)总内存是 8G,free 的内存也超过 4G,按道理是 OK 的,但总是直接 OOM。

于是便找上门来说,“你们这玩意有问题啊?”

内心 :“bug 是不可能有的,一定是你的打开姿势不对”,恩,不行,本着“客户第一”的原则,还是要来帮客户解锁姿势的。

本文就详细记录了这个 case 的排查过程。

具体过程


申请4g内存失败

如上图所示,记录显示为申请 4G 内存失败(4294967296 B / 1024 / 1024 = 4096 M)。

是否是 min_free_kbytes & nr_hugepage 配置错误?

第一反应是想起来之前的 vm.min_free_kbytes & nr_hugepage 导致的free大于available案例有关

memfree 统计的是所有内存的 free 内存,而 memavailable 统计的是可以拿来给程序用的内存,而客户设置了 vm.min_free_kbytes(2.5G),这个内存在 free 统计,但是不在 memavailable 统计,nr_hugepage 也会有这个问题。

二者的统计方式不一样, 具体参考 Documentation/filesystems/proc.txt

MemFree: The sum of LowFree+HighFree

MemAvailable: An estimate of how much memory is available for starting new applications, without swapping. Calculated from MemFree, SReclaimable, the size of the file LRU lists, and the low watermarks in each zone. The estimate takes into account that the system needs some page cache to function well, and that not all reclaimable slab will be reclaimable, due to items being in use. The impact of those factors will vary from system to system.

跟客户要 free -m && sysctl -p && /proc/meminfo 等信息分析问题。

HugePages_Total 为0,说明没有设置 nr_hugepage。

MemAvailable: 7418172 kB, 说明这么多内存可用。

# sysctl -pnet.ipv4.ip_forward = 0net.ipv4.conf.default.accept_source_route = 0kernel.sysrq = 1kernel.core_uses_pid = 1net.ipv4.tcp_syncookies = 1...net.ipv4.tcp_tw_recycle=1net.ipv4.tcp_max_syn_backlog=4096net.core.netdev_max_backlog=10000vm.overcommit_memory=2...#cat /proc/meminfoMemTotal: 8009416 kBMemFree: 7347684 kBMemAvailable: 7418172 kBBuffers: 18924 kBCached: 262836 kBSwapCached: 0 kBActive: 315188 kBInactive: 222364 kBActive(anon): 256120 kBInactive(anon): 552 kBActive(file): 59068 kBInactive(file): 221812 kB....HugePages_Total: 0HugePages_Free: 0HugePages_Rsvd: 0HugePages_Surp: 0Hugepagesize: 2048 kBDirectMap4k: 114560 kBDirectMap2M: 4079616 kBDirectMap1G: 6291456 kB

尝试重现

尝试自行测试使用java命令,去申请超出我的测试机物理内存,拿到报错。

实际上面的meminfo已经说明了问题,但是由于经验不足,一时没有看明白怎么回事。

下面测试证明正常申请内存不会有问题,超额的内存才会 OOM。

[root@test ~]# java -Xms4096M -versionopenjdk version "1.8.0_242"OpenJDK Runtime Environment (build 1.8.0_242-b08)OpenJDK 64-Bit Server VM (build 25.242-b08, mixed mode)[root@test ~]# java -Xms5000M -versionOpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000687800000, 3495428096, 0) failed; error='Cannot allocate memory' (errno=12)......

系统信息如下:

--------------- S Y S T E M ---------------OS:CentOS Linux release 7.4.1708 (Core)uname:Linux 3.10.0-693.2.2.el7.x86_64 #1 SMP Tue Sep 12 22:26:13 UTC 2017 x86_64libc:glibc 2.17 NPTL 2.17rlimit: STACK 8192k, CORE 0k, NPROC 15088, NOFILE 65535, AS infinityload average:0.05 0.05 0.05/proc/meminfo:MemTotal: 3881692 kBMemFree: 2567724 kBMemAvailable: 2968640 kBBuffers: 69016 kBCached: 536116 kBSwapCached: 0 kBActive: 355280 kBInactive: 326020 kB...VmallocTotal: 34359738367 kBVmallocUsed: 14280 kBVmallocChunk: 34359715580 kBHardwareCorrupted: 0 kBAnonHugePages: 30720 kBHugePages_Total: 256HugePages_Free: 256HugePages_Rsvd: 0HugePages_Surp: 0Hugepagesize: 2048 kBDirectMap4k: 57216 kBDirectMap2M: 3088384 kBDirectMap1G: 3145728 kB....Memory: 4k page, physical 3881692k(2567600k free), swap 0k(0k free)vm_info: OpenJDK 64-Bit Server VM (25.242-b08) for linux-amd64 JRE (1.8.0_242-b08), built on Jan 28 2020 14:28:22 by "mockbuild" with gcc 4.8.5 20150623 (Red Hat 4.8.5-39)time: Thu Feb 20 15:13:30 2020timezone: CSTelapsed time: 0 seconds (0d 0h 0m 0s)

重现失败,继续分析

Java 测试证明正常申请内存不会有问题,超额的内存才会 OOM,那么为什么超额呢,视线回归到 sysctl -p 有所发现。

vm.overcommit_memory=2

关于 overcommit_memory 设置项:

overcommit_memory=0

默认设置,当应用进程尝试申请内存时,内核会做一个检测。内核将检查是否有足够的可用内存供应用进程使用;

如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。

举个例子,比如1G的机器,A进程已经使用了500M,当有另外进程尝试malloc 500M的内存时,内核就会进行check,发现超出剩余可用内存,就会提示失败。

overcommit_memory=1

对于内存的申请请求,内核不会做任何check,直到物理内存用完,触发 OOM 杀用户态进程。

同样是上面的例子,1G 的机器,A进程500M,B进程尝试 malloc 500M,会成功,但是一旦kernel发现内存使用率接近1个G(内核有策略),就触发OOM,杀掉一些用户态的进程(有策略的杀)。

overcommit_memory=2

当请求申请的内存 >= SWAP内存大小 + 物理内存 * N,则拒绝此次内存申请。解释下这个N:N是一个百分比,根据overcommit_ratio/100来确定,比如overcommit_ratio=50(我的测试机默认50%),那么N就是50%。vm.overcommit_ratio 只有当 vm.overcommit_memory = 2 的时候才会生效,内存可申请内存为 SWAP内存大小 + 物理内存 * overcommit_ratio/100。

看看上面日志的 overcommit 信息:

CommitLimit: 4004708 kB (小于客户申请的4096M)

Committed_AS: 2061568 kB

具体而言:

CommitLimit:最大能分配的内存(测试下来在vm.overcommit_memory=2时候生效),具体的值是:SWAP内存大小(ecs均未开启) + 物理内存 * overcommit_ratio / 100;

Committed_AS:当前已经分配的内存大小;

5,两相对照,说明客户设置的 vm.overcommit_memory在生效,建议改回 0 再试试。

用 vm.overcommit_memory = 2 测试,分配内存失败;

[root@test ~]# grep -i commit /proc/meminfoCommitLimit: 1940844 kBCommitted_AS: 480352 kB# java -Xms2048M -version 失败了OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000080000000, 1431830528, 0) failed; error='Cannot allocate memory' (errno=12)## There is insufficient memory for the Java Runtime Environment to continue.# Native memory allocation (mmap) failed to map 1431830528 bytes for committing reserved memory.# An error report file with more information is saved as:# /root/hs_err_pid1267.log

用如下配置,即可恢复:vm.overcommit_memory = 0, vm.overcommit_ratio = 50

#vm.overcommit_memory = 0#vm.overcommit_ratio = 50[root@test ~]# java -Xms2048M -versionopenjdk version "1.8.0_242"OpenJDK Runtime Environment (build 1.8.0_242-b08)OpenJDK 64-Bit Server VM (build 25.242-b08, mixed mode)

最后

可以看出,这其实跟具体的编程语言没有关系,用 Java 申请不到,用 c++/c 也一样。一个容易忽略的小知识点,你 get 到了吗?

clq  2022-10-19 16:33:43 发表 编辑

"
备注:

如何修改Linux vm.overcommit_memory的值,可用的方法有以下三种:


1).以root身份登录Linux,编辑/etc/sysctl.conf ,改vm.overcommit_memory=1,然后sysctl -p使配置文件生效

2).sysctl vm.overcommit_memory=1

3).echo 1 > /proc/sys/vm/overcommit_memory
"


总数:7 页次:1/1 首页 尾页  
总数:7 页次:1/1 首页 尾页  


所在合集/目录
操作系统内存占用高 更多



发表评论:
文本/html模式切换 插入图片 文本/html模式切换


附件:



NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.

Copyright © 2005-2020 clq, All Rights Reserved
版权所有
桂ICP备15002303号-1