시스템 성능 엔지니어링 Ch.4 — 관측 가능성 도구와 모니터링 S/W의 본질
커널 카운터, /proc, /sys를 따라가며 vmstat부터 Prometheus Exporter까지 모니터링 도구가 같은 데이터를 읽는다는 점을 정리한다.
시리즈 · DevOps 서적5 / 5
- 서버/인프라를 지탱하는 기술 Ch.1 — 다중화와 부하분산의 기본
- 서버/인프라를 지탱하는 기술 Ch.2 — 리버스 프록시를 도입하는 이유
- 서버/인프라를 지탱하는 기술 Ch.4 — 부하 그리고 Load Average
- 시스템 성능 엔지니어링 Ch.1~2 — 소개와 방법론
- 시스템 성능 엔지니어링 Ch.4 — 관측 가능성 도구와 모니터링 S/W의 본질
『시스템 성능 엔지니어링』 4장 “관측 가능성 도구”를 읽고 정리한 내용이다. 읽고 나니 모니터링 소프트웨어의 본질은 결국 커널이 관리하는 카운터를 읽어 오는 것이라는 생각이 들었다.
고정 카운터
- 커널은 시스템 통계를 제공하기 위해 다양한 카운터를 관리한다.
- 주로 이벤트가 발생할 때마다 증가하는 정수 값으로 구현된다. 네트워크 패킷 수, 처리된 디스크 I/O 수, 발생한 인터럽트 수 등이 그 예다.
- 값은 누적된다. 서로 다른 시점에 두 번 읽어 그 차이를 계산하면 초당 이벤트 수 같은 비율을 구할 수 있다.
- 커널이 항상 관리하고 있으므로 사실상 공짜 지표다. 유일한 오버헤드는 값을 사용자 공간으로 읽어 오는 것뿐이고, 무시해도 될 정도다.
- 모니터링 S/W는 이 카운터를 Metric으로 노출한다.
시스템 전반
vmstat은 시스템 전반의 가상 메모리와 물리 메모리 통계를 보여준다. 첫 줄은 부팅 이후의 평균값이고, 이후 줄은 현재 값이다.
$ vmstat 1 3
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
3 0 1134592 252772 816 2093552 1 3 30 75 3 4 11 4 83 0 2
0 0 1134592 297128 816 2085824 0 0 0 61 3050 5350 8 4 88 0 0
0 0 1134592 294608 816 2085828 0 0 0 1062 855 897 4 2 93 0 0
mpstat은 CPU별 사용률을 보여준다.
$ mpstat
07:31:41 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
07:31:41 PM all 10.72 0.02 2.94 0.15 0.44 0.45 1.95 0.00 0.00 83.33
iostat은 디스크별 I/O 통계를 블록 장치 인터페이스 기준으로 보여준다.
$ iostat
avg-cpu: %user %nice %system %iowait %steal %idle
10.72 0.02 3.83 0.15 1.95 83.33
Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
nvme0n1 14.55 46.74 150.61 0.00 193655488 623936546 0
nvme1n1 0.23 13.32 1.13 0.00 55163620 4670311 0
sar는 다양한 통계를 제공하며, 과거 기록을 저장해 두었다가 보고할 수도 있다.
프로세스별
ps: 프로세스 상태top: CPU 사용률이나 다른 통계 기준으로 정렬된 프로세스 목록pmap: 프로세스의 메모리 세그먼트와 사용 통계
에이전트
- Prometheus의 Exporter처럼, 에이전트를 실행해 커널과 애플리케이션의 지표를 수집한다.
- MySQL, 웹 서버 등 특정 애플리케이션을 모니터링하는 에이전트는 시스템 카운터만으로는 알 수 없는 상세한 애플리케이션 요청 지표를 제공한다.
- 시스템 지표에 한해서는, 본질적으로
vmstat,iostat같은 시스템 도구가 제공하는 정보와 동일하다.
/proc
/proc은 커널 통계를 제공하는 파일 시스템 인터페이스다. 프로세스 ID마다 디렉토리가 있고, 그 안에 프로세스별 정보와 통계가 담긴 파일들이 있다. 그 외에 시스템 전반에 대한 정보를 제공하는 파일들도 있다.
$ ls -al /proc/
total 4
dr-xr-xr-x. 301 root root 0 Feb 5 20:43 .
drwxr-xr-x. 21 root root 4096 Mar 10 16:10 ..
dr-xr-xr-x. 9 root root 0 Feb 5 20:43 1
dr-xr-xr-x. 9 root root 0 Mar 20 14:02 11
dr-xr-xr-x. 9 root root 0 Mar 20 14:02 13
dr-xr-xr-x. 9 root root 0 Feb 5 21:29 13724
dr-xr-xr-x. 9 root root 0 Feb 5 21:29 13818
파일로 관리된다면 디스크에 저장되는 것 아닌가 하는 궁금증이 생길 수 있다. /proc의 파일들은 파일처럼 보이지만 실제 디스크 파일이 아니다. 커널이 만든 가상 파일 시스템(procfs)이며, 내용은 커널이 동적으로 생성하고 메모리에만 존재한다. 대부분 Read-Only이고 통계를 수집하는 데 사용된다.

limits: 해당 프로세스에 부과된 자원 제한cgroup: 프로세스가 어떤 cgroup에 속해 있는지
$ cat /proc/13724/limits
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size unlimited unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 29935 29935 processes
Max open files 524288 524288 files
Max locked memory 8388608 8388608 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 29935 29935 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
top은 /proc을 어떻게 읽는가
top이 프로세스별 통계를 /proc에서 읽는 과정을 strace로 트레이싱하면 다음과 같다.
stat("/proc/14704", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
open("/proc/14704/stat", O_RDONLY) = 4
read(4, "14704 (sshd) S 1 ...
close(4)
top은 시스템의 모든 활성 프로세스에 대해 이 작업을 반복하므로, 프로세스가 많을수록 오버헤드가 커진다.
CPU 통계 정확도
- 시스템 전반의 CPU 사용률 통계는
/proc/stat파일에서 확인할 수 있다. - 정확도는 커널 설정에 따라 다르다.
CONFIG_TICK_CPU_ACCOUNTING에서는 클럭 틱 단위로 측정한다. - 보통
CONFIG_HZ=250이 사용되며, 커널은 1초에 250번의 타이머 인터럽트를 발생시킨다. 1초를 250으로 나누면 클럭 틱 하나의 길이는 4ms이다.
/sys
/sys에 마운트되는 sysfs 파일 시스템이다.- 원래 장치 드라이버 통계를 제공하기 위해 설계되었고, 이후 다양한 통계 유형을 포함하도록 확장되었다.
- 커널 객체(device, driver, bus 등)를 계층 구조로 노출하는 인터페이스다.
/proc이 프로세스와 시스템 통계 중심이라면,/sys는 하드웨어와 커널 객체의 구조 중심이다.
예를 들어 CPU의 캐시 용량을 확인할 수 있다. 다음은 CPU 0의 1단계 캐시가 32K임을 보여준다.
$ cat /sys/devices/system/cpu/cpu0/cache/index0/size
32K