Slide 1

Slide 1 text

Feature Flag を利⽤した リリース戦略 黒曜 @kokuyouwind

Slide 2

Slide 2 text

$ whoami 森 俊介 / 黒曜 @kokuyouwind 株式会社Misoca SRE

Slide 3

Slide 3 text

本番リリース

Slide 4

Slide 4 text

スモールリリース アジャイルプラクティス ⼩さく、⾼頻度にリリースする 素早く価値を届けられる フィードバックを速く得られる

Slide 5

Slide 5 text

開発メリット 変更粒度が⼩さくなることで…… コードレビューしやすくなる コードが衝突しづらくなる 問題の原因特定がしやすくなる

Slide 6

Slide 6 text

😆

Slide 7

Slide 7 text

とはいえ… 現実にはそう簡単にいかないときもある プレスリリース合わせで全部出す ちょっとずつ出すとデータ不整合 ⼀揃いの機能がないとUX が悪い etc...

Slide 8

Slide 8 text

🤔

Slide 9

Slide 9 text

ビッグバンリリース

Slide 10

Slide 10 text

FeatureFlag 機能を動的にOn/Off できる仕組み ある環境でだけ有効にする あるユーザにだけ有効にする 管理者が全体の有効/ 無効を切り替える etc...

Slide 11

Slide 11 text

FeatureFlag のメリット ⼀般ユーザに⾒せないコードを⼊れられる ⼀般公開と別の単位でリリースできる 公開前の機能を本番で試せる 様々な⽬的に利⽤できる カナリヤリリース A/B テスト etc...

Slide 12

Slide 12 text

というわけで FeatureFlag の話をします

Slide 13

Slide 13 text

アジェンダ FeatureFlag の基本と分類 Misoca でのFeatureFlag の使い⽅ まとめ

Slide 14

Slide 14 text

アジェンダ FeatureFlag の基本と分類 Misoca でのFeatureFlag の使い⽅ まとめ

Slide 15

Slide 15 text

FeatureFlag if feature_enabled? process_with_feature else process_without_feature end 1 2 3 4 5 機能を動的にOn/Off する仕組み 真偽値を返す関数とif ⽂の組み合わせ

Slide 16

Slide 16 text

基本はこれだけ

Slide 17

Slide 17 text

feature_enabled? システム全体で共通 デプロイ時 ホットリロード リクエストごとに判定 特定ユーザにだけ機能を有効化 特定割合のユーザに機能を有効化 特定属性のユーザに機能を有効化

Slide 18

Slide 18 text

feature_enabled? 設定管理の⽅法は⾊々 環境変数 設定ファイル KVS クラウドサービス etc.

Slide 19

Slide 19 text

FeatureFlag の分類 Feature Toggles (aka Feature Flags) / Pete Hodgson https://martinfowler.com/articles/feature-toggles.html

Slide 20

Slide 20 text

FeatureFlag の分類 Feature Toggles (aka Feature Flags) / Pete Hodgson https://martinfowler.com/articles/feature-toggles.html

Slide 21

Slide 21 text

リリーストグル(Release Toggls) リリース前機能を隠すための分岐 不完全なコードのデプロイ デプロイとリリースの分離 短期( リリースしたら消される) 静的( 環境全体の設定)

Slide 22

Slide 22 text

FeatureFlag の分類 Feature Toggles (aka Feature Flags) / Pete Hodgson https://martinfowler.com/articles/feature-toggles.html

Slide 23

Slide 23 text

実験トグル(Experiment Toggls) 実ユーザで機能を実験するための分岐 マルチバリエイト分析 A/B テスト 短期〜中期( 実験期間による) 動的( ユーザコホートごとに振り分ける)

Slide 24

Slide 24 text

FeatureFlag の分類 Feature Toggles (aka Feature Flags) / Pete Hodgson https://martinfowler.com/articles/feature-toggles.html

Slide 25

Slide 25 text

運⽤トグル(Ops Toggles) 性能をコントロールするための分岐 パフォーマンス影響を⾒て機能デグレさせる 過負荷時の⾼負荷機能オフ 中期〜永続( 上記のいずれの⽬的かによる) 静的( 環境全体の設定)

Slide 26

Slide 26 text

FeatureFlag の分類 Feature Toggles (aka Feature Flags) / Pete Hodgson https://martinfowler.com/articles/feature-toggles.html

Slide 27

Slide 27 text

許可トグル(Permission Toggls) 特定のユーザに提供機能を変える分岐 プレミアム機能 α テスト / β テスト ⻑期〜永続 動的( リクエストごとに振り分ける)

Slide 28

Slide 28 text

同じバケツで管理しない すべてのFeatureFlag を同じ仕組みで管理 するのは危険な道 カテゴリごとに異なる設計を要する 同じ⽅法で管理すると、将来の痛みに つながる Feature Toggles (aka Feature Flags) / Pete Hodgson https://martinfowler.com/articles/feature-toggles.html

Slide 29

Slide 29 text

個⼈的⾒解 短期的なFeatureFlag での静的/ 動的の別は さほど重要ではない 柔軟に管理できたほうが便利 内部ユーザでの動作確認 カナリヤリリース 短いスパンで消えるコードなので管理 上のつらさも表⾯化しない

Slide 30

Slide 30 text

アジェンダ FeatureFlag の基本と分類 Misoca でのFeatureFlag の使い⽅ まとめ

Slide 31

Slide 31 text

Misoca でのFeatureFlag Feature Toggles (aka Feature Flags) / Pete Hodgson https://martinfowler.com/articles/feature-toggles.html 主にこのへん

Slide 32

Slide 32 text

