データベースの話になったので、ここで排他制御にも触れておきます。排他制御が必要なことは、今さら言うまでもないでしょう。HTTPは基本的にはステートレスなので、レコードロックを持ち続けることは不可能です。もし仮にそれが可能だったとしても(実際は有り得ませんが)、同時並行性から考えて、ユーザー操作をまたがった長時間のロックは好ましくありません。
そのためには、「一度読み込んだデータの更新前に、他のユーザーからの変更処理が行われていないか?」をチェックする機構が必要になります。「楽観的ロック」の機構です(以下の参考リンク参照)。これを実現するためには、対象のテーブルに対して更新チェックをするためのカラムが必要になります。一般に、このような場合、対象レコードにおける「更新履歴番号」や「更新日時」を利用することになります。
「更新日時」を利用する場合は、その精度について設計上の議論になることがよくあるので、使用するデータベースに従って精度の確認を行い、適切なデータ型を選択する必要があります。排他制御、また悲観的ロックについても以下の参考リンクを参照してください。
参考リンク
実は、ここにはアーキテクチャ上の検討課題があります。「データベースに何を使うか?」です。数年前であれば、リレーショナルデータベース、これ一択だったように思います。
リレーショナルデータベースが得意とするのは、集合演算です。複数のデータを結合(ジョイン)して分析を行うことが得意です。しかし、データ分析のシステムが別に存在しているのであれば、オンラインシステムが持つべき機能は、各個人単位のデータを高速かつ安全に登録できる機能であり、他のユーザーデータとの結合処理(ジョイン)機能などは有り得ません。
繰り返しになりますが、「多数のデータを、さまざな軸で分析するシステムが別に存在している」という条件下であれば、膨大なユーザー数、膨大なトランザクション量を処理する方法としての選択肢は、今やリレーショナルデータベース一択ではないと考えられます。
無論、もっともよく使われているのはリレーショナルデータベースですが、現在は他にも「key-value型」「全文検索型」などがあります。アーキテクトは、こういった中からユーザーニーズにマッチしたものを適切に選択する必要があります。双方(リレーショナルデータベースと全文検索型)を併用してシステムを構築するケースもあります。
「非機能要件」の観点では、アーキテクチャを考える上で重要なポイントに「性能」があります。システム構築においてよく起きる問題の一つは、「性能」に関するものです。このような「非機能要件」の実現が難しいのは、それを実現しているレイヤーがインフラストラクチャだったり、ソフトウェアだったり、その両者だったりするためです。それにより、責任分解点が曖昧になりがちなため問題が起きやすいのです。例えば、Webシステムの設計において、性能という観点を考慮しようとしても、「エンドユーザーが要求するビジネス上の処理を完了するためには、どうしてもこれだけの時間が必要となってしまいます」という話はよくあります。
ここで最初に検討すべきは、「ビジネスロジックの実装場所が適切か?」ということです。ビジネスロジック自体を高速なロジックに変更することや、完全解ではなく近似解を使うことで、処理時間を短縮するというアプローチもあります。もう少し簡単な話としては、プログラミング言語でロジックを組むよりも、SQLで処理した方が圧倒的に速い場合もあります。つまり、業務処理を複数のロジックに分割し、それらの実行コストを考えて適切に責務配置することが重要なのです。この非機能要件については、後ほど「ポイント10:非機能要件」で詳しく解説します。
また、現在の技術では、CPUのクロック数を高めることには限界があります。よって、「並列化されたマシンをいかにして効率よく使うか?」という観点が重要です。アーキテクチャ的には、マシンを増やせば、スループットがリニアに増加するように設計されていることが理想です。そこでは、「いかにしてボトルネックを発生させないか?」が重要となります。
Webアプリケーションは、基本的にはステートレスなので、マシンを増やせばスループットが増えるはずです。しかし、実際には何らかの形でユーザーの状態(ステート)を維持する必要があり、そのためにセッションが使われます。しかし、このセッションがボトルネックになる可能性があり、その取り扱いが一つの課題になります。
通常、Webアプリケーションサーバーは、セッションをメモリ中に保持します。この場合、アーキテクチャ設計上の留意点として、「前段に配置されているロードバランサーは、メモリ中のセッションを見つけるために、同一サーバーへリクエストを届ける必要がある」ことが挙げられます。よって、単純なラウンドロビンではボトルネックの回避は無理です。またこの場合、当該のサーバーがダウンすると、セッション情報は消失してしまいます。
参考リンク:DNSのラウンドロビン機能を利用する(@IT)
他の方法としては、セッションリプリケーションという機能の使用も考えられます。しかしサーバー台数が膨大になれば、そのためのコストも馬鹿にならない以上、容易にマシンを追加することも難しいものです。そこで、「セッションをデータベースに保存する」というアーキテクチャが採られることもあります。
つまりアーキテクチャの選定は、常に正しい唯一解があるわけではなく、技術の進歩や外的環境変化によって、その正しさも変化することを理解しておかなければいけません。例えば、「セッションをメモリ中に保持するアーキテクチャ」が間違っているわけでもありません。イントラシステムのように利用ユーザー数やトランザクション数の予測が可能であり、強固なサーバーを配置できるのであれば、それもまた正しい選択なのです。
Copyright © ITmedia, Inc. All Rights Reserved.