Linux系統調優

 

Linux在進行系統調優的時候,首先要考慮整個操作系統的結構,然後針對各個部分進行優化,下面展示一個Linux系統的各個組成部分:
 

由上圖可以看出,我們可以調整的有應用程序,庫文件,內核,驅動,還有硬件本身,所以接下來講對這些進行詳細的介紹,從而是系統的性能有所提高。
內核子系統中主要包括一下幾個方面:
1.         network(網絡)
2.         IO(輸入輸出子系統)
3.         process(進程)
4.         memory(內存)
5.         File System(文件系統)
一、    Linux的進程管理
1、進程的定義:進程是計算機資源分配單位,主要包括對系統資源的調度,如CPU時間,內存空間,是一個程序執行的一個副本。他們還包括一系列的資源,如文件的打開,釋放信號,內核內的數據,進程狀態,內存地址的映射,執行的多個線程,和數據段的全局變量。
2、進程狀態:running(運行)、interruptible(可中斷的睡眠態)、unitertible(非可中斷的睡眠態)、stopped(停止狀態)、zombie(僵死態)
 

Task_Running:一個進程要麼在CPU上執行,要麼等待CPU的時間再執行;
Task_Interruptible:一個處於sleeping狀態的進程,直到環境條件改變,重新掛起一個硬件中斷,使用系統釋放的資源,或者釋放一個信號,這個信號可以喚醒這個進程到Task_Running狀態,一般是一個IObound類型的;
Task_uninterruptible:這個和Task_Interruptible是一樣的,但是CPU bound類型的。
Task_stopped:程序執行已經完成,這個進程在接受到SIGSTOP、SIGTSTP, SIGTTIN, or SIGTTOU signal這些信號的時候,這個進程進入這個狀態;
Task_zombie:子進程執行完成,但是該子進程的父進程已近dead,無法回收這個子進程所佔用的資源;
3、進程週期:一個子進程都是父進程的一個副本,所以除了PID和PPID不同,其他的都是相同的,而子進程在執行一個程序的時候,需要在單獨在一個地址空間內進行,當執行完成之後,子進程鎖佔用的資源要有父進程進行回收,這就是一個進程的生命週期;
4、線程的概念:線程是比進程資源更小的資源調度單位,所以也叫輕量級的進程(LWP)
而線程的調度更加節省系統的資源,如果使用的是進程,即使是相同的進程也需要分配兩份資源,而線程就不同了,它可以在同一個進程中實現資源的重複利用,這就是nginx的性能比使用apache性能要好的原因,因爲nginx是基於線程的,而apache的prefork模式的是基於進程的,每一個進程連接都要分配4M的空間,而每一個線程確非配4k由此可以找出顯著的差別了,關於進程和線程資源調分配對比,我給大家準備了一個圖,可以簡單的看出他們之間的區別:
 

5、進程的調度:進程調度就是按照一定的調度算法,來實現不同進程之間的切換,常見的調度算法有一下幾種:
O(1)調度器<2.6之後>這種在調度的時候一秒一個,能實現公平的調度,公平分配時間,但是再有的時候會浪費時間,如edit和movie之間,edit就會浪費時間。
O(log n)
O(n)
O(n^2)
O(2^n)
爲了解決O(1)的不足,又引用了deadline,deadline有三個隊列,活動隊列,死亡隊列,deadline隊列,爲不同的進程做一個計數器,到時間就不管進程優先級的高低,而是“見死就救”。(deadline現在在磁盤上使用)現在進程調度使用的是CFS(完全公平調度算法)調度算法:不再爲每一個進程分配一個時間片,而是按照進程來分配一個時間比例。
6、進程的種類:交互式進程、批處理進程、實時進程;
7、進程的優先級:
 靜態優先級:1-99,100-139
 動態優先級:動態優先級調整的範圍100-139,通過調整nice值進行調整,調整後表現爲nice值。nice值範圍在-20—19
 實時優先級:0-99(數字越大,優先級越高)
