python の pickle って嬉しいの?

python には pickle という、オブジェクトをシリアライズして保存しておくことができるモジュールが存在する。

例えば、ファイルからデータを読み込んで、pythonのオブジェクトへ変換する、という作業を色んな所で何度も繰り返す場合、 そのたびに生成することになるので、一定のコストがかかる。

これを一度オブジェクトへ変換したらそのオブジェクトをシリアライズして保存することで、2回目以降の生成コストを下げようというもの。 デシリアライズするので、コストがゼロになるわけではない、またシリアライズするためのコストもある。

同じデータを2回使うくらいであれば、シリアライズ、デシリアライズするコストとオブジェクトへ変換するコストを比べるとあまり意味がないかもしれない。

サンプルとして、下記のような100万行程度のcsvを作成し、テストする。

import random

with open("test.csv","w+") as f:
    for i in range(1000000):
        v = [str(random.randrange(10)) for x in range(10)]
        f.write(",".join(v) + "\n")

読み込みのコードは下記のようなもの。何も出力しないと寂しいので一応columnsを出力している。

import pandas

df = pandas.read_csv('test.csv')
print(df.columns)

pickleを利用してシリアライズするコードは下記。

import pandas
import pickle

with open("test.pickle","wb+") as f:
    df = pandas.read_csv('test.csv')
    pickle.dump(df,f)

pickleを利用してデシリアライズするコードは下記。

import pandas
import pickle

with open("test.pickle","rb") as f:
    df = pickle.load(f)
    print(df.columns)

計測は単に

$ time python code.py

で行い、user 時間を測る。

計測結果

csv読み込み

user 0m1.012s, 0m1.045s, 0m1.053s, 0m0.970s

csv読み込み + シリアライズ

user 0m1.091s, 0m1.087s, 0m1.139s, 0m1.206s

シリアライズ

user 0m0.491s, 0m0.495s, 0m0.487s, 0m0.482s

ざっくり、csvをdataframeにするのに1.0sec シリアライズに 0.1-0.2sec、デシリアライズに 0.5sec くらいかかっていることがわかる。

これなら2度読み込む場合でも読み込んだらpickleでシリアライズしておいたほうが良いかも

ただし、シリアライズしてファイルに書き出すと、サイズがざっくり4倍くらいになるので、データサイズが膨大な場合はディスク容量に注意。 IOリードが心配になることもあるのかな?

InteropでJAIanの話を聞いた。

今年のみどころ | Interop Tokyo 2018

ShowNetのトポロジーを見るとわかるのですが、 monitoringの項にjaian というなんでこんな名前のものが?というコンポーネントがあります。

これは一体なんなんだ。ということで見に行ってきました。

ものとしては packet aggregator というか packet broker というかそんな感じのものでした。

DPDKを利用した、パケット転送システム という方が正確なのかもしれません。

Linuxのネットワークスタックを利用していると、ログの収集すらままならないレベルの巨大システムになりつつあるShowNetでは

安定してログを集め、配布する必要があるそうで、そのために利用されてるとのことでした。

パケット転送システムとして作成されており、どこへどう転送するか、みたいなところをコンポーネント化して、 外部から気軽に追加、削除できる仕組みが採用されており、ShowNetではログ収集、転送ツールとして利用されていましたが、他にもいろいろ使いみちはあるようです。単純に、ルーティングも出来るのでは。

ただ、Lagopus switchがメインのログ収集、転送ツールとして使われており、いわばバックアップ的な用途で構築されているようでした。 単純に、開発が進んでしっかりしているlagopusのほうが信頼度は高いということでしょうか。

lagopusもDPDKを利用した高速パケット転送スイッチなので、用途的には確かに似通っています。

各所からsyslog(udp)やミラーポートからのトラフィックが流れてきたものを、一旦 これら収集装置へ入れ、情報を流したい機器群へ分配するようなもので、 ログを吐き出す機器へは、とりあえずこの装置へ転送するよう設定しておけばあとは装置側の設定でどうとでも出来るようにするという思想は、今どきだなぁという感じです。

pub sub システムみたいなもので、 sub側はデータを取りにいくのではなく、口を開けて待っているタイプ。

Aruba 2530 でループ検知、ブロードキャストストーム検知を試した話

Arubga 2530 というお手頃スイッチがあります。 その中でも 48G (J9775A) でループ検知とブロードキャストストーム検知を試したのでそのメモ。

ループ作成にはFXCのスイッチを利用しました。ループ検知するけど遮断しないことが出来るスイッチです。

ループさせると赤く点滅してわかりやすいです(終売品ですが)

2530 - FXC =コ

という形で FXCの1番ポートを8番ポートに接続してループを作り、2番ポートを2530側に伸ばしています。

まず、普通に接続して2530からlldpだのを吐かせて一旦ループを作ります。

ループが出来たら2530との接続は切断してしまいます、。

この状態でしばらく待つと、FXCスイッチでループ状態がエージングされます。

その後

loop-protect 1
loop-protect transmit-interval 1

と 2530側でループ検知設定をして あらためて、2530とFXCスイッチを接続すると、1秒くらいでポートがシャットダウンされます。

めでたしめでたし。

次は ブロードキャストストーム

fault-finder broadcast-storm Port-List action [ warn | warn-and-disable ] < Seconds > [ pps Number | percent Number ]

こんなコマンドですが ブロードキャストストームを検知したときにログだけにするか、ポートをシャットダウンするかが選べます(warn | warn-and-siable)

また、検知の方法として pps と percentで選べます。

特に理由はありませんが ppsのほうが好きです。 設定する数値については、通常時、どのくらいブロードキャストパケットが飛んでくるか?というところで考えましょう。

fault-finder broadcast-storm 1 action warn-and-disable  0 pps 10000

こんな具合に設定し、

あらためて、2530とFXCスイッチを接続すると、数秒でポートがシャットダウンされます。

めでたしめでたし。

ところで、ブロードキャストストームが発生している状態でloop-protectをオンにして接続したところ、 ポートをシャットダウンするまでに800MBくらいのデータが流れてきました。

こんなもんですかね?