Knのアウトプット

Knです。IT系。学んだことをアウトプットします。詳細な記述は世の中いくらでもあるので、自分がそらで説明できるくらい短くまとめて。

LinuxにおけるIPフォワーディング

概要

LinuxにはIPパケットをフォワーディングする機能が具備されている。IPフォワーディングはあるネットワークから受け取ったパケットを別のネットワークに転送する技術である。言い換えると、2つのNICの間でパケットを転送する技術である。これにより、パケットが異なるネットワークの間を往き来できるようになる*1

LinuxでIPフォワードを有効にするには、カーネルパラメータ net.ipv4.ip_forwardの値を1にする必要がある(設定方法は過去エントリを参照 カーネルパラメータの設定方法(CentOS 8) - Knのアウトプット)。 カーネルパラメータを設定した段階では2つのNIC間でパケットが転送できるようになっただけで、適切な通信が行われるようになったわけではない。実際にフォワーディングされるためにはルーティングテーブルを適切に設定する必要がある。

設定例

サーバーA、B、Cの3台があり、Bに対しフォワーディングの設定を行う。 Bは2つのネットワーク、192.168.0.0/24192.168.122.0/24に所属している。

[root@nuc-centos8 ~]# ip a
(略)
4: wlp0s20f3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 0c:7a:15:da:07:37 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.14/24 brd 192.168.0.255 scope global dynamic noprefixroute wlp0s20f3
(略)
5: virbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 52:54:00:9c:81:ac brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
(略)

サーバAは192.168.0.0/24のみに所属している。

[root@virtualbox-centos7 ~]# ip a
(略)
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:08:35:9c brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.92/24 brd 192.168.0.255 scope global noprefixroute enp0s8
(略)

サーバCは192.168.122.0/24のみに所属している。

[root@kvm-centos8 ~]# ip a
(略)
2: ens2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:34:01:09 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.100/24 brd 192.168.122.255 scope global noprefixroute ens2
(略)

サーバAからサーバCへpingを打つ。このときサーバBでIPフォワーディングが有効になっており、ルーティングテーブルが設定されていればpingは到達する。 なお、サーバAからサーバBにパケットが飛ぶようにするため、サーバAのデフォルトゲートウェイはサーバBのIPアドレスにしてある。

[root@virtualbox-centos7 ~]# nmcli con show enp0s8
(略)
ipv4.addresses:                         192.168.0.92/24
ipv4.gateway:                           192.168.0.14
(略)

サーバBではすでにIPフォワーディングが有効( net.ipv4.ip_forward = 1)で、ルーティングテーブルも設定済みである*2

[root@nuc-centos8 ~]# sysctl -a | grep net.ipv4.ip.forward
net.ipv4.ip_forward = 1
net.ipv4.ip_forward_update_priority = 1
net.ipv4.ip_forward_use_pmtu = 0
[root@nuc-centos8 ~]# ip r
default via 192.168.0.1 dev wlp0s20f3 proto dhcp metric 600
192.168.0.0/24 dev wlp0s20f3 proto kernel scope link src 192.168.0.100 metric 600
192.168.0.0/24 dev wlp0s20f3 proto kernel scope link src 192.168.0.14 metric 600
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1

サーバAからpingを打つ。応答が返ってきていることがわかる。

[root@virtualbox-centos7 ~]# ping 192.168.122.100
PING 192.168.122.100 (192.168.122.100) 56(84) bytes of data.
64 bytes from 192.168.122.100: icmp_seq=1 ttl=63 time=106 ms
64 bytes from 192.168.122.100: icmp_seq=2 ttl=63 time=22.9 ms
64 bytes from 192.168.122.100: icmp_seq=3 ttl=63 time=41.1 ms
(略)

pingを打ちっぱなしのままサーバCでtcpdumpを使いパケットを監視してみると、ICMPのrequestが飛んできている。

[root@kvm-centos8 ~]# tcpdump -i any src host 192.168.0.92 -n
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
11:07:47.686403 IP 192.168.0.92 > 192.168.122.100: ICMP echo request, id 2747, seq 57, length 64
11:07:48.710472 IP 192.168.0.92 > 192.168.122.100: ICMP echo request, id 2747, seq 58, length 64
11:07:49.734488 IP 192.168.0.92 > 192.168.122.100: ICMP echo request, id 2747, seq 59, length 64
11:07:50.656000 IP 192.168.0.92 > 192.168.122.100: ICMP echo request, id 2747, seq 60, length 64
(略)