8、進程調度策略:
 SCHED_FIFO:先進先出【1-99】,只能調度實時優先級進程;
 SCHED_RR:輪調 引入了時間片,是FIFO改進後的算法,只能調度實時優先級進程;
 SCHED_OTHER:調度傳統的分時進程【100-139】;
 SCHED_BATCH:只用來調度nice=0或優先級爲120的;
 使用#ps axo comm.,rtprio顯示實時優先級;
 
實時進程定義啓動使用的調度類別和指定優先級:
chrt  -f [1-99] /path/to/program arguments //添加到FIFO隊列中去
chrt  -r [1-99] /path/to/program arguments //添加到RR隊列中
nice&&renice調整優先級
查看系統的瓶頸是否是CPU
1.平均負載 yum install sysstat
 負載的三個平均值不能大於3
 w  
 uptime
 top
 sar -q 1 3 
 vmstat 1 5
2.CPU的利用率
 mpstat -p 60%在用戶空間就是正常的
 sar -P ALL 1
 iostat -c 1 
 cat /proc/stat
9、cache 緩存:
緩存分爲cache-hit和cache-miss
#yum install x86info
#x86info –c 查看cpu的緩存類型
#valgrind --tool=cachegrind ls 查看緩存命中情況
# dmesg | grep -i cache 查看緩存大小
10、多個CPU和多核CPU之間進行均衡
#watch -n .5 'ps axo comm,pid,psr | grep httpd ' 查看進程在哪個CPU上
taskset [opts]
#taskset -c -p CPULIST PID 把某一個進程綁定到一個特定的CPU上
#taskset -c -p 0 5533 把5533進程綁定到0號CPU上
這種能提高緩存命中率,但是對均衡有缺陷
11、調度域:就是將某些進程綁定在多個CPU組成的域中。調度域的作用就是把CPU組定義爲調度域,一個CPU集合就是一個調度域,配置本地調度域:
#mkdir /cpusets
#vim /etc/fstab 添加一下內容
cpuset     /cpusets   cpuset     default    0 0
#cd /cpusets
#ls
 

#mkdir ro
#cd ro
#echo 0 > cpus 這樣就建立了一個ro的調度域,同時綁定到第一個CPU上了;
12、進程的地址空間
一個進程在使用自己的內存空間進行工作的,所以這就導致了每一進程都有自己的地址空間,每一個進程都有自己的特點和數據大小,進程必須持有大量的數據尺寸,對於Linux內核來說,每個進程使用動態內存分配的是結構化的,具體如下圖所示:
 

所以進程可以分爲代碼段、數據段、BBS、堆、棧。
 
二、      內存管理
1、內存管理要想了解內存的調度機制,下面我就結合下圖進行簡單的闡述:
 

我就從左向右一步一步的介紹用戶發出個請求,通過調用庫文件,有用戶空間進入內核空間,在內核空間中把數據從磁盤中讀入內存中進行操作,操作完成之後,在同步到磁盤中,而爲了提高CPU的工作效率,使用MMU(memory manger unit,內存管理單元)來替代CPU來執行整個進程的調度,在這個過程中,首先要交換分區slab allocator目錄找到對應的資源所在的位置,然後到對應的內存空間或磁盤空間中去尋找,當然爲了避免內存回收的外碎片,引入了zoned buddy allocator,這個就是合理分配內存資源的,等到進程調度佔用的空間使用完成之後,需要回收資源,這裏就是用到了pdflush,就是講內存中dirty pages的數據同步到磁盤上去。
PTE:page tables 頁表項
PAE:物理地址擴展
TLB:transition lookaside buffers 轉換後緩衝器
只用x86info –c 和 dmesg可以查看
2、內存空間結構:
下圖是對32位的系統和64位的系統內存空間的一個對比
 

