もう数ヶ月くらい前になるけど Rails (ActiveRecord) で R/W splitting を行う switch_point という gem を書いた。 Rails アップグレード作業の中で、魔改造された acts_as_readonlyable をメンテすることに嫌気がさして、もっとマシな実装方法があるはずと思って勢いでコアの実装をして、それから実際のアプリケーションに組み込んで本番に投入していきながら機能追加やバグ修正を重ねて今の形になった。
先日の RubyKaigi 2014 の LT で、R/W Splitting in Rails というタイトルで switch_point の紹介をした。 今まで使い方を真面目に書いてなかったけど、LT 内で軽く紹介しつつ会期中に典型的な使い方を README に書いた。メソッドやクラスのドキュメントは全然書いてない (要るのかな…)。
LT の発表では言ってなかったけど、mirakui さんによる開発者ブログの記事 にあるように、switch_point は今のクックパッド本体アプリケーションで実際に本番で使われている。
switch_point は、
- R/W splitting のみに注力
- シャーディングはしない
- マイグレーションも支援しない
- Rails の激しい変更についていきやすい設計・実装
- 内部実装 (普通の Rails アプリケーションからは直接使われることの無いクラスやメソッド) になるべく依存しない
- ActiveRecord の内部実装はなぜか変わりやすい…
- 内部実装 (普通の Rails アプリケーションからは直接使われることの無いクラスやメソッド) になるべく依存しない
- あまり implicit な動作は行わない
- いいかんじに Master/Slave の選択を行うようなことをなるべくサポートしない
- あえて Master に SELECT したいときには自然にそれが行えるようにする
あたりに気をつけて作っていて、実際このままのコードで次の Rails 4.2 でも動きそう。 自分には必要無いので全く検証してないけど、Rails 3.1 とか 3.0 とか、もしかしたら更に前のバージョンでもそのまま動くかもしれない。 ちなみに switch_point という名前はレールと切り替えからの連想で付けていて自分ではわりと気に入ってる。
octopus はよくできてそうだと思う一方、以下のことが気になって乗っかる気になれなかった。
- Rails バージョンアップ時が心配
- アプリケーションが依存している gem の対応が遅いと、アプリケーションの Rails バージョンアップ時に足枷になりやすい
- メンテされなくなったときが怖い
- 今のところ Rails の変更についていっているようだけど、今後どうなるか不安
- Rails バージョンアップで壊れやすそうなので、継続したメンテが必要
Octopus.rails41?
みたいなメソッドを見るのがつらい https://github.com/tchandy/octopus/blob/v0.8.3/lib/octopus.rb#L67-L77
- メンテされなくなったときに、自分でメンテしてしていくのがつらそう
- 今のところ Rails の変更についていっているようだけど、今後どうなるか不安
- メインの機能はシャーディング
- コード量やモンキーパッチ量が多くなっているのは、いいかんじにシャーディングを実現するためのように見える
- でもシャーディングは要らなくて、R/W splitting だけが欲しい
シャーディングが必要な場合は引き続き octopus がよさそうな現状ですが、R/W splitting のみで十分な場合は switch_point も検討してもらえると嬉しいです。