これはFDCServersを批判するためのレビューではありません。FDCServersのVPSを買うべきか、買うべきでないかを他人に決めてもらうための記事でもありません。私が経験したのは、1台のVPS、1つのworkload、そして一連の障害です。それだけでホスティング会社全体を評価することはできません。
開発者としての日常で起きた、ひとつのトラブルの記録です。VPSはしばらく正常に動作し、すでに3 TBを超えるトラフィックを転送していました。ところがその後、通常のworkloadで極端な遅延が発生するようになりました。ページの応答に非常に長い時間がかかったり、完全にtimeoutしたりします。最初に疑ったのはapplication、Nginx、memory、network、connection limit、あるいは単純な高負荷でした。しかしLinuxのmetricsは別の場所を示していました。
VPSは最初から遅かったわけではない
障害と障害の間には、完全に正常に見える時間帯もありました。ある正常時にはD-stateのprocessは0、CPU iowaitはほぼ0%、disk latencyは約2–4 ms、I/O PSIもほぼゼロでした。
D-state processes: 0
CPU iowait: ~0%
disk latency: ~2–4 ms
I/O PSI some: 0.04
I/O PSI full: 0.04この瞬間だけSSHで入り、top、free -h、df -h、systemctl status nginxを確認していたら、VPSは正常だと判断していたと思います。ところが通常のworkloadが戻ると、状態は急激に変化しました。
18.7秒のreadが調査の方向を変えた
特に決定的だったiostatのsampleのひとつがこれです。
r_await = 18744 ms
f_await = 53561 ms
aqu-sz = 128.54
util = 100.10%
read = 88 KB/s重要なのは、これらをまとめて見ることです。完了したreadの平均latencyは約18.7秒、flush latencyは約53.6秒。平均I/O queueは128を超えているのに、実際のread throughputはわずか88 KB/sでした。大量のデータを高速に処理しているためdiskがbusyだったわけではありません。storage pathがI/Oの完了待ちに膨大な時間を費やしていました。
iowaitとPSIがシステム全体のI/O pressureを示した
最悪の時間帯では、vmstatに4~9個のblocked process、97~100%のCPU iowait、0%のCPU idleが記録されました。iowaitはapplicationがCPUを100%消費しているという意味ではありません。実行できる仕事が、未完了のI/Oを待っているということです。
Linux Pressure Stall Informationを見ると、さらに明確でした。
I/O PSI some avg10 = 99.14
I/O PSI full avg10 = 95.55別の再現時にはfullが約98%まで上がりました。Disk utilizationはdeviceがbusyかどうかを示します。一方、PSIはそのresourceの不足によってworkloadがどれだけstallしているかを示します。95~98%のI/O pressureが持続する状態は、軽微なperformance低下ではありません。
D-stateとkernel stackはapplicationより下の層を指していた
次に、何がblockされているのかを確認しました。同じ時間帯にjbd2、systemd-journald、Nginx worker、Nginx cache process、その他のfilesystem処理がD-stateに入っていました。applicationだけが止まっているならapplicationを調べます。しかしNginx、system journal、EXT4 journalまで同時に止まっているなら、共通して依存しているstorageを疑うのが自然です。
EXT4のjournaling pathには次の関数が含まれていました。
wait_on_buffer
jbd2_log_wait_commit
jbd2_journal_commit_transactionNginx workerは通常のfile readで待機していました。
folio_wait_bit_common
filemap_read
generic_file_read_iter
ext4_file_read_iter
vfs_read
pread64ある時点では、Nginx taskが122秒以上blockされているとkernelが報告しました。それでもNginx自体はactiveと表示されます。しかしworkerが仕事を完了できるという意味ではありません。runningと正常稼働は別の状態です。
3 msで返るbackendがapplicationとfilesystem pathを切り分けた
もっとも分かりやすかったのは、Nginx経由とlocal backendへの直接アクセスを比較したテストです。Nginx経由ではconnectionまたはTLS timeoutでHTTP=000になりました。一方、backendへの直接requestは約3 msで完了しました。
connect = 0.000423 s
TTFB = 0.003063 s
total = 0.003139 sこのテストではHTTP statusそのものは重要ではありません。backendはconnectionを受け付け、requestを処理し、ほぼ即座にresponseを返していました。その一方でNginx workerはEXT4 readの待機中です。これによってapplicationの実行と、その前段にあるfilesystem依存のpathを切り分けることができました。
障害は再現でき、そしてまた消えることもあった
ある再現テストの直前は正常でした。
HTTP: 200
D-state: 0
CPU iowait: 3%
r_await: ~1.18 ms
I/O PSI full: ~2.95%約30秒後にはこうなりました。
D-state: 4
CPU iowait: 91%
CPU idle: 0%
I/O PSI some: 86.11%
I/O PSI full: 78.02%
r_await: 236.50 ms
HTTP: 000その後CPU iowaitは96~100%、I/O PSI fullは約98%、HTTPS queueは512に達し、HTTP checkは失敗したままでした。単にVPSが遅いと表現するより、はるかに有用な証拠です。
workloadを外すと、逆方向の変化もすぐに起こりました。
D-state: 0
CPU iowait: 6%
r_await: ~0.98 ms
queue depth: ~0.07
HTTP: 200これがintermittentなstorage障害の厄介なところです。復旧後にproviderが確認すれば、本当に正常なlatencyが見えることがあります。しかし、それでは10分前に起きたことは説明できません。そのため正確なUTC timestampを残すことが重要になりました。
誤解しやすい2つの指標:await=0と空き容量
障害中なのにr_await = 0と表示されるsampleもありました。その時点でもiowaitは高く、processはD-state、I/O requestはin-flightのまま、完了するreadはほぼありません。Latency statisticsは完了したI/Oを基準に計算されます。sampling interval内でoperationが完了しなければ、完了latencyの平均には入りません。そのためゼロだから即時応答しているとは限りません。
Disk fullnessも疑いました。後の時点ではfilesystemが私なら許容しないほど埋まっていましたが、同じ種類のfailureはroot filesystemが約24%しか使われていない時点でもすでに発生していました。その時は約1.2 GiBのRAMがavailableで、inode usageは約5%、network interfaceにもerrorやdropped packetはありませんでした。したがってdisk fullnessだけで一連の問題を説明することはできません。
証明できたことと、できなかったこと
VPS内部から観測できるのはapplication、Linux VFS、EXT4、virtual block deviceまでです。その先にはprovider側のvirtualization、distributed storage、storage network、physical device、schedulingなど、guestから見えない層があります。
したがって、特定のphysical SSDが故障していた、特定のstorage nodeやnetwork path、virtualization componentがroot causeだった、と断定することはできません。
一方で、次のことはかなり強く言えます。私のLinux guestに提示されたvirtual storage pathは繰り返し、通常のfilesystem I/Oが数秒を要する、あるいは妥当な時間内に完了しない状態に入っていました。 根拠はiostat、PSI、D-state、kernel wait stack、EXT4/jbd2のwait、Nginxのfilesystem wait、queue depth、request timingです。私に必要なengineering diagnosisとしては十分でしたが、physical root causeを確定するには不十分でした。
それまでの3 TB超のトラフィックと後のstallは矛盾しない
最初はここが不思議でした。storageに問題があるなら、なぜそれまで数TBを正常に転送できたのか。
理由のひとつは、network trafficとphysical disk I/Oが同じではないことです。あるfileをbacking storageから一度読み、Linux page cacheに残せば、その後はmemoryから何度も配信できます。ネットワークで3 TB転送したからといって、physical diskから異なるデータを3 TB読んだことにはなりません。
また、infrastructureの状態は時間とともに変わります。cache state、storage load、queueing、host placement、他のworkloadなどは一定ではありません。昨日正常だったVPSが、今日もまったく同じstorage behaviorを示す保証はありません。
最終的に、より深いroot causeを待つのをやめた
正確なtimestamp、vmstat、iostat、PSI、blocked processのsnapshot、kernel stack、filesystem wait、queue depth、HTTP timingを集めました。DiagnosticsをFDCServersに送り、infrastructure levelの詳しい説明を待ちました。
かなり長く待ちましたが、最終的には待つのをやめました。運用上の判断に必要なことはすでに分かっていました。問題は再現可能で深刻、application layerより下で観測され、物理的な原因は私のVPSから見えない領域にありました。
返金を求めたところ、FDCServersは返金した
収集したdiagnosticsと問題の概要をFDCServersへ送り、serviceのcancelとrefundを依頼しました。返金は実行されました。
つまり、この話は返金を巡る長い争いで終わったわけではありません。最終的な技術説明を待ちましたが、これ以上待たないと決め、手元の証拠を送り、返金を求めました。FDCServersは返金してくれました。
この経験のあとに変えたこと
一番役に立ったのは、あるhosting companyが良いか悪いかを決めたことではありません。遅いLinux serverをdebugする方法が変わったことです。
top、free -h、df -hは今も使いますが、以前より早い段階で次も確認します。
date -u
uptime
cat /proc/pressure/io
cat /proc/pressure/memory
cat /proc/pressure/cpu
vmstat 1 10
iostat -x 1 10
ps -eo state,pid,ppid,etime,wchan:50,comm,args | awk 'NR==1 || $1 ~ /^D/'
ss -lntp
journalctl -k --since '30 min ago' --no-pager可能ならrequest pathも分離して確認します。public request、local Nginx、direct backend、filesystem、block-device metricsです。問いは単に「なぜserverが遅いのか」ではなくなりました。どのlayerで、仕事が完了しなくなっているのか。 そこを探します。
また、可能であればrebootする前に証拠を取ります。Rebootでserviceは戻るかもしれませんが、intermittentな障害を診断するために重要なD-state、PSI、queue、latencyも同時に消えてしまうからです。
最後に
ホスティング記事を書く材料が欲しくてFDCServersのVPSを買ったわけではありません。欲しかったのは帯域の大きいserverです。しばらくはまさにそれが得られ、実際のworkloadを処理し、3 TBを超えるデータを転送しました。
その後、通常のworkloadで再現性を持って、iowait最大100%、I/O PSIほぼ100%、read最大18.7秒、flush latency 53秒超、大きなqueue、filesystem readでblockされるNginx、I/O待ちのEXT4/jbd2という状態が発生しました。
どのphysical componentやhost-side componentが原因だったのかは最後まで分かりませんでしたし、分かったふりをする必要もありません。障害が現れるlayerを特定し、application problemと切り分けるだけの証拠を集め、より深いroot-cause explanationを待つのをやめ、返金を求めました。FDCServersは返金しました。
これはすべてのFDCServers VPSに対する評価ではありません。Serviceがactive、processがrunningと表示されていても、machineが有効な時間のほぼすべてをstorage待ちに費やしていることがある。そのことを示す、ひとつの記録です。