由於硬件設備的限制,所以內核不能把所以的page視爲相同的,所以出現瞭如上圖的Zone,下面開始詳細的介紹這些內容了:
1.在32位的系統上一個單獨的進程最大的地址空間是4G(2^32),這4G被分爲1G的內核空間和3G的用戶空間;其中1G的內核空間是用來做頁表的虛擬地址和物理地址進行映射關係的,另外3G是用戶空間;
1G的內核空間中,其中有16MB是用來做DMA(直接內存區域)的,這個區域包括pages;從16MB-896MB這期間的880MB是內核使用的,還有128MB是用來做映射的,從虛擬地址空間映射到物理地址空間上去;而上面的3G就是整整的地址空間了。而對於64位的操作系統的空間,有1G是用來做DMA的,區域的都是用來做實際的地址空間的,所以在服務器上,不帶考慮的直接裝64位的系統;
2. 通常出現缺頁異常的原因:數據還在磁盤上、數據在交換分區上,如果數據持續從交換分區上進行數據調度的話,那麼這就直接可以斷定是內存瓶頸,內存不夠用,剩下的就不解釋了,你懂的,擴展內存,呵呵!
3.查看各個進程的資源使用情況的方法:
#cat /proc/PID/status 或cat /proc/PID/statm
 

然後你就可以查看一下里面的內容了,系統每啓動一個進程,都會佔用一定的地址空間。
也可以使用圖形化界面進行查看
#gnome-system-monitor
#pmap +PID 查看進程對應的庫文件,也可以定位內存的瓶頸
 
#yum install glibc-utils
#memusage +COMMAND 查看單個進程佔用的內存,同時以條形框的形式展示
#memusage –help可以獲取該命令的更多的幫助信息
 

#ps axo minflt,majflt 看所有進程的缺頁異常發生情況
 

其中minflt表示的是磁盤的使用情況,而majflt表示交換分區使用的情況,根據這些信息可以判斷,如果長期使用交換分區的話,那麼就是內存瓶頸了。
4.內存的配額分爲一下幾種:
 (1)Process forks or execs child process
2)New process requests memory
3)New process uses memory
4)Process frees memory
5.內存的類型:
SRAM:靜態(static RAM)
DRAM:動態 (Dynamic RAM)
   SDRAM
   DDR
   RDRAM(服務器上使用,窄帶,有奇偶校驗的內存)
6、提高TLB的性能
TLB:(transition lookais buffer)轉換後援緩衝器,就是存放虛擬地址到物理地址轉換的表,也稱爲頁表緩衝;
TLB存放的頁面在32位系統上支持4k和4M兩種,在其他系統上就更多了,如果想了解,可以藉助幫助文檔
#yum install kernel-doc
安裝完成之後位於 /usr/share/doc/kernel-doc-2.6.18/Documentation中;
如果我們想讓TLB的值大點,也就是做成Hugetlb Page(大頁表)可以設置內核參數,這樣可以提高TLB緩存的命中率,降低PTE的方位次數,來加速地址轉換的速度;
調整TLB值的大小:
/etc/sysctl.conf
 vm.nr_hugepages=n
臨時生效:
 #echo 4 > /proc/sys/vm/nr_hugepages
 #sysctl -w vm.nr_hugepages=n
永久有效:
 #vim /etc/sysctl.conf
 #sysctl -p 保存,生效
爲了以後使用大頁表,我們可以做一個大頁表文件系統
#mkdir /hugepages
#mount -t hugetlbfs none /hugepages 在以後就如果使用到了,就可以直接使用了;
當然爲了詳細的觀察進程詳細的調度情況,也可以追蹤系統調用
#strace -p PID 查看進程詳細調度的進程
#strace ls 可以看到所發出指令的詳細的系統調用
#strace ls -o /tmp/tmp.txt 保存在指定的文件中。
#strace -c -p PID 統計系統調用時間和所調用的次數,結合這些結果進行分析
7、內存使用應遵循的策略:
 a.減小內存小對象的消耗,使用的工具有slab cache
 b.降低那些比較慢的系統服務時間:
    i.文件系統的:buffer cache(slab cache)
    ii.DISK IO: page cache
    iii.Internetprocess:shared memory
    iv.network IO:buffer cache,arp cache,connection tracking (buffer是解決兩端速率不匹配的,而cache是爲了重複使用,提高緩存命中率的)
結合上面的理論,接下來就是做詳細的內存內核參數的調整的過程了:
1、vm.min_free_kbytes 至少要在內存中保留多大的K字節的空間
 說明:當一個應用反覆使用和釋放大的內存,磁盤的帶寬下,CPU使用低下,內存小,需要改變上面的參數,如果改小了,這樣就會導致服務時間降低,其他應用程序無法有足夠的內存,對zone_nomal照成很大的壓力;默認是2890
