おい、これは抽象的な概念の話じゃない。君の火曜日の話だ。6ミリ秒のリクエストがなぜか800ミリ秒もかかっている原因を追跡するシニアエンジニアの話だ。Kubeletが一体 何 なのか、画面いっぱいのYAMLを見つめながら首をかしげるジュニアエンジニアの話だ。これは、システムがあまりにもレイヤー化され、抽象化で覆い尽くされて、そもそも何が本来の問題だったのか誰も覚えていない、という事態についての話なのだ。
我々はレイヤーに手を伸ばす。それは普遍的な反射だ。コード。インフラ。プロセス。組織。APIをクライアントでラップする。クライアントをアダプターでラップする。アダプターをサービスオブジェクトでラップする。サービスオブジェクトをファクトリーでラップする。デプロイメントにはパイプラインができる。パイプラインにはオペレーターができる。オペレーターにはプラットフォームができる。プラットフォームにはポータルができる。チームにはトライブができる。トライブにはチャプターができる。センター・オブ・エクセレンス。どんな傷にもこの湿布薬はぴったりだ。傷そのもの? 決して調べられない。
この衝動はあまりにも根深いので、代替案はほとんど意識に上らない。ラップするのではなく、根本的なものを 取り除く ことはできないのだろうか? 滅多に問われない。それを作ったチームは隣の部屋にいる。プロジェクトは過去の四半期レビューで終わっている。それを掘り起こすエンジニアには、別の ラッパーでよりきれいにクローズできるチケットが13枚もある。だからラッパーが追加される。1年後、その ラッパーにもラッパーができる。
なぜこうなったのか? 封じ込めの神話
レイヤードアーキテクチャには高貴な起源があった。1968年のディクストラだ。複雑さを制限するための規律あるレイヤリング。各レイヤーは定義されたインターフェースを提示した。スタック全体を頭に入れなくても、1つのレイヤーについて推論できた。素晴らしい。今でもそうだ。
4年後、パーナスが情報隠蔽(Information Hiding)をもたらした。変化するものを安定したインターフェースの背後に隠す。1箇所での変更がすべてを壊さないようにする。レイヤーはその応用だった。その意図は複雑さを封じ込めることであった。遅延させるためではない。
Parnasと、第3世代のクラウド抽象化の間で、動詞が変化した。封じ込めることが延期することになった。かつて漏洩を防いだレイヤーは、今や下の雑多な部分を見なければならない瞬間を延期するためだけに存在する。Kubernetesオペレーターは安定した抽象化を隠すのではなく、誰も読みたくないYAMLを隠す。リトライデコレーターはクリーンなインターフェースを制限するのではなく、常に壊れているアップストリームサービスを糊塗する。ORMはデータベースを抽象化するのではなく、実際のクエリがどうあるべきかについての会話を遅延させる。
語彙は残った。規律は? 失われた。
複雑さのコスト:単なる遅延だけではない
ソフトウェア進化の第二法則(Lehman’s second law):明示的な作業をしない限り、複雑さは増大する。この言葉ほど色褪せないものはない。彼はそれを熱力学に例えた。エントロピーはデフォルトだ。秩序にはエネルギーが必要だ。そしてそのエネルギー? それは、新機能を出さず、チケットをクローズせず、アーキテクチャレビューのために派手な図を残さないため、誰も資金を出さない仕事のことだ。
防御的なコードパスが倍増する結果になる。すべてのAPI呼び出しにはリトライが含まれる。すべての値にはnullチェックが含まれる。すべてのキャッシュには無効化ロジックが含まれる。フィル・カールトンは有名な言葉を残した。「難しいことは2つしかない。キャッシュの無効化と、名前付けだ」。我々は勤勉にも最初のほうをデフォルトのアーキテクチャパターンにしてしまい、まだ結果を保持する変数の名前さえ合意できない。
コストはキャッシュだけではない。それは人だ。シニアエンジニアは午前中、6ミリ秒が800ミリ秒になった理由を追跡する。彼女はリトライデコレーター、アダプタークラス、サービスメッシュのサイドカー、2023年から触られていないフォールバックス戦略をナビゲートする。その一番下には? インデックスのないデータベースクエリだ。インデックスを追加する。800ミリ秒が6ミリ秒になる。リトライデコレーターは残る。アダプターは残る。サイドカーも残る。それらを削除する? それはまた別の四半期の仕事だ。しかし、その四半期には別の計画がある。
失われるのは効率だけではない。それは明瞭さだ。システムについて推論する能力だ。それは、何かを管理するのではなく、働くものを作るという根本的な喜びだ。しかも、それはデジタルダクトテープと難解な設定で常に維持されているものだ。これは単なる技術的な問題ではない。文化的な問題だ。我々は、真のエンジニアリングという、理解し、単純化し、削除するという困難で地味な作業よりも、新しい抽象化でラップされた機能を出荷するという、進歩の外観を評価してきた。
うまくいかないときは、上にレイヤーを重ねる。
これが問題だ。元のものが壊れているかどうかを尋ねない。ただそれを糊塗するだけだ。そして、その糊塗にさらに糊塗が必要だと文句を言う。
代替案はあるのか? もちろんだ。それは困難な会話、リファクタリング、そして時には最も速い道は後戻りすること、つまり便利に隠された根本的な問題に戻ることだと認めることを含んでいる。
我々は自問する必要がある。我々はシステムを構築しているのか、それとも延期された決定の記念碑を構築しているのか? なぜなら、今、それは後者のように強く感じられるからだ。
これがオープンソースの目的ではないのか?
オープンソースが解毒剤だと期待するかもしれない。透明性が支配し、レイヤーが可視化され、根本的なコードを検査・理解できる場所だと。そして、時々、それはそうなる。
しかし、オープンソースでさえ、同じプレッシャーが適用される。人気のあるプロジェクトは複雑なエコシステムになる。貢献したい開発者はしばしば同じ選択に直面する:既存のラッパーをハックするか、あるいは数ヶ月かけて深層の内部を理解してレイヤーを削除するかだ。もちろん、最も抵抗の少ない道は、さらなるラッパーだ。オペレーターの根本的なロジックをリファクタリングするよりも、オペレーターに新しい設定フラグを追加する方が簡単だ。
これは奇妙な皮肉を生む。我々はオープンソースをその検査可能性のために称賛するが、それをアクセス可能にするツール自体が、しばしば不透明になる。機械を理解するという約束は、機械が20層も深くなると崩壊する。
パターンは、それが普遍的であるため、見えない。コード、インフラ、プロセス、組織で、我々はそれを行う。
この声明は、元の資料から抜き出されたものだが、悲惨な現実だ。これはバグではなく、我々の集団的なアプローチの特徴なのだ。ツールはオープンかもしれないが、真の理解への道はますますバリケードで封鎖されている。
これが将来にとって何を意味するのか? さらなる複雑さ。さらなる混乱。エンジニアたちが新しい道を開拓するのではなく、日々結び目を解くことに費やす時間が増えることだ。もちろん、我々が意識的に単純化という困難な作業を受け入れると決断しない限り。それは、コードの追加と同じくらい、コードの削除を評価することを意味する。それは、機能速度だけでなく、明瞭さと削減に焦点を当てたプロジェクトに資金を供給することを意味する。
それは難しい売り込みだ。しかし、その代替案は、エンジニアが自ら作り出した複雑さの奴隷となり、機械の中の幽霊を永遠に追いかけるソフトウェアランドスケープだ。