Share
Embed
The burst of New Year greeting on LINE Sticker
約9倍のスパイクに備える取り組み(LINEスタンプのあけおめLINE)
LINE Toshiya Kato (@maruloop : https://twitter.com/maruloop )
23時59分に10k rps、1分後に90k rpsを超える突負荷を記録した2022年のあけおめLINE。LINEスタンプでこのような負荷に「耐える技術」だけではなく、「備える」ために行った具体的な取り組みを紹介します。SRE本21章の「過負荷への対応」の実践が難しいと感じている方へのヒントになればと思っています。
2022年3月12日開催「6社合同 SRE勉強会」
https://line.connpass.com/event/236497/
発表内容をもっと詳しく聞きたいという方は、Meetyでカジュアル面談を受け付けています。
https://meety.net/matches/iEVCdbIPJvdn
*本人の都合・判断で、クローズする場合やリクエストに対応できない場合もあります。予めご了承ください。
LINE Developers
March 12, 2022
Transcript
58 slides
-
スタンプ関連の組織 チーム構成 開発 Server-side 約25名 企画 運営 開発 UIT Design
開発 Client-side QA Embedded SRE 4 -
Pure SRE と Embedded SRE チーム構成 ༧ ࣏ྍ ࣾඪ४ͷ πʔϧఏڙ
0O$BMMରԠ ඪ४πʔϧͷಋೖ ಠࣗπʔϧ։ൃ ͦͷଞվળ શࣾԣஅ αʔϏεݻ༗ Use Feedback 開発 Server-side 約25名 Embedded SRE Pure SRE 5 -
Pure SRE と Embedded SRE チーム構成 ༧ ࣏ྍ ࣾඪ४ͷ πʔϧఏڙ
0O$BMMରԠ ಠࣗπʔϧ։ൃ νϡʔχϯά શࣾԣஅ αʔϏεݻ༗ Use Feedback PR 開発 Server-side 約25名 Embedded SRE Pure SRE 6 -
LINEスタンプのシステムが提供している主な機能 提供者向け(公式・クリエイター) • 商品の登録・修正 利用者向け • 検索・レコメンドなどのリスティング • 購入・ダウンロード •
スタンプの送受信 システム概要 Microservice Architectureで実装 8 -
検索 & レコメンド システム概要 API gateway Web site rendering Home
Contents Server Recommend system Search server 9 SSG rest api to thrift rpc -
システム全体 システム概要 API gateway Home Contents Server Recommend system Search
server Talk server Open Chat Web site rendering Akamai CloudFront MySQL MongoDB Image-server Object Storage Capability server 12 検索やレコメンド スタンプ送信 スタンプ画像取得 -
各マイクロサービスでの基本的な実装 基本的な高負荷対応の実装 • RxJavaとArmeriaを使って、ノンブロッキングな実装 • 特定の処理が遅くなっても、他のAPIが影響を受けにくくする • システム間通信はThrift RPC +
Client-side LB • Client-side LBでサーキットブレイカー、モニタリングなどの機能を注入 • ローカルとリモートでの多段キャッシュ • Hot keyによるRedis高負荷対策や低レイテンシのために • Caffeine(Javaライブラリ)を利用したローカルキャッシュ • Redisを用いたリモートキャッシュ 14 -
Gateway serverでの実装 基本的な高負荷対応の実装 • API単位のThrottling機能 • 特定のAPIの成功/失敗を割合で設定可能 • 各マイクロサービス で安易に実施すると、リトライによる連鎖障害リスクがあるため、Gatewayで実施
API gateway Service A Service B Service C 15 -
あけおめLINE自体の特徴 • 短時間で一気にスパイクする • スタンプの送信数が1分前の約9倍になる • 数時間の売上が急伸する • 年に1回きりのイベント •
今年ローンチした新機能は十分なデータの蓄積がない • 実装やアーキテクチャの変更に伴う負荷の変化を把握するのは難しい あけおめLINEについて 17 -
スタンプキーボードでの機能追加に起因 • スタンプキーボードの最下部に、同じ作者の最新スタンプを表示するようにした • このデータはキャッシュされておらず、毎回Elasticsearchに貫通 • 普段、スタンプ送信はバーストしないため、サーバーサイドで気付くことが出来ず • 「あけおめLINE」のタイミングでバーストしてElasticsearchが過負荷へ... 2021年元旦のスタンプ過負荷
下までスクロール 現在は、このデータが取得できなくても、 スタンプ送信に影響がないように修正済み。 20 -
あけおめLINEの難しさ = 把握・予測の難しさ • アクセス見積もり • 前年・前々年の障害によるアクセス需要データの不足 • 新規機能はそもそもデータがない •
様々なキャンペーンにより、ユーザー行動も平時とは大きく異なる • パフォーマンスキャパシティの変化 • 1年間に蓄積された全ての変更の影響度を把握するのは難しい 2022年のあけおめLINEに向けて 22 -
備えたこと 2022年のあけおめLINEに向けて 23 予防 検知 対処 • 以前の過負荷に対する個別対処 • 複数の方法を併用したアクセス数予測
• ボトルネックと1nodeあたりのキャパシティ確認 • トラフィックの削減 • サービスのコンテキストごとに担当者をアサイン • 専用のダッシュボード作成 • Playbook準備 • Priority load sheddingの運用の準備 -
備えたこと 2022年のあけおめLINEに向けて 24 予防 検知 対処 • 以前の過負荷に対する個別対処 • 複数の方法を併用したアクセス数予測
• ボトルネックと1nodeあたりのキャパシティ確認 • トラフィックの削減 • サービスのコンテキストごとに担当者をアサイン • 専用のダッシュボード作成 • Playbook準備 • Priority load sheddingの運用の準備 -
Elasticsearch dual cluster • 2021年のElasticsearchの過負荷への予防策 • もちろん、キャッシュ追加やクライアントサイドの変更も実施済み • コストのため、「あけおめLINE」が終わり次第、スケールインしたい 予防
- 以前の過負荷に対する個別対処 MongoDB MySQL indexer Search-server select indexing search 25 -
Elasticsearch dual cluster • バッチでElasticsearchにindexingしているアーキテクチャだった • クラスタレベルでスケールアウトすることに 予防 - 以前の過負荷に対する個別対処
MongoDB MySQL indexer Search-server select indexing search w/ round robin indexer 26 -
Gateway serverの過負荷分析 • 2021年の「あけおめLINE」時、Elasticsearchだけでなく、Gateway serverも過負荷になった • Async-profilerを使って、ボトルネックを分析 • 原因はJWT local
verificationだったため、Session storeを利用したremote verificationへ変更 予防 - 以前の過負荷に対する個別対処 27 -
備えたこと 2022年のあけおめLINEに向けて 28 予防 検知 対処 • 以前の過負荷に対する個別対処 • 複数の方法を併用したアクセス数予測
• ボトルネックと1nodeあたりのキャパシティ確認 • トラフィックの削減 • サービスのコンテキストごとに担当者をアサイン • 専用のダッシュボード作成 • Playbook準備 • Priority load sheddingの運用の準備 -
2つの予測方法の最大値利用 データが不十分だったり、信頼できないものがあったため、2つの予測方法を併用 「予測を当てること」ではなく、「過負荷を防ぐこと」が目的なため、最大値を予測値として利用。 予防 - 複数の方法を併用したアクセス数予測 CAGR(年平均成⻑率) 売上の予測などでしばしば使われる。キャンペーンや障害などで上振れや下振れがあっても、多少吸収できる。 最低2年分の元旦のデータがあれば良く、その場合は元旦のアクセス数の等⽐数列の⼀般項の計算結果と同じ。 通常時のアクセス数の前年⽐を成⻑率とみなす
前年と今年の10⽉第⼆⽔曜⽇のアクセス数の⽐率を、去年の元旦のアクセス数に掛ける。 元旦に障害やキャンペーンで⼤きな上振れや下振れがないことが前提。 29 -
通常時のアクセス数の前年比を成長率とする 前年と今年の10月第二水曜日のピークアクセス数の比率を計算。 この比率を成長率とみなし、前年の元旦のアクセス数に掛ける。 前年のアクセス数が信頼できないと、予測不可。 予防 - 複数の方法を併用したアクセス数予測 31 2020年 2021年
2022年 1000rps 2500rps 5000rps 2000rps 4500rps ???rps x2.5 x2 Weekday on Oct NY’s Day -
アクセス数予測値の決定 予防 - 複数の方法を併用したアクセス数予測 32 予測値あり 予測不可 予測値あり MAX(A,B) B
予測不可 A コンテキストの近いマイクロサービス の 予測値を参考 (B). CAGR (A). 通常時アクセス数の前年比 -
安全マージンの積み方を調整 予測精度に自信があるサービス • CPU使用率が最大70%になるように増設 • 基準の例: • CAGRと通常時比での予測誤差が5%以内 • その他懸念がない
予測精度に不安があるサービス • CPU使用率が最大50%になるように増設 • 基準の例: • 前年に障害があって不安 • なんか「匂う」 33 予防 - 複数の方法を併用したアクセス数予測 -
備えたこと 2022年のあけおめLINEに向けて 34 予防 検知 対処 • 以前の過負荷に対する個別対処 • 複数の方法を併用したアクセス数予測
• ボトルネックと1nodeあたりのキャパシティ確認 • トラフィックの削減 • サービスのコンテキストごとに担当者をアサイン • 専用のダッシュボード作成 • Playbook準備 • Priority load sheddingの運用の準備 -
ボトルネックを確認するのではなく、デザインする 予防 - ボトルネックと1nodeあたりのキャパシティ確認 35 CPUをボトルネックにする • CPUがボトルネックであれば、スケールアウトで線形に拡張できる • エンジニアリソース的に、すべてのマイクロサービスを分析しきれない...
スミルノフ・グラブス検定で、CPU利用率の外れ値を探す 外れ値のマイクロサービス から優先して深堀調査 正規分布を前提に、再帰的に実施して複数の外れ値を見つけることができる スミルノフ・グラブス検定を利用した。 ※正規性の確認には注意が必要 今回の用途では、仮に正規性がなく、外れ値が多く検出されたとしても 深堀調査する対象マイクロサービスが増えるだけで、全量調査よりマシなため利用 -
統計的な処理で外れ値のマイクロサービスを探す 予防 - ボトルネックと1nodeあたりのキャパシティ確認 36 ϦΫΤετ૿Ճྔ NBYNJO $16ར༻૿Ճྔ NBYNJO ϦΫΤετ૿Ճྔ
$16૿Ճྔ 4FSWJDF" 4FSWJDF# 4FSWJDF$ 4FSWJDF% 4FSWJDF ʜ ʜ ʜ この数値を使って、スミルノフ・グラブス検定 各サービスごとにリクエスト の最大と最小の比率を計算 リクエスト最大と最小時の CPU利用率の比率を計算 Heap memoryが枯渇して、GC頻度が高くなり、 リクエスト増加率以上に、CPU利用率が高くなるService Bが見つかった Heap memoryをscale-upして解決 -
実際のユーザーアクセスを利用した負荷試験 37 LB Server 1 Server 2 Server 3 Server
4 Server 5 Server 6 重要なサービスでは負荷試験も実施 • 負荷試験の準備が⼤変で、複数のマイクロサービス をやるリソースがない • サーバーをScale-inして、負荷を特定のノードに偏らせる⽅法で実施 • エラー率やレイテンシを確認 • CPUが70%以上使い切れていればOK • 簡単にできるチューニング箇所が⾒つかれば、"ついで”に実施 予防 - ボトルネックと1nodeあたりのキャパシティ確認 -
備えたこと 2022年のあけおめLINEに向けて 38 予防 検知 対処 • 以前の過負荷に対する個別対処 • 複数の方法を併用したアクセス数予測
• ボトルネックと1nodeあたりのキャパシティ確認 • トラフィックの削減 • サービスのコンテキストごとに担当者をアサイン • 専用のダッシュボード作成 • Playbook準備 • Priority load sheddingの運用の準備 -
マイクロサービス化に伴う無駄なトラフィックの削減 予防 - トラフィックの削減 Service A Service B (Monolithic) 39
モノリシックなサービスをマイクロサービス に分割するよくある⼿順 1. 必要な機能をマイクロサービス として実装する 2. モノリシックなサービスで実装を削除し、新しいマイクロサービス へプロキシするだけにする 3. クライアントが新しいマイクロサービスへ直接アクセスするように呼び替える Service A Service B (Monolithic) Service C Service A Service C 1. モノリシック 2. 過渡期 (ロジックをService Cに切り出す) 3. 切り離し完了 この切り離しだけ後回しに されていることがある -
どのように無駄なトラフィックを探すか? 予防 - トラフィックの削減 40 Codeを読む or Code ownerに聞いていくしかない •
増設規模が⼤きいサービスのCode ownerに対して、重点的にダメ元で確認していく この変更のおかげで、250VM以上の増設を回避 Service A Service C 3. 切り離し完了 -
備えたこと 2022年のあけおめLINEに向けて 41 予防 検知 対処 • 以前の過負荷に対する個別対処 • 複数の方法を併用したアクセス数予測
• ボトルネックと1nodeあたりのキャパシティ確認 • トラフィックの削減 • サービスのコンテキストごとに担当者をアサイン • 専用のダッシュボード作成 • Playbook準備 • Priority load sheddingの運用の準備 -
モニタリング待機の人員をコンテキストごとに配置 検知 – サービスのコンテキストごとに担当者をアサイン ελϯϓܥ -*/&4503&ܥ ը૾৴ܥ 42 サービスのコンテキストごとに待機⼈員をアサイン 1.過負荷はコンテキスト内に影響が波及する
2.ひとつの過負荷で、全待機⼈員の稼働が奪われないようにする • 発⽣する障害は⼀つとは限らないため -
備えたこと 2022年のあけおめLINEに向けて 43 予防 検知 対処 • 以前の過負荷に対する個別対処 • 複数の方法を併用したアクセス数予測
• ボトルネックと1nodeあたりのキャパシティ確認 • トラフィックの削減 • サービスのコンテキストごとに担当者をアサイン • 専用のダッシュボード作成 • Playbook準備 • Priority load sheddingの運用の準備 -
サービスのコンテキストを意識した専用ダッシュボードの作成 • サービスのコンテキストを意識し、近いマイクロサービス をダッシュボード的にも近くに配置 • スタンプの送信関連 • リスティング関連 • 画像配信関連
• その他 検知 – 専用ダッシュボードの作成 44 -
Prometheusに負荷をかけすぎないように 検知 – 専用ダッシュボードの作成 45 GrafanaのPanel機能をサービスごとに利⽤ 1. パネルを閉じていれば、PrometheusにGrafanaからクエリを投げない 2. パネルの開閉を⾏えば、そのサービスだけリロード可能
安定してモニタリングできるように、 共有Prometheusに負荷をかけすぎないようにする -
サービスのコンテキストを意識した専用ダッシュボードの作成 検知 – 専用ダッシュボードの作成 46 Requests /sec / nodeグラフ 1.
スケールアウトできるシステムにおいて、total rpsはそこまで意味がない 2. すべてのノードに偏りなくアクセスされていることが確認できる -
備えたこと 2022年のあけおめLINEに向けて 47 予防 検知 対処 • 以前の過負荷に対する個別対処 • 複数の方法を併用したアクセス数予測
• ボトルネックと1nodeあたりのキャパシティ確認 • トラフィックの削減 • サービスのコンテキストごとに担当者をアサイン • 専用のダッシュボード作成 • Playbook準備 • Priority load sheddingの運用の準備 -
Playbookの事前準備 異常が起きた際に、何をするのかを記載したPlaybookを用意 検知 – Playbook準備 48 予測したアクセス数を超えた 安定して処理できるアクセス数を超えた 1. チーム内で状況共有
2. 安全マージンでカバーできるか注視 1. 社内の緊急連絡チャンネルで状況共有 2. 予定していた即時対処(後述)を実施 -
備えたこと 2022年のあけおめLINEに向けて 49 予防 検知 対処 • 以前の過負荷に対する個別対処 • 複数の方法を併用したアクセス数予測
• ボトルネックと1nodeあたりのキャパシティ確認 • トラフィックの削減 • サービスのコンテキストごとに担当者をアサイン • 専用のダッシュボード作成 • Playbook準備 • Priority load sheddingの運用の準備 -
Priority load sheddingの運用準備 対処 – Priority load sheddingの運用の準備 50 ⾼度なドメイン知識がないと即座に運⽤できなかった
1.どの機能・どのviewで、このAPIが利⽤されているか︖ 2.エラーにした際、どのようなUXになるか︖ • 別の機能にフォールバックする︖ • エラーメッセージが表⽰される︖ • リトライアブルになっている︖ Gateway serverでAPI単位のThrottling機能は存在する 効果的な運用のハードルが高かった -
開発環境でThrottlingするワークショップ • ステークホルダーが集まり、1時間のワークショップを実施 • APIをアクセス数が多い順に列挙 • 実際に開発環境でThrottlingして、動作確認 51 企画 開発
UIT 開発 Client- side QA こういうエラーハンドリング ができるかもしれない こういうエッジケースで問題 になると思います 最悪この機能は諦めましょう こっちは死守しましょう 対処 – Priority load sheddingの運用の準備 -
開発環境でThrottlingするワークショップ • ステークホルダーが集まり、1時間のワークショップを実施 • APIをアクセス数が多い順に列挙 • 実際に開発環境でThrottlingして、動作確認 52 企画 開発
UIT 開発 Client- side QA こういうエラーハンドリング ができるかもしれない こういうエッジケースで問題 になると思います 最悪この機能は諦めましょう こっちは死守しましょう 時間内にすべてのAPIを試す必要はなし アクセス数が多い順に確認して、できるところまで 対処 – Priority load sheddingの運用の準備 -
APIをLoad sheddingの優先度ごとに分類 対処 – Priority load sheddingの運用の準備 ユーザー影響\アクセス数 ্Ґ ্Ґ
ະຬ Ϣʔβʔ͕ؾ͔ͮͳ͍ ༏ઌɿߴ ༏ઌɿߴ ༏ઌɿߴ ؾ͕͘ɺக໋తͰͳ͍ ༏ઌɿத ༏ઌɿ ༏ઌɿ க໋తͳӨڹ /" /" /" 53 -
それぞれにかかったエンジニアリソース ֓ཁ ΤϯδχΞਓ ظؒ &MBTUJDTFBSDIEVBMDMVTUFS ʮ͚͓͋Ί-*/&ʯ͕ऴྃޙɺ͙͢ʹεέʔϧΠϯ͢͠ ͍Α͏ʹɺ$MVTUFSMFWFMͰεέʔϧΞτ͢Δ ਓ 4%& िؒ
(BUFXBZTFSWFSͷ+85 WFSJGJDBUJPOվળ MPDBMWFSJGJDBUJPOͰ$16ෛՙ͕ඇৗʹߴ͔ͬͨͨΊɺ 4FTTJPOTUPSFΛར༻ͨ͠SFNPUFWFSJGJDBUJPOʹมߋ ਓ 4%& $MJFOU िؒ ΞΫηε༧ଌ աڈͷσʔλ͔Βɺฏۉ $"(3 ͱฏ࣌ͷΞΫ ηεͷൺΛར༻ͯ͠ɺ༧ଌΛߦͬͨ ਓ 43& ؒ ແବͳτϥϑΟοΫͷݮ ϚΠΫϩαʔϏεԽͷྲྀΕͰɺͨͩϓϩΩγ͢Δ͚ͩʹ ͳ͍ͬͯͨॲཧΛআ ਓ 43& िؒ 55 全体の振り返り -
それぞれにかかったエンジニアリソース ֓ཁ ΤϯδχΞਓ ظؒ ϘτϧωοΫΛ$16ʹ͢Δ େྔʹ͋ΔϚΠΫϩαʔϏε ͷத͔ΒɺϘτϧωοΫ͕ $16ʹͳ͍ͬͯͳ͍αʔϏεΛ౷ܭతख๏Ͱൃݟͨ͠ ਓ 43&
ؒ ෛՙࢼݧʹΑΔΩϟύγςΟ֬ೝ ࣮ࡍʹϢʔβʔͷϦΫΤετΛར༻ͨ͠ΩϟύγςΟ֬ ೝͷͨΊͷෛՙࢼݧΛ࣮ࢪͨ͠ ਓ 43& िؒ 1SJPSJUZMPBETIFEEJOHͷ४උ "1*͝ͱʹϢʔβʔΠϯύΫτͱෛՙͷΠϯύΫτΛ ֬ೝ͠ɺ5ISPUUMJOH͢ΔͨΊͷ༏ઌॱҐΛܾΊΔϫʔΫ γϣοϓΛ։࠵ͨ͠ ਓ 43& 4%& ؒ ઐ༻μογϡϘʔυͷ࡞ͱػ ਓһͷΞαΠϯ αʔϏεͷίϯςΩετΛҙࣝͨ͠μογϡϘʔυΛ࡞ ͠ɺίϯςΩετ͝ͱʹػਓһΛΞαΠϯͨ͠ ਓ 43& ؒ 56 全体の振り返り -
特に実施してよかった準備 1. Priority load sheddingのためのワークショップ • 障害発生を前提とした対策ができて、非常に有意義でした • 好評だったため、今後も半期や四半期ごとに定期開催する予定です 2.
統計的処理を用いたチューニング余地のあるマイクロサービス検出 • マイクロサービスの数が増えてもスケールする手法で、リーズナブルでした 3. Elasticsearch dual cluster • 負荷対策だけでなく、バージョンアップなどにも今後利用していく予定です 上記は特に「あけおめLINE」を契機でしたが、それ以外にも役に立つ準備でした。 また、来年の「あけおめLINE」もユーザーの信頼を損なわないように準備していきます。 全体の振り返り 57