偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Linux 內(nèi)存調(diào)優(yōu)之如何限制進(jìn)程、系統(tǒng)級別內(nèi)存資源

系統(tǒng) Linux
Cgroup(Control Groups)?最早由 google 開發(fā),后來內(nèi)置到了 Linux 內(nèi)核中,是Linux kernel(Linux內(nèi)核)的一項(xiàng)功能,目前是很多虛擬化容器技術(shù)的底層核心技術(shù)。

限制內(nèi)存使用量

今天和小伙伴分享一些Linux 內(nèi)存限制相關(guān)知識,主要涉及如何配置以及什么情況下需要配置,我們知道內(nèi)存屬于不可壓縮資源,當(dāng)沒有那么多的物理內(nèi)存可以映射,進(jìn)程都無法啟動(dòng),所以為了公平,亦或是考慮部分進(jìn)程 Qos 級別,一般情況下會對進(jìn)程進(jìn)行內(nèi)存限制,即保證機(jī)器上的多個(gè)進(jìn)程不會因?yàn)闃I(yè)務(wù)對基礎(chǔ)資源的彈性要求,相互影響,比如類似FTP進(jìn)程的內(nèi)存泄露問題影響到核心業(yè)務(wù)服務(wù)觸發(fā) OOM ,甚至直接被OOM killer 掉。

簡單介紹,關(guān)于內(nèi)存資源限制在 Linux 中,一般按照限制手段來劃分的話,分為

  • 內(nèi)核參數(shù)(包括啟動(dòng)配置)限制: 臨時(shí)修改交換分區(qū)頻率sysctl -w vm.swappiness=10, 啟動(dòng)引導(dǎo)配置大頁參數(shù)grubby --update-kernel=ALL --args="hugepagesz=1G hugepages=10"。
  • Cgroup(包括systemd)限制: 通過 Cgroup 的 memory 子系統(tǒng)限制 /sys/fs/cgroup/memory/myapp/memory.limit_in_bytes,MemoryMax=1G。
  • ulimit 限制: ulimit -v 2097152。

三種方式,按照限制類型劃分,一般分為:

  • 系統(tǒng)內(nèi)存限制: 比如修改內(nèi)核參數(shù)sysctl -w vm.overcommit_memory=2  禁止過度分配虛擬內(nèi)存。
  • 進(jìn)程內(nèi)存限制: Systemd 單元限制進(jìn)程物理內(nèi)存不超過 1G MemoryMax=1G。
  • 用戶會話內(nèi)存限制: echo "john hard as 2097152" >> /etc/security/limits.conf 限制用戶 john 的進(jìn)程最大虛擬內(nèi)存(地址空間)為 2 GB。

如果按照具體的內(nèi)存種類劃分,可以分為:

  • 物理、虛擬內(nèi)存限制: 硬限制物理內(nèi)存大小 memory.limit_in_bytes, 會話級別虛擬內(nèi)存限制 ulimit -v。
  • 數(shù)據(jù)段,數(shù)據(jù)棧限制: ulimit -d 262144 設(shè)置數(shù)據(jù)段的最大值。
  • 數(shù)據(jù)緩存區(qū): 釋放內(nèi)存緩存區(qū)設(shè)置 vm.drop_caches,網(wǎng)絡(luò)IO 相關(guān)緩存區(qū)配置 net.ipv4.tcp_rmem。
  • 大頁,臟頁相關(guān)內(nèi)存頁限制:大頁大小 vm.nr_hugepages。

Cgroup

Cgroup(Control Groups)最早由 google 開發(fā),后來內(nèi)置到了 Linux 內(nèi)核中,是Linux kernel(Linux內(nèi)核)的一項(xiàng)功能,目前是很多虛擬化容器技術(shù)的底層核心技術(shù)。

在一個(gè)系統(tǒng)中運(yùn)行的層級制進(jìn)程組,Cgroup 可對其進(jìn)行資源分配(如CPU時(shí)間、系統(tǒng)內(nèi)存、網(wǎng)絡(luò)帶寬或者這些資源的組合)。

通過使用cgroup ,系統(tǒng)管理員在分配、排序、拒絕、管理和監(jiān)控系統(tǒng)資源等方面,可以進(jìn)行精細(xì)化控制。硬件資源可以在應(yīng)用程序和用戶間智能分配,從而增加整體效率。

Cgroup可對進(jìn)程進(jìn)行層級式分組并標(biāo)記,并對其可用資源進(jìn)行限制。通過將cgroup層級系統(tǒng)與systemd單位樹捆綁, Linux 可以把資源管理設(shè)置從進(jìn)程級別移至應(yīng)用程序級別。

可以使用systemctl指令,或者通過修改systemd單位文件來管理系統(tǒng)資源。

為了控制重要的內(nèi)核資源,systemd 會自動(dòng)掛載/sys/fs/cgroup 目錄實(shí)現(xiàn) cgroup 分層架構(gòu),Linux 內(nèi)核的資源管理器,也叫 CGroup 子系統(tǒng),代表某一種單一資源(如 CPU 時(shí)間或內(nèi)存等。

Linux 內(nèi)核提供了一系列資源管理器,由 systemd 自動(dòng)掛載。如果需要查看已經(jīng)掛載的資源管理器列表,可以參考/proc/cgroups。

內(nèi)存子系統(tǒng)位于其中:

memory: 對 cgroup 中的任務(wù)使用內(nèi)存量進(jìn)行限制,并且自動(dòng)生成任務(wù)占用內(nèi)存資源的報(bào)告。

在安裝了 kernel-doc 軟件包后,可以在/usr/share/doc/kernel-doc-<version>/Documentation/cgroup 目錄下找相關(guān)管理器的說明文檔,從而配置合適的資源限制。

┌──[root@liruilongs.github.io]-[/usr/share/doc/kernel-doc-4.18.0/Documentation/cgroup-v1]
└─$ls
00-INDEX              cgroups.txt  cpusets.txt  freezer-subsystem.txt  memcg_test.txt  net_cls.txt   pids.txt
blkio-controller.txt  cpuacct.txt  devices.txt  hugetlb.txt            memory.txt      net_prio.txt  rdma.txt
┌──[root@liruilongs.github.io]-[/usr/share/doc/kernel-doc-4.18.0/Documentation/cgroup-v1]
└─$ll
total 184
。。。。。。。。。。。。。。。。
-r--r--r--. 1 root root  8480 Mar 27  2020 memcg_test.txt
-r--r--r--. 1 root root 37743 Mar 27  2020 memory.txt
................

簡單的信息可以通過索引文件的了解。

┌──[root@liruilongs.github.io]-[/usr/share/doc/kernel-doc-4.18.0/Documentation/cgroup-v1]
└─$cat 00-INDEX
。。。。。。。
memcg_test.txt
        - Memory Resource Controller; implementation details.
memory.txt
        - Memory Resource Controller; design, accounting, interface, testing.
。。。。。。。。。。。。。。。。。。。。。
┌──[root@liruilongs.github.io]-[/usr/share/doc/kernel-doc-4.18.0/Documentation/cgroup-v1]
└─$

Cgroup 限制內(nèi)存資源常見的有兩種,一種是 通過 systemd,一種是直接通過 cgroup 文件系統(tǒng)進(jìn)行配置,這里我們先介紹通過 systemd 的方式配置,因?yàn)檫@種方式比較簡單,而且可以做到進(jìn)程級別的配置,而通過 cgroup 的方式,可以做到系統(tǒng)級別的配置,前提是當(dāng)前Linux 機(jī)器使用 systemd,并且所有啟動(dòng)進(jìn)程納管到了 cgroup 子樹,那么可以通過限制頂層樹的資源限制,來實(shí)現(xiàn)整個(gè)系統(tǒng)的資源限制。

在 systemd 的 drop-in 文件文件[Service]段里面定義 MemoryLimit 值就可以限制你的程序所使用的內(nèi)存,單位可以是K,M,G或T。

這里看一個(gè)以臨時(shí)服務(wù)的方式運(yùn)行 /bin/bash命令的Demo ,對 內(nèi)存和CPU 進(jìn)行限制, 并將其標(biāo)準(zhǔn)輸入、標(biāo)準(zhǔn)輸出、標(biāo)準(zhǔn)錯(cuò)誤連接到當(dāng)前的 TTY 設(shè)備上:

┌──[root@liruilongs.github.io]-[~]
└─$ systemd-run  -p  MemoryLimit=5M  -p CPUShares=100 --unit=bash-limit   --slice=bash-test -t /bin/bash
Running as unit bash-limit.service.
Press ^] three times within 1s to disconnect TTY.

在生成的 bash Service 中我們可以運(yùn)行交互命令,查看當(dāng)前 Service 的單元文件,MemoryLimit=5242880 ,即限制內(nèi)存使用量 5M。

┌──[root@liruilongs.github.io]-[/]
└─$ systemctl cat bash-limit.service
# /run/systemd/system/bash-limit.service
# Transient stub

# /run/systemd/system/bash-limit.service.d/50-CPUShares.conf
[Service]
CPUShares=100
# /run/systemd/system/bash-limit.service.d/50-Description.conf
[Unit]
Description=/bin/bash
# /run/systemd/system/bash-limit.service.d/50-Environment.conf
[Service]
Environment="TERM=xterm-256color"
# /run/systemd/system/bash-limit.service.d/50-ExecStart.conf
[Service]
ExecStart=
ExecStart=@/bin/bash "/bin/bash"
# /run/systemd/system/bash-limit.service.d/50-MemoryLimit.conf
[Service]
MemoryLimit=5242880
# /run/systemd/system/bash-limit.service.d/50-Slice.conf
。。。。。。。。。。。。。。。。。。。。。。。。

通過 systemctl status bash-limit.service 我們可以看到cgroup的相關(guān)信息。