pingtcpdumpを仕掛けたまま、サーバB上でIPフォワーディングを無効化してみる。一時的に無効化するにはファイル/proc/sys/net/ipv4/ip_forwardの値を直接0に書き換える。

[root@nuc-centos8 ~]# echo 0 > /proc/sys/net/ipv4/ip_forward

サーバAのping応答が止まる。

(略)
64 bytes from 192.168.122.100: icmp_seq=126 ttl=63 time=98.5 ms
64 bytes from 192.168.122.100: icmp_seq=127 ttl=63 time=117 ms
(ここで止まる)

サーバCでもtcpdumpの更新が止まる。

(略)
11:11:26.734165 IP 192.168.0.92 > 192.168.122.100: ICMP echo request, id 2748, seq 126, length 64
11:11:27.757086 IP 192.168.0.92 > 192.168.122.100: ICMP echo request, id 2748, seq 127, length 64
(ここで止まる)

サーバB上でIPフォワーディングを再び有効にするとpingの応答が返り、tcpdumpの更新が再開される(応答が返ってきている様子等は割愛する)。

[root@nuc-centos8 ~]# echo 1 > /proc/sys/net/ipv4/ip_forward

参考にしたもの

IPフォワード(IP Forward) | Linux技術者認定 LinuC | LPI-Japan

xtech.nikkei.com

*1:フォワーディングとルーティングは厳密には区別される。ルーティングは転送先の経路を選択すること、フォワーディングは実際に転送することである。ただし、ルーティングといった場合に経路選択と転送をまとめて呼ぶケースもあるので、文脈に応じて読み取る必要がある。

*2:192.168.0.100はネットワークデバイスNIC)wlp0s20f3に振ったセカンダリIPアドレスであり、今回の実験には関係ないので無視してよい。

カーネルパラメータの設定方法(CentOS 8)

カーネルパラメータの設定箇所

世の中の記事では、net.ipv4.ip_forwardをはじめとしたカーネルパラメータは/etc/sysctl.confに記述するとあるが、ほかのファイルに分散されて書かれていることがある。 筆者の手元にある、CentOS 8では以下のように書かれていた。

[root@localhost ~]# cat /etc/sysctl.conf
# sysctl settings are defined through files in
# /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
#
# Vendors settings live in /usr/lib/sysctl.d/.
# To override a whole file, create a new file with the same in
# /etc/sysctl.d/ and put new settings there. To override
# only specific settings, add a file with a lexically later
# name in /etc/sysctl.d/ and put new settings there.
#
# For more information, see sysctl.conf(5) and sysctl.d(5).

To override a whole file, create a new file with the same in /etc/sysctl.d/ and put new settings there.とあるので、/etc/sysctl.dに自分がデフォルトから変えたいカーネルパラメータを記述したファイルを置くと思われる。 /etc/sysctl.dを見てみる。99-sysctl.confというファイルのみが置かれているが、/etc/sysctl.confへのシンボリックリンクになっている。

[root@localhost ~]# ls -lhtra /etc/sysctl.d/99-sysctl.conf
lrwxrwxrwx. 1 root root 14 Apr 23  2020 /etc/sysctl.d/99-sysctl.conf -> ../sysctl.conf

つまり、/etc/sysctl.confのファイルも含め、/etc/sysctl.d配下に置かれたファイルがユーザ設定として上書きされる。

Vendors settings live in /usr/lib/sysctl.d/とあるので、CentOSディストリビューションに同梱されているアプリケーションの設定に関わるカーネルパラメータがここにあると想定される。

[root@localhost ~]# ls -lhtr /usr/lib/sysctl.d/
total 24K
-rw-r--r--. 1 root root  246 May 11  2019 50-libkcapi-optmem_max.conf
-rw-r--r--. 1 root root  636 Apr 23  2020 50-pid-max.conf
-rw-r--r--. 1 root root 1.3K Apr 23  2020 50-default.conf
-rw-r--r--. 1 root root  524 Apr 23  2020 50-coredump.conf
-rw-r--r--. 1 root root 1.8K Apr 24  2020 10-default-yama-scope.conf
-rw-r--r--. 1 root root  499 May 28  2020 60-libvirtd.conf

デフォルトでは/run/sysctl.dは存在しなかった。

[root@localhost ~]# ls -lhtr /run/sysctl.d
ls: cannot access '/run/sysctl.d': No such file or directory

設定例

