背景
CDNとクラウドプロバイダーは、インターネット上で大量のトラフィックを配信し、パフォーマンスと信頼性を確保するために広範な監視ツールを採用している。 これらには、ネットワーク、サーバー、アプリケーションなどのトラフィック配信のさまざまな層をカバーするツールが含まれる。 このトラフィックの大部分はTCP/IPで占められている(UDPベースのQUICは世界的に増加しているが、TCPと比較してトラフィック全体のほんの一部である)。
ソケットは、データが送信されるクライアントとサーバの接続をリンクするオペレーティングシステム抽象である。 したがって、ネットワークの問題は、各ソケットに格納されているデータに直接反映される。 例えば、ネットワークの輻輳は、応答時間の遅れやラウンドトリップ時間(RTT)の増加につながる可能性がある。 また、ネットワーク帯域幅は利用可能だが、アプリケーションが過剰な要求で圧倒され、利用可能な帯域幅を十分に活用するために十分なデータでバッファを満杯にできず、アプリケーション限定の異常が発生する可能性もある。 多くの場合、サーバは同時に複数のソケットを処理するため、リソースの競合が発生し、CPUやメモリなどのシステムリソースに負荷がかかることがある。
したがって、TCPソケットのパフォーマンスを大規模に監視することで、応答時間の遅さや接続の切断などのトラフィックの振る舞いを重要に理解し、改善が可能なケースを特定できる。
既存のツール
Linuxの「ss」ユーティリティはソケット統計情報を取得するための一般的なツールである。 「netstat」と同様に、ssはソケットの状態、プロトコル、アドレスに対するフィルタを許可することで、より速く柔軟な情報取得機構を提供する。 我々はssからもソケット監視の旅を始めた ssはソケットと関連するメトリクスのリストを素早く取得する強力なツールであるが、ssの主な課題は、特に多数のソケットを持つシステムで使用された場合に、かなりのリソースを消費できることである。 これはシステムのパフォーマンスに影響を与え、他のプロセスの速度を低下させる。 さらに、ss出力は一貫性のないkey:valueの使用法のため解析に理想的ではなく、何千ものサーバから収集されたデータをストリームする機能を著しく複雑にする。
ssを使ったソケットコレクションの最初のバージョンは、選択したキャッシュサーバ上で実行されるbashスクリプトで、「ss–tcp–info」の出力をファイルにエクスポートした。 このファイルは要塞ホストにrsyncで送られ、Pythonスクリプトがそれを読み込み、解析してElasticsearchに挿入する。 これは仕事を終えたが、私たちが必要とする規模にはほど遠い。 この作業の次の反復はキャッシュサーバ上にPythonスクリプトを置き、HTTPインターフェイスから呼び出され、集約された統計情報を返してElasticsearchクラスタに挿入することだった。 この方法では解析ボトルネックを中央のバックオフィスから個々のキャッシュサーバに拡大したが、ソケット数が非常に多いサーバではメモリ使用率が大きくなった。 最終的に、我々はシステムのss部分の軽量代替の必要性を認識した。
この新しいツールの主な要件は、軽量であり、我々のCDNサーバーが持っている多数のソケットに拡張でき、プロトコルバッファなどの効率的なメカニズムを使用してデータをストリームバックできることであった。 MeasurementLabのtcp-infoツールはGolangで実装された素晴らしいユーティリティである。 しかし、時間の経過とともに同じソケットを追跡するように設計されている。 大量のソケット接続を考慮して、個々のソケットを追跡しない設計を選択した。 代わりに、各ポーリングループを独立させ、オープンソケットの現在の状態のスナップショットを提供する。 ここでの第一の目標は、個々のソケットではなく、システムの全体的なパフォーマンスを追跡することである。
xTCP
これらの課題を解決するために、我々はxTCP(extract, export, xray tcp)を導入し、オープンソース化する。 xTCPはGolangユーティリティでソケットデータを大規模にキャプチャしてストリーミングする。 xTCPはNetlinkを使ってソケット情報を取得し、データをprotobufsにパッケージ化し、UDPポート(最終的にKafkaなどに送信される)経由で送信するか、NSQに書き込む。
Netlinkはユーザ空間とカーネル空間の間の通信のための汎用インタフェースを提供する。 ソケット監視ツールss, tcp-infoはNetlinkプロトコルファミリの一部であるNetLink_INET_DIAGを使用して、カーネルからユーザ空間にソケット情報を取得する(マニュアルページからの注意:NetLink_INET_DIAGはLinux 2.6.14で導入され、AF_INETとAF_INET6ソケットのみをサポートした。Linux 3.3ではNetLink_SOCK_DIAGに改名され、AF_UNIXソケットもサポートされた)。
xTCPはカーネルTCP INET_DIAGデータを高速で抽出し、そのデータをprotobufs経由でエクスポートする。 ソケットが約120kあるマシンでは、Netlinkメッセージは約5-6MBであるが、ssのASCII出力は約60MBである。 さらに、ssはデフォルトではカーネルから~3KBのチャンクを読み込む。 xTCPは32KBのチャンクを読み込むので、システムコールを最小限に抑えることができる。 xTCPは、複数のワーカーを使ってNetlinkソケットデータを同時に読み込み、できるだけ早くキューをドレインし、ストリーミング用にNetlinkメッセージを解析する。 これらの最適化により、xTCPのフットプリントは本番キャッシュサーバ上で実行するために小さくなる。
Edgioでの使用
クライアントのパフォーマンスを分析するために、xTCPデータを多用する。 通常、RTTを追跡し、Point of Presence (POP)とASNによって集約された再送信を行う。
Aging Rateとは対照的に、TTLは特定のアイテムのキャッシュ能力を変更することができる。 TTL関数を使用して設定された期間では、アイテムはディスク上にある間はエージングされないため、(ほとんどありそうもない)退去する可能性は低い。 TTLが期限切れになると、アイテムは従来のLRU方式、または高速エージングまたは低速エージングのいずれかでエージングを開始できる(オペレータの設定による)。 下の図では、時間の経過が遅いTTLでは、ディスク上のアイテムがキャッシュ除去しきい値を超えないまで保持されていた。 反対側のTTLでは、イベントが発生した時間はライブビデオストリームがキャッシュされるようになっていたが、その後は高速エージングを使用してディスクから素早く削除された。
米国の大手プロバイダーのPOPS AGAおよびCHB用にサンプリングされたRTT、再送信、およびソケット数を示すxTCPダッシュボードの例。
前回のブログ記事では、パフォーマンスが低いクライアントに対して自動的にBBRを有効にする動的輻輳制御チューニングのパイプラインを紹介し、BBRのメカニズムが最も有用であることがわかっている。 xTCPデータは解析の主要なソースである。
我々は、輻輳の影響などの複雑な質問に答えるためにxTCPデータを使用する新しい方法や、パフォーマンスを予測し異常を検出するための機械学習を常に見つけている。 このようなソケットデータの解析については、今後のブログ記事で報告する予定である。
今日、xTCPはオープンソースのネットワーク監視ツールスイートにvFlow(sflow、NetFlow、IPFIXコレクタ)を追加した。 我々は、これがソケットデータ収集のためのインフラストラクチャパフォーマンスモニタリングコミュニティに役立つことを願っており、このツールをさらに活用するための積極的な参加を楽しみにしている。
確認
xTCPの成功と幅広いユーザビリティは、Edgioの個人やチームの貢献の結果である。 特に、xTCPの最初の開発者であるDavid Seddonに感謝したい。 特に、xTCPのテスト、取り込み、ダッシュボード、フィードバックを行ってくれたすべての内部コードレビュアーと貢献者に感謝する。