さよなら Stormなごみそ@kawasaki.rb #046
なごみそ
● @NagominHotMotto● 夏・冬の3日間だけ東京ビッグサイトで働いています
● 副業でSEっぽいことをしています
3
Apache Storm とは
ストリーミング処理するための分散処理基盤
● 処理を 有向グラフ で記述する (Topology)
●耐障害性 が高い
● 色んな 言語 が使える (multi-lang protocol)
Topology
SpoutSpout
BoltBolt
BoltBolt
BoltBolt
データを流す 流れてきたデータを処理
5
耐障害性
データの再送制御
次のコンポーネントにちゃんとデータが届いたかを確認して再送する仕組みがある
プロセスの自動再起動
何らかの原因でプロセスが死んでも自動で復活する
フェーエルソフト
一部が死んでも処理は継続する
Multi-lang Protocol
他の言語にSpout/Boltの処理を移譲できる
ShellShellBoltBolt
PythonPythonShellShellSpoutSpout
RubyRuby
Multi-lang (標準入出力)Multi-lang (標準入出力)
Stream
Multi-lang を使えばスクリプト言語を使って
お手軽に分散処理ができるね〜
分散処理が得意なフレンズになれるんだ!
でも世の中そんなに甘くない
Multi-lang はつらい
Apache Storm が何回もシグナルを送る● Java のサブプロセス (multi-lang) 終了→ SIGTERM
● Storm Worker の終了→ SIGTERM
● Storm Supervisor の終了→ SIGKILL
正常終了でもエラーが…
ふつうに殺したい
対処● SIGTERM 契機で終了シークエンス移行
– 1回目の SIGTERM で exit– rescue SystemExit でもろもろやる
– その前に SIGTERM を無視 するハンドラ登録
● 移譲先のプロセスの後始末が終わったら sync しまくる– Spout/Bolt に 俺は死んだアピール をする
– そうすると だいたい エラーがでなくなる
一件落着!!
じゃなかった....
ある時 Topology にストリームが流れなくなった
HAHAHA, RubyプロセスにSIGTERM送れば終了してくれるんだろ
(俺がそう作ったし)
死なない!!!!
よく調べたら
● Spout でエラーが発生して終了● ApacheStorm は Spout が死んでいると判断● ShellSpout が multi-lang 用の pipe を読まなくなる– Spout が ShellSpout に multi-lang でエラー報告をしようとする
– pipe が詰まる
– Ruby のガベージコレクタの io_flush_buffer_sync で止まる
– (ShellSpout は FD を握ったまま)
ちなみに gdb でアタッチしてわかりました#0 0x00007f068e7707cd in write () from /lib64/libpthread.so.0#1 0x00007f068ebee9eb in io_flush_buffer_sync (arg=0x7f068feee180) at io.c:994#2 0x00007f068ebf3647 in fptr_finalize (fptr=0x7f068feee180, noraise=1) at io.c:4172#3 0x00007f068ebf3ca2 in rb_io_fptr_cleanup (fptr=0x7f068feee180) at io.c:4222#4 rb_io_fptr_finalize (fptr=0x7f068feee180) at io.c:4262#5 0x00007f068ebe1c45 in run_final () at gc.c:2064#6 finalize_list () at gc.c:2080#7 rb_objspace_call_finalizer () at gc.c:2212#8 rb_gc_call_finalizer_at_exit () at gc.c:2146#9 0x00007f068ebc7d1d in ruby_finalize_1 (ex=1) at eval.c:129#10 ruby_cleanup (ex=1) at eval.c:230#11 0x00007f068ebc7eed in ruby_run_node (n=<value optimized out>) at eval.c:310#12 0x00007f068ebc2bdb in main (argc=5, argv=0x7ffff21cbe38) at main.c:36
終了シークエンス中は
SIGTERM を握りつぶす
ようにしたため
活かすも殺すも出来ない
…...
# kill -9
まとめ
● Storm は multi-lang で Sput/Bolt 処理の移譲ができる
● デフォルトだと作りが雑すぎるのでちょっとした工夫が必要
● 工夫しても駄目だった.......
● multi-lang は使っちゃ駄目● 他にも色々問題が発生