Webシステムのパフォーマンス設計に関するベストプラクティス(ネットワーク要素編)

 ITシステムがブラックボックス化している現代においてインフラエンジニアの需要は縮小していくという人もいますが、私は必ずしもそうではないと考えています。特にパフォーマンス分野のエンジニアは今後も絶対になくならない職種のひとつだと言ってよいでしょう。なぜならシステムがいくらブラックボックス化したとしても各システムの特性に適した難易度のパフォーマンスチューニングが必要不可欠だからです。しかしその分難易度も高く、どういった設計をしたらよいのか一般的なベストプラクティスがあまりないように思いましたので、パフォーマンス設計のベストプラクティスをまとめてご紹介しようと思います。今回はネットワークに関するパフォーマンス設計についてご紹介しますのでぜひご参照ください。

1. はじめに

今回のシリーズでは、一般的なLinuxシステムにおけるWeb3層のオンラインシステムを想定したパフォーマンスベストプラクティスをご紹介させていただきます。システムパフォーマンスを向上させるには、システムを構成するあらゆる要素を考慮する必要があります。たとえばミドルウェアのチューニングが完璧でもネットワークの通信速度が出ていなくて処理遅延につながることもあります。したがってパフォーマンスエンジニアはあらゆる要素に対する知見をもって対応する必要があります。一般的にシステムを動作させるために必要な要素を下図に記載します。

ネットワーク起因のパフォーマンス問題は他の要素と比較するとそれほど発生するものではありませんでしたが、クラウドが普及してきている状況においてネットワークがパフォーマンスにあたえる影響はより大きくなっていくでしょう。したがって基本的な設計ポイントを抑えていく必要があります。ネットワーク機器選定・設定、サーバ機器設定、回線、プロトコル等を適切に構成することによってネットワークのパフォーマンスを最適化することが必要です。

2. ネットワーク要素のパフォーマンス設計

2.1 ネットワーク機器選定

ネットワーク機器のパラメータについては、ハイパフォーマンスを引き出せるようにチューニング済みになっていることが一般的なので、そこまで考慮する要素は多くありません。しかし、導入する機器選定を誤るとチューニングでリカバリすることが難しいということも言えるので、製品選定については慎重に対応してもらえればと思います。以下に機器選定における注意点を記載します。

タログの値を鵜呑みにせず余裕を持った設計が必要
性能条件に合致するネットワーク機器を選定する際にカタログに記載されている値(bps(bit per second)、pps(packet per second))を鵜呑みにしてしまうのは適切ではありません。検証環境と実際に利用する環境が異なるので、まったく同じ性能が出ないことが多々あります。ある程度の余裕率を持たせたうえで機器選定をすることを推奨します。

常時と異なる利用シーンに注意
例えば1分間隔ではカタログの指標値に収まっていたとしても、一時的なピークトラフィックが発生した際にネットワーク機器の処理限界を超えてしまうということはあります。また、冗長構成をとっている機器の1台が故障したことによって性能目標を満たせなくなってしまうということもあります。通常時と異なる状況に陥っても安定してサービスを提供できるような設計をする必要があります。

CPU使用率を考慮した機器を購入する
ルータやスイッチ等のネットワーク機器もマイクロプロセッサを搭載しているので、負荷が高くなるとCPU使用率が高くなりパフォーマンスが出なくなることがあります。機器選定の際にはご留意ください。

2.2 ネットワーク機器のパフォーマンス設計

ネットワー機器のパフォーマンスを最大にするための設定内容についてご紹介します。デフォルトで問題ない項目がほとんどですが、トラブル時に対応できるようになるためにどういった考え方で設定しているのか理解しておくことをお勧めします。

デュプレックス設定の最適化
基本的なことですが、データの送信と受信を双方から同時に行う全二重通信(Full Duplex)方式になっているかどうかを確認しましょう。オートネゴシエーション機能を有効にしているから大丈夫と安心していると、対向側の設定によって実は半二重通信になっていて性能劣化していたということも起こりかねないのでしっかりと確認をしましょう。

リンクアグリゲーションの適用
リンクアグリゲーションとは複数の物理的な回線を仮想的に1本の回線として扱うことができる技術です。これにより1本の物理回線で実現できる帯域幅を増加させることができるうえに、1本故障した際に継続して使用することができるため可用性も向上するというメリットがあります。ぜひ導入を検討してみて下さい。

QoS(Quality of Service)の適用
QoSとは優先制御(特定の通信を優先して伝送)、帯域制御(通信量に制限をかけること)を行う技術となります。たとえばテレビ会議やIP電話に使う通信に関する処理を優先させて帯域を多くすることで、映像や音声を遅延させずに快適な会議をおこなえるようにするといったケースで利用されます。顧客やユーザの要件を考慮した設定が必要であるため要件定義の段階で方針を決めておくようにしましょう。

