Parity before cutover

Alex O'Callaghan

カットオーバー前にパリティを揃える

原文は Alex O'Callaghan により に公開されました。 このブログを購読する

私たちは、複数のチームやサービスが依存するサービスを運用している。何年もの間、そのサービスは二重に存在していた。本番環境でオンプレミスのサーバーにデプロイされたPython 2版と、別ブランチで管理されたモダンなPython 3版だ。後者は、クラウド移行によってようやく前者を置き換えられる日を待っていた。

多くのレガシー刷新はこのような形をとる。目指す最終形は明らかだ——新しい言語バージョン、新しいインフラ、古いシステムの撤廃——だからチームはそこへ一直線に向かおうとする。作業は長期存続するブランチや「v2」としての書き直しで進められ、本番から離れたところで難しい作業を済ませ、最後に一度で切り替える計画が立てられる。

着地しないリライト

その計画が約束どおりに実現することはめったにない。新しいバージョンが未リリースのまま置かれている間、リスクは消えるどころか積み重なっていく。

緊急の修正はすべて、まず古いバージョンに適用し、次に新しい方へ移植しなければならない——さもなければ忘れ去られる。二つのバージョン間の挙動の違いは、意図的なものもそうでないものも、カットオーバー後に下流のチームによって発見されるのを待つバグとなる。そのときには原因の特定が最も難しくなっている。

長命なブランチは、すべてを一つのイベントにまとめるため効率的に感じられる。しかし実際には、リスクを一点に集中させ、何かがおかしいと教えてくれるはずのフィードバックを遅らせるだけなのだ。

前に進むための後退

私たちが移行を引き継いだとき、直感的には最終形へ一直線に進みたくなった。モダンなバージョンをクラウドで動かし、利用側の移行を始める、という具合だ。私が主張したのは、まず一歩下がることだった。モダンなバージョンを古いインフラ上の本番環境で動かし、他の何かを動かす前に、旧と新を同じコードに揃えるのだ。

レガシーなホストが搭載していたOSは古く、対応するPythonは3.6が上限で、一方モダンなバージョンは3.7をターゲットにしていた。回避策はあった——Pythonをソースからビルドする、想定されていないホストに無理やりコンテナを載せるといった方法だ——しかし、すでに課題の多い移行に、回避策のたびに新たな複雑さが加わることになる。

そこで私たちはサービスを3.6にダウングレードし、オンプレ用のデプロイ設定を復活させ、設定は実行時に環境ごとに切り替えるようにした。一つのコードベースで、レガシーホストとKubernetesのどちらにもデプロイできる状態にしたのだ。

バージョンのダウングレードは後退に見える。しかしそれこそが、残りの移行をシンプルにしたのだ。

変数は一度に一つ

パリティを確保したことで、すべてのリリースが両方の環境にデプロイされるようになった。旧と新の挙動の違いは、カットオーバー時に一気に噴き出すのではなく、小さな差分としてすぐに表面化した。二つのバージョン間で何年にもわたって生じた乖離は、古いインフラがフォールバックとしてまだ存在する間に解消されていった。

クラウドへカットオーバーする頃には、それは純粋なインフラの変更になっていた。「プラットフォーム移行はうまくいったか?」と「リライトはうまくいったか?」を同時に問う必要はなかった。何かが壊れても、それはプラットフォームの問題だとわかった。コードは同一だったからだ。カットオーバーは退屈なものだった。そして退屈であることこそが望ましいのだ。これはマイクロフロントエンドでReactを段階的にアップグレードするのと同じ原則だ。変数が一つずつ変わるように順序立てるのである。

codeinfrastructureversionbig bang: everything at oncePython 2on-premPython 3.6on-premPython 3.6KubernetesPython 3.10Kubernetes

最終形ではなく道筋をリリースする

移行が完了すると、何年も止まっていたPythonのアップグレードは通常のリリースとして出荷された。古いホストによるバージョンの上限はなくなり、アップグレードすべきコードベースは一つだけになっていた。最終形に直接向かうのをやめたからこそ、かえって最終形により早くたどり着けたのだ。

もしブランチが何ヶ月も開いたままだったり、リライトが他チームの移行待ちになっていたりするなら、それは一度にやりすぎようとしているサインだ。今すぐリリース可能な中間状態を探すべきだ。たとえ一見後退に見えても。難しいのは最終形そのものではない。難しいのはそこに至る道筋であり、最も安全な道筋とは、一歩ずつリリースできる道筋なのだ。

この記事は「muse-spark-1.2-contributor」を使用して翻訳されました。

コメント