2、vm.overcommit_memory 內存過度使用,這個參數有三個數值可以設置0,1,2
0|拒絕過度使用(默認)
 1|總是過度使用 (不建議)
 2|僅能使用所有的RAM和swap的一個百分比建議設置爲30,50%已經是大的了<這個對啓動2纔有效>)儘可能根據committed_AS爲參照來設置
3、vm.overcommit_ratio 過度使用的比,就是上面swap的比(建議設置爲30%,50%已經是較大的了)默認:50
4、調整slab緩存小內存對象,緩存的是文件的innode(索引),每一種slab只能緩存一中小內存對象;
該文件在/proc/slabinfo文件中,我們可以看一下:
 

這個文件中可以該的值有limit,batchcount,sharedfactor,其中limited=N*batchcount
如:
#echo “ext3_inode_cache 108 27 8” >/proc/slabinfo
#slabtop //查看當前slab分配的信息
同樣可以使用vmstat –m 也可以查看當前slab分配信息
 

5、調整ARP cache:
#cat /proc/net/arp
 

可以看出現在arp緩存
也可以使用一下命令進行查看
#arp –a
#ip neigh show
arp -d hostname 刪除arp緩存
ip neighbor flush dev eth0 標記爲失效,過一會就會清空
當讓爲了減少arp cache佔用系統資源,可以設置其存儲的條目
net.ipv4.neigh.default.gc_thresh1 定義緩存上線,當緩存大於多少的時候就做清理(默認128)
net.ipv4.neigh.default.gc_thresh2 軟上線 512
net.ipv4.neigh.default.gc_thresh3 硬上線 1024
net.ipv4.neigh.default.gc_interval 緩存收集垃圾時間 默認30s
這些是對arp緩存大小的設置;
6、page cache :page緩存的是數據;
使用到的場所:直接讀、讀寫、讀寫快設備、訪問內存mapped files、訪問swap mapped files
vm.lowmem_reserve_ratio 低地址空間中預留的空間的百分比,一般指的是zone_normal放置OOM(內存地址耗盡);
vm.vfs_cache_pressure 定義內核回收slab cache、pagecache、swapcache中的內存的傾向性,默認是100,如果小於100,傾向性變小,如果設置爲0,就不會回收pagecache、swapcache中的內存(不建議),如果經常打開文件,要增大這個值,能快速回收內存,如果有足夠大的內存,可以維持在100,一般不需要降低這個值;
vm.page_cluster 頁簇:控制物理內存數據交換到交換分區的時候,一次交換的多少個頁面數2^n 這個值默認是3,也就是8個頁面,應用程序頻繁使用交換分區的時候,可以調大點;
vm.zone_reclaim_mode 內存區域回收的模型,當一個區域的內存消耗完的時候,如何回收此區域的空間,其值有:1(打開回收機制)、2(將此內存的章頁同步到磁盤在回收)、4(回收交換頁面所佔用的空間)
7、anonymous pages:匿名頁面
匿名頁面主要包括程序數據,arrarys,heap,allowcations等
 

8、SysV IPC interprocess communication 進程間通信:
*1.semaphores 信號
調整:
kernel.sem
cat /proc/sys/kernel/sem
250 每個數組信號量
32000
32
128 可以所使用的數組
*2.Messageing queues 消息隊列(rubbit MQ)通過交換信息
調整:
kernel.msgmnb
16384 一個單獨的消息隊列能容納多少消息信號
kernel.msgmni
16 消息隊列最大消息隊列數
kernel.msgmax
8192 單個消息最大上線8k
*3.shared memory 共享內存
調整:
kernel.shmmni
4096 共享內存段的最大數目
kernel.shmall
2097152 一次共享頁面的值
kernel.shmmax
shmall*4k 共享內存段的大小可以被創建
 
使用ipcs命令查看當前機器進程間通信的機制
ipcs -l顯示進程間通信的限制
 

如果文件的修改不是太多,可以把數據放在/dev/shm中,這個直接寫入內存,但是一旦斷電,數據就會丟失
 
