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