2008年10月27日月曜日

勘弁してください、ほんと・・・

何度もお話しているように、Google App Engineにはmemcacheという仕組みがあって、簡易な(そして不揮発でない)データベースのように使えるので、うまく使えばデータベースアクセスを減らすことができ(GAEではDatastoreアクセス回数にもQuotaがかかっているのだ→詳しくは:Understanding Application Quotas with Google App Engineの辺を見ると良い)、かつレスポンスも多少なりとも早くなるのでGoodなのだ。

だがしかし、memcacheの痛いところはロックができないことで、2つのプロセス(GAEに限定すれば2つのHTTPリクエストの処理が、と言い換えてもいい)が同時に同じエントリを更新しようとすると、どっちが採用されるかわからない。これはレスポンスのために割り切ってることなのでしょうがない。memcacheのせいではない。

んで、アプリ側でそれを回避するように作りたいので、以下のようにしてみた。
1.更新するmemcacheデータを読み出す
2.更新するmemcacheデータをキャッシュから消す
3.何やら処理をする
4.memcacheをaddで更新する
addはエントリがあると失敗するので、同時に同じ処理が走れば、後続のプロセスはaddが失敗するはずなのだ。失敗したとわかれば、その後の処理のしようもあるってもんだ。再度1からやるとかね。
(一方のプロセスが1~2の間にいるときに、もう一方が1~4まで終わらせちゃうとデータの矛盾がおきるかも知れないがそこまで考えるのはやめておこう)

で、SDK環境ではうまく動きました。サーバにアップデートしました。

結果。複数プロセスを同時に走らせなくてもaddが失敗するでないの。。。また本物環境とSDK環境の差ですか。。。勘弁してください、ほんとに。。。

多分、類推なのだが、deleteのあと、しばらく置かないとエントリはまだあるとみなされてaddが失敗するのではなかろうか。
代わりにエントリがあろうがなかろうが値をmemcacheに書き込むsetを使ってみると、何事もなく成功する。・・・成功するが目的は達成できんのだよそれじゃあ!

むぅ。。。なんとかならんのかね。。。

0 件のコメント: