Linux經過ulimit改善系統性能

系統性能一直是一個受關注的話題,如何經過最簡單的設置來實現最有效的性能調優,如何在有限資源的條件下保證程序的運做,ulimit 是咱們在處理這些問題時,常用的一種簡單手段。ulimit 是一種 linux 系統的內鍵功能,它具備一套參數集,用於爲由它生成的 shell 進程及其子進程的資源使用設置限制。本文將在後面的章節中詳細說明 ulimit 的功能,使用以及它的影響,並以具體的例子來詳細地闡述它在限制資源使用方面的影響。

ulimit的功能和用法mysql

ulimit功能簡述linux

假設有這樣一種狀況,當一臺 Linux 主機上同時登錄了 10 我的,在系統資源無限制的狀況下,這 10 個用戶同時打開了 500 個文檔,而假設每一個文檔的大小有 10M,這時系統的內存資源就會受到巨大的挑戰。而實際應用的環境要比這種假設複雜的多,例如在一個嵌入式開發環境中,各方面的資源都是很是緊缺的,對於開啓文件描述符的數量,分配堆棧的大小,CPU 時間,虛擬內存大小,等等,都有很是嚴格的要求。資源的合理限制和分配。sql

不只僅是保證系統可用性的必要條件,也與系統上軟件運行的性能有着密不可分的聯繫。這時,ulimit能夠起到很大的做用,它是一種簡單而且有效的實現資源限制的方式。ulimit用於限制shell啓動進程所佔用的資源,支持如下各類類型的限制:所建立的內核文件的大小、進程數據塊的大小、Shell進程建立文件的大小、內存鎖住的大小、常駐內存集的大小、打開文件描述符的數量、分配堆棧的最大大小、CPU 時間、單個用戶的最大線程數、Shell 進程所能使用的最大虛擬內存。同時,它支持硬資源和軟資源的限制。shell

做爲臨時限制,ulimit 能夠做用於經過使用其命令登陸的 shell 會話,在會話終止時便結束限制,並不影響於其餘 shell 會話。而對於長期的固定限制,ulimit 命令語句又能夠被添加到由登陸 shell 讀取的文件中,做用於特定的 shell 用戶。dom

如何使用ulimitsocket

ulimit經過一些參數選項來管理不一樣種類的系統資源。在本節,咱們將講解這些參數的使用。性能

ulimit命令的格式爲:線程

$ ulimit [options] [limit]
[options]

-H: 設置硬資源限制,一旦設置不能增長。如,ulimit -Hs 64;限制硬資源,線程棧大小爲64K。

-S: 設置軟資源限制,設置後能夠增長,可是不能超過硬資源設置。如,ulimit -Sn 32;限制軟資源,32個文件描述符。

-a: 顯示當前全部的limit信息。如,ulimit -a;顯示當前全部的limit信息。

-c: 最大的core文件的大小, 以blocks爲單位。如,ulimit -c unlimited;對生成的core文件的大小不進行限制。

-d: 進程最大的數據段的大小,以Kbytes爲單位。如,ulimit -d unlimited;對進程的數據段大小不進行限制。

-f: 進程能夠建立文件的最大值,以 blocks 爲單位。如,ulimit -f 2048;限制進程能夠建立的最大文件大小爲2048 blocks。

-l: 最大可加鎖內存大小,以Kbytes爲單位。如,ulimit -l 32;限制最大可加鎖內存大小爲32Kbytes。

-m: 最大內存大小,以Kbytes爲單位。如,ulimit -m unlimited;對最大內存不進行限制。

-n: 能夠打開最大文件描述符的數量。如,ulimit -n 128;限制最大可使用128個文件描述符。

-p: 管道緩衝區的大小,以Kbytes爲單位。如,ulimit -p 512;限制管道緩衝區的大小爲512Kbytes。

-s: 線程棧大小,以Kbytes爲單位。如,如,ulimit -s 512;限制線程棧的大小爲512Kbytes。

-t: 最大的CPU佔用時間,以秒爲單位。 如,ulimit -t unlimited;對最大的CPU佔用時間不進行限制。

-u: 用戶最大可用的進程數。如,ulimit -u 64;限制用戶最多可使用64個進程。

-v: 進程最大可用的虛擬內存,如,以Kbytes爲單位。如,ulimit -v 200000;限制最大可用的虛擬內存爲200000Kbytes。

ulimit使用實例server

用戶進程的有效範圍對象

ulimit 做爲對資源使用限制的一種工做,是有其做用範圍的。那麼,它限制的對象是單個用戶,單個進程,仍是整個系統呢?事實上,ulimit 限制的是當前 shell 進程以及其派生的子進程。舉例來講,若是用戶同時運行了兩個 shell 終端進程,只在其中一個環境中執行了 ulimit -s 100,則該 shell 進程裏建立文件的大小收到相應的限制,而同時另外一個 shell 終端包括其上運行的子程序都不會受其影響。

Shell 1

$ ll -h newfile 
-rw-r--r--. 1 root root 223K 4月  23 09:16 newfile
$ ulimit -f 100
$ cat newfile > shell1
File size limit exceeded (core dumped)
$ ll -h shell1
-rw-r--r--. 1 root root 100K 4月 23 09:20 shell1

Shell 2

$ cat newfile > shell2
$ ll -d shell2 
-rw-r--r--. 1 root root 227690 4月  23 09:23 shell2
$ ll -h shell2 
-rw-r--r--. 1 root root 223K 4月  23 09:23 shell2

那麼,是否有針對某個具體用戶的資源加以限制的方法呢?答案是有的,臨時生效(不限制打開文件大小限制):

