【AWS】LinuxインスタンスのEBS I/Oタイムアウト
ちょっと仕事でNitroベースインスタンスのI/Oタイムアウトについて整理する必要があったので、備忘がてらまとめておきます。
まず前提として、EBSボリュームは、Nitroシステム上に構築されたインスタンスにおいて、NVMeブロックデバイスとし接続されています。
ここで、Nitroシステムとは何かを簡単にまとめます。
Nitroシステムは、次世代のEC2インスタンの基盤となるプラットフォームで、ユーザーのコスト削減やセキュリティ強化に寄与することができるAWS独自の基盤。
従来のハイパーバイザは物理ハードウェアとBIOSを保護し、CPUやストレージ、ネットワークを仮想化してきた。Nitroシステムでは、これらの機能を分解し、専用のハードウェアとソフトウェアにオフロードすることでサーバーのリソースの大半をインスタンスに割り当てることでコスト削減が可能となった。
つまり、Nitroシステムは、高パフォーマンス、高可用性、高セキュリティを実現するAWSで構築されたファードウェアとソフトウェアのコンポーネントの集合のこと。
話を戻すと、
Nitroシステムで構築されたインスタンスに接続されたEBSボリュームでは、OSによって提供されるデフォルトのNVMeドライバを使用する。
通常ほとんどのOSは、NVMeデバイスに送信されるI/Oオペレーションのタイムアウトを指定するのだが、大抵デフォルトのタイムアウト値は30秒となっており、この値を任意のものに変更する場合は、nvme_core.io_timeoutブートパラメータを調整することとなる。
インスタンスとEBS間のI/Oレイテンシーがこのタイムアウト値を超えた場合、Linux NVMeドライバーはI/Oに失敗し、ファイルシステムはアプリケーションにエラーを返す。
I/Oレイテンシーがタイムアウトを超えるシチュエーションとして、例えば、AWSの責任範囲であるNitroシステム基盤やNMVeドライバの不具合等でインスタンのシステムステータスチェックがNGとなった影響でI/Oタイムアウトとなり、EC2にインストールしたソフトウェアがハングってしまう場合や、インスタンスステータスチェックに失敗してしまう場合が考えられる。
このような場合、たとえAWS責任範疇のコンポーネントが復旧したとしても、ユーザー責任範疇であるハングったOSやソフトウェアを復旧させるために再起動が必要であったりと、余計な調整(工数)がかかってしまう。
上記のような事態を回避するためにも、nvme_core.io_timeout値を可能な限り最大値に設定することが推奨されている。
現在のLinuxカーネルに置ける最大値は4294967295秒となる。(以前のカーネルでは255秒)
Linuxのバージョンに応じて、タイムアウト値はすでにサポートされている最大値に設定されている場合もあるが、タイムアウト値を確認して、デフォルトの30秒のままであれば、最大値に変更するという作業を忘れないようにしよう。
Linuxディストリビューションの最大値を確認するには、示されている最大値よりも高い値を /sys/module/nvme_core/parameters/io_timeout に書き込み、ファイルを保存する際に範囲外の数値結果エラーが出力されないかどうかを確認すれば良い。
以下、具体的な設定方法。
▶︎手順①
/sys/module/nvme_core/parameters/io_timeout に値を書き込む。
# echo 4294967295 > /sys/module/nvme_core/parameters/io_timeout
▶︎手順②
/etc/default/grubのGRUB_CMDLINE_LINUX行に上記設定値を追加する。
# vi /etc/default/grub
GRUB_CMDLINE_LINUX="...nvme_core.io_timeout=4294967295" # <=
nvme_core.io_timeout=4294967295
▶︎手順③
grubの設定ファイル再構成をかける。
# grub2-mkconfig -o /boot/grub2/grub.cfg
▶︎手順④
インスタンスを再起動して、catで設定が反映されていることを確認する。
# cat /sys/module_nvme_core/parameters_io_timeout
4294967295
以上です。
参考資料