본문 바로가기

DevOps

넷플릭스에서 리눅스 퍼포먼스 체크하기(in 60초)

원문 : https://medium.com/netflix-techblog/linux-performance-analysis-in-60-000-milliseconds-accc10403c55


항상 그렇듯이 서버에는 이상이 생길 수 있다. 만약 서버에 갑자기 이슈가 생기면 무엇부터 봐야할까?

 

넷플릭스에는 어마어마한 개수의 AWS EC2 리눅스 서버들을 가지고 있고 상당히 많은 수의 성능 체크 툴을 가지고 있다. 그 중에는 Atlas와 Vector도 포함된다.

 

> Atlas : Cloud-wide monitoring

> Vector : on-demand instance analysis

 

상기 2개의 모니터링 tool로 상당수의 이슈가 해결되지만 그럼에도 불구하고 서버에 로그인해서 리눅스 성능체크를 해야할 경우가 있다. 이런경우 넷플릭스에서는 아래와 같이 수행한다.

요약하자면

uptime
dmesg | tail
vmstat 1
mpstat -P ALL 1
pidstat 1
iostat -xz 1
free -m
sar -n DEV 1
sar -n TCP,ETCP 1
top

상기 10개의 standard linux tool을 사용하여 성능을 체크한다. 상기 command를 사용하면 60초 이내에 system resource 사용량과 running process들에 대한 정보를 얻을 수 있다.

 

상기 command들 중 몇가지는 sysstat package를 통해 설치되어야 사용가능하다. Command들을 사용하여 일련의 과정(USE method)을 수행하면 성능이 저하되는 병목지점을 찾을 수 있다.

 

USE Method는, 시스템을 평가하기 위한 활용도, 과부하, 오류에 대한 평가 방법론이다.

아래 이어지는 글들은 상용환경의 example들이다. 각각의 command에 대한 상세설명은 각 command의 manual을 확인하면 된다.

 

1. Uptime

$ uptime 
23:51:26 up 21:31, 1 user, load average: 30.02, 26.43, 19.02

uptime command는 load average를 빠르게 확인할 수 있다. 이 숫자들은 resource load로서 확인할 수 있으나 각 수치에 대한 분석은 하기 어려우므로 빠르게 보고 넘어가는편이 좋다. command의 맨 뒤 세 숫자는 각각 마지막 1분, 5분, 15분간의 cpu 평균 로드를 뜻한다. 이 숫자들을 통해 지난 시간동안의 로드 변화량을 추측할 수 있다.

 

예를 들어 이슈가 생겨 서버에 들어가 uptime command로 각 값에 대해 확인 했을 때 load 1min 값이 load 15min 값에 비해 낮다면 이슈를 확인하기에 너무 늦게 들어간 것이다.  

2. 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 | tail을 통해 마지막 10개의 시스템 메시지를 확인할 수 있다. 위 command 결과물을 보면 oom-killer과 TCP request에 대한 drop이 일어났음을 확인할 수 있다.

 

이 command는 꽤나 유용하기 때문에 반드시 짚고 넘어가자!

3. vmstat 1

$ 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
34  0    0 200889792  73708 591828    0    0     0     5    6   10 96  1  3  0  0
32  0    0 200889920  73708 591860    0    0     0   592 13284 4282 98  1  1  0  0
32  0    0 200890112  73708 591860    0    0     0     0 9501 2154 99  1  0  0  0
32  0    0 200889568  73712 591856    0    0     0    48 11900 2459 99  0  0  0  0
32  0    0 200890208  73712 591860    0    0     0     0 15898 4840 98  1  1  0  0
^C

vmstat은 프로세스, 메모리, 페이징, IO블럭, cpu활동에 대한 값을 나타낸다. vmstat과 변수 1을 함께 command를 날리면 1초 동안의 각 값에 대한 요약을 나타내게 된다. 

체크해야하는 값

- r : 실행가능한 프로세스 수 중 cpu 접근 대기중인 프로세스 개수. 만약 "r"의 값이 cpu개수보다 많다면 cpu자원이 포화상태인 것이다.

- free : 사용가능한 메모리 용량(kb). 만약 값이 매우 높다면 여유 메모리가 충분한 것이다.

- si, so : swap-in, swap-out 된 메모리 용량(kb). 만약 이 값이 0이 아니라면 메모리가 부족한 것이다.

- us, sy, id, wa, st : 모든 cpu의 평균값을 확인 할 수 있다.

4. mpstat -P ALL 1

$ mpstat -P ALL 1
Linux 3.13.0-49-generic (titanclusters-xxxxx)  07/14/2015  _x86_64_ (32 CPU)