Misoca でのFeatureFlag リリーストグル リリースせず開発期間が⻑期に渡る機能 時間合わせでのリリースが必要な機能 実験トグル・Ops トグル パフォーマンス改善 (A/B テスト、カナリヤテストを兼ねる)

Slide 33

Slide 33 text

実装 LaunchDarkly を検討したが⾒送り ⾼機能だが費⽤が結構かかる 機能を使いこなせなさそう Redis をバックエンドに⾃作 rollout gem とほぼ同じ仕組みに落ちついた 2 ファイル200 ⾏弱

Slide 34

Slide 34 text

設定と分岐 # initialize Misoca.feature_flag = Misoca::FeatureFlag.new Misoca.feature_flag.add_target( :new_feature, ' なんかすごい新機能' ) # use if Misoca.feature_flag.enabled?(:new_feature, curren Misoca::UseCase::NewFeature.new.call else Misoca::UseCase::CurrentFeature.new.call end 1 2 3 4 5 6 7 8 9 10 11 12 13

Slide 35

Slide 35 text

ユーザごとの有効化 class Misoca::FeatureFlag::Target def enable_for_user(user) redis.sadd(user_key, user.id) end end Misoca.feature_flag.enable_for_user(user) 1 2 3 4 5 6 7 feature_flag:new_feature:users ( 有効化したユーザid の集合) 42 123456 114514 user id: 123456 redis.sadd 123456

Slide 36

Slide 36 text

⽐率での有効化 feature_flag:new_feature:segments ( 有効化したユーザid 下2 桁の集合) 00 12 33 redis.sadd 04 87 04 87 例: 有効化率を3% から 5% に 元々含まれない 2 桁の数を2 つ選ぶ (3% から5% なので+2) 04 87

Slide 37

Slide 37 text

⽐率での有効化 class Misoca::FeatureFlag::Target def enable_percentage(percent) current_segments = redis.smembers(segment_ke unused_segments = ALL_SEGMENTS - current_seg diff_percent = percent - current_segments.co diff_percent.positive? ? redis.sadd(segment_key, unused_segments.sample(diff_percent)) : redis.spop(segment_key, diff_percent.abs end end Misoca.feature_flag.enable_percentage(50) 1 2 3 4 5 6 7 8 9 10 11 12 13 14

Slide 38

Slide 38 text

有効判定 有効化したユーザid の集合 42 123456 114514 user id: 123456 redis.sismember 123456 有効化したユーザid 下2 桁の集合 00 12 33 redis.sismember 56 04 87

Slide 39

Slide 39 text

運⽤ 内部ユーザ向けページから有効状況を⾒れる フラグの切り替え 内部ユーザ向けページ( ⾃分のみ) Thor タスク実⾏( ⽐率指定)

Slide 40

Slide 40 text

実⽤例 軽減税率対応 電卓機能 PDF のS3 キャッシュ

Slide 41

Slide 41 text

軽減税率対応

Slide 42

Slide 42 text

軽減税率対応 スモールリリースの難しい機能 影響範囲が広く、作業量が多い プレスリリース合わせでの有効化 リリーストグルを使⽤ コードを適宜master にマージ 内部ユーザはできたところから本番で動作確認 フラグを外して⼀般リリース

Slide 43

Slide 43 text

電卓機能

Slide 44

Slide 44 text

電卓機能 ヘルプ更新のため、時間合わせリリース コード量⾃体はそこまで⼤きくない リリーストグルを使⽤ 事前に内部ユーザで動作確認 デプロイせず設定変更のみでリリース デプロイ絡みでのトラブルの⼼配がない

Slide 45

Slide 45 text

PDF のS3 キャッシュ

Slide 46

Slide 46 text

PDF のS3 キャッシュ PDF ⽣成が重いため、S3 に2 次キャッシュ 初回PDF ⽣成時にS3 へ書き込み 1 次キャッシュがない場合、S3 から取得 どの程度改善するか⾒積りづらい S3 へのwrite 処理が増える S3 Read の重さによっては改善しない可能性も

Slide 47

Slide 47 text

PDF のS3 キャッシュ 10% のユーザにリリース→APM で効果測定 PDF Render: 800ms S3 PUT: 94ms S3 GET(miss): 40ms S3 GET(hit): 72ms ⽣成時に+134ms, 読み込み時に728ms 改善 いける!

Slide 48

Slide 48 text

利⽤者の声 富⼭県 30 代会社員 H.M さん デプロイとリリースが競合しないので 予想外のトラブルを避けられますし、 ロールバックも本当に簡単でした。 分岐処理を後から徐々に外せるのも良いですね。 不満は⼀切ないです。 FeatureFlag 最⾼! ※ 効果には個⼈差があります

Slide 49

Slide 49 text

気をつけること 汎⽤のフラグを使わない FeatureFlag を外すときに⼤変 ⼀緒に有効にしたくない機能まで有効になる 新しいフラグを簡単に⾜せると良い リリースしたらきちんとフラグを消す うっかりすると無限にフラグが増える うっかりするとリリース前に巻き戻る

Slide 50

Slide 50 text

気をつけること2 パフォーマンス影響をチェックする 軽いバックエンドとアルゴリズムにする Redis set はRW ともO(1) 、1~2ms 程度 繰り返し判定しない 1ms でも100 回呼んだら100ms になる 判定結果をキャッシュすると良い

Slide 51

Slide 51 text

アジェンダ FeatureFlag の基本と分類 Misoca でのFeatureFlag の使い⽅ まとめ

Slide 52

Slide 52 text

まとめ ⼤きいリリースはFeatureFlag を使って ⼩分けにデプロイすると便利 ⼩さいものでもFeatureFlag を使うと デプロイせずにリリースできて便利 簡単にフラグを⾜せる/ 消せる仕組みを 整備するのが必要