BEAR 0.8.x

現在のBEARは0.8.Xで、コアな機能は大分実装されてきてました。ここで機能追加を一旦fix、BEAR0.9は確認、テスト、パフォーマンスの向上など安定性の向上のためのバージョンにしてBEAR1.0に繋げようかと考えてます。実装前にその後の機能追加や方向性など単なるアイデアでまとまってないのも含めてかいてみようと思います。

リソースキャッシュ

Webフレームワークのキャッシュで最も一般的なのはビューキャッシュでしょうか。ビュー部分をページまるごと、あるいは表示の一部分をキャッシュし、その取得ロジックやDBアクセスのコストをセーブします。Smartyでも簡単に使えます。モデルをキャッシュしようとするとコントローラでモデル(オブジェクト)を直接アクセスするフレームワークでは、コントローラでキャッシュを利用するか、モデル側(ビヘイビアなどで)でキャッシュ対応するのが一般的だとおもいます。

BEARではページはリソースを直接扱わず、ページにインジェクトされたリソースブラウザサービスがリソースアクセスを行います。キャッシュ機構はページが使用するリクエストサービスが実装しています。(WebアクセスでWebブラウザがキャッシュ機構をもっているようなものです)

NoSQLキャッシュ

ROAの「ステートレス」と「統一インターフェイス」で、リソースへリクエストをメソッド、URI、バリュー(引数)それにオプションが決まれば事前準備なしに行う事ができます。そのリクエストはURIとバリューの値をシリアライズすれば1つのキーにすることが可能です。そのシリアライズされたリクエスト”キー”でリソース状態をバリューにキャッシュとしてNoSQLを使えばどうかと考えてます。キャッシュというより参照用RDBの代わりです。

キャッシュ更新を時間切れでなくメソッドで

キャッシュ破棄のタイミングは時間指定でなくメソッドを用いるのはどうかと考えてます。つまり、特定バリューのリソースアクセスにバージョンを持っておき、”サイドエフェクトがある操作”(update, delete)を行うとバージョン番号があがるというものです。

IDしか引き数を持たないリソースがあったとして、バージョン番号1,ID=3というキー”1:ID=3”でread()を何時間してもキャッシュに変化がなくオリジナルデータソース(RDB)にアクセスはありません。ですがID=3でのupdateやdeleteが発生するとリソースバージョンが1から2になりキャッシュキーは(2:ID=3)になります。キーが代わりキャッシュヒットしないので新しいキャッシュデータがストアされます。(古いキャッシュを明示的に破棄しないでGCにまかせます)

閉じたリソースと開いたリソース

以上の事はリソースが他のリソースに依存していないことを前提としています。(join先のテーブルが別リソースに使われてて更新されていたら機能しない)。それを解決するためにリソースにそのリソースの依存性がないというアノテーションを用意したり(@cache closedとか?)リソースキャッシュの依存性を示すようなアノテーション(@cache dependency profile, followerとか?)を用意すればいいのかなとか考えてます(まだ自信がありません)

ビューキャッシュ

リソース状態だけでなく、リソーステンプレートを(しかもUA別に)ストアしてやればビューキャッシュになります。キャッシュはレイヤーを持つのでリソース状態キャッシュはリソースクライアントで利用する事ができます。それにリソーステンプレートが適用されたキャッシュはビューキャッシュとなります。※その場合のキャッシュキーはURI + バリュー + バージョン + UA + テンプレート

こういう風にうまくRDBのデータをマスターとしてNoSQLのキャッシュにうまく乗せ、RDBの使いやすさとNoSQLのスケールアウト性がうまく合成できれば理想的なんじゃないかと。RDBのリクエストを最小化することができれば使用するDBライブラリ(MDB2, PDO, Zend_Db)等の性能差をあまり考えなくてよくなるメリットもあります。揮発性のあるキャッシュというより、参照用DB(スレーブDB)の代替になれば理想的です。容量や実装の問題もあるかもしれませんが高い可能性を感じています。