┌──[root@liruilongs.github.io]-[/]
└─$ systemctl status bash-limit.service
● bash-limit.service - /bin/bash
   Loaded: loaded (/run/systemd/system/bash-limit.service; static; vendor preset: disabled)
  Drop-In: /run/systemd/system/bash-limit.service.d
           └─50-CPUShares.conf, 50-Description.conf, 50-Environment.conf, 50-ExecStart.conf, 50-MemoryLimit.conf, 50-Slice.conf, 50-StandardError.conf, 50-StandardInput.conf, 50-StandardOutput.conf, 50-TTYPath.conf
   Active: active (running) since 六 2022-10-29 13:40:19 CST; 31s ago
 Main PID: 136529 (bash)
   Memory: 1.7M (limit: 5.0M)
   CGroup: /bash.slice/bash-test.slice/bash-limit.service
           ├─136529 /bin/bash
           └─136607 systemctl status bash-limit.service

10月 29 13:40:19 liruilongs.github.io systemd[1]: Started /bin/bash.
┌──[root@liruilongs.github.io]-[/]
└─$ bash
┌──[root@liruilongs.github.io]-[/]
└─$ bash

bash-limit.service 這個(gè) service  的上級子樹為 bash.slice 這個(gè)分組。

Memory: 1.7M (limit: 5.0M)
   CGroup: /bash.slice/bash-test.slice/bash-limit.service
           ├─136529 /bin/bash
           └─136607 systemctl status bash-limit.service

當(dāng)然上面的配置方式實(shí)際上是基于 Cgroup 來實(shí)現(xiàn)的,Cgroup V1 版本和 V2 版本有些區(qū)別,當(dāng)前機(jī)器環(huán)境的問題,我們只看一下 V1 的版本,MemoryLimit 參數(shù)可以控制Cgroup 內(nèi)存控制器的 memory.limit_in_bytes Cgroup參數(shù)。

對于運(yùn)行中的 service 可以直接通過set-property 的方式來修改。

# 如需使用命令列來限定 httpd.service 的 CPU 和內(nèi)存占用量,請輸入:
systemctl set-property httpd.service CPUShares=600 MemoryLimit=500M

下面為 system.slice 這個(gè) Cgroup 分組下面 tuned Cgroup 內(nèi)存相關(guān)資源限制,可以看到默認(rèn)的情況下沒有限制(memory.limit_in_bytes ),使用的最大值,這里的內(nèi)存限制是物理內(nèi)存,不是虛擬內(nèi)存。

tuned 小伙伴們應(yīng)該不陌生,一個(gè)開源的系統(tǒng)性能優(yōu)化的服務(wù),用于一些內(nèi)核參數(shù)限制。

┌──[root@liruilongs.github.io]-[/sys/fs/cgroup/memory/system.slice] 
└─$cat tuned.service/memory.
memory.events                       memory.kmem.tcp.failcnt             memory.memsw.failcnt                memory.qos_level
memory.events.local                 memory.kmem.tcp.limit_in_bytes      memory.memsw.limit_in_bytes         memory.soft_limit_in_bytes
memory.failcnt                      memory.kmem.tcp.max_usage_in_bytes  memory.memsw.max_usage_in_bytes     memory.stat
memory.force_empty                  memory.kmem.tcp.usage_in_bytes      memory.memsw.usage_in_bytes         memory.swappiness
memory.high                         memory.kmem.usage_in_bytes          memory.min                          memory.usage_in_bytes
memory.kmem.failcnt                 memory.limit_in_bytes               memory.move_charge_at_immigrate     memory.use_hierarchy
memory.kmem.limit_in_bytes          memory.low                          memory.numa_stat                    
memory.kmem.max_usage_in_bytes      memory.max_usage_in_bytes           memory.oom_control                  
memory.kmem.slabinfo                memory.memfs_files_info             memory.pressure_level

默認(rèn)情況下,沒有限制會顯示最大值。

┌──[root@liruilongs.github.io]-[/sys/fs/cgroup/memory/system.slice] 
└─$cat tuned.service/memory.limit_in_bytes 
9223372036854771712

配置方式我們可以通過上面的方式配置,通過 service unit 文件進(jìn)行限制。

限定最大可用內(nèi)存為 1GB,添加 MemoryLimit 設(shè)定。

┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system] 
└─$vim tuned.service

確認(rèn)配置,加載配置文件,重啟。

┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system] 
└─$systemctl cat tuned.service
# /usr/lib/systemd/system/tuned.service
[Unit]
Description=Dynamic System Tuning Daemon
After=systemd-sysctl.service network.target dbus.service
Requires=dbus.service polkit.service
Conflicts=cpupower.service auto-cpufreq.service tlp.service power-profiles-daemon.service
Documentation=man:tuned(8) man:tuned.conf(5) man:tuned-adm(8)

[Service]
Type=dbus
MemoryLimit=1G
PIDFile=/run/tuned/tuned.pid
BusName=com.redhat.tuned
ExecStart=/usr/sbin/tuned -l -P
Restart=on-failure