$ ulimit -f unlimited

或經過修改系統的/etc/security/limits.conf配置文件。該文件不只能限制指定用戶的資源使用,還能限制指定組的資源使用。該文件的每一行都是對限定的一個描述,格式以下:

 

domain 表示用戶或者組的名字,還可使用 * 做爲通配符。Type 能夠有兩個值,soft 和 hard。Item 則表示須要限定的資源,能夠有不少候選值,如 stack,cpu,nofile 等等,分別表示最大的堆棧大小,佔用的 cpu 時間,以及打開的文件數。經過添加對應的一行描述,則能夠產生相應的限制。例如:

* hard noflle 100

該行配置語句限定了任意用戶所能建立的最大文件數是 100。如今已經能夠對進程和用戶分別作資源限制了,看似已經足夠了,其實否則。不少應用須要對整個系統的資源使用作一個總的限制,這時候咱們須要修改/proc下的配置文件。/proc目錄下包含了不少系統當前狀態的參數,例如/proc/sys/kernel/pid_max,/proc/sys/net/ipv4/ip_local_port_range等等,從文件的名字大體能夠猜出所限制的資源種類。因爲該目錄下涉及的文件衆多,在此不一一介紹。有興趣的讀者可打開其中的相關文件查閱說明。

使用ulimit限制shell的內存使用

在這一小節裏向讀者展現如何使用-d,-m 和-v 選項來對shell所使用的內存進行限制。首先咱們來看一下不設置ulimit限制時調用ls命令的狀況:

$ ll shell1 -l
-rw-r--r--. 1 root root 227690 4月  23 09:16 shell1

你們能夠看到此時的 ls 命令運行正常。下面設置 ulimit:

$ ulimit -d 1000 -m 1000 -v 1000
這裏再溫習一下前面章節裏介紹過的這三個選項的含義:

-d:設置數據段的最大值。單位:KB。

-m:設置可使用的常駐內存的最大值。單位:KB。

-v:設置虛擬內存的最大值。單位:KB。

經過上面的 ulimit 設置咱們已經把當前 shell 所能使用的最大內存限制在 1000KB 如下。接下來咱們看看這時運行 ls 命令會獲得什麼樣的結果:

$ ll shell1 -l
Segmentation fault (core dumped)

使用ulimit限制程序所能建立的socket數量

考慮一個現實中的實際需求。對於一個 C/S 模型中的 server 程序來講,它會爲多個 client 程序請求建立多個 socket 端口給與響應。若是剛好有大量的 client 同時向 server 發出請求,那麼此時 server 就會須要建立大量的 socket鏈接。可是在 Linux 下一切資源皆文件,普通文件是文件,磁盤打印機是文件,socket 固然也是文件。在 Linux 下建立一個新的socket 鏈接,實際上就是建立一個新的文件描述符。而Linux對單進程能打開的文件描述符是有限制的,默認單進程能打開的最大文件數量爲1024,。ulimit 並無哪一個選項直接說是用來限制socket的數量的。可是,咱們有-n這個選項,它是用於限制一個進程所能打開的文件描述符的最大值。以下所示(查看某個進程當前打開的文件描述符信息):

$ ll /proc/36766/fd
總用量 0
lr-x------. 1 root root 64 4月  23 09:31 0 -> /dev/null
l-wx------. 1 root root 64 4月  23 09:31 1 -> /mydata/localhost.localdomain.err
lrwx------. 1 root root 64 4月  23 09:31 10 -> /mydata/ib_logfile1
lrwx------. 1 root root 64 4月  23 09:31 11 -> socket:[115703]
lrwx------. 1 root root 64 4月  23 09:31 12 -> /tmp/ibLxLFBt (deleted)
l-wx------. 1 root root 64 4月  23 09:31 13 -> /mydata/mysql-bin.000001
lrwx------. 1 root root 64 4月  23 09:31 14 -> socket:[115704]
lrwx------. 1 root root 64 4月  23 09:31 15 -> /mydata/mysql/host.MYI
.......................

所以,咱們能夠經過使用ulimit -n來限制但進程所能打開的最大文件描述符數量,默認單進程打開的文件描述符爲1024,就是表明單個進程只能同時最多隻能維持1024甚至更少(由於有其它文件的句柄被打開)。若是開啓4個進程維持用戶連接,那麼整個應用可以同時維持的鏈接數不會超過4*1024個,也就是說最多隻能支持4×1024個用戶在線。能夠增大這個設置以便服務可以維持更多的TCP鏈接,從而達到限制socket建立的數量。

若是單個進程打開的文件句柄數量超過了系統定義的值,就會提到「too many files open」的錯誤提示。如何知道當前進程打開了多少個文件句柄呢?經過lsof命令能夠幫你查看:

$ lsof -n |awk '{print $2}'|sort|uniq -c |sort -nr| head -n 2
    126 7015
     93 1831

上面說明了,7015進程打開了126個文件描述符,你能夠經過ps命令看看7015這個進程是什麼服務(這裏都是以個人舉例說明的,你在實驗時要根據本身的進程進行查看,相信你有這個意識)。

修改單進程所能打開的最大文件數

1)ulimit -n 102400

這只是在當前終端有效,退出以後,open files又變爲默認值。

2)將ulimit -n 102400寫到/etc/profile中,這樣每次登陸終端時,都會自動執行/etc/profile。

3)令修改open files的數值永久生效,則必須修改配置文件:/etc/security/limits.conf在這個文件後加上:

* soft nofile 1024000
* hard nofile 1024000
root soft nofile 1024000
root hard nofile 1024000
相關文章
相關標籤/搜索