サーバーが2台になった瞬間、世界のルールが変わるんですよね。

メッセージは重複するし、時計は合わないし、「死んだ」と「遅い」の区別がつかない。単一サーバーの常識が、ぜんぶ通用しなくなります。今回は、「二重課金」と「たまに消えるデータ」の生まれる場所から、マイクロサービスやAPI連携を作る人に効くものを8つ集めました。1つでも知らなかったら儲けものです。

① 「ちょうど1回だけ届ける」は、幻想です

分散システムの一番深い真実が、これです。

ネットワーク越しのメッセージ配送で、「ちょうど1回(exactly once)」を完全に保証することはできません。

送信して応答が来なかったとき、相手に「届いていない」のか「届いたが応答だけ失われた」のか、送り手には区別できないからです。再送すれば重複し、再送しなければ欠落する。

だから現実の設計は、「最低1回は届ける+受け手が重複を無害化する」の組み合わせになります。次の②が、その相棒です。

② 二重課金を防ぐのは、「冪等性」です

①の帰結です。メッセージは重複して届く前提で作る。

そこで効くのが冪等性(べきとうせい)——同じ処理を2回実行しても、1回と同じ結果になる性質です。

実装の定番は、リクエストに一意のIDを付けること。受け手は「このIDは処理済みか」を確認してから実行します。決済APIが「冪等性キー」を要求するのは、まさにこれなんですよね。

リトライを書くなら、冪等性とセット。片方だけだと、リトライが二重課金製造機になります。

③ サーバー同士の時計は、合っていません

複数サーバーのログを時刻で並べて、「こっちが先に起きたはず」——危ない推理です。

各サーバーの時計は、時刻同期(NTP)をしていてもミリ秒単位ではズレています。ズレは変動もします。

つまり分散システムでは、タイムスタンプの前後関係=実際の前後関係ではありません。障害調査で時系列を組み立てるときの、大前提です。

順序が本当に大事な場面では、時刻ではなく連番や論理的な順序づけで管理する。時計を信じない設計が、分散の作法なんです。

④ 「ネットワークは信頼できる」から始まる、8つのウソ

分散システムには、有名な「分散コンピューティングの8つの誤謬」というリストがあります。

  1. ネットワークは信頼できる
  2. 遅延はゼロ
  3. 帯域は無限
  4. ネットワークは安全
  5. 構成は変わらない
  6. 管理者は1人
  7. 転送コストはゼロ
  8. ネットワークは均質

——全部、ウソです。

分散システムに初めて触れる人がやりがちな思い込みとして1990年代に整理されたものですが、クラウド時代のいまも一言一句そのまま通用します。設計レビューのチェックリストとして、「この設計、8つのどれかを信じていないか?」と問えるんです。

⑤ 「死んだ」と「遅い」は、区別できません

相手サーバーから応答がない。落ちたのか、単に遅いのか。

外から見る限り、この2つは原理的に区別できません。だからすべての待ちにはタイムアウトが要り、タイムアウトは「諦める時間を自分で決める」という設計判断になります。

怖いのは、遅いだけの相手を「死んだ」と判断して切り替えた直後に、本人が復活するケース。処理が二重に走ります。

タイムアウト値は設定ではなく設計。「何秒で諦めて、諦めた後どうするか」までがセットなんです。

⑥ リトライは、障害を大きくすることがあります

エラーになったらリトライ。正しい姿勢ですが、集団でやると凶器になります。

サーバーが一瞬詰まったとき、全クライアントが同時にリトライすると、負荷が倍増して完全に沈みます。復活しかけたところに再突撃が来る。リトライストームです。

定石は2つあります。

  • エクスポネンシャルバックオフ:間隔を指数的に伸ばす
  • ジッター:待ち時間をランダムにずらす

全員が同時に戻ってこないようにするんですよね。「エラー時は3回リトライ」とだけ書かれた設計書を見たら、この2つを確認するタイミングです。

⑦ ネットワークが裂けると、リーダーが2人になります

サーバー群の間のネットワークが分断されると、恐ろしいことが起きます。

分断された両側が、それぞれ「相手が死んだ。自分が代表だ」と判断する——スプリットブレインです。2つの「正」が生まれ、データが枝分かれします。

対策の定番が多数決(クォーラム)。全体の過半数と通信できる側だけが代表になれるルールにすれば、代表は最大1人に絞られます。

クラスタ構成のノード数が奇数(3台、5台)なのは、多数決を成立させるためなんです。

⑧ 分断が起きたら、「正しさ」と「応答」は両立しません

⑦の状況を、理論として言い切ったのがCAP定理です。

ネットワーク分断が起きている間、システムは「一貫性(全員が同じ最新データを見る)」と「可用性(常に応答を返す)」のどちらかを諦めるしかありません。両取りは不可能です。

銀行の残高なら、応答を止めてでも一貫性を守る。SNSのタイムラインなら、多少古くても応答を返す。

「分断のとき、うちはどちらを捨てるのか」。この問いに答えを持っているかが、分散設計の成熟度なんです。

番外編:知っておくと会話が深くなる話

第一原則は「分散させないこと」
マーチン・ファウラーが唱えた「分散オブジェクト設計の第一法則:分散させるな」という、身も蓋もない教えがあります。1台で足りるなら1台が最強。分散は、必要に迫られて払うコストなんですよね。

光は1ナノ秒で、30cmしか進めません
計算機科学者グレース・ホッパーは、約30cmのワイヤを配って「これが1ナノ秒です」と説明しました。東京〜大阪間の往復は、物理法則として数ミリ秒を下回れない。遅延は設定ではなく、光の速さなんです。

マイクロサービスは、組織の話でもあります
「システムの構造は、組織のコミュニケーション構造に似る」という法則(コンウェイの法則)があります。分散アーキテクチャの議論が、いつの間にかチーム分割の議論になるのは、必然なんですね。

RJCでも、分散と向き合っています

RJCが携わる決済や交通のシステムは、外部サービスとの連携が止まらないことが前提の世界です。リトライと冪等性の設計は、そのまま品質になるんですよね。

こういう仕組みの話を、Techチームで共有しながら開発しています。

よくいただくご質問

Q. まずどれから押さえるべきですか?
A. ①②のセットかなと思います。「重複前提+冪等性」は、外部API連携を書く全員に今日から効きます。

Q. マイクロサービスにすべきか迷っています…
A. 番外編の第一原則をおすすめします。分散は解決策であると同時にコストなので、「分けないと困る理由」が言えるまでは1つでいいと思うんですよね。

Q. 障害調査のコツはありますか?
A. ③を思い出してください。複数サーバーのログを時刻だけで並べない。リクエストIDで追跡できる仕組みを先に入れておくのが、一番の近道です。

Q. 未経験からでも、分かるようになりますか?
A. なります。「手紙が届かないかもしれない世界で、どう約束を守るか」という思考実験なので、図を描けば必ず追えます。

ネットワークの向こうを、信じすぎない

今日の8つに共通していたのは、これでした。

届いたか分からない。時計は合わない。死んだか遅いか分からない。分散システムの設計は、疑うことから始まります。

そして疑った分だけ、冪等性・タイムアウト・多数決という道具で守る。疑い方を知っている人が、落ちないシステムを作るんですよね。

みなさんが踏んだ分散の事故、よかったら教えてください。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?