MTU(Maximum Transmission Unit)設定
MTUとは1フレームで送信できるデータの最大値を示す単位であり、一般的に使われるイーサネットであればMTUを1500 byteに設定しておけば問題ありません。しかし、MTUが標準サイズでないネットワークを利用している場合はMTUサイズを変更してフラグメントなしで通信できるようにする必要があります。
基本的には変更しなくて良いのですが、MTUの値が1500を超えるジャンボフレームというフレームサイズを適用することで、スループットの向上が見込まれる場合があります。ジャンボフレームを適用することとメリットとして、以下の3点があげられます。

1.処理のオーバーヘッドを削減できる
2.パケット分割処理(フラグメント化)を少なくできる
3.送受信パケット数減少による割り込み回数減少

しかし、MTUをすべての要素で揃えないとパケットロスなどの思わぬトラブルが発生する可能性もありますので、十分検討のうえ適用することを推奨します。

2.3 サーバ機器のネットワークパフォーマンス設計

サーバ機器、特にLinuxサーバに関するネットワーク設計をご紹介します。

ソケットバッファサイズ設計
ソケットバッファにはカーネルが受信したデータ、あるいは送信するデータが一時的に保存されます。TCPパケットが大きすぎてバッファサイズを超えている場合やパケットの送受信速度が速すぎる場合、カーネルはデータがバッファから削除されるまで新しい受信TCPパケットをドロップしてしまうことがあります。これを防ぐためにある程度のソケットバッファを確保しておくことでパケットロスを防いで全体のスループットを向上させることが可能です。ただし、バッファサイズを大きくすることで接続ごとに使われるメインメモリのコストが高くなる点にはご留意ください。

Linuxサーバに設定する具体的なパラメータを記載します。
下記のように送信バッファのサイズ、受信バッファのサイズを指定します。数値が意味しているのは左から最小バッファサイズ、初期バッファサイズ、最大バッファサイズです。

net.ipv4.tcp_wmem = 4096 65536 16777216

net.ipv4.tcp_rmem = 4096 87380 16777216

また、下記パラメータを設定することでTCP受信バッファの自動チューニングを適用することができます。

net.ipv4.tcp_moderate_rcvbuf = 1

ウィンドウ制御設定
フロー制御の中にウィンドウ制御という仕組みがあります。メモリ上にウィンドウと呼ばれるバッファ領域を設けることで、大きなサイズのデータ送受信を実現する技術となります。送信先からのACKを待つことなくウィンドウサイズで指定されたサイズまではデータを送信し続けることができます。ただしこのやり方だとウィンドサイズを超えた際にはACKが返ってこないと次のデータ送信ができなくなってしまうので、スライディングウィンドウという仕組みを使って効率的にデータ送信を実現しています。詳細については数を参照ください。

下記のパラメータを1(デフォルト値)に設定することでウィンドウサイズが最大で1GBのサイズまでスケールされますので、基本的には設定を有効にしておきましょう。送信側、受信側ともにこの設定が有効になっている必要があります。

net.ipv4.tcp_window_scaling=1

TCP輻輳制御の設定
TCP輻輳制御とはネットワーク高負荷による伝送遅延を解消したり防止したりする機能となります。ウィンドウサイズを調整することによってネットワークの輻輳を抑える方法が一般的であり、ウィンドウサイズを調整するための様々なアルゴリズムが実用化されています。Linuxにおいてはデフォルトでcubicというアルゴリズムが適用されています。前回の輻輳を検知したところまでは徐々にウィンドウサイズを増加させ、そこを超えたら増加の速度を上げるアルゴリズムとなっております。cubicアルゴリズムによるウィンドウサイズ調整のイメージは下図を参照下さい。


TCPバックログキューの設定
接続リクエストがバーストした際にドロップしないようにするために、TCPバックログキューという仕組みを取り入れて処理をしています。バックログキューは2つあって、TCP3ウェイハンドシェイクが確立されていない接続向けのキュー(SYN Backlog Queue)とTCP3ウェイハンドシェイク後のアプリケーションによる受け入れを待つためのキュー(Listen Backlog Queue)が存在しています。SYN Backlog Queueを導入することでSYN Flood攻撃を防ぐことができます。

Linuxサーバに設定する具体的な設定例を記載します。
net.ipv4.tcp_max_syn_backlogでSYN Backlog Queueの値を、net.core.somaxconnでListen Backlog Queueの値を設定します。

net.ipv4.tcp_max_syn_backlog = 4096
net.core.somaxconn = 1024

まとめ

ネットワークに関するパフォーマンス設計のご紹介は以上となります。ここまで読んでいただきありがとうございました。ネットワーク以外のパフォーマンス設計についてもまとめているので、ぜひ合わせて読んでもらえると嬉しいです。
Webシステムのパフォーマンス設計に関するベストプラクティス(システム構成・ハードウェア要素編)

参考文献

Best Practices for System Performance

Database Performance Tuning Guide

演習で学ぶネットワーク 性能設計

日経xTech:[ネットワーク編]機器のスペックをbpsだけで判断してはいけない

Cisco:Performance Tuning Basics

Redhat:高スループットのための TCP 接続のチューニング

TCP Window Control / Flow Control

コメント