07:38:49 PM  CPU   %usr  %nice   %sys %iowait   %irq  %soft  %steal  %guest  %gnice  %idle
07:38:50 PM  all  98.47   0.00   0.75    0.00   0.00   0.00    0.00    0.00    0.00   0.78
07:38:50 PM    0  96.04   0.00   2.97    0.00   0.00   0.00    0.00    0.00    0.00   0.99
07:38:50 PM    1  97.00   0.00   1.00    0.00   0.00   0.00    0.00    0.00    0.00   2.00
07:38:50 PM    2  98.00   0.00   1.00    0.00   0.00   0.00    0.00    0.00    0.00   1.00
07:38:50 PM    3  96.97   0.00   0.00    0.00   0.00   0.00    0.00    0.00    0.00   3.03
[...]

CPU별 cpu time을 확인할 수 있다. 만약 1개의 cpu가 특별히 높은 수치를 나타낸다면 single-thread application에 의해 생긴 현상임을 알 수 있다.

5. pipstat 1

$ pidstat 1
Linux 3.13.0-49-generic (titanclusters-xxxxx)  07/14/2015    _x86_64_    (32 CPU)

07:41:02 PM   UID       PID    %usr %system  %guest    %CPU   CPU  Command
07:41:03 PM     0         9    0.00    0.94    0.00    0.94     1  rcuos/0
07:41:03 PM     0      4214    5.66    5.66    0.00   11.32    15  mesos-slave
07:41:03 PM     0      4354    0.94    0.94    0.00    1.89     8  java
07:41:03 PM     0      6521 1596.23    1.89    0.00 1598.11    27  java
07:41:03 PM     0      6564 1571.70    7.55    0.00 1579.25    28  java
07:41:03 PM 60004     60154    0.94    4.72    0.00    5.66     9  pidstat

07:41:03 PM   UID       PID    %usr %system  %guest    %CPU   CPU  Command
07:41:04 PM     0      4214    6.00    2.00    0.00    8.00    15  mesos-slave
07:41:04 PM     0      6521 1590.00    1.00    0.00 1591.00    27  java
07:41:04 PM     0      6564 1573.00   10.00    0.00 1583.00    28  java
07:41:04 PM   108      6718    1.00    0.00    0.00    1.00     0  snmp-pass
07:41:04 PM 60004     60154    1.00    4.00    0.00    5.00     9  pidstat
^C

pidstat은 프로세스당 top command를 친것과 같다. 다만 요약해서 보여주기 때문에 빠르고 간편하게 확인할 수 있다. 

6. iostat -xz 1

$ iostat -xz 1
Linux 3.13.0-49-generic (titanclusters-xxxxx)  07/14/2015  _x86_64_ (32 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          73.96    0.00    3.73    0.03    0.06   22.21

Device:   rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
xvda        0.00     0.23    0.21    0.18     4.52     2.08    34.37     0.00    9.98   13.80    5.42   2.44   0.09
xvdb        0.01     0.00    1.02    8.94   127.97   598.53   145.79     0.00    0.43    1.78    0.28   0.25   0.25
xvdc        0.01     0.00    1.02    8.86   127.79   595.94   146.50     0.00    0.45    1.82    0.30   0.27   0.26
dm-0        0.00     0.00    0.69    2.32    10.47    31.69    28.01     0.01    3.23    0.71    3.98   0.13   0.04
dm-1        0.00     0.00    0.00    0.94     0.01     3.78     8.00     0.33  345.84    0.04  346.81   0.01   0.00
dm-2        0.00     0.00    0.09    0.07     1.35     0.36    22.50     0.00    2.55    0.23    5.62   1.78   0.03
[...]
^C

7. free -m

$ free -m
             total       used       free     shared    buffers     cached
Mem:        245998      24545     221453         83         59        541
-/+ buffers/cache:      23944     222053
Swap:            0          0          0

8. 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

9. 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

10. 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

상기 command 이후에는..?

이 포스팅에서 말한 command외에도 여러 추가적인 command와 방법론들이 존재한다. 2015 Velocity 컨퍼런스에서 Brendan Gregg는 벤치마킹, 튜닝, 프로파일링, 추적등을 위해 40개 이상의 command를 소개하기도 했다.

 

Brendan Gregg는시스템 성능 분석 분야의 전문가로 알려진 Netflix의 커널 및 성능 엔지니어이다. 이전에는 Sun Microsystems, Oracle Corporation 및 Joyent에서 근무했다.

시스템의 신뢰성(reliability)과 성능 이슈에 대한 트래킹은 넷플릭스에서 뽐낼만한 기술이다! 넷플릭스에서 이런 꿈을 펼치고 싶다면 여기(https://jobs.netflix.com/)에서 채용공고를 볼 수 있다.