Rails4 の counter_cache のカウントを redis-objects でカウントしてみた時の試作コード

みなさんこんにちは菊池です。
今週末は紅葉を見に行こうと思っているんですが、台風が!

さて、ActiveRecord の標準機能 counter_cache はお手軽なんですが、『ちょいちょい Deadlock するよー』という Google の検索結果が気になります。「んー、このまま使って良いものか」と悩ましいところです。

カウントアップ/ダウンと値の参照は redis-objects の counter を使っちゃって、時々データベースにカウント値を同期して  SQL で集計も出来るようにしてみたらどうかなーと思ったんでちょっと書いてみました。

別の記事を書きながら改めて動作確認したところ、sync_cache! 内に self.class.readonly_attributes.delete(dest) の追加が必要になることに気がついたので、追加してあります。この件につきましては別途記事にする予定。2014/12/05 追加(菊池)

app/models/concerns/redis_counter_cache.rb

これを使うには、モデルにちょっとした修正が必要になります


こんな感じに  〜_count がある方のモデルに include RedisCounterCache と counter_cache :〜_count を追加すると 〜_count_cache で redis-objects の counter が参照出来るようになります。

上のコードだと orders_count がデータベースに保存されている値で、orders_count_cache で redis-objects の counter を参照出来るようになります。

ということで、くどいんだけどこんな感じ
  • 〜_count が元々のカウンター
  • 〜_count_cache が redis-objects の counter を使ったカウンター
 になります。counter_cache の cache ってことでややややこしくなってしまった。。。まぁ試作なのでいいよね。

実際に使ってみると

このログとは別に Polymorphic Associations とも組み合わせて使ってみましたが、期待通りに動きました。

sync_cache! は定期的に動かしてもいいし、データ登録時に非同期のジョブを走らせてもいいかも。

ということで試作コードの紹介でした。

今週末の台風大丈夫かなー 

菊池