【研究課題レポート抜粋】LVSの統計情報のグラフ化プログラムの設計・実装 | サイバーエージェント 公式エンジニアブログ
これは第2回研究課題レポートの抜粋です。同レポートは、社員のMaedaさんによって作成され、優秀賞を受賞しました。

研究の背景

サイバーエージェントのインフラを構成するネットワーク機器の内、ロードバランサは以前から商用のロードバランサを使用していた。
Linuxのロードバランサである、ip_vs カーネルモジュール(以下、LVSと記す)をロードバランサとして使用する事で、下記の点でコストの削減が可能である。
  • ハードウェアが一般的なIAサーバで済む
  • 年間の保守費が不要になる

但し、日々の負荷状況の把握、増設計画を立てる上で、LVSの具体的な統計情報を取得することが求められる。
統計情報を有効に活用する為には、量的な変化を直観的に把握できるグラフでの表示が必要と考えた。

本研究の開始時点(2008年10月)において、LVSのグラフ化を行う方法、プログラムは既にいくつか存在していたため、何点かのプログラムについては、動作確認も含めて評価を行った。

評価結果は下表である。
プログラム実現方法評価結果
lvs-rrdシェルスクリプトで取得した、統計情報をrrdtoolでグラフ化し、CGIで表示グラフ表示項目の設定が必要。グラフ表示項目取得に際し、/proc/net/ip_vsの情報のみを使用しており、表示項目として不十分である。
net-snmp-lvs + cactisnmpエージェントの拡張モジュールとしてip_vsの情報をSNMPマネージャから取得する。グラフ化はSNMPマネージャの機能に依存。評価時はcactiを利用。Cactiのテンプレートを利用する事で、初期設定の手間はある程度軽減可能。但し、VirtualServer追加、削除時に、SNMPのOIDが変化する為、追加、削除等の操作後はグラフのデータソースが変化する。一つのグラフビューである時点から、元データが変わる、という事なのでバーチャルサーバの追加、削除を頻繁に行う運用では使い物にならない。対応するためには、バーチャルサーバの追加、削除の度に全グラフ設定を削除し、一から作成しなおすか、OIDとバーチャルサーバの対応テーブルを別途管理し、OIDが変わらないようにプログラムを拡張する必要がある。

上記に挙げた2つ以外にも動作の詳細を確認したものはあるが、いづれも表示項目が不足していると感じた。
また一番、理想に近い形で情報が得られたLVS用のsnmpモジュールに関しては問題が発生することが確認できたため、使用できないと判断した。

本研究の目的

前項で述べた通り、LVSの統計情報のグラフ化を実現するために、既存のプログラムで要件を満たしているものが無かったため、新たに作成する。

作成するプログラムの要求仕様

要求仕様を下記のように定めた。
  • 統計情報はip_vs カーネルモジュールの統計情報を有効に活用し、可能な限り多くの情報を取得すること(表示項目を勝手に削減しないこと)。
  • バーチャルサーバ毎に統計情報をグラフ化すること。
  • 複数のバーチャルサーバを統合したグラフビューを用意すること。例をあげると、トラフィックの総量に対する、各バーチャルサーバ毎のトラフィック量の比率を把握可能な積み上げグラフを用意すること。
  • 上記のいづれのグラフも、GUIから確認可能にすること。
  • グラフの表示範囲については、最低限、過去24時間の情報を確認可能にすること。また、重要度の高いグラフについては、過去1週間、過去1年間の情報を確認可能とすること。
  • 運用時におけるバーチャルサーバの追加、削除に際し、グラフ作成項目の設定変更を可能な限り不要にする事で、運用時の設定変更が極力発生しないよう、考慮すること。


プログラムの構成

前項で決めた要求仕様に基づき、プログラムを作成した。
プログラム名は、lvs-statsとした。
lvs-statsは下記の2 つの機能から構成される。
  1. 統計情報を取得し、グラフを生成する機能
  2. リクエストされたグラフを表示するCGI


動作概要

