대부분의 프로세스는 부모프로세스가 종료되면 자식프로세스들은 자동종료됨. 부모프로세스가 종료되었음에도 남아있는 자식프로세스를 좀비프로세스라고 하며, 시스템이 느려지는 원인이 됨. 대부분의 좀비 프로세스는 init 프로세스에 의해 관리되며, kill 명령으로 강제종료 시켜도 무방함.
표출 데이터 : 세 번째 줄
CPU의 사용 및 실행 상태를 출력. Cpu(s): 0.2%us, 0.1%sy, 0.0%ni, 99.8%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu(s): 0.2%us : 사용자가 실행시킨 프로세스들의 CPU 사용율.
0.1%sy : 시스템에서 사용하는 프로세스들의 CPU 사용율.
0.0%ni : noce 정책에 의해 사용되고 있는 CPU 사용율.
99.8%id : 사용되지 않고 남은 CPU 사용율.
0.0%wa : 입출력 대기상태의 CPU 사용율.
0.0%hi : IRQs에 사용된 CPU.
0.0%si : softIRQs에 사용된 CPU.
0.0%st : 다른 인스턴스 실행에 주어진 time, steal 값
표출 데이터 : 네 번째 줄
메모리 사용 상태 출력. Mem: 16291780k total, 16078316k used, 213464k free, 220104k buffers
운영중인 시스템이 리눅스에서 작동중인데 자꾸 알 수 없이 프로세스가 죽는 등의 문제가 있었다. 지금은 해결 했지만, 서버 컴퓨터의 상태를 확인하는데 삽질을 많이 했었고, 또 이런 일이 발생한다면, 구글링 없이 바로 찾아볼 수 있도록 기록 해 본다. 사실 이해를 100% 한것도 아니고, 어설픈 번역이라 누군가에게 도움이 될지는 모르겠다.
이 내용은 넷플릭스의 60초안에 리눅스 퍼포먼스 상태 파악하기라는 글의 각색 및 번역이다. 원문보기
리눅스 서버의 성능 이슈로 인해 원격으로 접속했을 때 먼저 체크해 봐야 할 사항.
리눅스는 AWS EC2를 사용하며, 서버를 모니터링하고 성능을 체크하는데 클라우드 전체를 모니터링하는 Atlas, 하나의 인스턴스를 확인하는 Vector 등의 툴을 사용한다. 이 툴을 사용하면 대부분의 이슈는 해결 가능하지만, 가끔 인스턴스에 접속하여 성능을 체크해야할 때가 있다.
첫 60초 요약
1분안에 표준적인 리눅스 환경에서 CLI를 이용하여 어떤 것들을 확인할지에 대한 순서 요약이다. 60초 안에 다음 10개 명령어를 실행하여 시스템 리소스 사용 및 실행 프로세스에 대한 높은 수준의 방안을 찾을 수 있음. 해석하기 쉬운 오류와 포화지표를 찾은 다음 리소스 활용도를 찾음. 포화 상태는 리소스가 처리할 수 있는 것보다 더 많은 부하를 가지고 있으며 요청 대기열의 길이 또는 대기 시간으로 확인 가능할 수 있음.
uptime
dmseg | tail
vmstat 1
mpstat -P ALL 1
pidstat 1
iostat -xz 1
free -m
sar -n DEV 1
sar -n TCP,ETCP 1
top
일부 명령어는 sysstat package를 설치해야 함. 이 측정 방법은 USE Method 라고 불리는 병목현상이 생기는 위치를 찾는 방법의 일부임. USE는 CPU, memory, disk 등의 모든 자원에 대해서 사용율, 포화도 및 오류 메트릭을 측정하는 방법임.
아래에서는 프로덕션 시스템의 예와 함께 이 명령어들을 요약이며, 명령어데 대한 자세한 설명은 해당 메뉴얼을 참고해야함.
uptime은 현재 대기중인 프로세스가 얼마나 있는지를 나타내는 load average 값을 확인하는 가장 쉬운 방법임. Linux 시스템에서 이러한 숫자에는 CPU에서 실행하려는 프로세스와 무중단 I/O(일반적으로 디스크 IO)에서 차단 된 프로세스가 포함됨. 이는 얼마나 많은 리소스가 사용되는지 확인할 수 있지만, 다른 도구 없이는 제대로 이해할 수 없음.
간단하게 살펴 보자면, 세 개의 숫자는 1, 5, 15분의 load average임. 세 개의 숫자는 시간이 지남에 따라 부하가 어떻게 변하는 지에 대한 부하를 알 수 있음. 예를 들어 문제가 있는 서버를 확인하라는 요청을 받았는데 1분 값이 15분 값보다 낮은 경우 너무 늦게 시스템에 접근하여 문제를 놓쳤을 수 있음.
위의 예에서 load average는 1 분 값이 약 30이고 15분 값이 19정도 되는 것으로 볼 때 최근 상승한 것을 알 수 있음. 숫자가 이렇게 크다는 것은 CPU 사용량에 문제가 있을 것으로, vmstat 또는 mpstat은 이 순서에서 실행하여 확인 해야 함.
dmesg | tail
dmesg | tail
[1880957.563150] perl invoked oom-killer: gfp_mask=0x280da, order=0, oom_score_adj=0
[...]
[1880957.563400] Out of memory: Kill process 18694 (perl) score 246 or sacrifice child
[1880957.563408] Killed process 18694 (perl) total-vm:1972392kB, anon-rss:1953348kB, file-rss:0kB
[2320864.954447] TCP: Possible SYN flooding on port 7001. Dropping request. Check SNMP counters.
dmesg는 마지막 10개의 시스템 메세지를 확인 할 수 있는 명령임. 시스템 문제를 일으킬 수 있는 오류가 있을 수도 있음. 위 예제는 oom-killer(out of memory)와 TCP request가 드랍된 것을 알 수 있음. 항상 확인 할 가치가 있음.
가상 메모리 통계의 약자인 vmstat은 일반적으로 사용 가능한 명령임. 각 행에 주요 시스템 통계 요약을 출력함.
1초 요약을 출력하기 위해 vmstat에 1을 인수로 실행함. 출력의 첫 번째 행에서는 이전 두 번째 대신 부팅 이후 의 평균을 표시하는 열이 있음.
확인 할 열
r : CPU에서 실행 중이고 차례를 기다리는 프로세스의 수. CPU 자원의 포화(saturation)가 발생하는지 확인할 때 참고 할 수 있음. CPU보다 큰 r 값은 포화상태임.
free : free memory를 kb 단위로 출력. free memory가 너무 자리수가 많을 경우 충분한 공간이 있음을 의미. free -m을 이용하면 좀 더 읽기 편함.
si, so : swap-in과 swap-out에 대한 값으로 0이 아니라면 시스템에 메모리가 부족한 것임.
us, sy, id, wa, st : 모든 CPU의 평균적인 CPU time을 측정 가능. 각각 user time, system time(kernel), idle, wait I/O, stolen time(가상 CPU를 서비스 하는 동안 실제 CPU를 차지한 시간을 의미) 순임.
CPU 시간 분석은 사용자 + 시스템 시간을 추가하여 CPU가 사용 중인지 확인함. 일정한 수준의 대기 I/O는 디스크 병목 현상을 의미. 대기중인 디스크 IO를 기다리는 작업이 차단되기 때문에 CPU가 유휴 상태임.
IO 처리에는 시스템 시간이 필요함. 20% 이상의 높은 시스템 시간 평균은 더 자세히 살펴 보는 것이 권장됨. 아마 커널이 IO를 비효율적으로 처리하고 있을 수 있음.
r/s, w/s rkB/s, wkB/s : 장치에 전달 된 읽기, 쓰기, 읽기 속도 및 쓰기속도임. 어떤 작업이 많이 들어오는지 확인 할 수 있음. 성능 문제는 단순히 과도한 로드(읽기나 쓰기)가 적용되었기 때문일 수 있음.
await : IO 처리 평균 시간을 밀리초로 표현한 값. 어플리케이션의 IO 요청이 queue에 있는 시간과 서비스 되는 시간을 모두 포함한 시간임(어플리케이션의 읽기 쓰기 소요시간). 일반적인 장치의 요청 처리 시간보다 길면 장치 포화 또는 장치 문제를 의미하게 됨.
avgpu-sz : 장치에 발행 된 평균 요청수. 1보다 큰 값은 포화의 증거임.
%util : 장치 사용율. 장치마다 다르지만 60% 보다 큰 값은 성능 저하를 의미함.
성능이 좋지 않은 디스크 IO는 어플리케이션 문제가 아닐 수 도 있음. 만은 기술이 일반적으로 IO를 비동기식으로 수행하는데 읽기를 위한 미리 읽기, 쓰기를 위한 버퍼링으로 지연 될 수도 있음.
위의 값들이 0에 가까워 지면 안됨. 이는 곳 높은 Disk I/O가 발생하고 있음을 의미함. (iostat으로 확인 가능함) 위는 각각 59MB, 541MB로 괜찮은 정도임.
'-/+ buffers/cache'는 사용중인 메모리와 여유 메모리 양을 의미함. 리눅스는 빠르게 어플리케이션 메모리가 다시 할당될 수 있도록 캐시메모리를 사용함. 따라서 캐시메모리도 여유 메모리에 포함되어 보여야 함. 캐시메모리 또한 여유 메모리로 계산하지 않는 착각으로 인해서 linuxatemyram란 싸이트도 있음 ㅋ.
sar -n DEV 1
sar -n DEV 1
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
12:16:48 AM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
12:16:49 AM eth0 18763.00 5032.00 20686.42 478.30 0.00 0.00 0.00 0.00
12:16:49 AM lo 14.00 14.00 1.36 1.36 0.00 0.00 0.00 0.00
12:16:49 AM docker0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
12:16:49 AM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
12:16:50 AM eth0 19763.00 5101.00 21999.10 482.56 0.00 0.00 0.00 0.00
12:16:50 AM lo 20.00 20.00 3.25 3.25 0.00 0.00 0.00 0.00
12:16:50 AM docker0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
^C
rzkB/s, txkB/s를 측정할 수 있음. eth0의 수신량이 약 22Mbytes/s(21999.10rxkB/s)임. 이는 176Mbit/s 인데 한계인 1Gbit/s에 못 미치는 값임. 위 값중 %ifutil은 nicstat으로도 측정 가능한 네트워크 장치 사용율임. 그러나 nicstat이라 위 예나 정확한 값을 가져오긴 어려움.
sar -n TCP,ETCP 1
sar -n TCP,ETCP 1
Linux 3.13.0-49-generic (titanclusters-xxxxx) 07/14/2015 _x86_64_ (32 CPU)
12:17:19 AM active/s passive/s iseg/s oseg/s
12:17:20 AM 1.00 0.00 10233.00 18846.00
12:17:19 AM atmptf/s estres/s retrans/s isegerr/s orsts/s
12:17:20 AM 0.00 0.00 0.00 0.00 0.00
12:17:20 AM active/s passive/s iseg/s oseg/s
12:17:21 AM 1.00 0.00 8359.00 6039.00
12:17:20 AM atmptf/s estres/s retrans/s isegerr/s orsts/s
12:17:21 AM 0.00 0.00 0.00 0.00 0.00
^C
TCP 측정 요약을 보여줌.
active/s : 로컬에서 외부로 요청한 초당 TCP 커넥션 수를 보여줌.
passive/s : 원격으로 요청한 초당 TCP 커넥션 수를 보여줌.
retrans/s : 초장 TCP 재연결 수를 보여줌.
active와 passive 수를 보는 것은 서버의 부하를 대략적으로 측정하는데 편함. localhost 끼리의 연결을 제외하면, 액티브를 아웃 바운드로, 패시브를 인 바운드로 보면 됨. retransmits는 네트워크나 서버의 이슈가 있음 의미하는데 신뢰성이 떨어지는 네트워크 환경이나, 서버가 처리할 수 있는 용량 이상의 커넥션이 붙어서 패킷이 드랍되는 것을 의미함. 위 예제는 초당 하나의 TCP 연결이 들어옴을 알 수 있음.
top
top
top - 00:15:40 up 21:56, 1 user, load average: 31.09, 29.87, 29.92
Tasks: 871 total, 1 running, 868 sleeping, 0 stopped, 2 zombie
%Cpu(s): 96.8 us, 0.4 sy, 0.0 ni, 2.7 id, 0.1 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem: 25190241+total, 24921688 used, 22698073+free, 60448 buffers
KiB Swap: 0 total, 0 used, 0 free. 554208 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
20248 root 20 0 0.227t 0.012t 18748 S 3090 5.2 29812:58 java
4213 root 20 0 2722544 64640 44232 S 23.5 0.0 233:35.37 mesos-slave
66128 titancl+ 20 0 24344 2332 1172 R 1.0 0.0 0:00.07 top
5235 root 20 0 38.227g 547004 49996 S 0.7 0.2 2:02.74 java
4299 root 20 0 20.015g 2.682g 16836 S 0.3 1.1 33:14.42 java
1 root 20 0 33620 2920 1496 S 0.0 0.0 0:03.82 init
2 root 20 0 0 0 0 S 0.0 0.0 0:00.02 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:05.35 ksoftirqd/0
5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
6 root 20 0 0 0 0 S 0.0 0.0 0:06.94 kworker/u256:0
8 root 20 0 0 0 0 S 0.0 0.0 2:38.05 rcu_sched
top 명령어는 전반적으로 값을 확인하기 쉽고 위에서 체크한 다양한 측정치를 쉽게 볼 수 있음. 화면지 지속적으로 바뀌기 때문에 패턴을 찾기 어려운 단점으로 다음 단축키도 사용 가능함.
프로그램을 실행시키면 운영체제로부터 프로그램이 동작하는 데 필요한 자원을 할당받아 동작을 시작한다. 이처럼 실행 상태에 들어간 프로그램을 프로세스라고 한다. 프로세스의 동작은 CPU가 그 프로세스의 명령들을 실행하는 것이다. 이때 CPU도 기억장치나 입출력장치와 마찬가지로 프로세스가 동작하는 데 필요한 자원이다. 운영체제는 실행할 준비가 된 프로세스들이 적절히 CPU를 배정받아 효율적으로 작업을 처리할 수 있도록 관리해야 한다. 운영체제의 핵심적인 구성 요소 중 하나인 프로세스에 대한 기본적인 이해와 함께 쓰레드의 개념을 학습하고, 스케줄링의 정책에 대하여 살펴보자.
학습 목표
프로세스의 개념을 설명할 수 있다.
프로세스와 쓰레드의 관계를 설명할 수 있다.
스케줄링의 필요성과 정책을 설명할 수 있다.
요약
프로세스는 실행 중인 프로그램을 의미하며, CPU, 메모리, 입출력장치, 파일 등 실행에 필요한 자원이 할당된다.
프로세스는 생성, 준비, 실행, 대기, 종료의 다섯 상태 중 하나로 존재하며, CPU의 스케줄링, I/O 대기 등에 따라 준비, 실행, 대기 등으로 상태가 변화되며 동작한다.
프로세스 제어 블록(PCB)은 프로세스를 명시해 주는 다양한 내용을 포함하고 있다.
쓰레드란 하나의 프로그램 내에서 제어의 단일 순차적 흐름으로 정의되며, 하나의 쓰레드 내에서는 하나의 실행점만이 존재하며, 각 쓰레드는 수행에 필요한 최소한의 정보만으로 구성된다.
하나의 프로세스 내에는 하나 이상의 쓰레드가 있을 수 있어 쓰레드를 생성하여 프로세스 내에서 다중처리를 할 수 있다.
프로세스의 스케줄링을 위해 상위단계, 하위단계 및 중간단계 스케줄러가 사용된다.
스케줄링 기법 중 어떤 프로세스도 CPU를 빼앗길 수 없는 경우를 비선점이라 하며, 그렇지 않으면 선점이라고 한다.
프로세스 개요
프로세스
프로세스는 실행 중인 프로그램을 의미
프로그램 : 동작을 하지 않는 정적이며 수정적인 개체.
프로세스 : 동작을 하는 능동적인 개체.
프로세스에는 실행을 위해 필요한 컴퓨터의 자원이 할당됨.
CPU, 주기억장치, 파일, 입출력 장치 등.
프로세스의 동작은 CPU가 그 프로세스의 명령들을 실행하는 것.
운영체제는 프로세스들을 생성시키고 종료시키기 위한 다양한 작업과 프로세스들을 실행시키기 위한 스케쥴링 작업을 처리.
프로세스의 상태 변화
프로세스의 5-상태
생성 : 처름 프로세스 생성 상태
준비 : CPU 할당을 기자리는 상태
실행 : 프로세스가 처리되는 상태
대기 : 특정 자원의 할당이나 입출력 작업의 종료 때까지 보류되는 상태
종료 : 모든 처리가 완료된 상태
프로세스의 상태 전이
생성 -> 준비 : 프로세스 생성이 완료된 경우.
준비 -> 실행 : 스케쥴러에 의해 선택된 경우, (Dispatch)
실행 -> 준비 : 할당시간 만료 또는 보다 높은 우선순위의 프로세스가 오는 경우.
실행 -> 대기 : 페이지 교환, 입출력 등의 작업이 필요한 경우.
대기 -> 준비 : 페이지 교환, 입풀력 등의 작업이 완료된 경우.
실행 -> 종료 : 프로세스를 성공적으로 긑마친 경우.
프로세스 제어 블록
프로세스 제어 플록 (PCB)
프로세스 관리를 위해 해당 프로세스의 정보를 보관.
프로세스 진행에 따라 정보의 변경도 발생.
프로세스 제어 블록 내 주요 정보
프로세스 상태 : 프로세스의 현재 상태.
프로세스 번호 (PID) : 프로세스의 구분 기준.
프로그램 카운터 : 프로세스 수행을 위한 다음 명령의 주소.
레지스터 : 실행상태에서 다른 상태로 전이되는 경우 CPU의 레지스터 정보를 이곳에 저장.
메모리 : 프로세스 저장 주소, 가상주소와 실주소의 사상 정보, 메모리 경계 정보 등.
프로세스 생성과 종료
부모 프로세스와 자식 프로세스
부모 프로세스 : 프로세스 생성 시스템 호출을 이용하여 다른 프로세스를 생성한 프로세스.
자식 프로세스 : 부모 프로세스가 생성한 새로운 프로세스.
프로세스 생성
프로세스의 이름(PID)이 지정되고 프로세스 제어블록이 만들어지며, 준비 큐에 삽입.
부모 프로세스와 자식 프로세스 사이의 상호작용을 위해 자원을 공유할 수 있음.
프로세스의 종료
처리할 작업을 마치면 실행 결과를 부모 프로세스에 되돌려 주며 종료.
연속적 종료 : 부모 프로세스가 종료되면 그 자식 프로세스들도 모두 종료.
프로세스 간의 관계
독립적 프로세스
실행 중인 다른 프로세스의 영향을 받지도 않고 주지도 않는 프로세스.
프로세스의 상태는 다른 프로세스와 공유되지 않음.
프로세스의 실행은 결정적 : 실행 결과는 입력에 의해서만 결정됨.
프로세스의 실행은 재생 가능 : 실행 결과는 같은 입력에 대해 항상 동일함.
타 프로세스와 무관하게 중단되거나 재시작될 수 있음
유기적 프로세스
실행 중인 다른 프로세스와 영향을 주고 받으며 동작하는 프로세스
프로세스의 상태는 다른 프로세스와 공유됨.
프로세스의 실행은 비결정적 : 실행 결과는 실행 순서에 좌우됨.
프로세스의 실행은 재생 불가능 : 실행결과는 같은 입력에 대해 항상 동일하지는 않음.
쓰레드
전통적인 프로세스
처리의 기본 단위.
자원 소유의 단위 + 디스패칭의 단위.
단일 프로세스 내에서는 동시 처리 불가능.
스레드
프로세스 내에서의 다중처리를 위해 제안된 개념.
프로세스는 자원 소유의 단위로, 쓰레드는 디스패칭의 단위로 구분.
하나의 프로세스 내에는 하나 이상의 쓰레드가 존재.
하나의 쓰레드 내에서는 하나의 실행점만 존재
쓰레드는 실행에 필요한 최소한의 정보만을 가지며, 자신이 속해 있는 프로세스의 실행환경을 공유함.
다중 쓰레드
멀티 CPU 혹은 멀티 코어 시스템에서는 병렬 처리 가능.
처리 속도 별로 쓰레드가 나워진 경우 효율적인 처리 가능.
스케쥴링
스케쥴링의 단계
상위단계 스케쥴링
시스템에 들어오는 작업들을 선택하여 프로세스를 생성한 후 프로세스 준비 큐에 전달하는 역할.
선택 기준 : 시스템의 자원을 효율적으로 이용할 수 있도록 하는 것.
입출력 중심 작업과 연산 중심 작업을 균형있게 선택
하위단계 스케쥴링
사용 가능한 CPU를 준비상태의 어느 프로세스에 배당할지를 결정.
이 결정을 통하여 CPU를 배당 받은 프로세스는 결국 실행상태가 되어 프로세스가 처리됨.
수행 주체 : Dispatcher
중간단계 스케쥴링
프로세스를 일시적으로 메모리에서 제거하여 중지 시키거나 다시 활성화 시켜서 시스템에 대한 단기적인 부하를 조절.
스케쥴링 정책
스케쥴링의 기본 목표
공정성 : 모든 프로세스가 적정 수준에서 CPU 작업을 할 수 있게 함.
균형 : 시스템의 자원들이 충분히 활용될 수 있게 함.
일괄처리 운영체제의 스케쥴링 목표
처리량의 극대화.
반환시간의 최소화.
CPU 활용의 극대화.
대화형 운영체제의 스케쥴링 목표
빠른 응답 시간.
과대한 대기 방지.
실시간 운영체제의 스케쥴링 목표
처리 기한을 맞춤.
선점 스케쥴링(Preemptive) 정책
진행 중인 프로세스에 인터럽트를 걸고 다른 프로세스에 CPU를 할당하는 스케쥴링 전략.
높은 우선순위의 프로세스를 긴급하게 처리하는 경우 유용.
대화식 시분할 시스템에서 빠른 응답시간을 유지하는데 유용.
문맥 교환에 따른 오버헤드 발생.
문맥(Context) : CPU의 모든 레지스터와 기타 운영체제에 따라 요구되는 프로세스의 상태.
문맥 교환 (Context Switching)
CPU가 현재 샐행하고 있는 프로세스의 문맥을 PCB에 저장하고, 다음 프로세스의 PCB로부터 문맥을 복원하는 작업.
운영체제는 문맥 교환이 매우 빠르게 실행되도록 만들어져야 함.
비선점 스케쥴링(Nonpreemptive) 정책
프로세스가 CPU를 할당받아 실행이 시작되면 작업 자체가 I/O 인터럽트를 걸거나 작업을 종료할 때까지 실행상태에 있게 됨.