Slide 1

Slide 1 text

AIネイティブな開発についての モヤモヤを吐き出す SRE maru (個人登壇)

Slide 2

Slide 2 text

の前に 障害報告からAI生成した 小説に少しだけお付き合いください

Slide 3

Slide 3 text

2-22-22 キャッシュが温まらなかった朝 Slackがダウンした日 https://slack.engineering/slacks-incident-on-2-22-22/

Slide 4

Slide 4 text

プロローグ

Slide 5

Slide 5 text

2022年2月22日。火曜日。 午前6時を少し過ぎたころ、Slackのいくつかのチームに、ほぼ同時に通知が走った。

Slide 6

Slide 6 text

2022年2月22日。火曜日。 午前6時を少し過ぎたころ、Slackのいくつかのチームに、ほぼ同時に通知が走った。 ユーザーからのサポートチケット。社内からの「つながらない」という声。

Slide 7

Slide 7 text

2022年2月22日。火曜日。 午前6時を少し過ぎたころ、Slackのいくつかのチームに、ほぼ同時に通知が走った。 ユーザーからのサポートチケット。社内からの「つながらない」という声。 複数のエンジニアリングチームへのページャー。

Slide 8

Slide 8 text

2022年2月22日。火曜日。 午前6時を少し過ぎたころ、Slackのいくつかのチームに、ほぼ同時に通知が走った。 ユーザーからのサポートチケット。社内からの「つながらない」という声。 複数のエンジニアリングチームへのページャー。 インシデント・コマンダーを務めることになるローラ・ノーランは、その日の朝、自分の Slackクライアントが起動しないこ とに気づいた。

Slide 9

Slide 9 text

(この続きは、最後時間があったら )

Slide 10

Slide 10 text

AIネイティブな開発についての モヤモヤを吐き出す SRE maru (個人登壇)

Slide 11

Slide 11 text

時代はAIじゃ AI Readyな環境を整備して AI Nativeな開発で 開発生産性を爆増するのじゃ

Slide 12

Slide 12 text

お任せください! AI Readyな環境として 問い合わせ窓口を AI chat bot化し ドキュメント検索をして最新のナレッジをベースに回答する ようにしました! また、MCPサーバーも提供し 、 Coding Agentからも直接利用できます! これでAI Nativeな開発ができます!

Slide 13

Slide 13 text

やったー!これで私たちも AI Nativeな開発で 開発生産性爆増だ!!

Slide 14

Slide 14 text

ってなってますか?

Slide 15

Slide 15 text

「AIが働きやすい環境」というのは、たしかに存在する ● 食器をすべて食洗機対応に切り替えるように ○ 子どもの水筒を丸ごと食洗機対応にして、世界が変わりました ● ロボット掃除機が掃除しやすい部屋にするように AI-Readyな環境とは?

Slide 16

Slide 16 text

AI-Readyといいつつやってることは、従来のDevEXが多い気がする ● プラットフォームはAPI/CLIを提供 ○ できれば、X as Codeで管理できるように ● テストカバレッジだけでなく、Mutation testなどでテスト品質も ● オブザーバビリティで非ドメインエキスパートでも解決できるように ● CI/CDをより高速に ● PRごとの即時的な開発環境を 現時点では、AI-Ready は Dev-Friendly にとても近い

Slide 17

Slide 17 text

AI-Readyといいつつやってることは、従来のDevEXが多い気がする ● プラットフォームはAPI/CLIを提供 ○ できれば、X as Codeで管理できるように ● テストカバレッジだけでなく、Mutation testなどでテスト品質も ● オブザーバビリティで非ドメインエキスパートでも解決できるように ● CI/CDをより高速に ● PRごとの即時的な開発環境を なんならDevOpsと関係なく、自明な話も ● タスクは完了条件を明確に ● コンテキストが大きすぎるタスクは適切に分解を 現時点では、AI-Ready は Dev-Friendly にとても近い

Slide 18

Slide 18 text

現時点でのAI-Readyと言われてるものの割合(maru調べ) 人間にとってもAIにとっても嬉しい AIにとって嬉しい (ただし流動的 )

Slide 19

Slide 19 text

現時点でのAI-Readyと言われてるものの割合(maru調べ) 人間にとってもAIにとっても嬉しい AIにとって嬉しい (ただし流動的 ) 「AIにとって嬉しい」ばかりを優先しすぎると...

Slide 20

Slide 20 text