[Install]
WantedBy=multi-user.target
┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system] 
└─$systemctl daemon-reload
┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system] 
└─$systemctl restart tuned.service

再次查看 Cgroup 內(nèi)存相關(guān)限制參數(shù)。

┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system] 
└─$cat  /sys/fs/cgroup/memory/system.slice/tuned.service/memory.limit_in_bytes 
1073741824
┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system] 
└─$

生產(chǎn)環(huán)境,更多的是通過  drop-in  的方式定義文件。

┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system] 
└─$vim  tuned.service.d/50-MemoryLimit.conf
┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system] 
└─$systemctl daemon-reload
┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system] 
└─$systemctl restart tuned.service
┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system] 
└─$systemctl cat tuned.service
# /usr/lib/systemd/system/tuned.service
[Unit]
Description=Dynamic System Tuning Daemon
After=systemd-sysctl.service network.target dbus.service
Requires=dbus.service polkit.service
Conflicts=cpupower.service auto-cpufreq.service tlp.service power-profiles-daemon.service
Documentation=man:tuned(8) man:tuned.conf(5) man:tuned-adm(8)

[Service]
Type=dbus
PIDFile=/run/tuned/tuned.pid
BusName=com.redhat.tuned
ExecStart=/usr/sbin/tuned -l -P
Restart=on-failure

[Install]
WantedBy=multi-user.target

# /usr/lib/systemd/system/tuned.service.d/50-MemoryLimit.conf
[Service]
MemoryLimit=1G
┌──[root@liruilongs.github.io]-[/usr/lib/systemd/system] 
└─$

這里我們簡單看一下,其他的 Cgroup 參數(shù)限制,部分參數(shù)在 Cgroup V2 中作了調(diào)整,感興趣小伙伴可以看看去。

核心內(nèi)存限制

參數(shù)

作用

memory.limit_in_bytes

物理內(nèi)存硬限制

(單位:字節(jié)),超出會觸發(fā) OOM Killer。

memory.memsw.limit_in_bytes

物理內(nèi)存 + swap 總限制

(需內(nèi)核啟用 swapaccount=1)。

memory.soft_limit_in_bytes

內(nèi)存軟限制

,系統(tǒng)優(yōu)先回收超過此值的內(nèi)存,但不會強(qiáng)制殺死進(jìn)程。

內(nèi)核內(nèi)存控制

參數(shù)

作用

memory.kmem.limit_in_bytes

內(nèi)核內(nèi)存(如 slab、dentry 緩存)的硬限制

。

memory.kmem.tcp.limit_in_bytes

TCP 緩沖區(qū)內(nèi)存的硬限制

(如 TCP socket 發(fā)送/接收緩沖區(qū))。

內(nèi)存回收與行為控制

參數(shù)

作用

memory.force_empty

強(qiáng)制釋放內(nèi)存緩存

(寫入 0 觸發(fā))。

memory.swappiness

調(diào)整內(nèi)存回收策略

(值越高,系統(tǒng)越積極使用 swap)。

memory.oom_control

控制 OOM Killer 行為

0 表示啟用 OOM Killer,1 表示禁用)。

memory.move_charge_at_immigrate

進(jìn)程遷移時(shí)是否轉(zhuǎn)移內(nèi)存占用

1 表示轉(zhuǎn)移)。

高級功能

參數(shù)

作用

memory.high

內(nèi)存使用軟限制

(v1 中較少使用,v2 中更常見)。

memory.low

內(nèi)存保護(hù)閾值

,系統(tǒng)盡量避免回收低于此值的內(nèi)存。

memory.pressure_level

內(nèi)存壓力事件通知

(需配合 cgroup.event_control 使用)。

對于這部分參數(shù)的配置,可以直接找到對應(yīng)的 Cgroup 文件進(jìn)行修改。

# 限制 TCP 緩沖區(qū)為 100MB
echo "100M" > memory.kmem.tcp.limit_in_bytes

ulimit

對于多用戶的系統(tǒng)不限制資源本身可能就是一種不公平, 限制系統(tǒng)資源比較老的方式是使用 ulimit,由 PAM 模塊在登錄和會話啟動(dòng)時(shí)強(qiáng)制實(shí)施,ulimit 命令是bash 內(nèi)置命令,主要限制了 shell 及其子進(jìn)程可用的資源。

在/etc/pam.d/system-auth 文件中調(diào)用了 pam_limits 模塊,此模塊讀取 /etc/security/limits.conf 和/etc/security/limits.d/,按配置文件設(shè)置資源限制。 查看模塊幫助文檔 man pam limits。

/etc/pam.d/system-auth 是什么?

/etc/pam.d/system-auth 是一個(gè) PAM(Pluggable Authentication Modules)配置文件。在 Linux 系統(tǒng)中,PAM 提供了一種靈活的方式來配置用戶認(rèn)證、授權(quán)和會話管理。

