vmstat コマンドでよく使うオプションのメモ。
vmstat コマンドでわりとよく使うオプションのメモ。
普段は AWS の EC2 インスタンスに入って使うことが多いのでこのエントリーを書くときも EC2 インスタンスに入って vmstat コマンドを実行した結果とかをメモっている。
vmstat コマンドのバージョン。
$ vmstat --version vmstat from procps-ng 3.3.10
vmstat コマンドのオプション
vmstat コマンドはプロセスのメモリ、プロセス、スワップ、IO、割り込みと CPU の情報を表示するコマンド。
vmstat コマンドの名前の由来は virtual memory statistics
だと思うんだけど、メモリだけじゃなくてシステムの一通りの情報が揃っているので「なにか変だな」みたいなときはまず使ってみる、みたいな使い方をすることが多いように思う。
自分はなんとなく使うことが多い気がするのでよく使うオプションをメモしておく。
--help オプション: ヘルプ
--help
オプションを指定すると vmstat コマンドの使い方を表示する……んだけど man vmstat
が使えないときにしか使わない。
$ vmstat --help Usage: vmstat [options] [delay [count]] Options: -a, --active active/inactive memory -f, --forks number of forks since boot -m, --slabs slabinfo -n, --one-header do not redisplay header -s, --stats event counter statistics -d, --disk disk statistics -D, --disk-sum summarize disk statistics -p, --partition <dev> partition specific statistics -S, --unit <char> define display unit -w, --wide wide output -t, --timestamp show timestamp -h, --help display this help and exit -V, --version output version information and exit
delay, count
オプションじゃないんだけど vmstat コマンドを使うときは必ずといっていいほど指定するやつ。
vmstat
みたいに delay なしで実行するとこんな感じで起動 (再起動) してからの平均値を表示するんだけど、
$ vmstat 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 579228 2088 348192 0 0 84 123 90 2074 10 17 72 0 0
vmstat 5
みたいに delay を指定すると指定した delay 秒ごとに表示を更新する。
$ vmstat 5 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 579360 2088 348192 0 0 80 117 87 1977 10 16 73 0 0 0 0 0 579352 2088 348192 0 0 0 0 27 50 0 0 100 0 0 0 0 0 579352 2088 348192 0 0 0 8 22 40 0 0 100 0 0 0 0 0 579352 2088 348192 0 0 0 0 4 7 0 0 100 0 0 0 0 0 579352 2088 348192 0 0 0 0 5 10 0 0 100 0 0 0 0 0 579352 2088 348192 0 0 0 0 7 9 0 0 100 0 0
vmstat 5 3
みたいに delay と count を指定すると指定した delay 秒ごとに count 回分だけ表示を更新する。
$ vmstat 5 3 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 579360 2088 348192 0 0 80 117 87 1977 10 16 73 0 0 0 0 0 579352 2088 348192 0 0 0 0 27 50 0 0 100 0 0 0 0 0 579352 2088 348192 0 0 0 8 22 40 0 0 100 0 0
-t, --timestamp オプション: 日時を表示する
vmstat --timestamp 5
みたいに -t
オプションか --timestamp
オプションを指定すると日時も表示する。
$ vmstat --timestamp 5 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- -----timestamp----- r b swpd free buff cache si so bi bo in cs us sy id wa st UTC 0 0 0 579388 2088 348196 0 0 72 105 79 1777 9 15 76 0 0 2020-02-20 12:10:25 0 0 0 579380 2088 348196 0 0 0 0 24 46 0 0 100 0 0 2020-02-20 12:10:30 0 0 0 579380 2088 348196 0 0 0 3 23 44 0 0 100 0 0 2020-02-20 12:10:35 0 0 0 579256 2088 348196 0 0 0 4 35 56 0 0 100 0 0 2020-02-20 12:10:40 0 0 0 579256 2088 348196 0 0 0 0 23 45 0 0 100 0 0 2020-02-20 12:10:45
-n, --one-header オプション: ヘッダーは最初の1回だけ表示
vmstat 5
とか実行すると定期的 (ウィンドウのサイズによる) にヘッダー行を表示するけど -n
オプションか --one-header
オプションを指定するとヘッダーは最初の1回だけ表示する。
-S, --unit オプション: メモリの単位を指定する
memory
の表示単位はキロバイトがデフォルトだけど -S
オプションか --unit
オプションを指定すると memory
の表示単位を変更できる。
-S
オプションと --unit
オプションに指定できる値と表示単位は以下のとおり。
指定できる値 | 表示単位 |
---|---|
k | キロバイト (KB) |
K | キビバイト (KiB) |
m | メガバイト (MB) |
M | メビバイト (MiB) |
vmstat コマンドの表示項目
vmstat コマンドの表示項目について軽くメモしておく。
procs
プロセスの情報。 r + b = ロードアベレージ。
項目 | 意味 |
---|---|
r | 実行中もしくは実行待ちのプロセス数 |
b | ディスク I/O やロック待ちのプロセス数 |
memory
メモリの情報。
項目 | 意味 |
---|---|
swpd | 使用中の仮想メモリの量 |
free | 空きメモリの量 |
buff | バッファとして使用中のメモリの量 |
cache | キャッシュとして使用中のメモリの量 |
inact | アクティブになっていないメモリの量 |
active | アクティブになっているメモリの量 |
swap
スワップの情報。
項目 | 意味 |
---|---|
si | ディスクからスワップインしているメモリの量。KB / 秒 |
so | ディスクにスワップアウトしているメモリの量。 KB / 秒 |
io
IO の情報。
項目 | 意味 |
---|---|
bi | HDD のようなブロックデバイスから1秒あたりに受け取ったブロック数 |
bo | HDD のようなブロックデバイスに1秒あたりに送ったブロック数 |
system
項目 | 意味 |
---|---|
in | 1秒あたりの割り込み回数。タイマー割り込みを含む |
cs | 1秒あたりのコンテキストスイッチ回数 |
cpu
CPU の情報。 単位はトータル CPU 時間におけるパーセンテージ。
項目 | 意味 |
---|---|
us | ユーザー CPU 時間。カーネル以外が CPU を使用した時間 |
sy | システム CPU 時間。カーネルが CPU を使用した時間 |
id | CPU がアイドル状態だった時間 |
wa | プロセスが IO 待ちだった時間 |
st | 仮想マシンから盗まれた時間 ※ |
st: 仮想マシンから盗まれた時間とは
「仮想マシンから盗まれた時間」とはなにを意味するのか。
vmstat の man page は Time stolen from a virtual machine
とだけ書いてあってなんのことかよく分からないんだけど vmstat と同じくシステムの負荷監視系コマンドの sar の man page が分かりやすい。
Percentage of time spent in involuntary wait by the virtual CPU or CPUs while the hypervisor was servicing another virtual processor.
Google 翻訳にかけると ハイパーバイザーが別の仮想プロセッサーにサービスを提供している間に、1つまたは複数の仮想CPUが不本意に待機した時間の割合
って感じで、OS が仮想マシン (仮想サーバー) 上で動いているときに意味を持ってくる値で、仮想マシンが CPU を要求するけど CPU の使用率の上限が決められていて仮想マシンが CPU を利用できないときとか、仮想マシンが CPU を要求するけど 他の仮想マシンが CPU を使いまくってて CPU を利用できないときに st が上昇する。
自分は普段あまり st の上昇は見ないような気がするけど AWS の EC2 の t2 とかのバーストパフォーマンスインスタンスを使ってるときに見たりする。 たとえば、t2 インスタンスとかで CPU をぶん回して CPU バーストして CPU 使用率が 100% に張り付くような状態を続けていくといずれ CPU クレジットを使い切って CPU 使用率が落ちていく。 このへんを vmstat で見てると st の値が上昇していくのが分かる。
プログラムが仮想マシン上で動いていて CPU 使用率はそんなに高くないんだけど CPU バウンドっぽい……みたいなときは st の値が上昇しているかチェックしてみるのがよさそう。
参考ページ
ps コマンドでよく使うオプションのメモ。
ps コマンドでわりとよく使うオプションのメモ。
普段は AWS の EC2 インスタンスに入って使うことが多いのでこのエントリーを書くときも EC2 インスタンスに入って ps コマンドを実行した結果とかをメモっている。
ps コマンドのバージョン。
$ ps --version procps-ng version 3.3.10
ps コマンドのオプション
ps コマンドはプロセスの情報を表示するコマンド。
自分はなんとなく使うことが多い気がするのでよく使うオプションをメモしておく。
--help オプション: ヘルプ
--help
オプションを指定すると ps コマンドの使い方を表示する……んだけど man ps
が使えないときにしか使わない。
$ ps --help all Usage: ps [options] Basic options: -A, -e all processes -a all with tty, except session leaders a all with tty, including other users -d all except session leaders -N, --deselect negate selection r only running processes T all processes on this terminal x processes without controlling ttys # 省略
--no-header オプション: ヘッダーを表示しない
--no-header
オプションを指定するとヘッダーを表示しない。
オプションなしの ps
は PID
とか TTY
とかヘッダーを表示するけど、
$ ps PID TTY TIME CMD 3288 pts/0 00:00:00 bash 22180 pts/0 00:00:00 ps
--no-header
オプションを指定すると PID
とか TTY
とかのヘッダーを表示しない。
$ ps --no-header 3288 pts/0 00:00:00 bash 22180 pts/0 00:00:00 ps
u オプション: プロセスの詳細情報を表示
u
オプションを指定するとプロセスの詳細情報を表示する。
$ ps u USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND ec2-user 3288 0.0 0.3 125068 4004 pts/0 Ss 14:01 0:00 -bash ec2-user 22117 0.0 0.4 124992 4140 pts/1 Ss 14:02 0:00 -bash ec2-user 22199 0.0 0.3 126116 3524 pts/1 S+ 14:15 0:00 man ps ec2-user 22210 0.0 0.2 117300 2624 pts/1 S+ 14:15 0:00 less -s ec2-user 25636 0.0 0.4 164368 4060 pts/0 R+ 14:37 0:00 ps u
-f オプション: プロセスの情報を完全なフォーマットで表示
-f
オプションを指定するとプロセスの情報を完全なフォーマットで表示する。
親子関係のプロセスをツリー表示してくれる。
$ ps -fu USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND ec2-user 22117 0.0 0.4 124992 4140 pts/1 Ss 14:02 0:00 -bash ec2-user 22199 0.0 0.3 126116 3524 pts/1 S+ 14:15 0:00 \_ man ps ec2-user 22210 0.0 0.2 117300 2624 pts/1 S+ 14:15 0:00 \_ less -s ec2-user 3288 0.0 0.3 125068 4004 pts/0 Ss 14:01 0:00 -bash ec2-user 25649 0.0 0.4 164368 4084 pts/0 R+ 14:40 0:00 \_ ps -fu
e オプション: 環境変数を表示
e
オプションを指定すると COMMAND
カラムのコマンドの表示のあとにプロセスの環境変数を表示する。
$ ps e PID TTY STAT TIME COMMAND 3288 pts/0 Ss 0:00 -bash LC_ALL=ja_JP.UTF-8 22117 pts/1 Ss 0:00 -bash LC_ALL=ja_JP.UTF-8
-L オプション: プロセスとスレッドを表示
-L
オプションを指定するとプロセスとスレッドを表示する。
ps -C dockerd
すると dockerd のプロセスは1つだけ表示するけど、
$ ps -C dockerd PID TTY TIME CMD 885 ? 00:00:04 dockerd
-L
オプションを追加するとたくさん表示する。
増えた表示の分がスレッド。
スレッドはたくさん表示するけど PID
は全部同じなので表示しているスレッドが同じプロセスのスレッドであることが分かる。
スレッド ID はLWP
のところに表示する。
$ ps -L -C dockerd PID LWP TTY TIME CMD 885 885 ? 00:00:00 dockerd 885 981 ? 00:00:00 dockerd 885 982 ? 00:00:00 dockerd 885 983 ? 00:00:00 dockerd 885 984 ? 00:00:00 dockerd # 省略
-A, -e オプション: すべてのプロセスを表示
-A
オプションか -e
オプションを指定するとすべてのプロセスを表示する。
man ページの -A
オプションの説明のところは select all processes. Identical to -e
と書いてあって -A
オプションと -e
オプションはまったく同じ。
オプションなしの ps
はちょっとしかプロセスを表示しないけど、
$ ps PID TTY TIME CMD 3288 pts/0 00:00:00 bash 22180 pts/0 00:00:00 ps
ps -e
するとプロセスがたくさん表示される。
$ ps -e PID TTY TIME CMD 1 ? 00:00:01 systemd 2 ? 00:00:00 kthreadd 4 ? 00:00:00 kworker/0:0H 5 ? 00:00:00 kworker/u30:0 6 ? 00:00:00 mm_percpu_wq 7 ? 00:00:00 ksoftirqd/0 8 ? 00:00:00 rcu_sched
a オプション: 端末を持つプロセスを表示
a
オプションを指定すると端末を持つすべてのプロセスを表示する。
端末を持つプロセスであれば他のユーザーのプロセスも表示する。
a
オプションを指定すると表示されるプロセスは当然のことながら端末を持っているので TTY
のところが tty
とか pts
みたいになる。
x
オプションと組み合わせて使うことが多い => x
オプション参照
$ ps a PID TTY STAT TIME COMMAND 3202 tty1 Ss+ 0:00 /sbin/agetty --noclear tty1 linux 3203 ttyS0 Ss+ 0:00 /sbin/agetty --keep-baud 115200,38400,9600 ttyS0 vt220 3288 pts/0 Ss 0:00 -bash 22117 pts/1 Ss 0:00 -bash 22160 pts/1 S+ 0:00 man ps 22171 pts/1 S+ 0:00 less -s 22196 pts/0 R+ 0:00 ps a
x オプション: 端末を持たないプロセスを表示
x
オプションを指定すると端末を持たないすべてのプロセスを表示する。
$ ps x PID TTY STAT TIME COMMAND 3287 ? S 0:00 sshd: ec2-user@pts/0 3288 pts/0 Ss 0:00 -bash 22116 ? S 0:00 sshd: ec2-user@pts/1 22117 pts/1 Ss 0:00 -bash 22199 pts/1 S+ 0:00 man ps 22210 pts/1 S+ 0:00 less -s 25561 pts/0 R+ 0:00 ps x
x
オプションと a
オプションを組み合わせると端末を持たないプロセスと端末を持つプロセスを表示するので表示するプロセスの数は -e
オプションを指定するときと同じになる。
=> 表示するときのカラムが違うとかの相違がある
$ ps -e | wc -l 90 $ ps ax | wc -l 90
r オプション: 実行中のプロセスだけ表示
r
オプションを指定すると実行中もしくは実行可能状態のプロセスだけ表示する。
ps u
すると何個かのプロセスが表示するけど、
$ ps u USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND ec2-user 3288 0.0 0.3 125068 4004 pts/0 Ss 14:01 0:00 -bash ec2-user 22117 0.0 0.4 124992 4140 pts/1 Ss 14:02 0:00 -bash ec2-user 22199 0.0 0.3 126116 3524 pts/1 S+ 14:15 0:00 man ps ec2-user 22210 0.0 0.2 117300 2624 pts/1 S+ 14:15 0:00 less -s ec2-user 25631 0.0 0.3 164368 3940 pts/0 R+ 14:30 0:00 ps u
r
オプションを追加して ps ru
すると STAT
が R
(R+
) のプロセスだけ表示する。
$ ps ru USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND ec2-user 25633 0.0 0.3 164368 4008 pts/0 R+ 14:30 0:00 ps ru
-C オプション: 実行ファイル名を指定して表示
-C
オプションで実行ファイル名を指定すると指定した実行ファイルのプロセスだけ表示する。
ps u
すると何個かのプロセスが表示するけど、
$ ps u USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND ec2-user 3288 0.0 0.4 125068 4168 pts/0 Ss 14:01 0:00 -bash ec2-user 22117 0.0 0.4 124992 4140 pts/1 Ss 14:02 0:00 -bash ec2-user 22199 0.0 0.3 126116 3524 pts/1 S+ 14:15 0:00 man ps ec2-user 22210 0.0 0.2 117300 2624 pts/1 S+ 14:15 0:00 less -s ec2-user 25758 0.0 0.4 164368 4064 pts/0 R+ 15:07 0:00 ps u
-C
オプションで -C bash
みたいに指定すると bash だけ表示する。
$ ps u -C bash USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND ec2-user 3288 0.0 0.4 125068 4168 pts/0 Ss 14:01 0:00 -bash ec2-user 22117 0.0 0.4 124992 4140 pts/1 Ss 14:02 0:00 -bash
ps コマンドのオプションでちょっと気にしておくこと
ps コマンドのバージョンによってはいくつかのオプション形式に対応している。
e
オプション (環境変数を表示) と -e
オプション (すべてのプロセスを表示) みたいに -
があるかないかでまったく意味が違うオプションがある。
This version of ps accepts several kinds of options: 1 UNIX options, which may be grouped and must be preceded by a dash. 2 BSD options, which may be grouped and must not be used with a dash. 3 GNU long options, which are preceded by two dashes.
EBS ボリュームを EC2 インスタンスに追加と削除する方法。
EC2 を運用中にディスクが足りなくなったので EBS ボリュームを追加とアタッチをして、ついでにデタッチと削除したときのメモ。
EBS ボリュームの追加
EC2 インスタンスが追加の EBS ボリュームを使うためには EBS ボリュームの作成と EC2 インスタンスへのアタッチをしていく。
追加する EBS ボリュームの作成
今回は汎用 SSD (gp2) の EBS ボリュームを作成して EC2 インスタンスへアタッチしていく。
作業開始前の EC2 インスタンスの状態。
$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT xvda 202:0 0 8G 0 disk └─xvda1 202:1 0 8G 0 part / $ df -h ファイルシス サイズ 使用 残り 使用% マウント位置 devtmpfs 475M 0 475M 0% /dev tmpfs 492M 0 492M 0% /dev/shm tmpfs 492M 404K 492M 1% /run tmpfs 492M 0 492M 0% /sys/fs/cgroup /dev/xvda1 8.0G 1.5G 6.6G 19% / tmpfs 99M 0 99M 0% /run/user/1000
EBS ボリュームを作成する。 EBS ボリュームは追加先の EC2 インスタンスと同じアベイラビリティゾーンに作成する必要があるので追加先の EC2 インスタンスが稼働しているアベイラビリティゾーンを確認しておくこと。
$ aws ec2 create-volume \ --availability-zone <アベイラビリティゾーン> \ --no-encrypted --volume-type gp2 \ --size 30
EBS ボリュームを EC2 インスタンスへアタッチ
作成した EBS ボリュームを EC2 インスタンスへアタッチする。
$ aws ec2 attach-volume --device /dev/xvdf --instance-id <EC2 インスタンス ID> --volume-id <作成した EBS ボリュームの ID> { "AttachTime": "2020-02-13T13:57:31.721Z", "InstanceId": "<EC2 インスタンス ID>", "VolumeId": "<作成した EBS ボリュームの ID>", "State": "attaching", "Device": "/dev/xvdf" }
EBS ボリュームの状態が in-use
になると EC2 インスタンスから見えるようになる。
$ aws ec2 describe-volumes --volume-ids <作成した EBS ボリュームの ID> | jq -r '.Volumes[].State' in-use
EBS ボリュームのファイルシステムの作成
作ったばかりの EBS ボリュームはファイルシステムがないのでファイルシステムを作成していく。
ファイルシステムを作成する前に今どうなってるか確認。
lsblk コマンドを実行すると EC2 インスタンスの /dev/xvdf
にアタッチした EBS ボリュームが見えるようになっている。
$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT xvda 202:0 0 8G 0 disk └─xvda1 202:1 0 8G 0 part / xvdf 202:80 0 30G 0 disk $ df -h ファイルシス サイズ 使用 残り 使用% マウント位置 devtmpfs 475M 0 475M 0% /dev tmpfs 492M 0 492M 0% /dev/shm tmpfs 492M 408K 492M 1% /run tmpfs 492M 0 492M 0% /sys/fs/cgroup /dev/xvda1 8.0G 1.5G 6.6G 19% / tmpfs 99M 0 99M 0% /run/user/1000
file コマンドで /dev/xvdf
を見るとまだファイルシステムを作成していないので data
とだけ出力される。
$ sudo file -s /dev/xvdf /dev/xvdf: data
mkfs コマンドで /dev/xvdf
にファイルシステムを作成していく。
$ sudo mkfs -t xfs /dev/xvdf meta-data=/dev/xvdf isize=512 agcount=4, agsize=1966080 blks = sectsz=512 attr=2, projid32bit=1 = crc=1 finobt=1, sparse=0 data = bsize=4096 blocks=7864320, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 ftype=1 log =internal log bsize=4096 blocks=3840, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0
file コマンドで /dev/xvdf
を見ると XFS ファイルシステムが作成されていることが分かる。
$ sudo file -s /dev/xvdf /dev/xvdf: SGI XFS filesystem data (blksz 4096, inosz 512, v2 dirs)
EBS ボリュームのマウント
マウントポイントのディレクトリを作成してボリュームをマウントしていく。
今回は /dev/xvdf
を /data
にマウントしていく。
$ sudo mkdir /data $ sudo mount /dev/xvdf /data
df コマンドを実行すると /dev/xvdf
が /data
にマウントされているのが分かる。
$ df -h ファイルシス サイズ 使用 残り 使用% マウント位置 devtmpfs 475M 0 475M 0% /dev tmpfs 492M 0 492M 0% /dev/shm tmpfs 492M 464K 492M 1% /run tmpfs 492M 0 492M 0% /sys/fs/cgroup /dev/xvda1 8.0G 1.5G 6.6G 19% / tmpfs 99M 0 99M 0% /run/user/1000 tmpfs 99M 0 99M 0% /run/user/0 /dev/xvdf 30G 63M 30G 1% /data
EBS ボリュームを作成して EC2 インスタンスから使えるようにする手順は以上。
EBS ボリュームの削除
EC2 インスタンスが使っている EBS ボリュームを削除するためには EBS ボリュームのアンマウントと EC2 インスタンスからのデタッチをしていく。 必要なデータが EBS ボリュームに入っているときは作業を進める前にデータを別の場所に移したりコピーなど取得しておく。
EBS ボリュームのアンマウント
$ sudo umount -d /dev/xvdf $ df -h ファイルシス サイズ 使用 残り 使用% マウント位置 devtmpfs 475M 0 475M 0% /dev tmpfs 492M 0 492M 0% /dev/shm tmpfs 492M 464K 492M 1% /run tmpfs 492M 0 492M 0% /sys/fs/cgroup /dev/xvda1 8.0G 1.5G 6.6G 19% / tmpfs 99M 0 99M 0% /run/user/1000 tmpfs 99M 0 99M 0% /run/user/0
EBS ボリュームのデタッチ
$ aws ec2 detach-volume --volume-id <削除する EBS ボリュームの ID> { "AttachTime": "2020-02-13T13:58:31.000Z", "InstanceId": "<EC2 インスタンスの ID>", "VolumeId": "<削除する EBS ボリュームの ID>", "State": "detaching", "Device": "/dev/xvdf" }
EBS ボリュームが EC2 インスタンスからデタッチが完了すると EBS ボリュームの状態が available
になる。
$ aws ec2 describe-volumes --volume-ids <削除する EBS ボリュームの ID> | jq -r '.Volumes[].State' available
EBS ボリュームの削除
$ aws ec2 delete-volume --volume-id <削除する EBS ボリュームの ID>
EBS ボリュームを EC2 インスタンスからデタッチして削除する手順は以上。
参考ページ
K6 を実行したら "connect: cannot assign requested address" がでたときにやったこと。
k6 で WEB サーバーに負荷をかけると "connect: cannot assign requested address" みたいなメッセージが表示されたときにやったこと。
k6 run すると "connect: cannot assign requested address" みたいなメッセージが大量に表示される
WEB サーバーに負荷をかけるために k6 run --vus <でかい数> --iterations <でかい数> --no-vu-connection-reuse script.js
みたいに k6 run
すると connect: cannot assign requested address
というメッセージが大量に表示される。
表示されているメッセージを見た感じだと k6 がエフェメラルポートを使い尽くしてソケットをバインドできていないっぽいので k6 run
しながら TIME_WAIT
のポート数を数えてみるとたくさんあった。
やっぱり k6 がエフェメラルポートを使い尽くしてソケットをバインドできていないっぽい。
$ netstat -anp | grep TIME_WAIT | wc -l 28223
ちなみに k6 のバージョンは 0.26.0
.
$ k6 version k6 v0.26.0 (2019-12-16T11:07:36+0000/v0.26.0-0-gaeec9a7f, go1.13.5, linux/amd64)
やったこと
k6 がエフェメラルポートを使い尽くしてソケットをバインドできないのは --no-vu-connection-reuse
オプションを指定しなければ k6 が TCP コネクションを再利用するようになるので解決できる……のだが、理由があって TCP コネクションは毎回貼り直すようにしたかったので --no-vu-connection-reuse
オプションは指定しておきたい。
k6 を実行するマシンは他の用途には使わないので、お行儀がよくないけど TIME_WAIT
のポートを再利用するようにした。
$ sysctl net.ipv4.tcp_tw_reuse net.ipv4.tcp_tw_reuse = 0 $ sudo sysctl -w net.ipv4.tcp_tw_reuse=1 $ sysctl net.ipv4.tcp_tw_reuse net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_reuse = 1
にしてから k6 run
すると connect: cannot assign requested address
みたいなメッセージが表示されなくなり、モリモリと WEB サーバーに負荷をかけられるようになった。
apt update すると GPG error: The following signatures were invalid になったときにやったこと。
apt update すると GPG error: The following signatures were invalid になったときにやったことのメモ。
apt update すると GPG error: The following signatures were invalid に
MySQL の Docker コンテナで apt update
したら GPG error: The following signatures were invalid
みたいなメッセージが出て update に失敗した。
# apt update Get:1 http://repo.mysql.com/apt/debian stretch InRelease [21.6 kB] Ign:2 http://deb.debian.org/debian stretch InRelease Get:3 http://deb.debian.org/debian stretch-updates InRelease [91.0 kB] Get:5 http://deb.debian.org/debian stretch Release [118 kB] Get:6 http://deb.debian.org/debian stretch Release.gpg [2365 B] Err:1 http://repo.mysql.com/apt/debian stretch InRelease The following signatures were invalid: EXPKEYSIG 8C718D3B5072E1F5 MySQL Release Engineering <mysql-build@oss.oracle.com> Get:4 http://security-cdn.debian.org/debian-security stretch/updates InRelease [94.3 kB] Get:7 http://deb.debian.org/debian stretch-updates/main amd64 Packages [27.9 kB] Get:8 http://deb.debian.org/debian stretch/main amd64 Packages [7086 kB] Get:9 http://security-cdn.debian.org/debian-security stretch/updates/main amd64 Packages [514 kB] Reading package lists... Done W: GPG error: http://repo.mysql.com/apt/debian stretch InRelease: The following signatures were invalid: EXPKEYSIG 8C718D3B5072E1F5 MySQL Release Engineering <mysql-build@oss.oracle.com> E: The repository 'http://repo.mysql.com/apt/debian stretch InRelease' is not signed. N: Updating from such a repository can't be done securely, and is therefore disabled by default. N: See apt-secure(8) manpage for repository creation and user configuration details.
やったこと
MySQL パッケージの鍵が期限切れになってるみたいなので apt-key
コマンドで W: GPG error: http://repo.mysql.com/apt/debian stretch InRelease: The following signatures were invalid: EXPKEYSIG 8C718D3B5072E1F5
のところの 8C718D3B5072E1F5
の新しい鍵をキーサーバーから取得する。
# apt-key adv --keyserver keys.gnupg.net --recv-keys 8C718D3B5072E1F5 Executing: /tmp/apt-key-gpghome.9ZCHkwdRZj/gpg.1.sh --keyserver keys.gnupg.net --recv-keys 8C718D3B5072E1F5 gpg: key 8C718D3B5072E1F5: "MySQL Release Engineering <mysql-build@oss.oracle.com>" 16 new signatures gpg: Total number processed: 1 gpg: new signatures: 16
新しい鍵を取得してから apt update
するとエラーが出なくなっている。
# apt update Ign:1 http://deb.debian.org/debian stretch InRelease Get:2 http://repo.mysql.com/apt/debian stretch InRelease [21.6 kB] Hit:3 http://deb.debian.org/debian stretch-updates InRelease Hit:4 http://deb.debian.org/debian stretch Release Hit:5 http://security-cdn.debian.org/debian-security stretch/updates InRelease Get:6 http://repo.mysql.com/apt/debian stretch/mysql-5.6 amd64 Packages [4798 B] Fetched 26.4 kB in 0s (41.9 kB/s) Reading package lists... Done Building dependency tree Reading state information... Done 31 packages can be upgraded. Run 'apt list --upgradable' to see them.
Redash の EC2 インスタンスのメモリが枯渇して CPU 使用率が高騰したときにやったこと。
Redash を動かしている EC2 インスタンスのメモリが枯渇して CPU 使用率が高騰したときにやったことのメモ。
EC2 インスタンスの CPU 使用率が高騰
ことの始まりは開発で使ってる EC2 インスタンスの CPU 使用率が60〜100%くらいをいったりきたりしているのに気が付いたときだった。
問題の EC2 インスタンスは t2.small
でここ数ヶ月は CPU クレジットが上限に張り付くくらい CPU 負荷が余裕がある感じだったので最近の変更が原因ぽいと思ったが、思い返してみると問題の EC2 インスタンスで動かしている Redash を少し前に v8 にアップデートしていた。
Redash のアップデートが関係してそうだなーと思いながらとりあえず ssh で問題の EC2 インスタンスに接続して状況を見てみた。
やったこと
kswapd0 プロセスが CPU を食いつぶす
ssh で問題の EC2 インスタンスに入れたので top コマンドを実行してみると kswapd0
という見慣れないプロセスが CPU を断続的に 50〜90% くらい使っていた。
調べてみるとメモリのスワップが発生しているときにときにスワップインしたりスワップアウトするカーネルスレッドっぽい。
メモリがスワップするということはメモリが枯渇している可能性が高いので free コマンドでメモリの状況を確認してみると used が 1.6GB くらいで free が 50MB くらいしかないようだった。
Redash の Docker コンテナがメモリをモリモリ食う
top, ctop コマンドを実行してしばらく様子をみていると Redash の server
と worker
の Docker コンテナが大量にメモリを使っているようだった。
問題の EC2 の Redash はあまり使っていないことが分かっているので、https://redash.io/help/open-source/admin-guide/env-vars-settings と Redashのメモリ使用量を節約する - ariarijp’s blog を参考にしながら REDASH_WEB_WORKERS
環境変数を 4 => 1 にして WORKERS_COUNT
環境変数を 2 => 1 にしてから Redash の Docker コンテナを再起動した。
Docker コンテナ再起動後に軽く Redash のクエリを発行したりダッシュボードを表示したりしてから free コマンドを実行してみると free が 100MB くらいになって少し余裕ができたが、まだスワップが発生するみたいで kswapd0
プロセスがときどき top コマンドに顔を出すようだった。
再び https://redash.io/help/open-source/admin-guide/env-vars-settings と Re:dashのキャッシュデータを削除する - Qiita を参考にして REDASH_QUERY_RESULTS_CLEANUP_MAX_AGE
環境変数を 7 => 1 にしてから Redash の Docker コンテナを再起動した。
REDASH_QUERY_RESULTS_CLEANUP_MAX_AGE
は過去のキャッシュを何日間保持するかを指定する環境変数だが、この EC2 の Redash はあまり使っていないのでキャッシュを保持する必要もあまりないのが分かっているので1日だけキャッシュを保持するようにしてみた。
Docker コンテナ再起動後にまた軽く Redash をいじってから free コマンドを実行してみると free が 350MB くらいになってだいぶ余裕ができたみたいで、 kswapd0
プロセスが top コマンドに顔を出すこともなくなった。
今後同じことが起きたら
とりあえず Redash を動かしている EC2 インスタンスのメモリが枯渇したり CPU 使用率が高騰することはなくなったけど、また同じ原因や違う原因でメモリが枯渇したりするようなら t2.small
=> t2.medium
にサイズアップすると思う。
今の使い方だと一ヶ月あたり 5USD くらい使用料金が高くなってしまうけど、調査したりとかの出費を一ヶ月あたり 5USD の出費でなくせるならむしろ安いと思うので。
参考にしたサイト
- https://redash.io/help/open-source/admin-guide/env-vars-settings
- Redashのメモリ使用量を節約する - ariarijp’s blog
- Re:dashのキャッシュデータを削除する - Qiita
とりあえずコレはやっておく
今回は Redash のミドルウェアのプロセス数を減らしたけど、参考にしたサイト Redashのメモリ使用量を節約する - ariarijp’s blog の ariarijp さんが「プラグインを無効にするともっとメモリを節約できますよ」と教えてくれたのでやっておく。
環境変数からプラグイン無効化すると、更に節約できると思います。以下は環境変数使った例ではないですが、メモリの節約具合は参考になるかとhttps://t.co/5f658WWF0r
— Takuya Arita (@ariarijp) 2019年12月13日
西暦と和暦を変換する wareki コマンドが Docker コンテナになりました。
はじめに
wareki コマンド が Docker コンテナ になりました。
もともと実行ファイル1つだけの構成でしたが、環境を汚したくないときの選択肢の1つとして Docker コンテナにしてみました。
もちろん、今までのように Releases ページからダウンロードしたり go get
とか HomeBrew でインストールして使うこともできます。
インストール方法
普通に docker image pull
でインストールします。
ただ、このあと docker conainer run
するときにイメージがローカルにないときは Docker が自動的にイメージを pull してくれるのでやらなくてもいいです。
$ docker image pull ebc2in2crc/wareki
使い方
普通に docker container run
します。
コマンドの実行が終わったらコンテナを削除するために --rm
オプションを付けるとよいと思います。
$ date "+%Y/%m/%d" 2019/05/01 $ docker container run --rm ebc2in2crc/wareki R1 $ docker container run --rm ebc2in2crc/wareki --kanji 令和1