/note/tech

Ozymandias on Rails. The Pedestal Inscription

要約:

■ 1. Ozymandias の比喩と問題の本質

  • シェリーの詩「Ozymandias」(1818年)を引用し、巨大なRailsモノリスが時間と共に廃墟となる比喩として使用
  • 筆者は15年近くRailsモノリスの内部で働いた経験を持ち、成功して成長したシステムほど問題が深刻化することを述べる
  • 大規模になったシステムに共通する状態:
    • 誰にも所有されない広大なコード領域が生まれる
    • エラーチャンネルが数ヶ月にわたって赤く点灯し続け、解決不能に見える
    • システム全体の形を把握できる人間が一人も存在しなくなる
  • 構築者たちが去り、知識が少しずつ失われ、残されたものは廃墟のように感じられる

■ 2. Vanilla Railsの限界

  • 「Vanilla Railsで十分」という議論:
    • コールバック、コンサーン、ファットモデルなど、Railsのデフォルトを規律正しく使えば、多くの人が思うより長く機能する
    • アーキテクチャの抽象化は不要な複雑さを招くとされる
  • DHHの一貫した立場:
    • 2016年にマイクロサービスよりモノリスを推奨
    • 2020年にモノリスが限界を迎えた際に単一サービスの切り出しを認める
    • RailsWorld 2025では「複雑さの商人」というフレームで批判を継続
  • 議論には前提条件が付いていることを指摘:
    • マイクロサービスは数千人規模の企業向けで、モノリスは小さなチーム向け
    • 37signalsでさえShopify規模では通用するか不明と認めている
  • 議論の本質的な問題:
    • すべての議論は特定の時点における特定チームについてのもの
    • チームが12人から数百人に成長し、10年で制度的な記憶が薄れることへの対処がない
    • 退職のたびにコンテキストと知識が失われ、多くは文書化されていない
    • 読者は「壮大なモノリス」「Vanilla Railsで十分」という見出しだけを記憶し、免責事項を忘れる
  • Ozymandiasの比喩との対応:
    • 台座には「特定規模の王国にしては印象的」とは書かれず、条件なしに「我が業を見よ」と刻まれている
    • 継承するシステムは免責事項を持たない見出しだけを信じた人々によって構築された

■ 3. Railsの技術的な問題点

  • コールバックが不可視の制御フローになる:
    • 30個のコールバックを持つモデルは単一の保存操作で16の実行パスを生む
    • 12番目のコールバックを追加した人は、他のコールバックとの順序関係を把握できない
    • コントローラーを読む人はコールバックの存在自体に気づかない
    • バイパス経路がRailsガイドにも記載されており、一括操作で常用される
  • ActiveRecordが境界を越えてリークする:
    • リレーションはライブなデータベースハンドルとして返され、呼び出し元が書き込み、N+1クエリを発生させ、契約外のカラムに依存できる
    • すべてのActiveRecordオブジェクトは生成元のコードとそれ以降のすべての利用箇所との間の暗黙的な結合を生む
  • ポリモーフィック関連の構造的欠陥:
    • notable_typeカラムにはRubyクラス名が、notable_idには任意のテーブルへの整数が格納される
    • データベースは外部キーで強制できず、文字列だけがテーブルを識別する情報となる
    • デリゲーターがクエリからtype句を消し去る可能性がある
    • クラス名変更時にすべての保存済み文字列が無効になる
    • ジョインが不可能で、3チームが同一テーブルに書き込み、誰も管理しない状況が生まれる
  • インデックスが制御不能なクエリのために構築される:
    • どのコードからもSeat.where(column: value)が実行できる環境では、最適化すべきクエリの形が無限になる
    • すべてのフィルタ対象カラムにインデックスを作成し書き込みオーバーヘッドを支払いながら、未知のクエリへの対処は困難

