0

テーブルをスキャンしてダーティービットを検出し、ダーティー行をバッチでdelayed_jobにスケジュールするデーモンがあります。私はいくつかのsleep 0.0001または、そのようなを追加しない限り、一定select from data where dirty = 1を避けるために、我々はMemcachedの読み込みでRuby on Railsをブロックすると、CPUを食べることはできません。

loop do # daemon 
    until Rails.cache.fetch("have_dirty_rows") do end 
    page = 1 
    loop do # paginate dirty rows 
     dirty_batch = paginate(#:select  => "*", 
          :order  => "id", 
          :per_page => DIRTY_GET_BATCH_SIZE, 
          :conditions => {:dirty => 1}, 
          :page  => page) 
     if dirty_batch.empty? 
     Rails.cache.write("have_dirty_rows",false) 
     break 
     end 
     ... 
     page = page.next 
    end 
    end 

のようなテーブルスキャンをラップmemcachedの障壁を、設定し、ループはまだ100%のCPUを食べます。 Ruby/Railsにmemcached値のようなものをブロックする、またはmemcached値からフィードすることができる効率的なメカニズムがあるので、常にポーリングしていませんか?

+0

ポーリングは煩雑ですが、多くの異なるタイプのプロセスをインターフェースするためにはうまくいきます。唯一の他の方法は私が考えることができるcronジョブです。 – Dex

+2

このソリューションの前に問題を調べて、サーバーを停止させます。つまり、ダーティー行はどこから取得されますか? 汚れたビットを設定しているのを知った瞬間に、コードで何かをすることはできませんか? – kain

+0

実際、AMQPクライアントなど、一般的にどのように待機が実装されているのだろうかと思います。あなたが変更するために見ている値のソースのコントロールを持っていない多くのケースがあります... – Alexy

答えて

1

アクティブポーリングは不良です! ダーティビットはどこから届いていますか? このプロセスが他のプロセスに通知するためにメッセージキューメカニズム(例:RabbitMQ)を使用すると良いでしょう。データベース内の何かが変更されました。

+0

Rubyプロセスをブロックする能力に関する質問。 RabbitMQは確かに考慮事項ですが、ブロック自体は面白いです... – Alexy

+0

mmh、これはあなたを助けるでしょう:http://makandra.com/notes/1026-simple-database-mutex – Klaus

関連する問題