Oracle Coherenceの導入をしようと、いまプロトタイプ作成にいそしんでいる。
やはりKVSはDBとは勝手が違うって戸惑うばかりだ。
まだ、本格的にプロジェクトで検討を始めてから2週間だが現時点での所管を述べる。
一言でいえば、KVSの設計はむずい。
RDBの感覚が抜けないからなのかな、、、
ORMの問題とトランザクション管理をどうするか?
そもそもオブジェクトとRDBのテーブルはデータの粒度としてのミスマッチがあるという問題があるが、それに加えてトランザクションのACID的な緩さをどう補うかを検討しなければならない。これが問題だ。
一つだけ言える事は、現時点でのKVSにはRDBのように見事に汎用化、パッケージ化されたトランザクション管理アーキテクチャはないということだ。
これはコミット・ロールバック、ものによっては2フェイズコミットをアプリケーションで実装するか?という問題に行き着く。
そんなことに労力はさけないので、永続化オブジェクトの設計をうまいことやって、トランザクションの粒度をオブジェクトモデルの粒度とあわせることで逃げようと検討することになる。
こうするとオブジェクトモデルにトランザクションという非機能要件が紛れ込む。
非機能要件が、ドメインオブジェクトに影響を与えるというのは好ましくない。
どちらにせよ業務設計にまで深く突っ込まないと、最適なトランザクション管理方法が決定できないというのが現時点での所感だ。
キャッシュとDB更新の戦略
KVSで登録したデータは、どうがんばっても「キャッシュ」であるとの割り切りが必要だと感じている。
Oracleのコンサルさんも入ってるのでいろいろヒントをもらった。
「ライトスルー/リードスルー/キャッシュアサイド/ライト・ビハインド」という基本的な更新/参照の設計パターンを知っておくだけでも有用だということで、
http://otndnld.oracle.co.jp/document/products/coherence/34/doc_cd/coh.340/B52977-01/readthrough.htm
たしかにこれはヒントになる。
リードスルーは、キャッシュを参照しようとしたエントリがキャッシュになかったときに自動的にDBからロードしてキャッシュに入れるやりかただ。
ライトスルーは、キャッシュ+DB更新が完了するまでput の結果を返さないことでで、更新速度を犠牲にしてでもDBとキャッシュの整合性を担保する方法だ。
キャッシュアサイドとは、DBとキャッシュの更新をそれぞれ別々にアプリケーションが管理するやりかたであり、DBとキャッシュの整合性は厳密には担保できない。
これらのパターンをどだいに、業務内容を分類する必要がある。
僕は、DBへの更新は速度を多少犠牲にするでもいいかと思い始めている。
つまり、まずはJDBCなりでトランザクションありでDBを更新する。
それからキャッシュへのエントリはトランザクションなしでとりあえずputする。
そうして、参照系のみがキャッシュの恩恵を受けるようなやり方をするのはどうだろうかと考えている。
念のためリードスルーでキャッシュミスをカバーする。
更新速度を犠牲にしないなら、ACIDの厳密さを犠牲にするなど、KVSではトレードオフを我慢する必要がある。
しかし、それを補うほどの可用性とパフォーマンスがあり、今後もクラウドならずとも増えそうなアーキテクチャではある。
現段階ではまとまらないが、以上。