Linuxの負荷調査
はじめに
前回は負荷について書きました。 chimay.hatenablog.com
今回は、Linux OSにおける各リソースの利用状況の調査方法をまとめてみます。 インフラエンジニアの道具となるためのコマンドがほとんどなので、それぞれのコマンドの特徴を理解して使い分けができるようにしましょう。
負荷調査の流れ
大まかな流れ
- 現状把握
- 原因調査
- 復旧対処
現状把握
まずは、サーバで発生している状況を理解しない事には始まりません。 CPU、メモリ、トラフィック、ディスクの使用率を調査しましょう。
筆者は下記の順番で見る事が多いです。LoadAverageは全体把握のためですが、それ以外の理由は可能性が高いと考えている順番です。
1.LoadAverage
2.CPU使用率
3.メモリ使用率
4.ディスク使用率
5.トラフィック使用率
LoadAverage
まずは、LoadAverageです。 サーバの負荷状態を数値化したようなものだと思ってください。高ければ高いほど、サーバ負荷は高いです。 但し、CPU数に依存するので LoadAverage / CPU数 でサーバ毎に計算してください。
uptime
現在時刻、稼働時間、ログインユーザ数、load average がわかります。
$ uptime 07:53:23 up 1:20, 1 user, load average: 0.00, 0.01, 0.02 $
w
uptime でわかる情報にプラスで、実際にログインしているユーザとログイン元、ログイン時間などがわかります。調査時は、uptime よりも w で済ませる事の方が多いと思います。
※スクリプトでデータを取得する際は uptime の方がデータ加工しやすいです。
$ w 07:01:57 up 28 min, 1 user, load average: 0.00, 0.01, 0.01 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT ec2-user pts/0 xxx.xxx.xxx.xxx 07:00 4.00s 0.00s 0.00s w $
CPU使用率
CPU使用率が高い原因が、CPU不足なのか 処理待ちによる wait値の上昇なのかを見るようにしましょう。
top
出力される情報が多く、リアルタイムで情報が更新されるので 負荷調査時にはよく使われます。オプションが非常に多いので、詳細は割愛します。
$ top top - 08:01:05 up 1:27, 1 user, load average: 0.00, 0.01, 0.02 Tasks: 69 total, 1 running, 68 sleeping, 0 stopped, 0 zombie Cpu(s): 0.0%us, 0.1%sy, 0.0%ni, 99.7%id, 0.1%wa, 0.0%hi, 0.0%si, 0.1%st Mem: 503380k total, 253740k used, 249640k free, 67308k buffers Swap: 0k total, 0k used, 0k free, 90516k cached
sar
このコマンドもオプションを使い分ける事でいろいろな情報を確認出来ます。詳細はそのうち別記事で書きます。リアルタイムで見たい場合は、 1 のオプションを付与しましょう。
※1 は実際には間隔(秒)の指定なので、5 を付与すれば 5秒間隔で出力出来ます。
$ sar Linux 4.1.13-19.31.amzn1.x86_64 (igrashi) 05/03/2016 _x86_64_ (1 CPU) 06:33:15 AM LINUX RESTART 06:40:01 AM CPU %user %nice %system %iowait %steal %idle 06:50:01 AM all 0.00 0.00 0.00 0.01 0.00 99.99 07:00:01 AM all 0.01 0.00 0.01 0.01 0.00 99.97 07:10:01 AM all 0.01 0.00 0.01 0.02 0.00 99.96 07:20:01 AM all 0.00 0.00 0.01 0.01 0.00 99.99 $ sar 1 Linux 4.1.13-19.31.amzn1.x86_64 (labo) 05/03/2016 _x86_64_ (1 CPU) 09:00:30 AM CPU %user %nice %system %iowait %steal %idle 09:00:31 AM all 0.00 0.00 0.00 0.00 0.00 100.00 09:00:32 AM all 0.00 0.00 0.00 0.00 0.00 100.00 09:00:33 AM all 0.99 0.00 0.00 0.00 0.00 99.01 09:00:34 AM all 0.00 0.00 0.00 0.00 0.00 100.00 09:00:35 AM all 0.00 0.00 0.99 0.00 0.00 99.01 09:00:36 AM all 0.00 0.00 0.00 0.00 0.00 100.00 09:00:37 AM all 0.00 0.00 0.00 0.00 0.00 100.00 09:00:38 AM all 0.00 0.00 0.99 0.00 0.00 99.01 ^C $
メモリ使用率
スパップアウトが発生しているかどうかを確認するようにしましょう。
free
Amazon Linuxでは、-a オプションを付与する事をおすすめします。available という列が追加されて表示されます。これは、buffers/cacheの開放できるメモリを含めた空き容量になります。
$ free -a total used free shared buffers cached available Mem: 503380 255532 247848 60 67484 91988 455580 -/+ buffers/cache: 96060 407320 Swap: 0 0 0 $
vmstat
とはいえ、リアルタイムでスパップアウトが発生しているかどうかはこちらのコマンドでの確認になります。si と so がそれぞれスパップインとスパップアウトになります。
※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 0 0 0 247748 67528 91988 0 0 27 3 11 18 0 0 100 0 0 0 0 0 247732 67528 91988 0 0 0 0 13 17 0 0 100 0 0 0 0 0 247732 67528 91988 0 0 0 0 9 12 0 0 100 0 0 0 0 0 247732 67528 91988 0 0 0 0 13 21 0 0 100 0 0 0 0 0 247732 67528 91988 0 0 0 0 12 18 0 0 100 0 0
cat /proc/meminfo
実はいろいろ用意されているコマンドは /proc 配下に格納されている情報を読み込んで整形しているだけだったりします。なので、直接該当ファイルを開いてもOKです。
※当然ですが、意味がわかるかどうかは別にして、こちらの方が情報量は多いです。
$ cat /proc/meminfo MemTotal: 503380 kB MemFree: 247716 kB MemAvailable: 455520 kB Buffers: 67552 kB Cached: 91988 kB SwapCached: 0 kB Active: 133556 kB Inactive: 43148 kB Active(anon): 17164 kB Inactive(anon): 52 kB Active(file): 116392 kB Inactive(file): 43096 kB Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 0 kB SwapFree: 0 kB Dirty: 0 kB Writeback: 0 kB AnonPages: 17184 kB Mapped: 15804 kB Shmem: 60 kB Slab: 67904 kB SReclaimable: 58876 kB SUnreclaim: 9028 kB KernelStack: 1376 kB PageTables: 2540 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 251688 kB Committed_AS: 65324 kB VmallocTotal: 34359738367 kB VmallocUsed: 1560 kB VmallocChunk: 34359732383 kB AnonHugePages: 0 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 22528 kB DirectMap2M: 501760 kB $
ディスク使用率
意外と100%になるディスク使用率。100%になると、新しいファイルの生成が出来なくなるのでシステムの挙動がおかしくなります。なので、確実に確認はしておきましょう。
df
使用量を確認する事が出来ます。ついでに、i-node も確認すると尚良。
$ df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 7.8G 3.7G 4.0G 49% / devtmpfs 237M 56K 237M 1% /dev tmpfs 246M 0 246M 0% /dev/shm $ df -i Filesystem Inodes IUsed IFree IUse% Mounted on /dev/xvda1 524288 165728 358560 32% / devtmpfs 60669 430 60239 1% /dev tmpfs 62922 1 62921 1% /dev/shm $
iostat
リアルタイムでI/O状況の確認には、iostatを利用しましょう。先程紹介した、vmstat の bi と bo を見ることでもI/Oを確認する事が出来ます。
$ iostat Linux 4.1.13-19.31.amzn1.x86_64 (labo) 05/03/2016 _x86_64_ (1 CPU) avg-cpu: %user %nice %system %iowait %steal %idle 0.08 0.00 0.05 0.09 0.08 99.70 Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn xvda 3.06 53.48 13.99 388969 101776 $
トラフィック使用率
sar -n DEV
sar のオプションの1つで過去のトラフィック値を確認出来ます。こちらもオプションに 1 を付与する事でリアルタイムで確認する事が出来ます。
$ sar -n DEV Linux 4.1.13-19.31.amzn1.x86_64 (igrashi) 05/03/2016 _x86_64_ (1 CPU) 06:33:15 AM LINUX RESTART 06:40:01 AM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s 06:50:01 AM eth0 0.11 0.11 0.01 0.01 0.00 0.00 0.00 06:50:01 AM lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 07:00:01 AM eth0 0.12 0.12 0.01 0.01 0.00 0.00 0.00 07:00:01 AM lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 07:10:01 AM eth0 0.24 0.24 0.02 0.03 0.00 0.00 0.00 07:10:01 AM lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 07:20:01 AM eth0 0.10 0.10 0.01 0.01 0.00 0.00 0.00 07:20:01 AM lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00
ifstat
リアルタイムの確認には、ifstat などもあります。
$ ifstat #kernel Interface RX Pkts/Rate TX Pkts/Rate RX Data/Rate TX Data/Rate RX Errs/Drop TX Errs/Drop RX Over/Rate TX Coll/Rate lo 2 0 2 0 140 0 140 0 0 0 0 0 0 0 0 0 eth0 8495 0 6041 0 5656K 0 1769K 0 0 0 0 0 0 0 0 0 $
ifstatus
視覚的に判りやすいのコマンドでは、ifstatus などがあります。 テキストだと解りづらいので、キャプチャです。
原因調査
ある程度リソースの利用状況がわかったら、次はそれを引き起こしている原因(プロセス)の特定です。
ps
psコマンドでは各プロセス毎のリソースの利用状況がわかるので、前もって調べておいた情報を元に特定しましょう。
$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.4 19644 2496 ? Ss 06:33 0:00 /sbin/init root 2 0.0 0.0 0 0 ? S 06:33 0:00 [kthreadd] root 3 0.0 0.0 0 0 ? S 06:33 0:00 [ksoftirqd/0] root 5 0.0 0.0 0 0 ? S< 06:33 0:00 [kworker/0:0H] root 6 0.0 0.0 0 0 ? S 06:33 0:00 [kworker/u30:0] root 7 0.0 0.0 0 0 ? S 06:33 0:00 [rcu_sched] root 8 0.0 0.0 0 0 ? S 06:33 0:00 [rcu_bh] root 9 0.0 0.0 0 0 ? S 06:33 0:00 [migration/0] root 10 0.0 0.0 0 0 ? S< 06:33 0:00 [khelper] root 11 0.0 0.0 0 0 ? S 06:33 0:00 [kdevtmpfs] root 12 0.0 0.0 0 0 ? S< 06:33 0:00 [netns] root 13 0.0 0.0 0 0 ? S< 06:33 0:00 [perf] root 14 0.0 0.0 0 0 ? S 06:33 0:00 [kworker/u30:1] root 16 0.0 0.0 0 0 ? S 06:33 0:00 [xenwatch] root 21 0.0 0.0 0 0 ? S 06:33 0:00 [xenbus] root 22 0.0 0.0 0 0 ? S 06:33 0:00 [kworker/0:1] root 124 0.0 0.0 0 0 ? S 06:33 0:00 [khungtaskd] root 125 0.0 0.0 0 0 ? S< 06:33 0:00 [writeback] root 127 0.0 0.0 0 0 ? SN 06:33 0:00 [ksmd] root 128 0.0 0.0 0 0 ? S< 06:33 0:00 [crypto] root 129 0.0 0.0 0 0 ? S< 06:33 0:00 [kintegrityd] root 130 0.0 0.0 0 0 ? S< 06:33 0:00 [bioset] root 132 0.0 0.0 0 0 ? S< 06:33 0:00 [kblockd] root 479 0.0 0.0 0 0 ? S< 06:33 0:00 [md] root 610 0.0 0.0 0 0 ? S 06:33 0:00 [kswapd0] root 681 0.0 0.0 0 0 ? S 06:33 0:00 [fsnotify_mark] root 696 0.0 0.0 0 0 ? S< 06:33 0:00 [kthrotld] root 740 0.0 0.0 0 0 ? S< 06:33 0:00 [deferwq] root 1366 0.0 0.0 0 0 ? S< 06:33 0:00 [ata_sff] root 1380 0.0 0.0 0 0 ? S 06:33 0:00 [scsi_eh_0] root 1381 0.0 0.0 0 0 ? S< 06:33 0:00 [scsi_tmf_0] root 1391 0.0 0.0 0 0 ? S 06:33 0:00 [scsi_eh_1] root 1392 0.0 0.0 0 0 ? S< 06:33 0:00 [scsi_tmf_1] root 1457 0.0 0.0 0 0 ? S 06:33 0:00 [jbd2/xvda1-8] root 1458 0.0 0.0 0 0 ? S< 06:33 0:00 [ext4-rsv-conver] root 1489 0.0 0.0 0 0 ? S< 06:33 0:00 [kworker/0:1H] root 1501 0.0 0.5 11464 2736 ? Ss 06:33 0:00 /sbin/udevd -d root 1591 0.0 0.0 0 0 ? S< 06:33 0:00 [kpsmoused] root 1632 0.0 0.4 11460 2172 ? S 06:33 0:00 /sbin/udevd -d root 1646 0.0 0.0 0 0 ? S 06:33 0:00 [kworker/0:3] root 2080 0.0 0.0 0 0 ? S 06:33 0:00 [kauditd] root 2088 0.0 0.4 15936 2384 ? Ss 06:33 0:00 crond root 2121 0.0 0.0 0 0 ? S< 06:33 0:00 [ipv6_addrconf] root 2252 0.0 0.4 9360 2240 ? Ss 06:33 0:00 /sbin/dhclient -q -lf /var/lib/dhclient/dhclient-eth0.leases -pf /var/run/dhclient-eth0.pid eth0 root 2293 0.0 0.3 46536 1964 ? S<sl 06:33 0:00 auditd root 2311 0.0 0.5 243236 2584 ? Sl 06:33 0:00 /sbin/rsyslogd -i /var/run/syslogd.pid -c 5 root 2327 0.0 0.0 4380 88 ? Ss 06:33 0:00 rngd --no-tpm=1 --quiet rpc 2341 0.0 0.4 35292 2252 ? Ss 06:33 0:00 rpcbind rpcuser 2358 0.0 0.6 39860 3308 ? Ss 06:33 0:00 rpc.statd dbus 2389 0.0 0.0 21792 228 ? Ss 06:33 0:00 dbus-daemon --system root 2421 0.0 1.3 152080 6820 ? S 06:33 0:00 /usr/sbin/snmpd -LS0-6d -Lf /dev/null -p /var/run/snmpd.pid root 2484 0.0 0.5 77816 2572 ? Ss 06:33 0:00 /usr/sbin/sshd ntp 2509 0.0 0.8 29292 4368 ? Ss 06:33 0:00 ntpd -u ntp:ntp -p /var/run/ntpd.pid -g root 2584 0.0 1.2 92948 6424 ? Ss 06:33 0:00 /usr/libexec/postfix/master postfix 2591 0.0 1.3 93200 6552 ? S 06:33 0:00 qmgr -l -t fifo -u nobody 2593 0.0 0.7 159124 3720 ? Ss 06:33 0:00 proftpd: (accepting connections) root 2618 0.0 0.3 6460 1616 ttyS0 Ss+ 06:33 0:00 /sbin/agetty ttyS0 9600 vt100-nav root 2620 0.0 0.2 4312 1492 tty1 Ss+ 06:33 0:00 /sbin/mingetty /dev/tty1 root 2623 0.0 0.2 4312 1444 tty2 Ss+ 06:33 0:00 /sbin/mingetty /dev/tty2 root 2625 0.0 0.2 4312 1388 tty3 Ss+ 06:33 0:00 /sbin/mingetty /dev/tty3 root 2627 0.0 0.2 4312 1392 tty4 Ss+ 06:33 0:00 /sbin/mingetty /dev/tty4 root 2629 0.0 0.2 4312 1488 tty5 Ss+ 06:33 0:00 /sbin/mingetty /dev/tty5 root 2631 0.0 0.3 10876 1628 ? S 06:33 0:00 /sbin/udevd -d root 2632 0.0 0.2 4312 1408 tty6 Ss+ 06:33 0:00 /sbin/mingetty /dev/tty6 root 2689 0.0 1.3 117784 6712 ? Ss 07:00 0:00 sshd: ec2-user [priv] ec2-user 2691 0.0 1.1 117784 5652 ? S 07:00 0:00 sshd: ec2-user@pts/0 ec2-user 2692 0.0 0.6 115348 3288 pts/0 Ss 07:00 0:00 -bash postfix 2907 0.0 1.3 93032 6584 ? S 08:13 0:00 pickup -l -t fifo -u ec2-user 3050 0.0 0.6 115348 3396 pts/0 S 08:22 0:00 bash ec2-user 3220 0.0 0.4 117204 2460 pts/0 R+ 08:44 0:00 ps aux $
netstat
トラフィックの場合は、netstat コマンドで接続が多いプロセスを特定しましょう。下記のようなオプションで、PIDも出力する事が出来ます。
$ sudo netstat -anep Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 0 10059 2484/sshd tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN 0 10309 2584/master tcp 0 0 0.0.0.0:33410 0.0.0.0:* LISTEN 29 9566 2358/rpc.statd tcp 0 0 127.0.0.1:199 0.0.0.0:* LISTEN 0 9825 2421/snmpd tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 0 9488 2341/rpcbind tcp 0 464 172.31.15.196:22 xxx.xxx.xxx.xxx:19752 ESTABLISHED 0 12759 2689/sshd tcp 0 0 :::21 :::* LISTEN 99 10425 2593/proftpd tcp 0 0 :::22 :::* LISTEN 0 10061 2484/sshd tcp 0 0 :::39943 :::* LISTEN 29 9572 2358/rpc.statd tcp 0 0 :::111 :::* LISTEN 0 9491 2341/rpcbind udp 0 0 0.0.0.0:820 0.0.0.0:* 0 9487 2341/rpcbind udp 0 0 0.0.0.0:68 0.0.0.0:* 0 8856 2252/dhclient udp 0 0 127.0.0.1:838 0.0.0.0:* 0 9560 2358/rpc.statd udp 0 0 0.0.0.0:111 0.0.0.0:* 0 9486 2341/rpcbind udp 0 0 172.31.15.196:123 0.0.0.0:* 0 10144 2509/ntpd udp 0 0 127.0.0.1:123 0.0.0.0:* 0 10143 2509/ntpd udp 0 0 0.0.0.0:123 0.0.0.0:* 0 10136 2509/ntpd udp 0 0 0.0.0.0:161 0.0.0.0:* 0 9824 2421/snmpd udp 0 0 0.0.0.0:47782 0.0.0.0:* 29 9563 2358/rpc.statd udp 0 0 :::820 :::* 0 9490 2341/rpcbind udp 0 0 :::52050 :::* 29 9569 2358/rpc.statd udp 0 0 :::111 :::* 0 9489 2341/rpcbind udp 0 0 fe80::4b2:53ff:fe38:5837:123 :::* 0 10146 2509/ntpd udp 0 0 ::1:123 :::* 0 10145 2509/ntpd udp 0 0 :::123 :::* 0 10137 2509/ntpd
復旧対処
調査の結果わかった内容で対策を考えましょう。
まとめ
こんなに書いといてあれですが、実際には、いきなり ps コマンドで特定する事の方が多いかもしれません。
また、サーバにログインして確認するコマンドを紹介しましたが、実際の運用では可能な限りモニタリングツールを導入してサーバへのログインなしに確認できる環境を作りましょう。サーバが複数台の環境だとコマンドで見るよりもグラフを見た方が何倍も判りやすく、早い解決が期待出来ます。
おすすめ書籍
より詳しい内容は下記書籍が初心者にもわかりやすいと思います。今回の内容だと特に最初の1冊をお勧めします。