試しにパケット転送を制御するカーネルパラメータであるnet.ipv4.ip_forwardを設定してみる。デフォルトではオフ(=0)になっている。なお、カーネルパラメータは<TUNABLE_CLASS>.<PARAMETER>=<TARGET_VALUE>という形式になる。この例では<TUNABLE_CLASS>netipv4<PARAMETER>ip_forward<TARGET_VALUE>が0か1、という具合である*1

[root@localhost ~]# sysctl -a | grep net.ipv4.ip_forward
net.ipv4.ip_forward = 0
net.ipv4.ip_forward_update_priority = 1
net.ipv4.ip_forward_use_pmtu = 0

/proc/sys/<TUNABLE_CLASS>/<PARAMETER>カーネルパラメータの<TARGET_VALUE>のみが記載されたテキストファイルがあり*2、それでも確認可能*3

[root@localhost ~]# cat /proc/sys/net/ipv4/ip_forward
0

設定ファイルを作成し*4、設定を反映する。

[root@localhost ~]# echo "net.ipv4.ip_forward = 1" > /etc/sysctl.d/net.ipv4.ip_forward.conf
[root@localhost ~]# cat /etc/sysctl.d/net.ipv4.ip_forward.conf
net.ipv4.ip_forward = 1
[root@localhost ~]# sysctl -p /etc/sysctl.d/net.ipv4.ip_forward.conf
net.ipv4.ip_forward = 1

設定が反映されている。

[root@localhost ~]# sysctl -a | grep net.ipv4.ip_forward
net.ipv4.ip_forward = 1
net.ipv4.ip_forward_update_priority = 1
net.ipv4.ip_forward_use_pmtu = 0
[root@localhost ~]# cat /proc/sys/net/ipv4/ip_forward
1

ちなみに、再起動後も反映されている。

[root@localhost ~]# reboot
(略)
localhost login: root
Password:
Last login: Fri Jan 15 19:49:21 on ttyS0
[root@localhost ~]# sysctl -a | grep net.ipv4.ip_forward
net.ipv4.ip_forward = 1
net.ipv4.ip_forward_update_priority = 1
net.ipv4.ip_forward_use_pmtu = 0
[root@localhost ~]# cat /proc/sys/net/ipv4/ip_forward
1

参考にしたもの

第5章 ランタイム時のカーネルパラメーターの設定 Red Hat Enterprise Linux 8 | Red Hat Customer Portal

IPフォワード(IP Forward) | Linux技術者認定 LinuC | LPI-Japan

*1:ipv4は分類上、ではなく<TUNABLE_CLASS>のほうに属するというのは筆者の予測が入っている(出典がないので)。

*2:<TUNABLE_CLASS>が階層化されている場合は、ディレクトリも階層化されている。まさに、この例だとnetディレクトリの中にipv4ディレクトリがあるというように階層化されている。

*3:ここの値を書き換えてもカーネルパラメータの変更はできるが再起動したら元に戻る。

*4:ファイル名は何でもよい

SGIDを実行ファイルに設定した際の挙動

SGIDとは

SGID(Set Group ID)とは、実行権のあるファイルに設定される特殊なアクセス権の1つ。 実行ファイルにSGID(Set Group ID)が設定されている場合は、その実行ファイルを実行すると、実行ファイルの所有グループの権限でファイルが実行される。

知りたいこと

実行ファイルの所有グループの権限でファイルが実行されるとは具体的にはどういうことか?

Linuxのプロセスにおいては、実効グループIDというIDが設定される*1。通常はプロセスは、実行ファイルを実行したユーザの所有グループが実効グループIDになる。ここで、実行ファイルにSGIDというフラグを設定すると、実行ファイルの所有者がプロセスの実効グループIDになる。

動作検証

概要

philというユーザで検証用のプログラムを実行し、実行中のプロセスの実効グループIDを確認する。検証用のプログラムの所有グループはtestuserである。

philの所有グループIDは1007である。

[phil@nuc-centos8 ~]$ id
uid=1002(phil) gid=1007(accounting) groups=1007(accounting) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

testuserの所有グループIDは1001である。

[testuser@nuc-centos8 test]$ id
uid=1001(testuser) gid=1001(testuser) groups=1001(testuser),10(wheel) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

検証用プログラムの作成

簡単なC言語のプログラムを用意する。無限ループするだけのものである。

#include <stdio.h>

int main() {
        printf("now executing\n");
        while (1) {
        }
}

コンパイルする。loopという名前の実行ファイルができている。