$サイバーエージェント 公式エンジニアブログ-研究課題レポート
  1. 統計情報を取得し、グラフを生成する機能
    1. cronにより5分毎にlvs_stats.shを実行
      lvs_stats.shはlvs_rrdstore.rbとlvs_rrdgraph.rbを順に呼び出す。
    2. lvs_rrdstore.rbによるrrdデータベースへの情報の蓄積
      “ipvsadm –L –n –stats –exact”、”ipvsadm –L –n”の各結果を1つのrrdデータベースに格納。
    3. lvs_rrdgraph.rbによるグラフの生成
      rrdデータベースファイルから、各グラフをpng形式の画像で生成。その際、グラフのタイトルにバーチャルサーバのIPとホスト名を埋め込む処理を行う。
      バーチャルサーバのホスト名はVIPのIPを、/etc/hosts ファイルを見て解決する。
  2. リクエストされたグラフを表示するCGI
    1. グラフのリクエスト
      トップ画面から、表示したいグラフへのリンクをクリック。
      グラフは“graph_type”クエリでCGIへ送られる。
    2. リクエストされたグラフをレイアウト表示
      リクエストされた”graph_type”に基づき、レイアウトして表示


表示可能なグラフ項目について

グラフ項目を下記の表に示す。
グラフ項目内容想定される用途
コネクション/秒(CPS)1秒当たりの新規コネクション数。LVSの処理負荷は、主に秒間の新規コネクション数に比例して大きくなるため、日々の負荷状況の観測に使用する。
bit/秒(In and Out Traffic)秒あたりの入力、出力通信量バーチャルサーバー別に確認可能なため、特定のVIPや、サービス毎に帯域使用量を判別することが可能。
パケット/秒秒あたりのパケット数サービス別にパケット数を把握する。
5分平均パケットサイズ( In and Out )5分平均のパケットサイズの遷移。
5分間の通信量をパケットサイズで割ることで、5分間の平均パケットサイズをIn(リクエスト)、Out(レスポンス)毎に表示
パケットサイズの急激な変化を視覚的に検知可能なため、アタック調査への用途が考えられる。また、サービス別にパケットサイズを比較する事でサービス毎のトラフィック特性( ショートパケットが多いサービス等 )を確認可能。
bit/コネクション1コネクションあたりの平均通信量コネクション数(=リクエスト数)が増えた場合に必要な帯域の試算に使用可能。
Activeコネクション同時Activeコネクション数サービス別の把握
Inactiveコネクション同時Inactiveコネクション数サービス別の把握


表示の方法(ビュー)について

ビューは下記のものを用意した。
  1. All VirtualServer ビュー

  2. CPS、BPS、同時コネクション(Active/Inactive)数に関して、バーチャルサーバ毎の計測値を積み上げグラフの形式で1つのグラフにして表示。機器全体の通信における各サービスの使用比率を把握可能。

    サイバーエージェント 公式エンジニアブログ-研究課題レポート
    サイバーエージェント 公式エンジニアブログ-研究課題レポート

  3. Per VirtualServer view

  4. バーチャルサーバ別に、CPS、BPS、コネクション数、平均パケットサイズ等、取得可能なグラフをすべて表示。

    サイバーエージェント 公式エンジニアブログ-研究課題レポート

  5. 関連性の高いグラフを並べて表示するビュー

  6. 下記の3種類を用意。
    ビュー内容
    New Connection per seconds(CPS)
    and Throughput(BPS)
    新規コネクション数と、トラフィック量を横並べにして表示
    Concurrent ConnectionsActive/Inactive コネクションを横並べにして表示
    Packets per seconds(PPS)
    and Average packet size
    秒間パケット数と、平均パケットサイズを横並べにして表示
    Bit/connection
    and Packet/connection
    1コネクション当たりの通信量と、パケット数を横並べにして表示


    例)New Connection per seconds(CPS) and Throughput(BPS)
    サイバーエージェント 公式エンジニアブログ-研究課題レポート

  7. 1つの指標をタイル上に並べるビュー

  8. 指標は下記の通り
    • New Connection only
    • Throughput only
    • Active Connection only
    • Inactive Connection
    • PPS only
    • Packet size only
    • Bit/connection only
    • Packet/connection


    例)New Connection only
    サイバーエージェント 公式エンジニアブログ-研究課題レポート


運用負荷の軽減に関する考慮

