この時期、ここ近年は夏休みなんて関係ないぜだったんですが、今年は諸般の事情により夏休みになりました。
みなさんは夏休みいかがお過ごしでしょうか。
で、夏休みに入る前にトラブルを片付けておくということで、お客さんのところでNASとMacを10GBase-Tでつないだのに、NAS上のQuickTimeムービーを再生したらコマ落ちするから性能出てないんじゃないかというお話が来てたのを片付けに。
状況を確認したところ、QuickTimeムービーを再生すると確かにコマ落ちするんですが、ファイル転送はそんなに遅くないし、ベンチマークソフトでNASへのディスクアクセスを計測しても軽く500MByte/sec以上とか出るので一見全く問題なさそう。
変だなーと思ってパケットキャプチャしてみたところ、4パケットごとにACKがMacから返してるんだけど、それが約100msぐらい遅れてる。
んー。これなんか昔に見たよなーと思い調べたところ、Delayed ACKとNagleアルゴリズムの組み合わせによる問題。
あーそういえばそんなのあったあった。
どういう問題かを簡単に説明しときましょう。
まず、前提知識。
Delayed ACKとNagleアルゴリズムはいずれもTCPのプロトコルオーバーヘッドを削減するための実装です。
Delayed ACKは受信側でACK応答を遅らせ、受信ウィンドウの更新や応答データをまとめて送ります。遅延を解除し、送信する条件は以下のとおり。
一方Nagleアルゴリズムはデータの送信を遅らせ、複数の小さなパケットをまとめて1つのパケットで送信するものです。こちらの送信する条件は以下のとおり。
Delayed ACKが受信側、Nagleアルゴリズムが送信側で有効になっていると、以下の様な状況が起こることがあります。
この問題、昔からあって最近見かけなかったから対策されたんじゃないのかなーと思ってたら、以下のようなBlog記事を発見。
Performance Tuning the Network Stack on Mac OS X Part 2
これのExplanation of Configuration Optionsの7番目にDelayed ACKとNagleアルゴリズムの話が書いてあるんですが、どうやらAppleはGigabit Ethernetまでは対策したけど、10Gには対策がまだ出来てないようだとのこと。
上記Blogを参考に、sysctlを使用してカーネルパラメータを修正し、Delayed ACKを無効化。
$ sudo sysctl -w net.inet.tcp.delayed_ack=0
本来ならばNAS側の方でNagleアルゴリズムを無効化すべきなんでしょうが、ちょっと今回は見送り。というかNASはQNAPなんですが、中身SambaなんだしsocketオプションにNO_TCPDELAY入ってないのかなぁ…。
とりあえずMac側でDelayed ACKを無効化することで問題の解消が確認できたので、設定を永続化するため、/etc/sysctl.confを編集し、以下の行を追加。
net.inet.tcp.delayed_ack=0
うーん。久しぶりにネットワークエンジニアっぽい仕事をした気分…。
というところで今回はここまで。
ちなみにお客さんが使ってたMac用10GEthernetアダプタはこれ↓