9、內存詳細使用情況的命令:
free -m 顯示內存使用情況
page tables:cat /proc/vmstat 
system memory:cat /proc/meminfo (total physical memory,cache,active use,inactive) 使用vmstat -s
#yum install sysstat
sar -r 1 10 (每個一秒取一次,取十次)
 
10、頁面分類:
1.free 
2.inactive clean 可以被直接回收使用
3.inactive dirty 頁面中有數據沒有同步到磁盤上去,只要同步到磁盤上去了,就能回收
4.active 正在被使用的頁面
 
Bubby system:夥伴系統,是避免內存回收的外碎片的,保存內存空間是連續的一片空間
 
內核中的有個線程叫kswapd來回收空閒分區,把內存中使用較少的(非活動clean狀態的)放到交換分區,騰出空間供其他的使用
 
使用vmstat -a |-s 顯示頁框使用狀態
 
頁面主要作用:page cache 和進程地址空間,所有回收page cache中的頁面
 
11、如何回收dirty pages:
1.同步到磁盤上,靠的是pdflush的內核線程(每隔一段時間就會同步,可以多個同時運行的,可以定義pdflush的數目,如CPU,DISK多,可以在一個CPU上一個,提高併發能力)
2.放到交換分區
vm.nr_pdflush_threads 就是定義pdflush線程個數,建議一個磁盤一個pdflush線程
vm.dirty_background_ratio 當髒頁總數佔整個內存比例的時候,啓動pdflush
vm.dirty_ratio 某一個單進程的髒頁所佔用的比例,然後啓動pdflush進行刷寫
vm.dirty_expir_centisecs 每隔一段時間進行一次刷寫操作(默認30s,0表示禁用)
vm.dirty_writeback_centisecs 默認5s,定義一個數據修改超過這個時間就可以刷寫了
 
12、如何回收乾淨頁面:
sync
fsync
echo s > /proc/sysrq-trigger   手動同步到磁盤
echo x > /proc/sys/vm/drop_caches
x=
 1 free pagecache 
 2 free dentries and inodes
 3 buffer and cache
out-of-memory killer進程在內存佔用滿了,就開始殺死一些進程
/proc/PID/oom_score 進程的分數,分數越大,就會在內存oom的時候最先殺死
 
13、優化OOM策略:
echo n >/proc/PID/oom_adj
echo f > /proc/sysrq-trigger 手動殺死進程
vm.panic_on_oom=1 禁止oom-kill ,但是內存耗盡也會照成系統恐慌
 
14、探測內存泄漏:一個進程退出的時候,內存未釋放
內存泄漏分爲兩種:
 1.虛擬(virtual)內存泄漏:只申請,但不使用
 2.real:內存釋放失敗
#sar -R 查看內存申請、釋放情況,正數是申請的,負數是釋放,其中frmpgz正好相反
#yum install valgrind
#valgrand --tool=memcheck ls 查看內存泄漏
**作爲管理員要經常關注內存是否泄漏
 
15、swap 交換分區:
swap-out=page-out 就是把內存中的數據放到交換分區
swap-in :把內存中的數據放到交換分區;
 
那些pages要進行交換:
inactive pages
anonymous pages
 
16、提高swap的性能:
1.降低決策時間 :快速換入喚出小頁面,匿名pages
2.降低訪問次數:做swap集羣,多個分區做相同的優先級
3.降低服務時間:儘可能使用分區,不實用文件;儘量把交換分區放到磁盤外道;把交換分區放到raid0上
vm.swappiness 定義多大傾向喚出交換分區的匿名頁,裏面是一個%比,達到了就使用交換內存,如果不想使用交換分區,可以把值設置小於100,默認是60
 
 
17、交換分區的大小:
批處理服務:> 4*RAM
數據庫服務:<=1G
應用程序服務:>=0.5*RAM
 
vm.page_cluster=n (2^n個頁面)
vm.swap_token_timeout 一旦發現交換分區頻繁的不參與這個的時間
 
18、監控內存工具:
vmstat -n 顯示內存和swap分區的數據
sar -r 顯示內存和swap分區的數據
sar -R 顯示內存的數據
sar -W 像是swqp數據
sar -B 顯示頁面的數據
 
還有網絡、IO調優待續。。。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章