SiNBLOG

140文字に入らないことを、極稀に書くBlog

M/SからHRDへの変更した場合、設計は変える必要があるのか?

appengine office hoursで、松尾殿にDatastoreの2つの形式は今後どうなるのか聞いてみた。

「これからのDatastoreの主流はHRDとなり、いずれ、M/Sは使えなくなるだろう。」

既にPython2.7はHRD限定だし、javaでも新規AppはHRDだ。

M/Sも最低数年はサポートするが、いずれ無くなる可能性があるとのことだった。


僕が作成中のAppはM/Sのままだったので、Appを一度削除し、作りなおした。

しかし、ここで疑問が沸く。

HRDにしたのは良いが、実装はどう変えれば良いの?

そんなことを考えながら調べていたら、以下の話を見つけた。

Google グループ

put直後にqueryで取得しようとすると、Indexが更新されてなくて、

意図したデータが取れないことがあるよ!

ということだろう。

そして、それを考慮した設計が必要であると・・・!


が、しかし!!!

それを考慮した設計というのが、具体的にどのようにすることなのか分からない!

ということで、もう一回appengine office hoursで、松尾殿に聞いてみた!


まず、Indexの更新にかかる時間だが、99%は数十msで更新。残りの1%は遅くて2sぐらいらしい。

強い結果整合性を求めない限りは、そういうものですとユーザに伝える程度でも大丈夫。

しかし、強い結果整合性が欲しい!という場合は、以下のような対処の方法がある。

1.Keyによるgetに切り替える。
 とても単純。

2.ancestor query を使う。
 ancestor queryは強い結果整合性を持つ。
 マルチユーザのブログの場合、各ユーザに親Entityを作成し、記事をそれの子Entityとする。
 しかし、その記事にコメントを付ける場合は、同じ設計にするかは考える必要がある。
 コメントは不特定多数のユーザが書き込むため、datastore contention が発生しやすくなる。
 これかな?http://code.google.com/intl/ja/appengine/docs/java/datastore/hr/overview.html

3.クエリの結果を、再度検証する。
 銀行口座で、100円以上口座に預けているデータをqueryで取得する場合。
 ユーザAの口座にはある時点で、120円あったが、30円引き出し、90円となった。
 もし、Index更新前にqueryを実行した場合、ユーザAの口座も取得してしまうかもしれない。
 そのため、取得後に再度データを検証する。(ループで回して100円未満の口座をはじくなど)


教えていただいたのは、この3つ。

特に3の話を聞いた時に、

最新のデータが取れないわけではなく、Indexが更新されていないことがある。

の意味が分かった。

口座に100円以上あるという条件で、90円のデータが取れてしまうのだ。

しかし、120円の時点のデータが取れてしまうわけではない。

データは90円に更新されているが、Indexが120円のままなのだ。


HRDにしたからと言って、物凄く神経質になることは無いということが分かったので、安心した。