HN 日本語サマリー

← 一覧へ戻る
プログラミング

フィーチャーフラグが有効な場合とそうでない場合

When Feature Flags Do and Don't Make Sense (software.rajivprab.com)

16 pointsby whack8 コメント

要約

フィーチャーフラグはA/Bテスト、複雑な機能開発の段階的リリース、デプロイ制御が難しい状況での機能切り替えに有効です。しかし、すべての変更をフラグで管理する、テストやロールバックの代替とする、といった過度な利用は、複雑性の増大やデバッグの困難さを招き、かえってリスクを高める可能性があります。フィーチャーフラグは強力なツールですが、そのコストと適切な使用シナリオを理解することが重要です。

全文翻訳

過去数年間、私はフィーチャーフラグに関して非常に異なる戦略を採用する複数のチームで働いてきました。両方の長所と短所を見てきましたが、時間の経過とともに、その使用に関するいかなる原理主義的な立場にも同意できなくなりました。このトピックには多くのニュアンスがあり、フィーチャーフラグが有効な場合とそうでない場合の両方のさまざまなシナリオをより注意深く検討する価値があると思います。 理由 フィーチャーフラグが非常に有効なシナリオがいくつかあります。最初のものはA/Bテストに使用される場合です。この場合、ランダムに割り当てられた治療に基づいて、ユーザーごとに異なる動作を確実にしたいと考えます。私はAmazonでこの戦略が非常にうまく活用されているのを見てきました。そこでは、新しい機能は実際には内部A/Bテストフレームワークによって制御される「フィーチャーフラグ」によってゲートされています。このフレームワークは、一部のAmazon顧客に新しい機能をランダムに公開し、その後の行動を監視して、機能のビジネスへの影響を推定します。最初は懐疑的でしたが、フレームワークの使いやすさと、特定の機能の利点(または欠点)に関する貴重な洞察が得られたことで、すぐに納得しました。「今月のフレーバー」の決定は、実際のデータに置き換えられました。そして、新しい機能を動的に切り替える「フィーチャーフラグ」を使用せずに、これらすべては不可能です。 フィーチャーフラグのもう1つの優れたユースケースは、システムのさまざまな部分で多くの異なるサブタスクの完了を必要とする非常に複雑なエピックに取り組んでいる場合です。サブタスクが多すぎて、単一のプルリクエストで実行するには侵襲的すぎます。そのような場合、これらのさまざまな変更をサイドブランチに保持し、同時マージとデプロイを調整しようとすることは、災害への道です。すべての破壊的な変更をマスターフラグの後ろにゲートし、サブコミットを段階的にマージしてデプロイし、すべてのピースが配置されたらフラグを反転する方がはるかに管理しやすくなります。 フィーチャーフラグの最後のユースケースは、デプロイを制御できない場合です。たとえば、FacebookのAndroidアプリを考えてみてください。これは、数百の異なるチームからのコードで構成されており、すべてが単一のバイナリとして結合およびデプロイされています。このようなシナリオでは、ロールバックの実行は実行不可能になる可能性があります。実用的、政治的、官僚的、あるいはマーケティング上の理由で。そのような場合、フィーチャーフラグを使用すると、チームは新しいバイナリをロールバックまたはデプロイすることなく、新しい機能を切り替えたり、リスクの高い変更を軽減したりできます。Redditの誰かがフィーチャーフラグの同様のユースケースを指摘しました。マーケティング上の理由で非常に特定のローンチ日をターゲットにしますが、安定性を確保するためにコードははるかに早くデプロイします。その後、特定の時間に自動的に有効になる「動的」フィーチャーフラグを持つことができます。これは、新しいバイナリのデプロイが非現実的な状況で機能変更を行うという同様の理由で、優れたユースケースでもあります。 リスク回避 上記はすべてフィーチャーフラグの素晴らしいユースケースですが、ポリシーによって利用が過剰になり、チームが停滞しているのも見てきました。たとえば、すべてのコード変更を「万が一間違いがあった場合」のためにフィーチャーフラグの後ろに置くことを義務付けるなどです。リスク管理は確かにすべてのチームにとって優先事項であるべきです。しかし、特にチームがデプロイを自分で制御できる場合、フィーチャーフラグに依存するよりも、これを行うためのより良い方法があります。バグの大部分は、自動テストスイートやQAプロセスによって検出されるはずです。そして、残りの少数派は、段階的なデプロイ、本番アラーム、およびロールバックを使用して処理されるべきです。 さらに、問題が検出されるとすぐに、Googleのような場所での推奨事項は、まずロールバックしてから問題を調査することです。「Googleでは何度も、性急にデプロイされたロールフォワード修正が元の問題を解決しないか、実際には状況を悪化させるのを見てきました。問題が解決した場合でも、システム内の他の潜在的なバグを明らかにする可能性があります。既知の良い状態から、通常の厳格なQAテストを受けていないリリースのワイルドに移動しています。Googleでは、私たちの哲学は「ロールバックは普通」ということです。新しいリリースでエラーが見つかるか、合理的に疑われる場合、リリースチームはまずロールバックし、次に問題を調査します。火事になっているとき、あなたがしたい最後のことは、バグの根本原因を突き止め、どのフラグの切り替えが安全に問題を解決するかを理解することです。そして、それは物事を解決しないかもしれません。たとえあなたのチームメイトが彼の変更をフィーチャーフラグの後ろに置こうとしたとしても、フラグの切り替えでは解決できないバグを誤って導入しなかったという保証はありません。フィーチャーフラグは、バイナリロールバックの貧弱な代替手段であり、優れた自動テストスイートと堅牢なQAプロセスを持つことの代替にはなりえません。本番バグを修正するためにフィーチャーフラグに依存している場合は、チームのプラクティスを停止して評価する必要があります。リスク回避は、チームが時間の経過とともにますます悪化するだけである破滅のループに入っている兆候であることがよくあります。 フィーチャーフラグによる死 この時点で、なぜそもそもフィーチャーフラグを使用しないのか疑問に思っているかもしれません。結局のところ、「多層防御」...そして、より細かい柔軟性を持つことは決して害にはなりませんよね?フィーチャーフラグはいくつかのケースで素晴らしいですが、そのコストも念頭に置くべきです。ソフトウェアエンジニアリングは、主に複雑性を管理する演習です。そして、各フィーチャーフラグは、プログラマーが理解する必要があるコーナーケースの宇宙を即座に倍増させ、コードが処理する必要があります。「しかし、Fooが有効で、Barが無効で、BazとKazで同じ日に独立したA/Bテストを実行したらどうなるでしょうか?」私の経験では、この複雑性の組み合わせ爆発はバグにつながる可能性があり、実際にそうなります。チームが変更を行う速度を低下させることは言うまでもありません。オンラインで共有された面白い逸話から引用すると、「1年間オフに設定されていないフラグは、重大な回帰を隠している可能性があります。私の最後の仕事では、2年間に2回の重大な障害が発生しました。これは、フィーチャーフラグシステムがフラグの状態を返せなかったときに、無効なフラグがデフォルトで「オフ」になったためです。」 「しかし、これらのフィーチャーフラグは一時的なものです。できるだけ早く削除すべきです!」確かに、技術的負債を蓄積させないようにすべきであり、すべてのベストプラクティスを律儀に守るべきです。残念ながら、これはどの企業環境でも決して起こりません。優れたチームでさえ、新しいリクエストに直面すると、技術的負債はしばしば優先順位が下がります。チームの新規参加者や退職する人々は、ロールアウトが成功した後、フラグをクリーンアップするのに常に規律があるわけではありません。そして時々、これらのタスクは単に抜け落ちて忘れられてしまいます。 HackerNewsの誰かが、2020年9月現在、Windowsのリリースバージョンには約2500のフィーチャーフラグが含まれていると指摘しました。一部は常にオンの位置に、一部はオフの位置に固定されており、残りは実験フレームワークやハッカーによって構成可能です。これをこれ以上示すものはありません。KCGの失態です。金融会社が30分で5億ドルを失い、ほぼ破産した事件で、その原因の一部はフィーチャーフラグの後ろにあったデッドコードでした。失敗の原因は複数の要因によるものでした。しかし、最も重要な要因の1つは、以前はPower Pegを有効にするために使用されていたフラグでした...Power Pegは2003年から廃止されていましたが、8年後もコードベースに残っていました。2005年、Power Pegコードに変更が加えられ、このようなシナリオを防ぐはずだった安全チェックが誤って無効になりました。しかし、この更新は当時、Power Peg機能がまだ機能するかどうかの検証努力なしに、本番システムにデプロイされました。 フィーチャーフラグは、新しい機能を試したり、複雑なエピックのロールアウトを管理したり、チームのデプロイを制御できない問題に対処したりするのに役立つ強力なツールです。しかし、