データ指向アプリケーションデザイン第8章分散システムの問題
プロセスの一時停止
- 分散システムにおけるクロックの危険な使い方例
while(true) { request = getIncomingRequest(); // ロックの有効期限は別のマシンで設定されたもの // 比較されているのは、ローカルクロック // 問題1: ローカルクロックの同期がずれているとおかしな結果になる if (lease.expiryTimeMillis - System.currentTimeMillis() < 10000) { lease = lease.renew(); } if (lease.isValid()) { // 問題2: もし仮に isValid メソッドが実行されてから以下の行が実行されるまでに // アプリケーションが15秒停止したら、リースの有効期限は切れてしまっている // が、リースの有効期限が切れているかどうかの判定は次のループまでわからない process(request); } }
- アプリケーションスレッドが長い時間停止すると想定するのはおかしい?
- おかしくない
- ランタイムに実装されている GC は時折実行中のスレッドをすべて停止する
- 仮想マシンはサスペンド(すべてのプロセスが一時停止され、メモリがディスクに退避される) されうる
- パーソナルコンピュータだったら、液晶パネルを閉じるだけでサスペンドされることがある
- コンテキストスイッチやハイパーバイザーが他の仮想マシンへのスイッチを行うとき
- スチール時間: ほかの仮想マシンで消費される CPU 時間
- 同期的なディスクアクセスの場合、ディスク I/O の読み取り完了まで待機される
- ディスクへのスワッピング(ページング)が起きているなら、ディスクからメモリにページが読み込まれている間スレッドは一時停止される
- スラッシング: ページングが頻発して、実際の作業を行う時間がほとんど取れない状態になること
- SIGSTOP シグナル
- 上記の状況はすべて、実行中のスレッドを任意の時点でプリエンプション(一時的に中断)するが、すべてそのスレッド自身は気がつかない
- 単一マシン上のマルチスレッド制御のために使用可能な道具: ミューテックス、セマフォ、アトミックなカウンタ、ブロッキングキュー等
- これは分散マシンでは使えない。共有メモリが存在しないため。ネットワークを通じてメッセージを送信するしかない。
- おかしくない
レスポンスタイムの保証
- ソフトウェアが反応する時間に期限が指定されているものがある。これがハードリアルタイムシステム
- Web の世界におけるリアルタイムは、厳密なレスポンスタイムの制約のないストリーム処理とう指す曖昧な言葉
- 組込システムにおけるリアルタイムは、あらゆる環境下で指定されたタイミングの保証が満たされるように注意深くシステムの設計とテストが行われるという意味
- RTOS: 指定された間隔で CPU 時間の割当保証を伴うプロセスのスケジューリングが必要
GC によるインパクトの制限
- GC による一時停止を事前に計画された短時間のノードの停止のように扱い、一つのノードが GC を待っている間は、
他のノードがクライアントからのリクエストを処理する、という方式もある
- これにはノードの GC による一時停止がもう直ぐ必要になることをランタイムがアプリケーションに通知できる必要がある
- ヤング GC だけ行い、Old GC (Full GC) が必要になる前にプロセスを再起動するという方法もある
- 再起動するノードは一つだけにして、トラフィックはそのノード以外に流されるようにすればよい
知識、真実、虚偽
- 分散システムにおいて他のノードの状態を知るためには、ネットワークを通じたメッセージ交換を行うしか方法はない
- 分散システムでは、ある前提条件を仮定し、その前提の範囲内で正しく動作することを保証するシステムモデルがある
真実は多数決で決定される
- ノードが自身の状況に対して下す判断は常に信じられるわけではない
リーダーとロック
あるものを一つだけにしなければならない状況
ノードの過半数から落ちているとみなされるにもかかわらず自分がリーダとして振る舞い続けようとすると、問題が生じる可能性がある
フェンシングトークン
ロックサーバーがロックやリースを渡すたびに、同時にフェンシングトークンも渡す
ロックサービスとして Zookeeper が使われている場合、トランザクション ID の zdix やノードバージョンの cversion をフェンシングトークンとして使用できる
ビザンチン障害
分散システムを難しくする問題は、ノードが嘘つくケース
ビザンチン耐性をもつとは、一部のノードに不具合があってプロトコルに従わなかったり、悪意を持った攻撃者がネットワークにおいて妨害をしたりしているような状況においても正しく動作し続けられることをいう
- ビザンチン耐性を持たないといけないシステム
弱い嘘
- ハードウェアの問題やソフトウェアのバグのような弱い嘘に対応する仕組みを持たせることに価値はある
システムモデルと現実
システムモデル: 分散アルゴリズムが前提としているシステム中で生じると予想されるフォールトの種類の定式化
タイミングの前提に関する 3 つのシステムモデル
- 同期モデル
- ネットワークの遅延やプロセスの一時停止機関、クロックの誤差に限度があることを前提とする
- ほとんどの分散システムにおいて同期モデルは現実的ではない
- 部分同期モデル
- システムのほとんどの場合同期モデルのように振舞うものの、ネットワークの遅延、プロセスの一時停止、クロックの変動が上限をこえることが時々生じることを意味する
- 非同期モデル
- タイミングに関するいかなる前提を置くことも許されない
- クロックを持っていないので、タイムアウトは利用できない
- タイミングに関するいかなる前提を置くことも許されない
- 同期モデル
ノードに関する一般的なモデル
アルゴリズムの正しさ
- アルゴリズムの正しさは、その性質を記述することによって定義できる
例フェンシングトークンの性質
あるアルゴリズムが何らかのシステムモデルにおいて正しいとは、そのシステムモデルにおいて生じうるあらゆる状況下においてその性質が満たされること
安全性とライブ性
ライブ性の性質: 最終的にはよいことが生じること。eventually という言葉その定義に含まれることが多い (eventual consistency)
安全性の性質: 何も悪いことが起こらないこと