以下は、ChatGPT(model: GPT-4)にSREのインシデント対応のシナリオを創作してもらったときのプロンプトとその回答です。
SRE(Site Reliability Engineering)のエキスパートになりきってください。
あなたは、Twitterのような架空の短文メッセージ投稿サービスを開発・運用するエンジニアです。このサービスには、メッセージの投稿、ユーザー同士のフォロー、フォローしたユーザーのメッセージタイムラインの閲覧、といった機能が含まれています。
1. このサービスに名前をつけてください。
2. 以下の要件を満たす、架空のWebアプリケーションの具体的なシステム構成をなるべく詳細に思い浮かべてください。システム内の各ロールに名前をつけた上で、システム構成を説明してください。
- PostgreSQL、Redis Cluster、Elasticsearch、Go言語によるWebサーバを最低限含むものとします。
- アプリケーションはKubernetes上で動作しているものとします。
- 秒間1000個以上のメッセージが投稿され、メッセージのタイムラインの読み込み数は投稿数の10倍の規模感とします。
このサービスの名前は「Chirpy」(チャーピー)とします。
システム構成:
以下のシステム構成を提案します。
- Frontend: ユーザーインターフェースを提供するためのフロントエンド。ReactやVue.jsなどのフレームワークを使用します。
- API Gateway: クライアントからのリクエストを適切なサービスにルーティングするためのAPI Gateway。例えば、KongやAmbassadorを使用します。
- Web Server (Chirpy-Server): Go言語で開発されたWebサーバ。RESTful APIを提供し、ユーザーからのリクエストを処理します。
- Authentication Service: ユーザー認証・認可を管理するサービス。OAuth2やJWTを使用します。
- Timeline Service: ユーザーのタイムラインを取得・生成するためのサービス。
- Post Service: メッセージの投稿や削除を処理するサービス。
- Follower Service: ユーザー間のフォロー関係を管理するサービス。
- PostgreSQL: ユーザー情報、メッセージ、フォロー関係などのリレーショナルデータを格納するデータベース。
- Redis Cluster: メッセージのタイムラインキャッシュやセッションデータを高速に取り扱うための分散キャッシュストレージ。
- Elasticsearch: メッセージの全文検索やアナリティクスを行うための検索エンジン。
- Kubernetes: コンテナオーケストレーションプラットフォーム。アプリケーションのスケーリングやローリングアップデートを管理します。
システムの動作は以下のようになります。
1. ユーザーがフロントエンドでアクションを実行します。
2. API Gatewayがリクエストを適切なサービスにルーティングします。
3. Chirpy-Serverがリクエストを受け、必要に応じてAuthentication Service、Timeline Service、Post Service、Follower Serviceに処理を依頼します。
4. 各サービスが処理を行い、必要なデータをPostgreSQL、Redis Cluster、Elasticsearchから取得・更新します。
5. Chirpy-Serverが結果をクライアントに返します。
Kubernetes上で動作しているアプリケーションは、負荷に応じて自動的にスケーリングされます。この構成では、秒間1000個以上のメッセージ投稿と、タイムラインの読み込みを問題なく処理できるようになります。具体的には、次のような手法でパフォーマンスを最適化します。
6. Horizontal Pod Autoscaler (HPA): Kubernetesの機能で、CPU使用率やメモリ使用率などのリソース使用状況に基づいて、Podの数を動的にスケーリングします。これにより、Chirpy-Serverや各サービスのインスタンス数が自動的に増減し、負荷に適応します。
7. Redis Cluster: キャッシュを分散させることで、読み込み性能を向上させます。また、RedisのPub/Sub機能を使用して、リアルタイムにタイムラインを更新することができます。
8. Elasticsearch: 検索性能を向上させるために、シャーディングとレプリケーションを適切に設定します。これにより、検索クエリの負荷が分散され、高速な検索が可能になります。
9. Connection Pooling: PostgreSQLへの接続にコネクションプーリングを使用することで、データベースへの接続数を制限し、データベースサーバのリソースを効率的に使用します。例えば、PgBouncerを使用することができます。
10. Database Sharding: データベースのシャーディングを行い、データを複数のデータベースインスタンスに分散させることで、読み込み・書き込み性能を向上させます。
これらの最適化手法を適用することで、Chirpyは高いパフォーマンスを維持しながら、大規模なメッセージ投稿やタイムラインの読み込みに対応できるシステム構成となります。また、システムの監視やアラート設定を行うことで、異常や障害が発生した際に迅速に対応し、システムの安定性を確保します。
あなたが提案してくれたChirpyにおいて、現実に発生しそうなシステム障害に対するインシデント対応のシナリオとその調査と対策過程をなるべく詳細に創作してください。
- 日付と時刻、それ以外に必要な数値も含めるものとします。
- あなたが調査時に注目したシステムログの文字列とメトリクス名、メトリクス名の変動を、あなたが注目した理由も含めるものとします。
- 対策のために使用したコマンドの文字列を含めるものとします。
- ログとコマンドの文字列、メトリクス名には、このシステム固有の名詞を含めることにより、実際に存在しそうな対応過程に近づけるものとします。
- 対応過程の各ステップにおける時刻、それ以外に必要な数値も具体的に含めるものとします。
- 対応開始からインシデントの収束までには30分要したものとします。
2023年3月20日 14:00
インシデント発生:ユーザーからの報告により、Chirpyの一部のタイムラインが更新されない事象が発生していることが確認されました。
14:01
調査開始:まずはChirpy-Serverのログを確認します。
kubectl logs -l app=chirpy-server --since=5m
14:03
ログ確認:Chirpy-Serverのログには、Timeline Serviceへのリクエストがタイムアウトしていることがわかります。
2023-03-20T14:02:34.000Z [ERROR] Request to Timeline Service timed out: url=https://timeline-service.chirpy.svc.cluster.local
14:04
メトリクス確認:Timeline ServiceのCPU使用率が急激に上昇していることを確認しました。
kubectl top pods -l app=timeline-service
また、Prometheusで以下のメトリクス名を確認します。
timeline_service_request_duration_seconds
14:06
メトリクス確認:Timeline Serviceのレスポンスタイムが通常の10倍になっていることがわかりました。
14:07
対策開始:Timeline ServiceのPodの数を増やして、負荷を分散させます。
kubectl scale deployment timeline-service --replicas=10
14:10
状況確認:Timeline ServiceのCPU使用率が下がり、レスポンスタイムも改善されましたが、依然としてタイムラインが更新されない事象が発生していることが確認されました。
14:12
調査再開:Redis Clusterのログを確認します。
kubectl logs -l app=redis-cluster --since=10m
14:15
ログ確認:Redis Clusterのログに以下のエラーメッセージがありました。
2023-03-20T14:14:12.000Z [WARN] Node redis-cluster-2 is down: host=redis-cluster-2.redis-cluster.chirpy.svc.cluster.local
14:16
対策開始:Redis Clusterの問題を修正するために、故障しているノード(redis-cluster-2)を再起動します。
kubectl delete pod redis-cluster-2
14:18
状況確認:Redis Clusterのノード(redis-cluster-2)が再起動され、全てのノードが正常に稼働していることを確認しました。
kubectl get pods -l app=redis-cluster
14:20
調査継続:故障していたRedis Clusterのノードが復旧したことで、タイムラインの更新が正常に行われるか確認します。
14:22
状況確認:タイムラインが正常に更新されていることが確認できました。ユーザーからの報告も、問題が解決されたとの連絡がありました。
14:23
インシデントの原因分析:今回のインシデントは、Timeline Serviceの負荷によるタイムアウトと、Redis Clusterのノード故障が同時に発生したことで、タイムラインの更新が行われない状況が発生しました。
14:25
対策検討:今後の対策として、以下の項目を検討します。
Timeline Serviceの性能監視を強化し、異常値を検出した場合に自動的にスケーリングが行われるように設定を調整します。 Redis Clusterのノード監視を強化し、障害が発生した際に自動的に再起動が行われるように設定を調整します。
14:30
インシデント収束:今回のインシデントは、システム障害の原因が特定され、対応策が実施されたことで解決されました。今後は、上述の対策を適用して、同様のインシデントが再発しないように努めます。また、インシデントに関する報告書を作成し、関係者に共有します。
このインシデントに対応中の関係者のSlackチャットログ(エンジニアの名前と時刻を含む)を以下の条件に沿って再現してください。
- 登場人物にそれぞれ小文字のアルファベットと数字を含む風変わりな架空のハンドルネームを与えるものとする。
- エンジニアが3人で対応しているものとします。1人はシニアエンジニア、2人はジュニアエンジニアです。
- チャットにはアラートbotによるアラートメッセージも含むものとします。アラートは状況の悪化と回復を示すものとします。アラートメッセージのみ英語で、それ以外は日本語です。
- 一人のプロダクトマネージャーからの質問や、一人のカスタマーサポートからの対応状況の問い合わせに対応する様子も含めてください。
- エンジニア同士はジョークや悪態を交えて、くだけた様子で話すものとします。
- このインシデント対応では、途中過程で誤った調査や対策を行います。
14:00
alert-bot:[ALERT] タイムライン更新エラーが発生しました。原因を調査してください。
14:01
pika7:みんな、タイムライン更新に問題があるらしいぞ。調査しよう。
hoge123:了解!ログをチェックしてみるよ。
fizz456:僕もCPU使用率とかメトリクス見てみるね。
14:04
hoge123:Chirpy-Serverのログ見たら、Timeline Serviceへのリクエストがタイムアウトしてるみたい。
fizz456:Timeline ServiceのCPU使用率がすごいことになってる!スケーリングしようか?
14:07
pika7:いいね、やってみよう。でもまずRedis Clusterを見てみたほうがいいかも。
hoge123:あ、そうだね。ちょっと見てみるね。
14:08
product_manager:対応状況はどうですか?ユーザーからクレームが増えてきています。
pika7:調査中です。少々お待ちください。
14:10
hoge123:Redis Clusterは問題なさそうだね。
fizz456:じゃあスケーリングしてみるか。kubectl scale deployment timeline-service --replicas=10 でいいよね?
pika7:うん、やってみよう。
14:15
customer_support:対応状況はいかがですか?ユーザーからの問い合わせが増えています。
hoge123:対応中です。もう少し時間がかかりそうですが、頑張っています。
14:16
fizz456:スケーリングしたけど、まだ問題解決しないみたい。
pika7:うーん、じゃあやっぱりRedis Clusterに問題があるのかも。もう一度確認してみて。
hoge123:おっけー。
14:20
hoge123:やっぱりRedis Clusterのログにエラーがあったよ!Node redis-cluster-2がダウンしてるみたい。
pika7:そうか、じゃあ再起動してみよう。
14:22
fizz456:えっ、ちょっと待って。さっきスケーリングしたから、多分Timeline Serviceに問題がないんじゃない?
pika7:まあ、そうだけど、とりあえずRedis Clusterのノード再起動してみるか。
hoge123:じゃあ、kubectl delete pod redis-cluster-2 で再起動させてみるね。
14:25
hoge123:再起動したら、Redis Clusterのノードは正常になったみたいだよ。
fizz456:よかったね!じゃあ、タイムライン更新も確認してみようか。
14:27
pika7:タイムライン更新、今度こそ正常に戻ったみたいだぞ!
fizz456:おお、本当だ!ありがとうRedis Cluster!(笑)
hoge123:さすが僕ら、最後は解決できるよね!(笑)
14:30
product_manager:対応状況はどうですか?
pika7:今回の問題は解決しました!タイムライン更新が正常に戻りました。
product_manager:素晴らしいです!お疲れ様でした。
14:31
customer_support:対応ありがとうございました!ユーザーにもご報告します。
hoge123:いえいえ、どういたしまして!
fizz456:また問題が起きたら、僕らが解決するよ!(笑)
pika7:おお、ジュニアたちも大胆になってきたな(笑)。じゃあ、後でインシデント報告書を作成して、関係者に共有しよう。今後も同じような問題が起きないように対策を考えておこう。
感想
システム構成
インシデントシナリオ
チャットログ