お世話になります。
今、2台構成(複製数2,各ノードで roma プロセスは1つだけ)で、
1台を停止させて、新品のノードと入れ替えて復旧させるという想定の
作業をしています。(データは300万件ほど突っ込んでいます)
このときに、追加したノードに対して get をすると値が見つからない
という状況に出くわしました。動き続けている側のノードに対して、
get をすると値はあります。
ノードの復旧(追加)は、join で起動して、acquire_vnodes の終了後
recover コマンドで複製数不足分を補うとういことをしています。
調べてみた感じでは、BasicStorage.each_vn_dump の
@hdb[i].each{|k,v|
...
}
のループが正常にまわっていないようです。ループ数が@hdb[i].size
より少なかったり、多かったりします。
どうも、storage_clean_up_process から呼び出される BasicStorage.
each_clean_up での
hdb.each{ |k, v|
...
}
とバッティングしているように見受けられました。
Romad.timer_event_10sec では、@stats.run_iterate_storage が true
であれば、storage_clean_up_process は始まりませんが、すでに、
storage_clean_up_process が動作中でも、BasicStorage.each_vn_dump
は始まる(reqpushv を受け入れる)と思います。
そこで、下記のような修正を加えて見たところ、ループは正常にまわる
ようにはなり、get で値が見つからないという事象も起きなくなりました。
== パッチ:ここから ==
--- vn_command_receiver.rb.original 2010-03-14 22:57:31.000000000
+0900
+++ vn_command_receiver.rb 2010-03-15 14:03:24.000000000 +0900
@@ -94,6 +94,14 @@
return
end
+ if @stats.run_storage_clean_up
+ @log.warn("reqpushv rejected:#{s}")
+ @storages.each_value{|st| st.stop_clean_up}
+ @log.info("stop a storage clean up process")
+ send_data("REJECTED\r\n")
+ return
+ end
+
Roma::AsyncProcess::queue.push(Roma::AsyncMessage.new('reqpushv',
[s[1],s[2],s[3]]))
send_data("PUSHED\r\n")
rescue =>e
== パッチ:ここまで ==
この件については、そもそもやり方の問題では?ということであれば、
ご指摘いただけると幸いです。
recoverlost とかいうツールを使ったりするのでしょうか?まだこれ
試していないので、いつ使う物かも理解してないのですが。。。
よろしくお願いします。
まず、join 後の recover は正しい使い方です。
仮想ノードは確率的に割り当てられますので場合により足らない時があります。
その場合は、recover で冗長度を復帰します。
さて本題の現象は、こちらでも把握しておりませんでした。
ストレージの種類に依存する問題と思いますが、現在の実装はご指摘の通り排他が甘いです。
clean_up のフラグが立っている場合、ストップを投げてリジェクトしてしまう処理は正しいと思われます。
パッチ当てさせて頂きます。
最後に、recoverlost についてです。
このツールは2冗長の構成で、2ノードがつぶれどこかのデータをロストした時に、
つぶれたノードのデータファイルを使ってデータをアップロードする物です。
Config::DEFALUT_LOST_ACTION が :no_cation か :auto_assign の時に使います。
:no_action の場合は、ロストした仮想ノードへのアクセスができなくなります。
recoverlost はロストしたデータを任意のノードにアップロードし、その後経路表を更新します。
:auto_assign の場合は、ロストの検知と同時に適当なノードに仮想ノードを割り当て
データが空になった状態で運用を続けます。recoverlost は再割り当てされた仮想ノードの
データを ROMA にアップロードします。
データをアップロードする前にアップロードすべきデータを統合するコマンドが mkrecent になります。
いつも適切なパッチありがとうございます。
鳥居 順次
ご返答ありがとうございます。
ストレージは、TCStorage を使っています(スイマセン、説明が抜けていました)。
対処方法が正しかったようでなによりです。
また、recoverlost のご説明、ありがとうございました。
では。
300万件ですか、そこそこインパクトありますね。
データがキャッシュに載らなくなるような状況ですとストレージアクセスが性能の
ボトルネックになってくると思います。既にご存じのことかもしれませんが、
TCStorage の場合 Tokyo Tyrant っぽくオプションが指定できます。
この辺の設定はかなり効きますのでチューニングのポイントと認識している次第です。
ファイルシステムの方もジャーナルを切るなどすると速いです。(リスクありますが・・・)
オプション指定に関しては以下が参考になります。
http://1978th.net/tokyotyrant/spex.html
チューニングに関するアドバイスありがとうございます。
まだそこまで手がついていないのですが、今後検討していかなければと思っています。
もっとも、超高速を要求しているわけでもないので、RDBよりそれなりに早ければ、
スケールアウトのしやすさや、拡張(カスタマイズ)のしやすさにROMAの利点を
感じています。
では、また。