TCP の Dup Ack がどのくらい発生しているか WireShark で grep 等でFiltering しようとしたものの、トレースをCSV として保存しても 1GByte になってしまいました。
このサイズだと、大きすぎて手持ちのマシンではテキストエディター等で Grep しようとしてもそもそも CPU が張り付いて取り扱えませんでした。
はじめはトレースを取る時間を短くする等してトレーズのサイズを小さくする事で対処していたのですが、そのままのデータを取扱いたくなり、GCP(Google Cloud Platform) で提供しているサービスである、BigQuery を使ってみました。
どこまで無償なのかわかりませんが、無償期間があるので、今の所は無償で使えています。
1)前提として Google のアカウントを持っていて、そのアカウントで GCP(Google Cloud Platform) のコンソールにログインしているとします。
2) GCPのコンソールのトップページから 「サービス」→「BiqQuery」を選びます。
3) 説明画面が出るので「コンソールへ移動」をクリックします。
4)左側のペインから「Create new dataset」を選択します。
5)「Dataset ID」を記入します。”Dataset” とは、テーブルをまとめる”グループ”のようなイメージになります。
この例では WireShark の export したデータファイル毎にテーブルを作ります。それをまとめるのが”Dataset”です。
6) この例では「my_dataset1」という”データセット”を作ったので、左側に「my_dataset1」というカテゴリが表示されます。
小さな+マークをクリックすると、この「my_dataset1」の下にテーブルを追加できます。
7) この画面は「Skip」します。
一度テーブルを作った後から再度画面キャプチャーを取り直しているので、この画面は初回は表示されないかもしれません。
9) この例では、GCS (Google Cloud Storage) にデータを置いているので、Google Cloud Storage 上のデータの位置を指示します。
私は試行錯誤している時に、GCS にデータを上げてしまっていたので、この例ではGCS からロードしています。
この画面の「File upload」から FIle をアップロードする事も可能のようです。おそらくそちらの方が簡単でしょう。
GCS(Google Cloud Storage)上のバケットにデータを事前にアップロードしている場合は、指定すべきデータのパスは
gs://<バケット名>/<データファイル名>
gsutil コマンドをデスクトップにインストールしている場合は、gsutil コマンドでもデータのパスを確認できます。
10) ロードしたデータのスキーマ(データの構造)を設定します。
WireShark で標準ではき出した場合は以下のようになっているはずです。
※ 幾つかの古い情報では、BiqQuery には、timestamp 型が無いという記述がありますが、実際には、かなり前に追加されているようです。
この記事を書いた時は、勘違いして Wireshark のcsv ファイルの timestamp の部分も 上記の例のようにSTRING でインポートしていましたが、後で試した所、TIMESTAMP型を指定して CSV をインポートすると以下のように、msec を落とした形でフォーマットされます。BigQuery でデータを分析するという事は、msec レベルのデータを操作する事は無いと思うので、はじめから TIMESTAMP 型でインポートするのが良いと思います。
秒単位で GROUP BY したりデータの統計の取り方が容易になります。
11) カンマ区切りである事と、CSV に Export した場合1行目はカラム名が入っているので飛ばすように設定します。
それ以外の項目は指定されたフォーマットに揃ってないデータがあった場合の処理の設定ですが、お好みだと思います。
特に何も設定しなくても上手く行くかも知れません。
12) 以下のようにテーブルにデータが読み込みが開始されます。1GByte の CSV のパケットキャプチャーであれば数分もあれば終わるはずです。(目を離していて正確な時間は・・・)
13)データをインポートしたら左上の「COMPOSE QUERY」をクリックします。
とりあえず行数を数えたいので、
slect count (* ) from my_dataset1.my_table1」
と入力しています。一般的なSQLの構文とほぼ同じです。(細かい所で違う場合があるようです)
my_dataset1.my_table1 は、<データセットID>.<テーブルID> のフォーマットになっています。
14) 以下が Query の実行結果です。
8,269,634 行ある事がわかります。1.7秒で Query が完了していようです。
8百万行のデータのカウントを何のチューニングも無しに1.7S で完了するとはすごい時代になったものです。
15)今度は、「TCP Dup Ack」と出ている行をカウントしたいので以下のような Query を作ってみました。
select count(*) from my_dataset1.my_table1 where regexp_match(info,'TCP Dup ACK')
単純に ’TCP Dup ACK’ と入れているだけで正確な正規表現では無いですが、これでも info 列に、’TCP Dup ACK’ の文字列を含む行を抽出してくれるようです。
info 列は、このガイドのステップ10 でデータをロードする時に、定義したスキーマ内の列名です。
こちらも以下のように、1.4秒かかって 98,424行の TCP Dup ACK を含む行をカウントしてくれました。
先ほど単純な行数のカウントで1.7秒だったので、何故かそれより早くなっています。
8百万行から、「TCP Dup ACK」という文字列を含んだ行を抽出するのに 1.4秒っていうのも凄いですね。。
16) 使用した Query は後で再利用するために「Save Query」で保存する事ができます。
保存した Query は以下のように「New Query」ボックスの下の「Saved Queries」に表示されます。が、たまに不安定で表示されない場合があるようです。
その場合は「COMPOSE QUERY」のボタンや「Query History」のボタンを何度か適当にクリックしていると表示されるようになります。