「AIにとって嬉しい」ばかり優先しすぎると... 人間にとってもAIにとっても嬉しい AIにとって嬉しい (ただし流動的 ) MCP-Serverもいいんだけど、人間も使える CLIを出してくれないかな? RAGは確かに重要なんだけど、そもそもドキュメント自体メンテナンスされてない ローカル開発環境の流行り廃りの話題ばかり

Slide 21

Slide 21 text

改めて、この時代は何が変わったのか?

Slide 22

Slide 22 text

木こりのジレンマを乗り越えた ある⽊こりが、がんばって⽊を切っている。 通りがかった旅⼈がその様⼦を眺めていたが、斧を振るう勢いのわりに、なかなか⽊が切れていない。 ⾒ると⽊こりの使っている斧が刃こぼれしているようなので、旅⼈は⾔った。 「斧を研いだほうがいいのでは?」 すると、⽊こりは⾔った。 「わかっちゃいるんだけどね、⽊を切るのに忙しくて、それどころじゃないよ」

Slide 23

Slide 23 text

木を切りながら、斧を研げる時代 ● 開発しながら並行して ○ CI/CDの不満を改善する ○ オブザーバビリティの不満を改善する ○ etc

Slide 24

Slide 24 text

良い不満を持つのが大事 当たり前や慣れを常に疑い、現状の開発に不満を持つ。 プログラマの三大美徳(怠惰・短気・傲慢)をAIにぶつけていきたい。

Slide 25

Slide 25 text

良い不満を持つのが大事 当たり前や慣れを常に疑い、現状の開発に不満を持つ。 プログラマの三大美徳(怠惰・短気・傲慢)をAIにぶつけていきたい。 「AI利用促進」のために、 現場から離れすぎると良い不満から遠ざかってしまうかも。

Slide 26

Slide 26 text

とはいえ、良い課題を見つける評価軸は? AI-Readyに求められる能力 意味 例 Context Capability 必要な情報が集約・関連付けられている ドキュメント、API/CLI/UI、Skills、MCP、RAG Traceability Capability 元情報・根拠・履歴を辿れる パーマリンク、git history Validation Capability 機械的に(決定論的に)判定できる テスト、高速なCI/CD、明確な完了条件 Equivalence Capability 変換や変更の意味保存を検証できる E2Eテスト、翻訳・移行・リファクタリングの QA Policy Capability 組織ルールや禁止事項を判定できる Policy as Code (OpenPolicyAgent) Permission Capability 権限・アクセス範囲を制御できる RBAC、File access、Networks access Execution Capability 成果物や変更を安全に試せる実行環境がある ローカル実行、ブランチごとの開発環境 Governance Capability 承認・監査・実行履歴を保証できる リリース承認、作業承認

Slide 27

Slide 27 text

どの不満から優先するべきか? 誰か(AIベンダー, OSS)が解決してくれそうな不満 自分(たち)じゃないと解決できない不満 人間とAI両方に 嬉しい AIに嬉しい No.1最優先 No.? No.? No.?

Slide 28

Slide 28 text

どの不満から優先するべきか? 誰か(AIベンダー, OSS)が解決してくれそうな不満 自分(たち)じゃないと解決できない不満 人間とAI両方に 嬉しい AIに嬉しい No.1最優先 No.? No.? No.? 優先度をつけなくても、全部AIを使えば、 OSS貢献も何もかもできてしまう気がする けど、実際に自分のお金と時間はそれでも有限だし 投資・節約を判断するのが一番人間の仕事っぽい

Slide 29

Slide 29 text

Appendix: 障害を小説にして共有する 障害を振り返ることは古くから価値が高いと言われている。 より組織的に、グループワークとして読む文化が定着している組織もある。 でも、なかなか開催すること、継続することのハードルは高い。 過去のポストモーテムを小説にすると、楽しんで読み返せて良いぞ。

Slide 30

Slide 30 text

2-22-22 キャッシュが温まらなかった朝 Slackがダウンした日 https://slack.engineering/slacks-incident-on-2-22-22/

Slide 31

Slide 31 text

第1章 静かに張られた糸 Slackのクライアントは、起動のたびに「ブート」と呼ばれる手順を踏む。 チャンネル一覧、ユーザー設定、最近の会話。それらをサーバーから取得して、キャッシュする。 ブートが終わらなければ、 Slackは使えない。

Slide 32

Slide 32 text

第1章 静かに張られた糸 Slackのクライアントは、起動のたびに「ブート」と呼ばれる手順を踏む。 チャンネル一覧、ユーザー設定、最近の会話。それらをサーバーから取得して、キャッシュする。 ブートが終わらなければ、 Slackは使えない。 裏側では、Vitess が立っていた。MySQLを水平にスケールさせるためのシステム。 データは「キースペース」と呼ばれる論理データベースに分かれて格納される。 複数のキースペースを使い分けることで、クエリは効率化され、ワークロードは隔離される。

