d3.jsで通信トラフィック可視化をやってみた

f:id:levelfour:20160621075117p:plain:w300

ゼミでSparkのノード間通信を可視化しようという話になった。
肝心のクラスタがグローバルネットワークから隔離されており、ログインノードからしかアクセスできないという環境だったので、

  1. クラスタで収集したパケットキャプチャログをログインノードに送る
  2. ログインノードでログを元にして可視化アプリケーションを立てる

という方針にした。VNCとポートフォワーディングを頑張ればEtherApeとか使えたのかもしれないけど、面倒くさいのと、JavaScriptで可視化出来たほうが見た目がいじりやすいしなんとなくカッコいい。

というわけで、デモはここで見れる。
ちなみに、デモで可視化しているトラフィックはダミーである。

実際にはクラスタ上でパケットキャプチャプログラム(僕はtcpdumpのバックエンドのサブセットみたいなのをCで書いた)を走らせ、吐いたログをrsyncでログインノード側で取得し、JavaScriptで表示した。
JavaScriptで1秒おきにログの変更を監視しているが、

function watch() {
  var now = new Date();
  d3.json(status_file + "?timestamp=" + now.getTime(), function(error, graph) {
    var new_status = JSON.stringify(graph.links);

    if(saved_status !== new_status) {
      console.log("update");
      links.length = 0;
      Array.prototype.push.apply(links, graph.links);
      draw();
      saved_status = new_status;
    }
  });
}

のように、

status_file + "?timestamp=" + now.getTime()

タイムスタンプをつけてアクセスする必要がある。というのも、素朴にアクセスするとキャッシュにひっかかって更新差分がとれないことがあるからだ。