コンピュータの性能は価格の 2 乗に比例する
グロッシュの法則は 1980 年代以降のコンピュータに対して成り立たなくなってきた。
それに伴い、システムのスループットを向上させるために、より優れたハードウェアを導入する方法 (スケールアップ, scale-up) より安価なハードウェアの台数を増やす方法 (スケールアウト, scale-out) が、コスト面で有利であると考えられるようになった。
分散システムは以下の原則を満たすことを期待する。
「透過的である」とは、ユーザー (ex. 分散データベースの場合はアプリケーション開発者) がそのシステムの技術的詳細を意識することなく使えることを意味する。
アムダールの法則は、並列処理において並列度を上げた場合に並列化できない部分の存在がボトルネックになることを示した法則である。
アムダールの法則を分散システムに適用すると、処理の分散によるシステム全体の性能向上率は次の式で表される。
一方で並列化可能な部分は、処理の大きさに関わらず一定であるとし、「十分に大きな規模の処理は、効率的に分散化して解くことができる」ことを示した法則もある → グスタフソンの法則
CAP 定理 (CAP theorem) とは、ノード間のデータ複製において、同時に次の 3 つの保証を提供できないことを示す定理である。
すべてのデータ読み込みにおいて、最新の書き込みデータもしくはエラーのどちらかを受け取る性質。
ノードの障害により生存ノードの機能性が損なわれない性質。つまり、単一障害点 (SPoF = Single Point of Failure) が存在しないという性質。
システムは任意の通信障害などによるメッセージ損失に対し、継続して動作する性質。
CP 型は基幹系システムや勘定系システムなど、ミッションクリティカル (mission critical) な SoR (System of Records) 領域に適している。 AP 型は UX (= User eXperience, ユーザ体験) や可用性を重視する SoE (System of Engagement) 領域に適している。
BASE 特性とは前述の CAP 定理の制約の下、高可用性を達成するシステムの特性である。
結果整合性とは、厳密な一貫性は保証しないものの、時間経過で正しい状態に収束する性質のことである。
NoSQL に代表されるデータストアでは、結果整合性を採用することで、容易なスケールアウトを実現している。
クラスタリング (clustering) とは、複数のコンピュータを結合し、あたかも 1 つの大きなシステム (クラスタ, cluster) として利用可能にすることをいう。
クラスタリングには以下の目的がある。
クラスタは目的によって以下の 2 つに分類される。
また、クラスタはリソースの共有形態によって以下の 2 つに分類される。
クラスタを構成するノード間で一部のリソース (CPU/メモリ/ディスク) を共有するもの。 共有リソースは単一障害点となるため、別の冗長化と併用する場合が多い。
クラスタを構成するノード間でネットワーク以外に直接のリソース共有がないもの。 ネットワークがボトルネックになりやすい。
2 相コミット (two-phase commit) は、分散システムでトランザクションのコミットについての一貫性を保証するためのプロトコルである。 要求を受け取ったノードが調整者 (coordinator) となり、参加者 (cohort) であるリモートノードを調整する。
2 相コミットは完全な一貫性を保証するものではない。 コミット可否の問い合わせとコミットを連続して行い、コミットの処理中に障害が起きる確率を下げるものである。
2 相コミットの処理内容を、コミット要求フェーズとコミットフェーズに分けて下記に示す。
全参加者がコミットに合意した場合の処理を以下に示す。
コミットに合意しない参加者がいた場合の処理を以下に示す。
2 相コミットは以下のようなデメリットがある。
レプリケーション (replication, 複製) とはリソース (ex. 分散データベースにおけるコミットログやデータ) の複製、あるいは複製する処理のことをいう。
論理レプリケーション (トランザクション・レプリケーション, 計算レプリケーション)
トランザクションログのレプリケーション。 ログ構造化ファイルシステムは論理レプリケーションの 1 つである。
物理レプリケーション (データレプリケーション, 状態機械レプリケーション)
ローカルストレージとリモートノードの両方から完了通知があるまで、書き込み要求が完了したとはみなさない。 そのため、全体の性能が低下する。 また、一部ノードに障害が発生している間の書き込み要求は全て失敗となるため、可用性は保証できない。
ローカルストレージで書き込み完了すると同時に書き込み要求が完了したとみなす。 リモートノードのストレージ更新までには遅延があるため、一貫性は保証できない。
書き込み要求が完了したとみなすために必要な最低限の票 (リモートノードからのコミット完了通知) の数。 前述の同期レプリケーションでは write quorum = リモートノードの数, 非同期レプリケーションでは write quorum = 0 とみなすことができる。
読み込み要求を完了するために必要な最低限の票 (同一なレプリケーションの数)。
あるデータのレプリケーション数を V, write quorum を , read quorum を とすると、以下の条件を満たすとき、強い一貫性が保証される。
パーティション (シャード, shard) は分散システムにおけるデータの分割を指す。
テーブルの分割方法には以下の 2 種類がある。
あるデータがどのパーティションに含まれるかを管理するデータ構造に、MurmurHash をハッシュ関数とするブルームフィルタ (bloom filter) がしばしば使われる。
ブルームフィルタには偽陰性 (false negative) はないが、偽陽性 (false positive) による誤検出の可能性がある。 偽陽性の発生率 は以下の式で表される。
ブルームフィルタは同様の集合的データ構造の中で、圧倒的に空間効率 (メモリ使用量) において優れる。
シェアード・エブリシング (shared everything) は、分散システムにおいて、各ノードが同じパーティションを共有するモデルを指す。
古典的な分散システムの多くがこのモデルを採用している。 書き込み要求を司るプライマリノードと読み込み要求を司るバックアップノードに役割を分担する。 プライマリノードが何らかの障害で停止すると、バックアップノードが役割を交代して計算を引き継ぐ。(フェイルオーバー) 非同期レプリケーションではプライマリノードの障害発生のタイミングによってはログの一部が失われる。
任意のノードに更新要求を送ることができ、そこから他のサーバーに通知する。 トランザクションがかち合うのを防ぐことが課題となり、非同期レプリケーションでは衝突を防ぐことはできないため、何らかの方法 (ex. 分散ロックマネージャ) で一貫性を保証しなければならない。
Oracle RAC が採用している、各ノードが同じストレージを共有する構成。 ここでは詳しく解説しない。
シェアード・ナッシング (shared nothing) は、分散システムにおいて、各ノードが同じパーティションを共有しないモデルを指す。 いずれかのノードが何らかの障害で停止すると、そのノードに割当てられていたパーティションが読めなくなるため、分断耐性は保証できない。
シェアード・ナッシングでは、異なるパーティションに対する結合を含むような問い合わせにおいて、シェアード・エブリシングよりも処理時間がかかる。
データが属するパーティションを決定する (パーティショニング, partitioning) 方法には以下の 2 つがある。
データの任意の部分 (ex. パーティションキー) にハッシュ関数を適用し、そのハッシュ値をパーティション数で割ったときの剰余によってパーティションを決定する。
トランザクションが参照するパーティション数 (問い合わせるノード数) が最小になるよう、アプリケーションのユースケースの知識を含めて、アプリケーション側で最適なパーティションを決定する。 前述した「異なるパーティションに対する結合を含むような問い合わせ」というシェアード・ナッシングの弱点を解消する。
ロードバランサ (load balancer) は、クライアントからの要求を適切なノードに割り当てることで負荷を分散 (ロードバランシング, load balancing) する。 ロードバランサをマスター, 処理を行うノードをワーカー (worker) と呼ぶ。
また、ロードバランサはワーカーの死活状態を確認して (ヘルスチェック, health check) を行い、応答がないワーカーを選択対象から除外する。
ロードバランサには以下の 2 種類が存在する。
L4 (トランスポート層) レイヤーで NAT (= Network Address Translator) として機能する。 宛先 IP アドレスを選択されたワーカーの IP アドレスに書き換える。
ワーカーのヘルスチェックには以下のようなものがある。
ICMP (= Internet Control Message Protocol) echo リクエストを送信し、echo リプライが返ってくるかを確認する。
ワーカーの選択方法には以下のようなものがある。
ラウンドロビンを採用するロードバランシングにおいて、DNS (Domain Name System) をロードバランサとして利用する。 ワーカーの情報がクライアントにキャッシュされたり、ヘルスチェックが不可能だったりと問題点が多い。
Web アプリケーションのロードバランシングでは、異なるワーカー間でセッションを共有する必要がある。 具体的に以下のような方法がある。
分散システム上で統制なしに作成できるデータの識別子の設計として UUID がある。
UUID v1 は 48 ビットのノードの MAC アドレス, 60 ビットのタイムスタンプ, 14 ビットのクロックシーケンスをもつ。
UUID v4 は乱数から 122 のビットのビットを生成する。 2 つの ID が偶然一致するまでの生成数の期待値は である。