Slide 33

Slide 33 text

第1章 静かに張られた糸 その中の一つに、「チャンネル所属情報をユーザー単位でシャーディング」したキースペースがあった。 ユーザーがどのチャンネルに入っているかを引くには、最適化された設計だった。

Slide 34

Slide 34 text

第1章 静かに張られた糸 その中の一つに、「チャンネル所属情報をユーザー単位でシャーディング」したキースペースがあった。 ユーザーがどのチャンネルに入っているかを引くには、最適化された設計だった。 問題は、逆向きの問いだった。 あるグループDM(GDM)に、誰が入っているか。

Slide 35

Slide 35 text

第1章 静かに張られた糸 その中の一つに、「チャンネル所属情報をユーザー単位でシャーディング」したキースペースがあった。 ユーザーがどのチャンネルに入っているかを引くには、最適化された設計だった。 問題は、逆向きの問いだった。 あるグループDM(GDM)に、誰が入っているか。 ユーザーでシャーディングされた表に対し、チャンネルから引く。 それは、全シャードへの問い合わせ —— Vitess の言う「スキャッタークエリ」になる。

Slide 36

Slide 36 text

第1章 静かに張られた糸 しかし、それでも普段は問題なかった。 GDMのメンバー情報は、チャンネル IDをキーにキャッシュされていた。 GDMのメンバーは不変。だから TTL は長い。キャッシュはほぼ常にヒットする。 すべては、キャッシュが温まっている、という前提の上に立っていた。

Slide 37

Slide 37 text

キャッシュ層には、Memcached と Mcrouter がいる。 Mcrouter はコンシステントハッシュで、リクエストを健全な Memcached インスタンスに振り分ける。そして、その設定ファイ ルを生成しているのが、比較的新しいコンポーネント、 Mcrib だった。 第2章 善意の効率

Slide 38

Slide 38 text

キャッシュ層には、Memcached と Mcrouter がいる。 Mcrouter はコンシステントハッシュで、リクエストを健全な Memcached インスタンスに振り分ける。そして、その設定ファイ ルを生成しているのが、比較的新しいコンポーネント、 Mcrib だった。 Mcribは、サービスディスカバリの Consul を監視している。Memcached インスタンスが利用不能になったと Consulが判断 すれば、Mcribは即座にスペアを昇格させる。古いインスタンスが復帰してきたら、データの整合性を保つために、フラッシュ してから戻す。 第2章 善意の効率

Slide 39

Slide 39 text

Mcribは、賢く、速かった。 その日、Consul エージェント自身のアップグレード作業が走っていた。 各ホスト上で動くエージェントを、新しいバイナリに置き換える。 一斉再起動を避けるために、 25%ずつ、ゆっくり段階的に。 第2章 善意の効率

Slide 40

Slide 40 text

前週、25%、25%と二段階。いずれも、何事もなく完了していた。 2月22日。三段階目の25%。 第2章 善意の効率

Slide 41

Slide 41 text

前週、25%、25%と二段階。いずれも、何事もなく完了していた。 2月22日。三段階目の25%。 Consul エージェントがシャットダウンする。ノードはサービスカタログから登録解除される。 Mcrib がそれを検知する。即座に スペアを昇格させる。新しいキャッシュノードは、空。 そしてエージェントが再起動する。ノードが戻る。 Mcrib がフラッシュする。 第2章 善意の効率

Slide 42

Slide 42 text

前週、25%、25%と二段階。いずれも、何事もなく完了していた。 2月22日。三段階目の25%。 Consul エージェントがシャットダウンする。ノードはサービスカタログから登録解除される。 Mcrib がそれを検知する。即座に スペアを昇格させる。新しいキャッシュノードは、空。 そしてエージェントが再起動する。ノードが戻る。 Mcrib がフラッシュする。 一つずつ。 順番に。着実に。 ピーク時刻に向かって、キャッシュのヒット率が、静かに落ちていった。 第2章 善意の効率

Slide 43

Slide 43 text

ある一線を、システムは越えた。 第3章 反転

Slide 44

Slide 44 text

ある一線を、システムは越えた。 GDMメンバー情報のキャッシュに穴が空く。 たった一つのチャンネルがキャッシュにない、ただそれだけで、アプリケーションはキースペースの全シャードに問い合わせを 投げる。 第3章 反転

Slide 45

Slide 45 text