[testuser@nuc-centos8 test]$ gcc loop.c -o loop
[testuser@nuc-centos8 test]$ ls -lhtra
total 20K
-rw-rw-r--. 1 testuser testuser 123 Jan 13 07:33 loop.c
drwxrwxrwx. 5 testuser testuser 144 Jan 13 07:33 ..
drwxrwxr-x. 2 testuser testuser  32 Jan 13 07:33 .
-rwxrwxr-x. 1 testuser testuser 13K Jan 13 07:33 loop

loopをコピーしてloop-sgidという実行ファイルを用意し、loop-sgidにSGIDを設定する。見づらいが、パーミッションが-rwxrwxr-xから-rwxrwsr-xに変化している。

[testuser@nuc-centos8 test]$ cp loop loop-sgid
[testuser@nuc-centos8 test]$ ls -lhtra
total 36K
-rw-rw-r--. 1 testuser testuser  93 Jan 13 07:48 loop.c
drwxrwxrwx. 5 testuser testuser 144 Jan 13 07:48 ..
drwxrwxr-x. 2 testuser testuser  49 Jan 13 07:48 .
-rwxrwxr-x. 1 testuser testuser 13K Jan 13 07:48 loop
-rwxrwxr-x. 1 testuser testuser 13K Jan 13 07:52 loop-sgid
[testuser@nuc-centos8 test]$ sudo chmod g+s loop-sgid
[testuser@nuc-centos8 test]$ ls -lhtra
total 36K
-rw-rw-r--. 1 testuser testuser 123 Jan 13 07:33 loop.c
drwxrwxrwx. 5 testuser testuser 144 Jan 13 07:33 ..
-rwxrwxr-x. 1 testuser testuser 13K Jan 13 07:33 loop
drwxrwxr-x. 2 testuser testuser  49 Jan 13 07:35 .
-rwxrwsr-x. 1 testuser testuser 13K Jan 13 07:35 loop-sgid

実効グループIDの確認

SGIDの設定されていないプログラム(loop)を実行した場合。このとき、philの所有グループ1007が実効グループIDになることが期待される。

[phil@nuc-centos8 test]$ ./loop
now executing

別端末でプロセスIDを確認し、実効ユーザIDを出力する。期待通り、testuserの所有グループのIDの1007で実行されている。

[root@nuc-centos8 ~]# top

top - 08:18:21 up 16 days,  8:07,  4 users,  load average: 0.38, 0.43, 0.28
Tasks: 237 total,   2 running, 235 sleeping,   0 stopped,   0 zombie
%Cpu(s): 12.7 us,  0.0 sy,  0.0 ni, 87.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :  31778.6 total,  30562.0 free,    471.7 used,    744.8 buff/cache
MiB Swap:  16036.0 total,  16036.0 free,      0.0 used.  30888.3 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 280107 phil      20   0    4328    808    744 R  93.8   0.0   0:17.97 loop

(略)

[root@nuc-centos8 ~]# ps -o sgid 280107
 SGID
 1007

一方、SGIDを設定したプログラム(loop-sgid)を実行する。このとき、testuserの所有グループ1001が実効グループIDになることが期待される。

[phil@nuc-centos8 test]$ ./loop-sgid
now executing

期待通り、所有グループID 1001で実行されている。

[root@nuc-centos8 ~]# top

top - 08:22:14 up 16 days,  8:11,  4 users,  load average: 1.00, 0.75, 0.46
Tasks: 240 total,   3 running, 237 sleeping,   0 stopped,   0 zombie
%Cpu(s): 12.9 us,  0.0 sy,  0.0 ni, 87.1 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :  31778.6 total,  30561.7 free,    472.1 used,    744.8 buff/cache
MiB Swap:  16036.0 total,  16036.0 free,      0.0 used.  30887.9 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 280140 phil      20   0    4328    688    624 R  93.8   0.0   1:17.09 loop-sgid

(略)

[root@nuc-centos8 ~]# ps -o sgid 280140
 SGID
 1001

今後の課題

実行中プロセスの所属グループ(Linux) - Qiita によると、/proc/プロセスID/statusGroupsでもプロセスの所属グループが確認できるとのこと。

ところが、実行してみると、どうも実効グループIDを表していない様子。

SGIDを設定していないプログラムを実行した場合。

[root@nuc-centos8 ~]# cat /proc/280107/status | grep Group
Groups: 1007

SGIDを設定したプログラムを実行した場合(実効グループIDを表すのであれば1001になっているはず)。

[root@nuc-centos8 ~]# cat /proc/280140/status | grep Group
Groups: 1007

おそらく、ここは実グループIDのほうを設定していると予想されるだが、詳細を確認する時間がなくなったので今後の課題とする。

参考にしたもの

SGID(Set Group ID) - 特殊なアクセス権

unix.stackexchange.com

qiita.com

*1:実効ユーザIDもある。それに関する記事は多いのだが実効ユーザIDについて書かれているものが少ないので記事を書いた。また、実ユーザID、実グループIDもあり、これらも実効ユーザIDや実効グループIDとは別である

sar

sarとは

sar(System Admin Reporter)とはLinux上でのリソース情報を取得するツール(コマンド)で、sysstatパッケージの一部に含まれている。CPU、メモリ、ディスク、ネットワークに関する情報が取得できる。取得対象は実行時のオプションを指定することで変更することができる。本記事ではオプションや、実行時の各データの意味の詳細は割愛する。

使い方

コマンドによる一時的な実行

sar (取得対象を指定するオプション) 情報取得間隔 情報取得回数を実行すればよい。以下は実行例である。取得対象を指定しなかったため、デフォルトのCPUに関する値が取得されている。

# sar 1 5
Linux 3.10.0-1127.el7.x86_64 (localhost.localdomain)    2020年10月02日  _x86_64_        (1 CPU)

07時14分02秒     CPU     %user     %nice   %system   %iowait    %steal     %idle
07時14分03秒     all      0.00      0.00      0.00      0.00      0.00    100.00
07時14分04秒     all      0.00      0.00      0.99      0.00      0.00     99.01
07時14分05秒     all      0.00      0.00      0.99      0.00      0.00     99.01
07時14分06秒     all      0.00      0.00      0.00      0.00      0.00    100.00
07時14分07秒     all      0.00      0.00      0.00      0.00      0.00    100.00
平均値:      all      0.00      0.00      0.40      0.00      0.00     99.60

定期的なシステムの状態の保存

人がコマンドでsarを実行する以外に、sysstatとして定期的にシステム状態を保存する仕組みが用意されている。

sysstatにはsarのほかにsadcコマンドが含まれている。sarはsadcと連動して動作する。sadcはシステム状態をバイナリ形式で収集するコマンドで、sarはsadcが収集したバイナリデータをテキスト形式に変換する。sysstatパッケージにはsa1、sa2*1というスクリプトが用意されている。sa1はsadcコマンドの実行を行うもの、sa2はsarの実行を行うもので、スクリプト内では入出力ファイル等を定義している。sa1はsaXX(XXは日付)というファイルにバイナリデータを出力する。sa2はsaXXをsarXX(XXは日付)というテキストファイルに変換する。sa1とsa2の定期実行はcronに記載されている。デフォルトの実行設定はではsa1は10分ごと、sa2は1日1回である*2

f:id:tanke25616429:20201002064843p:plain
sar/sadcの関係(https://www.atmarkit.co.jp/ait/articles/0303/15/news004_2.htmlより引用)

sadf

sarによって作られたテキストデータをCSVXML等のフォーマットに整形するsadfというツールもある。システムのログ情報を機械可読性の高い形式にすることがsadfの1つの目的である。

参考にしたもの

wing-degital.hatenablog.com

linux.die.net

障害の兆候を見逃さないためのサーバ監視 (2/3):Linux管理者への道(7) - @IT

sar で収集したリソース使用情報が sadf コマンドで TSV として出力できる - 映画は中劇

linux.die.net

qiita.com

*1:sa1は/usr/lib/sa/sa1もしくは/usr/lib64/sa/sa1に配置されている。sa2も/usr/lib/sa/sa2や/usr/lib64/sa/sa2に配置。

*2:データの出力(sadc)は頻繁に行い、データの変換(sar)は1日1回まとめて、ということだろう。

udev

udevとは

udevとは、Linuxカーネル用のデバイス管理ツールのこと。

udev

udevはデバイスファイルを動的に管理するための仕組みで、ハードウェアがシステムに接続された際に対応するデバイスファイルを作成する役割を持つ。udevdというデーモンプログラムとして動作している。なお、ハードウェアの検出はudevの役割ではなくカーネルが行っており、udevdはカーネルからその情報を受け取り、機能する。

参考にしたもの

https://ja.m.wikipedia.org/wiki/Udev

いますぐ実践! Linuxシステム管理

ストレージ

ストレージとは

データを蓄積する入れ物のこと。具体的には文脈に応じて取る意味が異なる。IT*1の文脈に限っても以下の使い方がある。

  • コンピュータ内の記憶装置(HDDやSDD等の補助記憶装置や、USBメモリ等の外部記憶装置)
  • ストレージサーバのこと

ITシステムにはストレージは不可欠な存在であり、必ずストレージ機能を提供しているものがどこかにある。個々のシステムで「ストレージ」と言う言葉が何を指しているのかは利用している機器、ソフトウェア、アーキテクチャなどにより多岐にわたる*2

ストレージサーバについて

ストレージサーバは、サーバの一種でストレージを機能として提供することを目的としている*3。ストレージを制御するソフトウェアがストレージサーバには搭載されている。

ストレージサーバもハードウェアと一体化しているものが多いが、ソフトウェアとして提供されており汎用のサーバ機器上にストレージソフトウェアをインストールして利用するものもある*4

参考にしたもの

「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典>ストレージ

ストレージOSって何?初心者のための基礎講座 | ストレージチャンネル

*1:本ブログの主旨からして当たり前だが。

*2:LinuxサーバにNFSをインストールしてデータ置き場にしているパターンや、VMwareのESXiサーバにvSANをインストールして仮想ストレージを形成するパターン、物理的なストレージをネットワーク経由で接続しているパターン等。人と会話するときはどういう意味で「ストレージ」と言っているかを確認しながら進めるのがよい。

*3:実は、この記述の裏付けとなる記事はなかったので、筆者の独自定義である。

*4:CiscoやJuniper等のハードウェア一体のネットワーク機器と、ネットワークにおけるNFVの関係と似ている。

記憶領域ごとのレイテンシの目安

背景

以前の記事(コンピュータにおける記憶領域 - Knのアウトプット)で、コンピュータでの各記憶領域の入出力の速さを比較した。実際のスケール感をイメージしておくためメモする。

レイテンシのスケール感比較

レイテンシの目安を示したサイトがあったので(計算機の代表的なレイテンシとスケール感Latency Numbers Every Programmer Should Know)、それを参考にまとめる*1。両サイトで数値にずれがある場合*2、両サイトの最大値と最小値を採用しその間に収まるものとする。カッコ内の何倍、というのはかなり端折った値にしている(規模をつかむのが重要なため)。

  • CPUサイクル(基準):0.3ns*3
  • キャッシュ:1ns~10数ns(基準の3倍~5倍程度、数クロック程度)*4
  • メモリ:100ns~120ns(基準の30倍~40倍、キャッシュアクセスの10~100倍)
  • SSD:16μs~150μs(基準の5×104倍~5×105倍、メモリアクセスの100倍~1000倍)
  • HDD:1ms~10ms(基準の3×106~3×107倍、SSDの100倍~1000倍)

いろいろなケースをすごく乱暴に省略すると、CPUサイクルは1ns未満、キャッシュはその数倍、メモリはその100倍、SSDはその100倍、HDDはその100倍、というのが覚えやすい。

その他興味深い数値

Latency Numbers Every Programmer Should Know によると同一データのラウンドトリップタイムは500μs程度。

一方、第2回 ネットワーク遅延と高速化:教科書には載っていない ネットワークエンジニアの実践技術|gihyo.jp … 技術評論社によれば、東京~大阪でのネットワーク遅延が20ms程度が目安なので、当たり前だが同一マシン内のデータアクセスや同一データセンタ内のデータアクセスに比べれば低速である。ping値の測定方法と速度目安 どれくらいの速度ならOK? | フレッツ光ナビによると、オンラインゲームをするケースでは20msは超高速ではないが高速といった体感で、50msを超えると人間に遅延が体感されるらしい。

参考にしたもの

計算機の代表的なレイテンシとスケール感 - ゆううきメモ

Numbers Every Programmer Should Know By Year

NetApp HCI -番外編- NetApp HCIの圧倒的ストレージパフォーマンスっ!!|技術ブログ|C&S ENGINEER VOICE

www.idcf.jp

e-words.jp

ping値の測定方法と速度目安 どれくらいの速度ならOK? | フレッツ光ナビ

第2回 ネットワーク遅延と高速化:教科書には載っていない ネットワークエンジニアの実践技術|gihyo.jp … 技術評論社

*1:IOPSやスループットの指標は本記事の対象外とする

*2:おそらく、実験条件の違いや、ハードウェアそのもの速度の進歩があるため、計測した時期によって違う。

*3:クロック周波数がだいたいGHz(=109 Hz)オーダーなのでクロック周期はその逆数で10-9でnsオーダーになる。

*4:当然L1<L2<L3だが、いずれにしてもこの範囲に収まる。