該文件是一個(gè)包含 PAM 配置行的文本文件,用于定義不同的認(rèn)證、授權(quán)和會話模塊及其參數(shù)。PAM 模塊負(fù)責(zé)處理用戶登錄、密碼驗(yàn)證、權(quán)限檢查等操作。

查看文件中資源限制相關(guān)的模塊,有時(shí)候我們做一些基線整改,可能需要修改該文件的相關(guān)配置。

┌──[root@liruilongs.github.io]-[~]
└─$cat /etc/pam.d/system-auth  | grep pam_limits
session     required                                     pam_limits.so
┌──[root@liruilongs.github.io]-[~]
└─$

在PAM配置中,pam_limits.so 模塊被要求進(jìn)行會話限制。

PAM(Pluggable Authentication Modules)是一個(gè)用于對用戶進(jìn)行認(rèn)證的系統(tǒng)級框架。pam_limits.so 模塊是 PAM 框架的一部分,它用于設(shè)置會話級別的資源限制,例如進(jìn)程可打開的文件數(shù)、進(jìn)程可使用的內(nèi)存等。

ulimit 命令是用于限制用戶級別資源的工具,它通常用于控制 shell 進(jìn)程及其子進(jìn)程的資源使用。修改 ulimit 值只會對當(dāng)前 shell 會話有效,對其他用戶或系統(tǒng)進(jìn)程不會產(chǎn)生影響(不一定)。

通過 ulimit 是限制系統(tǒng)資源的一種途徑,ulimit 支持 hard 和 soft 限制。

#<type> can have the two values:
#        - "soft" for enforcing the soft limits
#        - "hard" for enforcing hard limits
#
#<item> can be one of the following:
#        - core - limits the core file size (KB)
#        - data - max data size (KB)
#        - fsize - maximum filesize (KB)
#        - memlock - max locked-in-memory address space (KB)
#        - nofile - max number of open file descriptors
#        - rss - max resident set size (KB)
#        - stack - max stack size (KB)
#        - cpu - max CPU time (MIN)
#        - nproc - max number of processes
#        - as - address space limit (KB)
#        - maxlogins - max number of logins for this user
#        - maxsyslogins - max number of logins on the system
#        - priority - the priority to run user process with
#        - locks - max number of file locks the user can hold
#        - sigpending - max number of pending signals
#        - msgqueue - max memory used by POSIX message queues (bytes)
#        - nice - max nice priority allowed to raise to values: [-20, 19]
#        - rtprio - max realtime priority

普通用戶可以設(shè)置自己的軟限制,但不能高于硬限制??梢允褂?nbsp;ulimit -a 查看資源限制列表。

軟限制 (soft maxlogins):軟限制是一個(gè)警告閾值,當(dāng)達(dá)到或超過該限制時(shí),系統(tǒng)會發(fā)出警告信息,但不會阻止用戶登錄。硬限制 (hard maxlogins):硬限制是一個(gè)嚴(yán)格的限制,當(dāng)達(dá)到或超過該限制時(shí),系統(tǒng)將阻止用戶登錄。

┌──[root@liruilongs.github.io]-[~]
└─$ulimit -Hn #限制數(shù)
262144
┌──[root@liruilongs.github.io]-[~]
└─$ulimit -Sn #限制數(shù)
1024
┌──[root@liruilongs.github.io]-[~]
└─$

當(dāng)指定限制數(shù)時(shí)限制,不指定時(shí)輸出當(dāng)前設(shè)置。

通過配置文件的方式對登錄次數(shù)進(jìn)行限制,配置 kiosk 組 在多個(gè)終端中只能同時(shí)登錄 2 次。

┌──[root@liruilongs.github.io]-[~]
└─$cat /etc/security/limits.conf | grep -v ^# | grep -v ^$
@kiosk soft maxlogins 2
@kiosk hard maxlogins 2
┌──[root@liruilongs.github.io]-[~]
└─$

涉及到內(nèi)存相關(guān)的資源限制:

  • memlock:最大鎖定內(nèi)存地址空間限制(以 KB 為單位)
  • rss:最大常駐集大小限制(以 KB 為單位)物理內(nèi)存
  • stack:最大堆棧大小限制(以 KB 為單位)
  • as:地址空間限制(以 KB 為單位)虛擬內(nèi)存
  • msgqueue:POSIX 消息隊(duì)列使用的最大內(nèi)存限制(以字節(jié)為單位)

配置虛擬內(nèi)存限制可以通過 ulimit 進(jìn)行會話基本的虛擬內(nèi)存設(shè)置,下面是一個(gè) Demo,僅對 當(dāng)前 Shell 及其子進(jìn)程 生效 as 虛擬地址空間限制,以 KB 為單位。

┌──[root@liruilongs.github.io]-[~]
└─$ulimit -v 8186 # 配置 當(dāng)前 ulimit 大小為 8MB
┌──[root@liruilongs.github.io]-[~]
└─$ls
ls: error while loading shared libraries: libc.so.6: failed to map segment from shared object

修改 as 的大小之后,提示 ls 命令無法加載共享庫 libc.so.6,并且無法從共享對象映射段。

永久配置(全局或用戶級)需要修改 /etc/security/limits.conf, 感興趣小伙伴可以看看我之前的博文,生效條件:用戶重新登錄后生效。

# 格式:<domain>  <type>  <item>  <value>
liruilong  hard  as      819200   # Hard Limit 800MB
liruilong  soft  as      409600   # Soft Limit 400MB

其他的一些限制項(xiàng),也可以通過上面的方式進(jìn)行,比如內(nèi)存鎖定,最大棧,數(shù)據(jù)段等內(nèi)存相關(guān)的限制。

內(nèi)核參數(shù)

通過內(nèi)核參數(shù)對內(nèi)存的限制主要是一些緩存區(qū)的內(nèi)存占用限制,以及部分 OOM 和 內(nèi)存使用策略的修改,內(nèi)存頁分配限制策略等。

這里關(guān)于怎么修改內(nèi)核參數(shù)以及內(nèi)核參數(shù)的加載方式,可以參考我之前的博文,這里就不再贅述了。

緩存區(qū)內(nèi)存限制

下面為通過關(guān)鍵字過濾部分的內(nèi)核參數(shù)。

[root@developer ~]# sysctl -a | grep mem
kernel.bind_memcg_blkcg_enable = 1
net.core.optmem_max = 81920
net.core.rmem_default = 212992
net.core.rmem_max = 212992
net.core.wmem_default = 212992
net.core.wmem_max = 212992
net.ipv4.fib_sync_mem = 524288
net.ipv4.igmp_max_memberships = 20
net.ipv4.tcp_mem = 78777105039157554
net.ipv4.tcp_rmem = 40961310726291456
net.ipv4.tcp_wmem = 4096163844194304
net.ipv4.udp_mem = 157557210078315114
net.ipv4.udp_rmem_min = 4096
net.ipv4.udp_wmem_min = 4096
vm.hugepage_pmem_allocall = 0
vm.hugetlb_optimize_vmemmap = 0
vm.lowmem_reserve_ratio = 256256320
vm.memcg_qos_enable = 0
vm.memcg_swap_qos_enable = 0
vm.memory_failure_early_kill = 0
vm.memory_failure_recovery = 1
vm.nr_hugepages_mempolicy = 0
vm.overcommit_memory = 0
[root@developer ~]#

緩存區(qū)的話,一般用的比較多的是網(wǎng)絡(luò)方面的,比如 TCP,UDP,Stock 等。這部分參數(shù)沒有固定的值,一般根據(jù)機(jī)器使用場景動(dòng)態(tài)設(shè)置。

在上面的輸出中,前部位為 socket 級別的網(wǎng)絡(luò)緩存區(qū)限制,socket接受和發(fā)送數(shù)據(jù)的緩存的最大值,這里的配置往往結(jié)合 BDP 進(jìn)行配置,感興趣小伙伴可以看看我之前網(wǎng)絡(luò)調(diào)優(yōu)的博文。

net.core.optmem_max = 81920
net.core.rmem_default = 212992
net.core.rmem_max = 212992
net.core.wmem_default = 212992
net.core.wmem_max = 212992

后部分為 TCP/UDP 級別的網(wǎng)絡(luò)緩存區(qū)限制,TCP 緩沖區(qū)的大小應(yīng)根據(jù)系統(tǒng)和網(wǎng)絡(luò)的需求進(jìn)行調(diào)整。較大的緩沖區(qū)可以提高網(wǎng)絡(luò)性能,特別是在高負(fù)載或高延遲的網(wǎng)絡(luò)環(huán)境中。但是,過大的緩沖區(qū)可能會導(dǎo)致內(nèi)存占用增加或延遲問題。

net.ipv4.tcp_rmem 和 net.ipv4.tcp_wmem 用于配置 TCP 套接字的接收緩沖區(qū)和發(fā)送緩沖區(qū)的大小。

net.ipv4.tcp_rmem = 40961310726291456
net.ipv4.tcp_wmem = 4096163844194304
net.ipv4.udp_rmem_min = 4096
net.ipv4.udp_wmem_min = 4096

下面的兩個(gè)為 系統(tǒng)級別內(nèi)存限制,單位是Page 內(nèi)存頁,4K,分別代表了TCP和UDP的系統(tǒng)層面內(nèi)存限制的值,即網(wǎng)絡(luò)連接的內(nèi)存分配,包括三列:min,pressure,max。

net.ipv4.tcp_mem = 78777  105039  157554
net.ipv4.udp_mem = 157557 210078  315114

這里格式有點(diǎn)問題,我們換一個(gè)方式查看。

[root@developer ~]# cat /proc/sys/net/ipv4/tcp_mem
78777 105039  157554
[root@developer ~]#

內(nèi)存超售限制

