全力で怠けたい

怠けるために全力を尽くしたいブログ。

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 オプションを指定するとヘッダーを表示しない。

オプションなしの psPID とか 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 すると STATR(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 オプションを指定しなければ k6TCP コネクションを再利用するようになるので解決できる……のだが、理由があって 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 の serverworker の Docker コンテナが大量にメモリを使っているようだった。 問題の EC2 の Redash はあまり使っていないことが分かっているので、https://redash.io/help/open-source/admin-guide/env-vars-settingsRedashのメモリ使用量を節約する - 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-settingsRe: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 の出費でなくせるならむしろ安いと思うので。

参考にしたサイト

とりあえずコレはやっておく

今回は Redash のミドルウェアのプロセス数を減らしたけど、参考にしたサイト Redashのメモリ使用量を節約する - ariarijp’s blogariarijp さんが「プラグインを無効にするともっとメモリを節約できますよ」と教えてくれたのでやっておく。

西暦と和暦を変換する 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

参考にしたサイト