ある一線を、システムは越えた。 GDMメンバー情報のキャッシュに穴が空く。 たった一つのチャンネルがキャッシュにない、ただそれだけで、アプリケーションはキースペースの全シャードに問い合わせを 投げる。 ほぼすべてのユーザーが、ほぼすべてのシャードに、ほぼ同時にクエリを投げ始めた。 データベース負荷は、キャッシュミス率に対して、線形ではなく、超線形に増えていく。 第3章 反転

Slide 46

Slide 46 text

ある一線を、システムは越えた。 GDMメンバー情報のキャッシュに穴が空く。 たった一つのチャンネルがキャッシュにない、ただそれだけで、アプリケーションはキースペースの全シャードに問い合わせを 投げる。 ほぼすべてのユーザーが、ほぼすべてのシャードに、ほぼ同時にクエリを投げ始めた。 データベース負荷は、キャッシュミス率に対して、線形ではなく、超線形に増えていく。 クエリはタイムアウトする。タイムアウトすれば、キャッシュは埋まらない。 キャッシュが埋まらなければ、また全シャードに飛ぶ。 第3章 反転

Slide 47

Slide 47 text

カスケード障害。安定状態が反転して、もう一つの安定状態に落ちる。負荷を下げるか、容量を増やすか —— 外から手を入 れなければ、戻ってこない状態。 クライアントは、リトライする。指数バックオフとジッターは入っている。 それでも、リトライは負荷になった。 問題のトリガーであった Consul エージェントの再起動は、この時点ではすでに停止されていた。ただし、それが原因だとは、 まだ誰も気づいていなかった。 そして、もう関係なかった。糸はすでに張り終えられていた。 第3章 反転

Slide 48

Slide 48 text

対応は、トレードオフの選択から始まった。 データベースを圧迫しているのは、クライアントのブート要求だった。長く待たされ、しばしば失敗する。そしてその間、 すでにブート済みのユーザーへのリクエストまで巻き添えにする。 ブート要求を絞る。新規接続はつながらなくなる。だが、すでに接続できているユーザーには、平常に近い体験が戻 る。 タイムアウトが減れば、キャッシュも埋まり始める。 絞る。効く。少し開ける。崩れる。もう一度絞る。少しずつ開ける。 第4章 絞る

Slide 49

Slide 49 text

並行して、根本のクエリに手が入った。 スキャッタークエリは、キャッシュから返ってきた分は除いて、ミスした分だけをデータベースに問い合わせるよう書き 換えられた。GDMメンバーは不変だから、レプリカからも読める ——プライマリだけでなく、レプリカも読み取り対象に加えた。 キャッシュが、徐々に温まっていく。ヒット率が上がる。 データベース負荷が下がる。 ブート要求のレートリミットは、少しずつ、慎重に、緩められていった。 完全復旧。 第4章 絞る

Slide 50

Slide 50 text

なぜ、Slackは落ちたのか。 ピーク時刻にぶつかった Consul エージェント再起動が、Mcribにキャッシュノードの入れ替えを連続的に行わせた。キャッ シュヒット率が落ちた。 なぜ、それが致命傷になったのか。 GDMメンバー情報のクエリは、本来「ユーザー単位でシャーディングされた表」をチャンネルから引いていたスキャッタークエ リ。普段はキャッシュが守っていた前提のクエリ。 なぜ、Mcribという「良くできた仕組み」が、事態を悪化させたのか。 Mcribは、旧来の方式より、ダウンを速く検知し、設定を速く修復した。効率的だった。だからこそ、キャッシュ層の入れ替わり を激しくし、障害を広げた。 エピローグ 〜なぜ起こってしまったのか〜

Slide 51

Slide 51 text

>「より速く、より正しく動くコンポーネントが、より大きなシステムを、より危うくすることがある。」 Slackは、Consul の段階展開の手順を見直した。スキャッタークエリは、チャンネル単位でシャーディングされたテーブルに 向け直された。同種の高頻度スキャッタークエリがほかにないかも、洗い直された。 ローラ・ノーランは、ことが終わってから、リチャード・クックの『 How Complex Systems Fail』の第4節を、また読んだ。 > 複雑なシステムには、つねに潜在的な障害が、入り混じった状態で含まれている。個々には致命的でないため、運用中は 些細なものと見なされる。 潜在的な障害は、一つでは何も起こさない。何かの拍子に、それらが手をつなぐ朝が、来るだけだ。 エピローグ 〜なぜ起こってしまったのか〜

Slide 52

Slide 52 text

毎日、過去のポストモーテムから1件 AI生成で小説にして投稿することで 毎日1件ずつポストモーテムを読むようになった