下面這組內(nèi)核參數(shù)用于限制內(nèi)存的超售問題,內(nèi)存的分配和使用是兩個(gè)階段,在分配的時(shí)候是虛擬內(nèi)存,而且實(shí)際使用才會分配物理內(nèi)存,對于虛擬內(nèi)存的分配,可以是一個(gè)很大的值,但是物理內(nèi)存的分配,是有限制的,如果分配的虛擬內(nèi)存大于物理內(nèi)存,那么就會導(dǎo)致內(nèi)存超售,那么這個(gè)時(shí)候,就需要限制內(nèi)存的超售問題,避免內(nèi)存超售導(dǎo)致系統(tǒng)崩潰。

[root@developer ~]# sysctl -a | grep overcomm
vm.nr_overcommit_hugepages = 0
vm.overcommit_kbytes = 0
vm.overcommit_memory = 0
vm.overcommit_ratio = 50

vm.overcommit_memory = 0 :控制內(nèi)核的內(nèi)存超分配策略,決定是否允許進(jìn)程申請超過物理內(nèi)存 + Swap 的空間。

  • 0(默認(rèn)):啟發(fā)式超分配(Heuristic Overcommit)。內(nèi)核根據(jù)當(dāng)前空閑內(nèi)存、可回收緩存(PageCache/SLAB)和 Swap 綜合判斷是否允許分配。若申請量顯著超過可用資源則拒絕。
  • 1:無條件允許超分配(Always Overcommit)。來者不拒,但可能因?qū)嶋H內(nèi)存不足觸發(fā) OOM Killer。
  • 2:禁止超分配(Never Overcommit)。嚴(yán)格限制分配總量 ≤ (物理內(nèi)存 × overcommit_ratio%) + Swap。

vm.overcommit_ratio = 50: 當(dāng) overcommit_memory=2 時(shí),定義物理內(nèi)存的可超配比例(默認(rèn)值 50%)。  計(jì)算公式:  CommitLimit = (物理內(nèi)存 × overcommit_ratio / 100) + Swap 。

vm.overcommit_kbytes = 0:與 overcommit_ratio 互斥,直接指定超配的字節(jié)級上限(優(yōu)先級高于 ratio)。

vm.nr_overcommit_hugepages = 0:控制標(biāo)準(zhǔn)大頁(HugePages)的超配數(shù)量,允許臨時(shí)分配超出 vm.nr_hugepages 預(yù)設(shè)值的大頁。

上面講到了大頁,這里我們順便看看內(nèi)存頁相關(guān)的內(nèi)存限制。

內(nèi)存頁限制

hugepages 用于限制分配的大頁數(shù)量,這里的大頁指的是標(biāo)準(zhǔn)大頁,即 2MB 的大頁。

sysctl -w vm.nr_hugepages=1024  # 分配1024個(gè)大頁(默認(rèn)2MB/頁)

如果需要自定義大頁的大小,比如 1GB 的大頁,需要通過 hugepagesz 來進(jìn)行限制,一般啟動(dòng)時(shí)通過GRUB配置。

hugepagesz=1G hugepages=4 default_hugepagesz=1G  # 分配4個(gè)1GB大頁

關(guān)于內(nèi)存頁,內(nèi)核相關(guān)的參數(shù)中還有透明大頁的配置,比如透明大頁的開啟,khugepaged 進(jìn)程的掃描頻率等等,感興趣的小伙伴可以看看我之前關(guān)于大頁的博文。

下面為臟頁/換頁/內(nèi)存回收與保留相關(guān)參數(shù)的內(nèi)存限制。

臟頁指內(nèi)存中已被修改但未寫入磁盤的數(shù)據(jù)頁。內(nèi)核通過以下參數(shù)控制其回寫行為:

[root@developer ~]# sysctl -a | grep dirty
vm.dirty_background_bytes = 0 # 觸發(fā)后臺異步刷盤的臟頁絕對字節(jié)閾值(優(yōu)先級高于ratio)。0表示未啟用,使用dirty_background_ratio控制
vm.dirty_background_ratio = 10 # 觸發(fā)后臺異步刷盤的臟頁內(nèi)存占比閾值(默認(rèn)10%)。臟頁超限時(shí)內(nèi)核啟動(dòng)后臺線程異步刷盤,不阻塞應(yīng)用
vm.dirty_bytes = 0 # 觸發(fā)同步阻塞刷盤的臟頁絕對字節(jié)閾值(優(yōu)先級高于ratio)。0表示未啟用,使用dirty_ratio控制
vm.dirty_expire_centisecs = 3000 # 臟頁在內(nèi)存中的最長存活時(shí)間(默認(rèn)3000=30秒)。超時(shí)后強(qiáng)制刷盤,減少數(shù)據(jù)丟失風(fēng)險(xiǎn)
vm.dirty_ratio = 30 # 觸發(fā)同步阻塞刷盤的臟頁內(nèi)存占比閾值(默認(rèn)30%)。超限時(shí)應(yīng)用寫入被阻塞,直至臟頁落盤
vm.dirty_writeback_centisecs = 500 # 內(nèi)核刷盤線程的喚醒間隔(默認(rèn)500=5秒)。值越小刷盤越頻繁,過高可能導(dǎo)致I/O堆積
vm.dirtytime_expire_seconds = 43200 # 僅修改時(shí)間(atime/mtime)的臟元數(shù)據(jù)超時(shí)時(shí)間(默認(rèn)43200=12小時(shí))。通常無需調(diào)整

