ひどいことになるので。

DRECOM Award on Rails 2007にエントリーしました。応募するアプリケーションはまもなく運用を開始する予定です。お楽しみに。


acts_as_searchableを使ったアプリケーションを運用中、Hyper Estraierのインデックスが破損した場合などはModel#reindex!を使ってインデックスの再生成をする必要がある。運が良ければestcmd repairで直るんだけど。この際、このメソッドは大量にリソースを消費する。
全レコードを一気にHEに登録するわけだから、CPU負荷は仕方ない。しかしそれだけじゃなくて、メモリも大量に持っていってくれる。これは、メソッド内で単にfind(:all)をしているせい。全レコードを一気にメモリ上に展開するわけだから、そりゃあ場所を取る。レコード数が多いと致命傷になりかねない*1ので、ここをちょっと弄ってやる。


acts_as_searchable.rb220行目付近

        # Peform a full re-index of the model data for this model
        def reindex!
          find(:all).each { |r| r.update_index(true) }
        end

となっているところを、

        # Peform a full re-index of the model data for this model
        def reindex!
          max = count
          (0..max/100+1).each{|index|
            find(:all, :limit => 100, :offset => index*100).each{|r|
              r.update_index(true)
            }
            GC.start
          }
        end

とやってやる。やってることは簡単で、一気にfindするんじゃなくて100件ずつ取ってこさせる。これなら、処理速度は落ちるけどメモリ上に展開する量は抑えられるので、結果的にメモリの少ないマシンでは軽快に動くようになる。

*1:というかついさっきなった