2014年9月10日水曜日

【GAE】初級実装編 インサート実行3 時間差反映

株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。

只今、クラウド基盤「Google App Engine(以下、GAE)」の連載しています。

ここ数回はDBへのインサートについてご紹介していますが、今回がその最後です。

登録成功!! しかし……

前回までの処理で、無事にレコードをDBに登録する「put」が出来るようになりました。

では、さっそく、登録したレコードを取得する「get」をやってみましょう。

ShohinDao dao = new ShohinDao();
Shohin shohin = dao.get(key);

あれ?取れないな。
おかしいぞ。
もう一回!
よいしょ!!
よいしょ!!
お、取れた。

変ですね。
目の錯覚でしょうか?

違うんですよ。
GAEは遅延するんです!!

分散処理の宿命

そう、普通のDBであれば、テーブルに書き込んでコミットした瞬間に処理が完了しますから、遅延なんて起きません。

しかし、GAEは分散処理システムですからそうは行かないのです。
put処理が完了した後でも、その向こう側では非同期で色々と処理が走っており、それら全てが完了した時、初めてgetでレコードが取得出来るようになります。


この現象、ツイッターなんかやっていらっしゃる方だとご理解頂けると思います。

「ツイートするぜ、ポチッ!」とやっても、送信完了の瞬間に自分のツイートが反映されてませんよね?
でも数秒すると出てくるようになる。
アレが正にこの現象です。

即時性を犠牲する代わりに、可用性や耐久性などを優先しているのです。


こういうのを「結果整合性(eventual consistency)」と言います。


処理が多少遅延したとしても、最終的にはDBへの登録はもちろん、レプリケーションへの反映まで一通り一貫性を保って完了すればOKという考え方です。

「最終的にはちゃんとやっておくから、過程についてゴチャゴチャ言うな」と言わんばかりのこの発想。
日本人では出て来ない発想かもしれません。。。

どうすりゃいいの?

さて、問題はこの遅延とやらの所要時間ですね。

遅延するのは分かったけど、どれくらい遅延するのか?

ネットで調べた所、どうも「長くて1秒くらい」という声が見受けられます。
私も実際何度か実験してみましたが、同感ですね。大体こんなもんかと思います。

しかし、更にネットを調べてみますと「反映まで半日かかった」なんて声も見つかりました。

半日の遅延は流石に看過できませんが、要はこういう時は障害が起きているのです。
流石GAEということか、障害が起きても完全ダウンするわけではなく、大幅遅延でも縮退運転で耐える堅牢性を誇ります。
(半日も遅延させるんだったら、いっそのことダウンさせてくれた方がマシな気もしますが)

何が言いたいかと言いますと、結局、何秒遅延するかは分からないということです。

平常運転なら1秒未満で反映されますが、少々混み合っていた場合は数秒くらい要することだってあります。

つまり、『登録⇒即表示』を厳密にやらなきゃいけない仕様はNGと言う事です。

例えば、


  • 登録完了⇒即座に登録結果確認画面へ自動遷移。


なんて仕様は実現不可能です。
また、

  • 商品発注完了⇒確認画面をチェックしたけど何も出てない。⇒もう一回⇒二重発注。

なんて、運用的に確認が必須な業務の場合もキツいものがありますね。
こういう場合は、

「商品を発注しました。発注番号はXXXXXXです。発注履歴の確認は商品発注確認画面をご覧下さい。
システムが混み合っている場合は反映が遅れる場合があります。予めご了承下さい」

みたいに注意書きで逃れる、とかですかね。

「発注しましたッ!!」「発注番号はこれッ!!」という感じに発注完了メッセージにインパクトを持たせて、
「あれ~? 今、俺ってちゃんと操作したっけ? もう一回やってみよう」みたいな不安感を利用者に与えない画面設計が重要になります。

逆に、「二重送信したら後で消せばいいだろ」みたいな水準で十分な要件である場合は知らんぷりを決め込むのもアリ。

インターフェース設計のセンスが問われる所になりますね。

終わりに

これでDBへの登録関連は完了です。

次はDBから取り出した値を画面に表示するわけですが、GAEではjspを使わないのがお約束。

フルAjaxで勝負します。

次回からはAjaxライブラリを使った描画処理についてご紹介です。

1 件のコメント: