Load Average
1. Load Average의 정의
# Load Average : 프로세스 상태 중 R, D 상태에 있는 프로세스 개수의 1분, 5분, 15분 마다의 평균 값
# Load Average가 높다면 많은 수의 프로세스가 실행 중이거나, I/O 등을 처리하기 위한 대기상태에 있다는 것이며,
# 낮다면 적은 수의 프로세스가 실행 중이거나 대기 중이라는 의미
# Load Average값으로만 부하가 일어나는지 확인하기는 어렵다.
2. CPU Bound, I/O Bound
# 부하를 일으키는 프로세스는 크게 두 가지로 CPU Bound 프로세스와 I/O Bound 프로세스이다.
# 부하원인 확인 간 CPU 부하인지, disk I/O 부하인지를 확인해야함.
# CPU Bound 테스트
$ vi cpu.py
#!/usr/bin/python
test = 0
while True:
test = test + 1
$ chmod 755 cpu.py && ./cpu.py
$ uptime
21:43:02 up 77 days, 11:46, 1 user, load average: 0.49, 0.13, 0.04
21:43:09 up 77 days, 11:46, 1 user, load average: 0.57, 0.16, 0.05
21:43:16 up 77 days, 11:46, 1 user, load average: 0.60, 0.17, 0.06
21:43:24 up 77 days, 11:46, 1 user, load average: 0.66, 0.20, 0.07
# uptime으로 부하가 일어나는 것을 확인할 수 있다.
# I/O Bound 테스트
$ vi io.py
#!/usr/bin/python
while True:
f = open("./io_test.txt", 'w')
f.write("TEST")
f.close()
$ chmod 755 io.py && ./io.py
$ uptime
21:42:43 up 77 days, 11:46, 1 user, load average: 0.28, 0.07, 0.02
21:42:47 up 77 days, 11:46, 1 user, load average: 0.34, 0.08, 0.03
21:42:48 up 77 days, 11:46, 1 user, load average: 0.34, 0.08, 0.03
21:42:48 up 77 days, 11:46, 1 user, load average: 0.39, 0.10, 0.03
# uptime으로 CPU Bound와 같이 부하가 일어나는 것을 확인할 수 있다.
# 둘다 부하량은 비슷하지만 발생원인은 서로 다르다. CPU 부하와 disk I/O 부하이다.
# 부하원인 파악 시 어떤 부하인지르 알아야 해결할 수가 있다.
2.1 vmstat으로 부하정체 확인하기
# CPU Bound 테스트 스크립트를 실행시켜 시스템의 상태를 측정하기
$ ./cpu.py
$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 416096 0 399996 0 0 0 2 3 0 0 0 100 0 0
1 0 0 416096 0 399996 0 0 0 0 381 293 50 0 50 0 0
1 0 0 416096 0 399996 0 0 0 0 371 264 50 0 50 0 0
# I/O Bound 테스트 스크립트 실행
$ ./io.py
$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 1 0 416096 0 399996 0 0 0 0 377 276 50 0 50 0 0
0 1 0 416096 0 399996 0 0 0 0 385 284 50 0 50 0 0
0 1 0 416096 0 399996 0 0 0 0 429 337 50 0 50 0 0
# 두 출력 값 사이의 차이점은 "r", "b" 열의 값이다.
# "r"은 실행되기를 기다리거나 현재 실행되고 있는 프로세스의 개수
# "b"는 I/O를 위해 대기열에 있는 프로세스의 개수
# 두 스크립트를 돌려보면 비슷한 수준의 Load Average가 나오지만 vmstat으로 확인해보면
# CPU인지, disk I/O인지 확인이 가능하다.
# "b" 값이 낮다고 해도 지속적으로 I/O를 일으키는 프로세스가 존재하는 것만으로 시스템에 문제를 일으킬 수 있다.
Memory
1. 메모리 사용량 확인하기
$ free -m
total used free shared buff/cache available
Mem: 957 117 720 0 118 713
Swap: 0 0 0
# total : 시스템에 설치되어 있는 전체 메모리의 양
# used : 시스템에서 사용하고 있는 메모리의 양
# free : 시스템에서 아직 사용하고 있지 않는 메모리의 양
# shared : 프로세스 사이에 공유하고 있는 메모리의 양
# buffer : 버퍼캐시, 버퍼 용도로 사용하고 있는 메모리의 양, 시스템 성능 향상을 위해 커널에서 사용하고 있는 영역
# cache : 페이지캐시, 캐시 영역에 있는 메모리의 양, I/O 관련 작업을 빠르게 진행하기 위해 커널에서 사용하고 있는 영역
2. buffers와 cached 영역
# 커널은 한번 읽은 디스크의 내용을 메모리에 저장해 두어 동일한 내용을 읽고자 하면 디스크로 요청하지 않고
# 메모리로 요청하게 된다. 이런 캐싱 기능을 통해서 커널은 다수의 디스크 요청을 좀 더 빠르게 처리할 수 있다.
# 버퍼캐시 = 파일 시스템의 메타데이터를 담고 있는 블록을 저장하고 있는 캐시
# 페이지 캐시 = 파일의 내용을 저장하고 있는 캐시
# 시간의 흐름에 따른 메모리 사용 영역의 변화
A.
--------------------ㅣ----------
가용영역 사용영역
B.
--------ㅣ-------------ㅣ-------
가용영역 캐시영역 사용영역
C.
---ㅣ--------ㅣ-----------------
가용 캐시 사용영역
D.
---ㅣ----ㅣ---------------------
가용 캐시 사용영역
# 서버의 운영 기간이 길지 않을 때는 "A"번과 같은 메모리 사용현황을 볼 수 있다.
# 하지만 "B"와 같이 시간이 조금 지나면 커널은 가용역역 중 일부를 캐시영역으로 사용하게 된다.
# 시간이 흐를수록 "C"와 같이 애플리케이션에서 사용하게 되는 영역이 더 넓어진다.
# 하지만 "C", "D"와 같이 사용영역이 점점 더 커져서 cache 영역이 줄고 애플리케이션의 사용 영역이 늘어난다.
# 시간이 더 지나면 가용영역이 없어지게 되는 시점이 발생하게 되는데 이때부터 "swap"이라는 영역을
# 사용하게 되고 시스템의 성능이 줄어든다.
# 이처럼 buffers와 cached 영역은 시스템의 I/O 성능 향상을 위해서 커널이 사용하는 영역이다.
3. /proc/meminfo 읽기
$ sudo cat /proc/meminfo
MemTotal: 980016 kB
MemFree: 734780 kB
MemAvailable: 729004 kB
Buffers: 0 kB
Cached: 107072 kB
SwapCached: 0 kB
Active: 125900 kB
Inactive: 56744 kB
Active(anon): 69028 kB
Inactive(anon): 488 kB
Active(file): 56872 kB
Inactive(file): 56256 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 140 kB
Writeback: 0 kB
AnonPages: 75660 kB
Mapped: 102868 kB
Shmem: 492 kB
Slab: 32740 kB
SReclaimable: 17468 kB
SUnreclaim: 15272 kB
KernelStack: 2136 kB
PageTables: 6132 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 490008 kB
Committed_AS: 551044 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 0 kB
VmallocChunk: 0 kB
HardwareCorrupted: 0 kB
AnonHugePages: 0 kB
ShmemHugePages: 0 kB
ShmemPmdMapped: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 143336 kB
DirectMap2M: 876544 kB
DirectMap1G: 0 kB
# SwapCached : swap으로 빠진 메모리 영역 중 다시 메모리로 돌아온 영역을 의미
# Active(anon) : 페이지 캐시 영역을 제외 한 메모리 영역을 의미한다, 비교적 최근에
# 메모리 영역이 참조되어 swap 영역으로 이동되지 않을 메모리 영역을 의미한다.
# Inactive(anon) : Active와 같이 영역을 의미하지만, 비교적 참조된 지 오래되어 swap 영역으로
# 이동될 수 있는 메모리 영역을 의미한다.
# Active(file) : I/O 성능 향상을 위해 사용하는 영역을 의미, 비교적 최근까지 메모리 영역이
# 참조되어 swap 영역으로 이동되지 않을 메모리 영역
# Inactive(file) : I/O 성능 향상을 위해 사용하는 영역으로, 비교적 참조된 지 오래되어 swap 영역
# 으로 이동될 수 있는 메모리 영역이다.
# Dirty : I/O 성능 향상을 위해 커널이 캐시 목적으로 사용하는 영역 중 쓰기 작업이 이루어져서
# 실제 블록 디바이스의 블록에 씌어져야 할 영역을 의미한다.
# Slab : 메모리 영역 중 커널이 직접사용하는 영역, dentry cache/inode cache 등 커널이 사용하는 메모리 가 포함된다.
# SReclaimable : Slab 영역 중 재사용 될 수 있는 영역이다. 캐시 용도로 사용하는 메모리들이 주로 여기에 포함된다.
# 메모리 부족 현상이 일어나면 해제되어 프로세스에 할당될 수 있는 영역
# SUnreclaim : Slab 영역 중 재사용될 수 없는 영역, 커널이 현재 사용 중인 영역이며, 해제해서 다른용도로 재사용될 수 없다.
- slabtop 명령으로 정보확인 해보기
$ sudo slabtop -o
Active / Total Objects (% used) : 112409 / 140524 (80.0%)
Active / Total Slabs (% used) : 4968 / 4968 (100.0%)
Active / Total Caches (% used) : 72 / 101 (71.3%)
Active / Total Size (% used) : 24683.98K / 31749.73K (77.7%)
Minimum / Average / Maximum Object : 0.01K / 0.23K / 11.25K
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
27417 14117 51% 0.10K 703 39 2812K buffer_head
17934 12300 68% 0.19K 854 21 3416K dentry
14382 14382 100% 0.04K 141 102 564K Acpi-Namespace
10590 10590 100% 0.13K 353 30 1412K kernfs_node_cache
10439 10181 97% 0.60K 803 13 6424K inode_cache
# slab 영역 중 가장 많이 사용 되는 캐시가 dentry, inode_cache
# dentry : 파일에 자주 접근하고 디렉터리의 생성/삭제가 빈번한 시스템이라면 Slab 메모리가
# 높아질 수 으며, 그중 dentry, inode_cache가 높아질 수 있다.
# 또한, Slab 할당자는 free 명령에서 used로 포함되어 계산된다.
# 그래서 간혹 프로세스들이 사용하는 메모리 영역을 모두 더하고도 used와 맞지 않을 경우
# Slab 메모리에서 누수가 발생하는 것일 수도 있다.
# 참고) 서버의 프로세스들이 메모리를 사용하지 않을때 커널 관리용도의 프로세스들에게 cache 메모리를
# 할당하는 경우도 있다.
# 주로 dentry, inode_cache 영역에 캐시메모리를 할당한다.