■ 4. 所有権の崩壊

  • コードが全員に属する場合、誰にも属さない
  • DHHが言う「所有権」との区別:
    • DHHの所有権は垂直: フレームワークからOSまでスタック全体を所有し、ベンダーを排除する
    • モノリストで崩壊する所有権は水平: 30チームが同じコードに触れる際に、どのチームがどのモデルやテーブルに責任を持つか
  • 規模と所有権の関係:
    • 小チームでは所有権は暗黙的で全員が互いに話しているため機能する
    • 3〜4チームを超えると暗黙的な所有権は崩壊し、誰も所有しない状態に移行する
    • チーム間のギャップにあるコードが最も早く成長し、最も頻繁に壊れ、最も変更困難になる
  • 所有権のないハザードの複合効果:
    • 16パスのコールバックは危険であり、誰も所有しないコールバックは誰も修正責任を持たない危険
    • 構造的に不健全なポリモーフィックテーブルに3チームが書き込み誰も管理しない場合、政治的にも変更困難
  • 大企業の対応事例:
    • GitLab: ポリモーフィック関連を禁止
    • Shopify: Packwerkを構築
    • Gusto: Packwerkを採用しモジュール性ツールのエコシステムを構築
    • GitHub: 200万行以上のモノリストに1000人以上のエンジニアが継続的にアーキテクチャと境界に投資
  • 中間規模の企業が直面する現実:
    • 37signalsでもShopifyでもない多くの企業が存在する
    • 共有コンテキストが機能しなくなった後、独自の境界ツールを構築できる規模には達していない
    • Railsは最速のスタートを提供したが、モノリストの次に進む「舗装された道」を用意していない
    • ドクトリンは境界ツールの必要性を規律の失敗として扱い、成長の段階とは見なさない

■ 5. 回復のアプローチ

  • 「全部書き直す」の誘惑と失敗:
    • Joel Spolsky(2000年): 大規模な書き直しが失敗するパターンを説明
    • Fred Brooks: 「第二システム効果」として命名 ─ 第二版は過剰設計になりがち
    • Netscape: Navigatorをゼロから書き直し、3年間何もリリースできずブラウザ戦争に敗れた
  • AIによる書き直しの誘惑:
    • AIにより書き直しが安価に見えるが、Gartnerの2026年予測によれば、AIを活用したレガシー変換の3分の2以上が失敗する
    • 難しいのは既存コードが何をしているかを理解することであり、AIはシステムの形を数時間で再現できても10年分の修正とコンテキストを見落とす
  • 部分的な抽出が正当化される条件:
    • 明確な所有権と明確に定義されたインターフェースを持つシステムの独立した部分
    • モノリスの構造が修正を妨げていることの測定可能な痛みがある
    • どのリクエストが、どのチームにとって、何が修正不能かという具体的な証拠が必要
  • 機能するアプローチ: 段階的な回復:
    • 見た目ではなくコストで測定して何が壊れているかを理解する
    • 障害をコード内の発生箇所まで追跡すると、未所有コード・共有モデル・全員が書き込むテーブルに集中する
    • それらの場所の周囲に境界を引き、所有権を割り当て、暗黙を明示的に変える
    • システムをサービス中のまま実施する
  • 回復の本質:
    • 所有権、境界、トラフィックを処理しながら適用する忍耐
    • 数年規模の取り組みで、機能開発・インシデント対応・採用と並行して実施する
    • ドラマチックな話にはならないが、機能することが確認された唯一のアプローチ

■ 6. シリーズについて

  • シリーズ名「Ozymandias on Rails」の意味:
    • 詩は永続性が幻想であることを示す
    • 国王に何が起きたかは不明であり、業績は残らず碑文だけが残った
  • Railsと大規模システムの関係:
    • Railsは素早い構築を可能にした
    • 構築されたシステムは成功し、成長し、雇用し、10年以上にわたって機能し続けた
    • これはフレームワークや使用した人々の失敗ではない
    • モノリスは機能し続け、なぜそのような形をしているかを誰も覚えていない時点まで機能した
  • このシリーズの目的:
    • これらのシステムの内部にいる人たちに向けて、次に何をするかを示す
    • 10年以上続くシステムを次の10年も生き続けさせること
    • 本当に炎上しているものと単に問題があるように見えるものの区別を学ぶことから始まる
  • 次回のポスト: 「炎上」と「危険に見えるだけ」の区別について