私が学部生だった頃、「コンピュータシステム工学」という授業の一環として、私たちはシステム設計の数多くの古典的な論文を読みました。私はこれらの論文から多くを楽しみ、学びましたが、特に心に残ったのは Saltzer らの「システム設計におけるエンドツーエンドの原則」でした。この論文はシステム設計に関する非常に一般的な論文であり、具体的なシステムやアプリケーションのいくつかの例を探求していますが、最終的にはエンドツーエンドの原則を、ほぼすべてのシステム設計に適用できる視点または設計のヒューリスティックとして詳述しています。
私はこの論文を読むことをお勧めします。短くて非常に読みやすいですが、簡単に言うと、システムの多くの機能は、各低レベルのインターフェース境界ではなく、システムの「端」でより良く対処されると主張しています。具体的な例として、論文はファイル転送システムが、各基盤となるネットワーク層からの完全なロスレス転送を主張するよりも、必要に応じて強力なチェックサムと再試行を通じてエンドツーエンドでの正確性を保証することでより良く機能すると主張しています。
ソフトウェアとデザインの分野でプロとして働けば働くほど、私はエンドツーエンドの議論とそのニュアンス、システム設計への影響を反映することが多くなります。ここで、私が特に興味深いと感じる 2 つの異なる視点について書くことを約束したいと思います。
どちらの視点を理解するためにも、まず「システム」と「システム設計」が何を意味するのかを考える必要があります。メリアム・ウェブスターは「システム」を「統一された全体を形成する定期的に相互作用または相互依存するアイテムのグループ」と定義しています。したがって、システムの本質的な特徴は、それがいくつかのサブコンポーネントに分解でき、これらが互いに実質的に孤立して理解または考慮されることができるユニットであるということです。したがって、システム設計はこの分解を実行するプロセスであり、望ましいシステムを機能する全体に構築できる個々のユニットに分割する方法を決定することです。
落胆する見解:正確性を構成することはできない#
システム設計において私たちが期待するかもしれない特性の 1 つは、ある意味で、正しいサブシステムを適切に構成することで正しいシステムに到達できるということです。この希望は、ソフトウェア設計のための「LEGO ブロック」を望むという形で表現されることがあります。もし私たちがソフトウェア設計のための正しい、堅牢な基本的なビルディングブロックを設計できれば、任意の方法でそれらを組み合わせて、低コストと労力で複雑なシステムを設計できるでしょう。
エンドツーエンドの議論は、この楽観主義に直接挑戦します。基盤となるビルディングブロックの洗練度に関係なく、私たちは常にシステムの最上位のエンドツーエンドの設計層で本質的な正確性の特性を定義し、強制しなければならないと主張します。私たちはサブシステムの正確性から正確性を自明に導き出すことはできません。常にそれをエンドツーエンドの特性として考慮しなければなりません。
したがって、エンドツーエンドの議論は、抽象化とシステム設計におけるスケール不変性の欠如についても言及しています。「端」を所有するシステムはエンドツーエンドの原則に従い、正確性を強制する責任があります。逆に、より大きな全体のサブシステムやコンポーネントとして存在するシステムは、そのような責任を持たない場合があり、スコープ外のエンドツーエンドシステムに特定の保証を委任することができます。
このスケール依存性は、したがって、世界における「根本的に正しい」抽象化の欠如を示唆しています。特定の機能クラスのコンポーネントを設計したい場合、適切な設計制約と保証は、エンドツーエンドのシステムを構築しているのか、単により大きなシステムのコンポーネントを構築しているのかによって異なります。そして、コンポーネントを設計している場合、提供しなければならない保証は、最上位のシステムが自ら強制する準備ができている特性に依存します。
この点に関して、私はエンドツーエンドの議論に対するこの見解が、すべての十分に複雑な抽象化はある程度漏れがあるという「漏れのある抽象化の法則」と密接に関連していると思います。両方の原則は、抽象化スタックの上位レベルと基盤となるシステムの実装詳細との間の「バンド外」相互作用に対するある種の避けられない性質を表現しています。
これは、私が大学で初めて論文を読んだときに最も強く感じた視点です。当時、私はかなり落胆しました。若くて熱心なシステムデザイナーを目指す者として、私は基本的な機能のための理想化されたプラトン的抽象化のセットが存在することを信じたかったのです。それをソフトウェアの生のエーテルから抽出できれば、ソフトウェアデザイナーが働く抽象化のレベルをシームレスに、永遠に引き上げることができると。エンドツーエンドの原則は、世界が混沌としており、「十分に良い」抽象化がほぼ普遍的に存在するかもしれませんが、私たちは常にシステム設計スタックのより高いレベルに複雑さを持ち込むことになるという声明です。
楽観的な見解: TCB の視点#
この第二の視点は、実際のシステム設計を行う中でますます評価するようになったものであり、論文の著者たちが伝えたかった知恵に近いと思います。
正確性は難しいです。長い間ソフトウェアに関わっている人なら誰でも、ほとんどの時間機能するソフトウェアを書くことが、常に機能するソフトウェアを書くよりも劇的に簡単であるという現実に精通しています。この真実は、大規模なシステムではさらに真実です。なぜなら、私たちは不確実な信頼性特性を持つ外部コンポーネントと相互作用しなければならないからです。
エンドツーエンドの議論は、私たちにこの現実を受け入れ、受け入れるよう促します。システムのすべての部分から絶対的な正確性を要求するのではなく、いくつかの本質的な正確性の特性(例:メッセージはポイント A からポイント B に変更されずにコピーされる;すべてのトランザクションは私たちの台帳に正確に 1 回表示される)を選択し、それらの特性をシステムのサブセット(「端」)内に位置付けることができます。この設計ステップを完了したら、これらのエンドツーエンドコンポーネントから正確性を要求し、システムの残りを最適化問題として扱うことができます。
私はこれを「TCB」視点と呼びます。なぜなら、オペレーティングシステム理論における「信頼できるコンピューティングベース」の概念に似ているからです。私たちは、バグがシステム全体の整合性を直接脅かす部分を減らすことを目指します。そうすることで、エラーがパフォーマンスの問題や全体のシステムにおける検出可能な故障として現れる可能性があることを安全に開発できるようになりますが、静かに壊滅的な失敗を引き起こすことは不可能であるべきです。
結論#
システム設計は複雑であり、トレードオフ、ツール、トリック、そして複雑なシステムをコンポーネントから組み立てるためのヒューリスティックで満ちています。私はエンドツーエンドの議論とそれに関するこの論文が大好きです。なぜなら、これはシステム設計のための最良の「トップダウン」ツールの 1 つだと思うからです。多くの技術や原則は「構築する」ことに焦点を当てています。つまり、コンポーネントを取り、組み合わせ、私たちが利用できる実装のプリミティブからアーキテクチャを構築することです。しかし、最終的には、私たちの目標は全体のシステムで具体的な問題を解決することであり、エンドツーエンドの議論はこの全体的な目標をシステムをコンポーネントやモジュールに分解することに関連付ける強力なツールです。
この視点は、トップダウンで作業し、エンドツーエンドの機能をコンポーネント設計に関連付けることにおいて、フラストレーションを引き起こすことがあります。なぜなら、私たちはすべてのシステム設計の問題を実質的に新たに訪れる必要があるかもしれないからです。2 つの問題の間で似たように見えるコンポーネントは、最終的な目標に応じて重要に異なる機能要件を持つ場合があります。しかし同時に、これはこの分解を行い、システム設計について考えるための強力なツールと構造を私たちに提供します。