티스토리 뷰
2015.03.10 : 최초작성
2016.05.12 : dirty_info.sh OS Version별 분기처리, Real Memory 사용율, NW Session, Packet Error, Drop Count 추가갱신
Linux Kernel은 Disk I/O에 대한 응답성능 향상을 위해 Disk에 적재된 데이터에 대한 Cache 즉 Page 확보를 통해 장치간 성능차를 극복한다고 일전의 게시물을 통해 설명한적이 있다. (http://blog.helperchoi.com/86)
Page Cache로 적재된 데이터에 대해서 Update성 I/O 가 인입되면 즉 Dirty Page Cache가 발생되면, Linux kernel 은 다음과 같은 설정값에 의해 해당 데이터를 Disk 영역으로 Flushing 하게된다.
[root@s-node01 shell]# [root@s-node01 shell]# cat /proc/sys/vm/dirty_background_ratio 10 [root@s-node01 shell]# [root@s-node01 shell]# cat /proc/sys/vm/dirty_ratio 40 [root@s-node01 shell]# [root@s-node01 shell]# cat /proc/sys/vm/dirty_expire_centisecs 3000 [root@s-node01 shell]# [root@s-node01 shell]# cat /proc/sys/vm/dirty_writeback_centisecs 500 [root@s-node01 shell]# [root@s-node01 shell]# cat /proc/sys/vm/nr_pdflush_threads 2 [root@s-node01 shell]# |
1. dirty_background_ratio - 기본적으로 Kernel은 시스템 메모리에 적재된 Page Cache의 총량중 Dirty Page의 양이 설정된 임계비율을(Default 10%) 초과 했을 경우 kthread 이하 pdflush thread를 통해 Disk에 동기화 수행을 하게 된다.
2. dirty_ratio - Linux Kernel은 dirty_ratio 임계비율을 기준으로 Page Cache의 총량 대비 Dirty Page의 총량이 임계비율을 초과하게되면 kernel은 Memory 영역에 적재된 Dirty Page cache의 동기화 처리 수준이(Disk I/O) 전체 요청량에 비해 떨어진다고 판단을 하고 Kernel 이하의 모든 프로세스에 대하여 쓰기작업에 대한 차단을 수행한다.
즉 시스템의 모든 작업에 영향을 주게되며, 이에 따라 시스템의 Loadaverage는 급증하며, Disk 및 CPU Latency Time이 폭증하는 양상을 띄게 된다.
때문에 일반적인 System Resouce (CPU / Memory) 의 사용량이 평이함에도 시스템에 지연현상이 나타날때는 dirty_ratio 임계비율과 함께 아래와 같이 전체 Page Cache량 대비 Dirty Page 비율을 체크하면 도움이 된다.
[root@s-node01 ~]# [root@s-node01 ~]# cat /proc/meminfo | egrep -i 'cache|dirty' Cached: 289104 kB SwapCached: 100 kB Dirty: 2140 kB [root@s-node01 ~]# [root@s-node01 ~]# |
3. dirty_expire_centisecs - Memory 영역에 적재된 Dirty Page Cache는 dirty_background_ratio 임계비율과는 별개로 dirty_expire_centisecs 값에 의해 생성된지 30초가 지나게 되면 Disk 영역으로 동기화 처리 된다. (1/100 초 단위로 표기)
4. dirty_writeback_centisecs - 상기 1번 항목에서 설명했던 pdflush Thread 가 활성화되는 조건값을 나타내며, 기본값은 5초이다. 즉 pdflush 는 5초에 한번씩 Dirty Page 에 대한 Disk Flushing을 수행하며, pdflush 의 처리시간이 1초이상 초과할때 다음 nr_pdflush_threads 값에 정의된 만큼 추가 Thread를 생성하여 Disk 동기화를 수행하게 된다.
5. nr_pdflush_threads - 상기 4번에서 설명한 대로 pdflush Thread의 최소개수를 정의한다. 기본값은 2개이며 최대 8개까지 증가된다.
다만 이는 kernel 2.6.31 버전까지만 해당하며, kernel 2.6.32 부터는 기존 pdflush 성능적 단점을 보완하기 위해 아래와 같이 /proc/sys/vm/nr_pdflush_threads 값은 무의미한 값(0)으로 처리되어 졌으며, OS 할당된 물리 Device의 수만큼 개별 처리 프로세스를 할당하여 필요시 처리하게 되었다.
추가적으로 nr_pdflush_threads 값은 아래와 같이 kernel 이하 sysctl.c Code에 의해 읽기 전용으로 제한되어 있어 변경이 불가 하다는 사실을 확인하였음.
※ 발췌 - Redhat Support
The sysctl vm.nr_pdflush_threads is a read-only value and cannot be changed. It is defined in sysctl.c in the kernel source as: { .ctl_name = VM_NR_PDFLUSH_THREADS, .procname = "nr_pdflush_threads", .data = &nr_pdflush_threads, .maxlen = sizeof nr_pdflush_threads, .mode = 0444 /* read-only*/, .proc_handler = &proc_dointvec, }, The min and max number of pdflush threads is also hard coded in the kernel as 2 (minimum number of threads) and 8 (maximum number of threads). Whenever all existing pdflush threads are busy for at least one second, an additional pdflush thread is spawned. The new ones try to write back data to device queues that are not congested, with the goal to have each device that is active get its own thread flushing data to that device. Each time a second has passed without any pdflush activity, one of the threads is removed until min number of threads is reached. |
※ Kernel 2.6.31 이하
[root@s-node01 ~]# [root@s-node01 ~]# uname -a Linux s-node01 2.6.18-371.11.1.el5 #1 SMP Wed Jul 23 15:12:55 EDT 2014 x86_64 x86_64 x86_64 GNU/Linux [root@s-node01 ~]# [root@s-node01 ~]# cat /proc/sys/vm/nr_pdflush_threads 2 [root@s-node01 ~]# [root@s-node01 ~]# ps -ef | grep -v grep | grep flush root 131 11 0 Feb27 ? 00:00:00 [pdflush] root 132 11 0 Feb27 ? 00:00:15 [pdflush] [root@s-node01 ~]# [root@s-node01 ~]# |
※ Kernel 2.6.32
[root@TEST02 ~]# [root@TEST02 ~]# uname -a Linux TEST02 2.6.32-358.el6.x86_64 #1 SMP Fri Feb 22 00:31:26 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux [root@TEST02 ~]# [root@TEST02 ~]# [root@TEST02 ~]# cat /proc/sys/vm/nr_pdflush_threads 0 [root@TEST02 ~]# [root@TEST02 ~]# [root@TEST02 ~]# ps -ef | grep -v grep | grep flush root 836 2 0 2014 ? 07:01:04 [flush-8:0] root 59936 2 0 Feb16 ? 01:48:07 [flush-8:16] root 59937 2 0 Feb16 ? 01:46:43 [flush-8:48] root 59938 2 0 Feb16 ? 01:41:28 [flush-8:32] [root@TEST02 ~]# [root@TEST02 ~]# [root@TEST02 ~]# grep ^ /sys/class/block/*/dev | grep sd /sys/class/block/sda/dev:8:0 /sys/class/block/sda1/dev:8:1 /sys/class/block/sda2/dev:8:2 /sys/class/block/sda3/dev:8:3 /sys/class/block/sdb/dev:8:16 /sys/class/block/sdb1/dev:8:17 /sys/class/block/sdc/dev:8:32 /sys/class/block/sdc1/dev:8:33 /sys/class/block/sdd/dev:8:48 /sys/class/block/sdd1/dev:8:49 [root@TEST02 ~]# [root@TEST02 ~]# [root@TEST02 ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/sda3 1.8T 1.4T 353G 80% / tmpfs 24G 0 24G 0% /dev/shm /dev/sda1 985M 44M 891M 5% /boot /dev/sdb1 1.8T 1.3T 509G 71% /data2 /dev/sdc1 1.8T 1.2T 514G 71% /data3 /dev/sdd1 1.8T 1.3T 485G 73% /data4 [root@TEST02 ~]# |
6. Shell Script를 통한 Dirty Page에 의한 시스템 부하 감시 모니터링
1) 1회성 실행 예시
[root@TEST01 shell]# [root@TEST01 shell]# ./dirty_info.sh [ Total Memory ] : 509728KB [ Free Memory ] : 20272KB [ Page Cache ] : 384628KB [ Dirty Page ] : 148KB [ Flush Thread ] : 2 [ Dirty Ratio LIMIT ] : 40/100% [ Dirty Ratio Status ] : .03/100% [ Swap Memory Status ] : 728KB / 1048568KB [ System Loadaverage ] : 1.06 (1 Core System) [ Dirty Page Status ] : NORMAL [root@TEST01 shell]# |
2) 지속 모니터링 예시
[root@TEST01 shell]# [root@TEST01 shell]# watch -n1 -d "./dirty_info.sh" Every 1.0s: ./dirty_info.sh Thu Mar 12 15:32:33 2015 [ Total Memory ] : 509728KB [ Free Memory ] : 5660KB [ Page Cache ] : 385116KB [ Dirty Page ] : 206244KB [ Flush Thread ] : 8 [ Dirty Ratio LIMIT ] : 40/100% [ Dirty Ratio Status ] : 53.55/100% [ Swap Memory Status ] : 728KB / 1048568KB [ System Loadaverage ] : 5.37 (1 Core System) [ Dirty Page Status ] : CRITICAL [ Operations Notice ] : Kernel will block all write operations !!! [ Loadaverage Notice ] : Latency time of all process increased !!! |
3) Script 내용
[root@TEST01 shell]# vi ./dirty_info.sh #!/bin/bash #Make by Kwang Min Choi / http://blog.helperchoi.com / helperchoi@gmail.com #TEST OS : CentOS 5.x, 6.x, 7.x export LANG=C export LC_ALL=C CHECK_OS=`uname -a | cut -d "/" -f 2 | tr '[A-Z]' '[a-z]'` if [ $CHECK_OS = "linux" ]; then if [ -e "/etc/oracle-release" ] then export OS_VERSION=`cat /etc/oracle-release` export OS_TYPE="OEL" else export OS_VERSION=`cat /etc/redhat-release` export OS_TYPE="RHEL" fi fi KERNEL_MAJOR_CHECK=`uname -r | cut -d "-" -f 1 | cut -d "." -f 1` KERNEL_MINOR_CHECK=`uname -r | cut -d "-" -f 1 | cut -d "." -f 3` LOG_DIR=/root/collect LOG_NAME=$/`date +%Y-%m-%d`_collect.log declare -a ARRAY_TIME declare -a ARRAY_MEMLIST ARRAY_TIME=("$" "`date`") for MEM_LIST in `cat /proc/meminfo | awk ''` do ARRAY_MEMLIST=("$" "`echo $`") done DIRTY_FLUSH_RATIO=`cat /proc/sys/vm/dirty_background_ratio` DIRTY_CRITICAL_RATIO=`cat /proc/sys/vm/dirty_ratio` DIRTY_CRITICAL_LIMIT=`echo "$DIRTY_CRITICAL_RATIO - 5" | bc` CPU_CORE=`cat /proc/cpuinfo | grep -i process | wc -l` LOAD_AVERAGE=`cat /proc/loadavg | awk ''` LOAD_AVERAGE_LIMIT=`echo "scale=3; $ * 2.5" | bc` export LOAD_DIFF=`echo "$ >= $" | bc` CPU_IDLE=`sar -p 1 1 | grep Aver | awk ''` CPU_USAGE=`echo "100 - $" | bc` RF_USAGE=`df -hP | awk '$6 ~ /\/$/ '` MEM_TSIZE=$ MEM_FSIZE=$ CACHE_SIZE=$ if [ $ -eq 2 -a $ -lt 32 ] then PDFLUSH_THREAD=`ps -ef | grep -v grep | grep flush | wc -l` SWAP_SIZE=$ SWAP_FREE=$ DIRTY_SIZE=$ CONTEXT_SWITCH=`sar -w 1 1 | awk '$1 ~ /^[0-9]/ ' 2>&1 | sed -n '2,2p'` elif [ $ -eq 2 -a $ -ge 32 ] then PDFLUSH_THREAD=`ps -ef | grep -v grep | grep flush- | wc -l` SWAP_SIZE=$ SWAP_FREE=$ DIRTY_SIZE=$ CONTEXT_SWITCH=`sar -w 1 1 | awk '$1 ~ /^[0-9]/ ' 2>&1 | sed -n '2,2p'` elif [ $ -eq 3 ] then if [ $ = "OEL" ] then SWAP_SIZE=$ SWAP_FREE=$ DIRTY_SIZE=$ else CACHE_SIZE=$ SWAP_SIZE=$ SWAP_FREE=$ DIRTY_SIZE=$ fi PDFLUSH_THREAD=`ps -ef | grep -v grep | grep kworker | wc -l` CONTEXT_SWITCH=`sar -w 1 1 | awk '$1 ~ /^[0-9]/ ' 2>&1 | sed -n '2,2p'` fi MEM_USIZE=`echo "(($ - $ - $) * 100) / $" | bc` SWAP_USE=`echo "$ - $" | bc` EXPR1=`echo "$ * 100" | bc` EXPR2=`echo "scale=2; $ / $" | bc` export EXPR_DIFF1=`echo "scale=3; $ >= $" | bc` export EXPR_DIFF2=`echo "scale=3; $ >= $" | bc` OPEN_FILE=`sudo /usr/sbin/lsof | wc -l` RUN_PROC=`ps -ef | wc -l` RUN_THREAD=`ps -eL | wc -l` echo echo "$(date) / [ OS Version ] : $ / `uname -r`" echo "$(date) / [ CPU Usage ] : $ %" echo "$(date) / [ Real Memory Usage ] : $ %" echo "$(date) / [ Root Filesystem Usage ] : $" echo "$(date) / [ Total Memory ] : $ KB" echo "$(date) / [ Free Memory ] : $ KB" echo "$(date) / [ Page Cache ] : $ KB" echo "$(date) / [ Dirty Page ] : $ KB" echo "$(date) / [ Disk Flush Thread ] : $" echo "$(date) / [ Dirty Ratio LIMIT ] : $%" echo "$(date) / [ Dirty Ratio Status ] : $ / 100%" echo "$(date) / [ Swap Memory Status ] : $ KB / $ KB" echo "$(date) / [ Open File Count ] : $" echo "$(date) / [ Process Total Count ] : $" echo "$(date) / [ Thread Total Count ] : $" echo "$(date) / [ CPU Context Switch ] : $" echo "$(date) / [ System Loadaverage ] : $ ($ Core System)" echo "$(date) / [ Network Reassembles Failed ] : `netstat -s | grep -i 'reassembles failed'`" if [ $ -eq 1 ] then echo "$(date) / [ Dirty Page Status ] : CRITICAL" echo echo "$(date) / [ Operations Notice ] : Kernel will block all write operations !!!" elif [ $ -eq 1 ] then echo "$(date) / [ Dirty Page Status ] : WARNING" echo else echo "$(date) / [ Dirty Page Status ] : NORMAL" echo fi if [ $ -eq 1 ] then echo "[ Loadaverage Notice ] : Latency time of all process increased !!!" echo fi for STAT in `netstat -na | grep tcp | awk '' | sort -u` do echo "$(date) / $ - `netstat -na | awk '$6 ~ /^'"$STAT"'$/ ' | wc -l`" done echo for LIST in `ip addr | grep -w mtu | cut -d ":" -f 2 | egrep -v 'lo|inet|virbr|sit'`; do echo "$ - `ethtool $ | egrep 'Link detected'`" && echo; done | grep yes | awk '' | xargs -i{} netstat -n -I={} echo |
'System Story > CentOS 5,6' 카테고리의 다른 글
Linux Disk 성능 측정 (0) | 2015.07.14 |
---|---|
Bash Shift 연산 (0) | 2015.04.01 |
Yum을 통한 RPM Package Downgrade 또는 Download (0) | 2015.02.06 |
[정보] Redhat RHCE 모의 테스트 (5) | 2015.02.02 |
ext3 ->ext4 전환 마이그레이션 수행 (0) | 2014.12.15 |