管理者の負荷を軽減するために考慮した点は下記の通り。
  1. グラフのデータ元( rrd ファイル )の自動作成

  2. “ipvsadm –L –n” の結果からバーチャルサーバを抜き出し、バーチャルサーバ別のrrdファイルに格納する。この時、rrd ファイルが存在しなければ新たに作成する( rrd create )。
    rrdファイルのファイル名には一定の規則を設けることで、バーチャルサーバ(VIPとPortの組み合わせ)から計測値の格納先のrrdファイル名が一意に決定可能にする。
    このファイル命名規則を用いることで、バーチャルサーバの追加、削除時に逐次、”新しいバーチャルサーバのデータを収集するための設定変更”が不要になる。
    ファイル命名規則VIP_Port .rrd
    例)192.☆★.★.1:80 の場合、192.☆★.★.1_80.rrd となる。VIPとPortの区切りに ":"(コロン) を使用せず、 "_"(アンダーバー) を使用しているのは、rrdtoolの1レコードのフィールドの区切り分字が ":" であるため、エスケープ処理などの煩雑さを避けるためである。


  3. サービス名をグラフのタイトルに埋め込む

  4. グラフと対応サービスの識別を容易にする為、グラフのタイトルにVIPと、ホスト名を埋め込む処理を行った。ホスト名はVIPを /etc/hosts 名に記載しておく事で、解決している。

  5. 新規バーチャルサーバーをビューに自動的に追加

  6. グラフの画像ファイル(png)に対しても、命名規則を設けることで、”全バーチャルサーバのトラフィックグラフのみを抽出”といった処理を行いやすいよう考慮した。CGIをファイル命名規則を利用して、作成することで、バーチャルサーバの追加、削除時に逐次、”新しく作成されたグラフをGUI上から閲覧可能なように設定する”という手順が不要になる。
    ファイル命名規則VIP_Port-GraphType .png
    例)192.☆★.★.1:80 の、CPSのBPSの場合、192.☆★.★.1_80-traffic.png となる。

上記の工夫を組み合わせる事で、バーチャルサーバ変更がそのまま”グラフのデータ元の変更”、”表示するグラフの変更”へと反映されるように作成した。これにより初期導入後は管理者によるメンテナンスが不要になる。

その他の注意点

バーチャルサーバの追加、削除のタイミングで、ip_vs カーネルモジュールの統計カウンタがゼロクリアされる。その結果、ipvsadm –L –n –stats コマンドの5分前からの変化量は数値としてみた場合、マイナスになる。
一般的なトラフィック量を格納する場合にはRRDtoolではデータソースタイプとして”COUNTER”を使用するが、ip_vsカーネルモジュールの様に、カウンタが最大値に達する前にゼロクリアされるデータソースに対しては、マイナスデータを無効として取り扱う必要がある。
今回の要件では、データソースタイプを”DERIVE”に、許容値の最低を”0”としてrrdデータソースを作成する事で対応した。

rrdファイルを作成する処理は下記の部分である。
def rrd_stats_create(rrd_name)
 RRD.create(
 rrd_name,
 "--start", "#{Time.now.to_i-1}",
 "--step", "300",
 "DS:ActiveConn:GAUGE:600:U:U",
 "DS:InActConn:GAUGE:600:U:U",
 "DS:Conns:DRIVE:600:0:U",
 "DS:InPkts:DRIVE:600:0:U",
 "DS:OutPkts:DRIVE:600:0:U",
 "DS:InBytes:DRIVE:600:0:U",
 "DS:OutBytes:DRIVE:600:0:U",
 "RRA:AVERAGE:0:5:1:28800",
 "RRA:AVERAGE:0:5:6:4800",
 "RRA:AVERAGE:0:5:24:2400",
 "RRA:AVERAGE:0:5:288:797",
 "RRA:MAX:0:5:1:28800",
 "RRA:MAX:0:5:6:4800",
 "RRA:MAX:0:5:24:2400",
 "RRA:MAX:0:5:288:797",
 )
end


結果考察

課題であった、統計情報のグラフ化は実現した。
また、LVSのバーチャルサーバの追加の度にグラフ出力項目を設定する、といった運用操作を行うことなく、自動的にグラフを出力する、という点についても実現した。

今後の課題としては、現状のプログラムが対応していない下記の項目についても同様の方法、ビューを用いてグラフの生成、確認を可能にすることである。
  • ip_vs のUDPバーチャルサーバへの対応、fw markを使用したバーチャルサーバへの対応
  • TCP Proxy タイプのオープンソース ロードバランサである、haproxy の統計情報のグラフ化


参考資料