下面為交換分區(qū)使用限制:

vm.memcg_swap_qos_enable = 0   # 內(nèi)存控制組(memcg)的Swap服務(wù)質(zhì)量(QoS)功能開關(guān)
vm.swap_extension = 0          # 擴(kuò)展Swap空間的機(jī)制(通常用于特殊場景,如內(nèi)存壓縮)
vm.swappiness = 30             # 控制內(nèi)核使用Swap的傾向性(范圍0-100)

還有兩個(gè)特殊的參數(shù)需要單獨(dú)說明一下:

  • vm.min_free_kbytes:系統(tǒng)保留的最小空閑內(nèi)存(單位 KB),用于應(yīng)對突發(fā)需求。
  • vm.watermark_scale_factor:調(diào)整內(nèi)存回收敏感度(默認(rèn) 10,范圍 1-1000)。
[root@developer ~]# sysctl -a | grep min_free_kbytes
vm.min_free_kbytes = 45056
[root@developer ~]# sysctl -a | grep watermark_scale_factor
vm.watermark_scale_factor = 10
[root@developer ~]#

OOM 相關(guān)內(nèi)存限制

下面為OOM相關(guān),的內(nèi)存限制,關(guān)于 OOM 是什么,什么原理不是本文重點(diǎn),小伙伴可以看看我之前的博文。

[root@developer ~]# sysctl -a | grep oom
vm.enable_oom_killer = 1       # 啟用OOM Killer機(jī)制(默認(rèn)值)。當(dāng)系統(tǒng)內(nèi)存耗盡時(shí),內(nèi)核自動(dòng)終止進(jìn)程釋放內(nèi)存
vm.oom_dump_tasks = 1          # OOM觸發(fā)時(shí)記錄所有進(jìn)程的內(nèi)存狀態(tài)到日志(/var/log/messages),便于事后分析
vm.oom_kill_allocating_task = 0 # 禁用“直接殺死觸發(fā)OOM的進(jìn)程”。內(nèi)核會掃描所有進(jìn)程,選擇badness分?jǐn)?shù)最高的進(jìn)程終止
vm.panic_on_oom = 0            # OOM時(shí)禁止內(nèi)核崩潰(panic)。0表示調(diào)用OOM Killer而非重啟系統(tǒng)(生產(chǎn)環(huán)境推薦
[root@developer ~]#

NUMA內(nèi)存限制

[root@developer ~]# sysctl -a | grep zone_reclaim_mode
vm.zone_reclaim_mode = 0  # 關(guān)閉本地NUMA節(jié)點(diǎn)內(nèi)存強(qiáng)制回收。允許從其他節(jié)點(diǎn)分配內(nèi)存,避免因本地回收降低性能
[root@developer ~]# sysctl -a | grep min_unmapped_ratio
vm.min_unmapped_ratio = 1  # 每個(gè)NUMA節(jié)點(diǎn)保留1%的未映射內(nèi)存(用于臨時(shí)內(nèi)存分配)
[root@developer ~]#

對于內(nèi)存資源的限制內(nèi)核參數(shù)還有很多,這里只是列舉了部分。

責(zé)任編輯:武曉燕 來源: 山河已無恙
相關(guān)推薦

2023-11-28 08:43:48

2025-04-27 04:22:00

2010-09-26 10:53:00

JVM內(nèi)存調(diào)優(yōu)設(shè)置

2010-09-25 15:52:27

JVM內(nèi)存JVM

2014-12-19 11:07:40

Java

2019-07-17 15:45:24

Spark內(nèi)存Java

2020-08-10 17:49:25

JVM內(nèi)存溢出

2023-05-29 07:43:32

JVM內(nèi)存調(diào)優(yōu)

2023-02-10 09:28:23

優(yōu)化工具

2021-09-07 17:18:19

Linux內(nèi)存資源釋放內(nèi)存

2013-03-20 17:18:07

Linux系統(tǒng)性能調(diào)優(yōu)

2018-05-18 08:43:27

Linux內(nèi)存空間

2022-05-27 11:59:22

Linux內(nèi)存CPU

2016-10-08 12:46:08

Linux監(jiān)控限制

2011-03-21 09:35:38

LAMP調(diào)優(yōu)網(wǎng)絡(luò)文件

2010-05-27 17:10:03

MySQL數(shù)據(jù)庫內(nèi)存

2023-10-18 08:01:27

Java虛擬機(jī)

2014-09-22 13:31:46

Linux

2020-12-30 15:06:39

開發(fā)技能代碼

2023-03-07 21:41:23

JVM內(nèi)存服務(wù)器
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號