Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The burst of New Year greeting on LINE Sticker

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
*本人の都合・判断で、クローズする場合やリクエストに対応できない場合もあります。予めご了承ください。

A3966f193f4bef226a0d3e3c1f728d7f?s=128

LINE Developers
PRO

March 12, 2022
Tweet

More Decks by LINE Developers

Other Decks in Technology

Transcript

  1. ໿ഒͷεύΠΫʹඋ͑ΔऔΓ૊Έ -*/&ελϯϓͷ͚͓͋Ί-*/& ࣾ߹ಉ 43&ษڧձ -*/&גࣜձࣾ 43&5FDI-FBE Ճ౻ ढ़໻ !NBSVMPPQ

  2. 発表概要 • 約9倍のスパイクを過負荷なしに処理するための準備を紹介します • 50を超えるマイクロサービスで構成されたアーキテクチャ • 2022年のあけおめLINEは障害なしで乗り越えることができました • 前年・前々年より大きなアクセス数を、サーバーリソースを3割以上削減した上で処理しました 2

  3. チーム構成 3

  4. スタンプ関連の組織 チーム構成 開発 Server-side 約25名 企画 運営 開発 UIT Design

    開発 Client-side QA Embedded SRE 4
  5. Pure SRE と Embedded SRE チーム構成 ༧๷ ࣏ྍ ࣾ಺ඪ४ͷ πʔϧఏڙ

    0O$BMMରԠ ඪ४πʔϧͷಋೖ ಠࣗπʔϧ։ൃ ͦͷଞվળ શࣾԣஅ αʔϏεݻ༗ Use Feedback 開発 Server-side 約25名 Embedded SRE Pure SRE 5
  6. Pure SRE と Embedded SRE チーム構成 ༧๷ ࣏ྍ ࣾ಺ඪ४ͷ πʔϧఏڙ

    0O$BMMରԠ ಠࣗπʔϧ։ൃ νϡʔχϯά શࣾԣஅ αʔϏεݻ༗ Use Feedback PR 開発 Server-side 約25名 Embedded SRE Pure SRE 6
  7. システム概要 7

  8. LINEスタンプのシステムが提供している主な機能 提供者向け(公式・クリエイター) • 商品の登録・修正 利用者向け • 検索・レコメンドなどのリスティング • 購入・ダウンロード •

    スタンプの送受信 システム概要 Microservice Architectureで実装 8
  9. 検索 & レコメンド システム概要 API gateway Web site rendering Home

    Contents Server Recommend system Search server 9 SSG rest api to thrift rpc
  10. スタンプ送信 システム概要 Talk server Capability server Open Chat MySQL MongoDB

    10
  11. スタンプの受信 システム概要 Akamai Image-server MySQL CloudFront Object Storage MongoDB 11

    check publishable
  12. システム全体 システム概要 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 検索やレコメンド スタンプ送信 スタンプ画像取得
  13. 基本的な負荷対策の紹介 「あけおめLINE」対策の紹介の前に パフォーマンスのために⽇頃から⾏っていることを紹介 13

  14. 各マイクロサービスでの基本的な実装 基本的な高負荷対応の実装 • RxJavaとArmeriaを使って、ノンブロッキングな実装 • 特定の処理が遅くなっても、他のAPIが影響を受けにくくする • システム間通信はThrift RPC +

    Client-side LB • Client-side LBでサーキットブレイカー、モニタリングなどの機能を注入 • ローカルとリモートでの多段キャッシュ • Hot keyによるRedis高負荷対策や低レイテンシのために • Caffeine(Javaライブラリ)を利用したローカルキャッシュ • Redisを用いたリモートキャッシュ 14
  15. Gateway serverでの実装 基本的な高負荷対応の実装 • API単位のThrottling機能 • 特定のAPIの成功/失敗を割合で設定可能 • 各マイクロサービス で安易に実施すると、リトライによる連鎖障害リスクがあるため、Gatewayで実施

    API gateway Service A Service B Service C 15
  16. あけおめLINEについて 16

  17. あけおめLINE自体の特徴 • 短時間で一気にスパイクする • スタンプの送信数が1分前の約9倍になる • 数時間の売上が急伸する • 年に1回きりのイベント •

    今年ローンチした新機能は十分なデータの蓄積がない • 実装やアーキテクチャの変更に伴う負荷の変化を把握するのは難しい あけおめLINEについて 17
  18. あけおめLINE自体の特徴 • 1時間ごとにピークがある • LINEはアジア圏を中心に複数の国と地域でサービスを提供している • 日本(UTC+9)→台湾(UTC+8)→タイ(UTC+7)と負荷が累積する あけおめLINEについて UTC+7 UTC+8

    UTC+9 18
  19. 2021年(前年)元旦のスタンプ過負荷 19

  20. スタンプキーボードでの機能追加に起因 • スタンプキーボードの最下部に、同じ作者の最新スタンプを表示するようにした • このデータはキャッシュされておらず、毎回Elasticsearchに貫通 • 普段、スタンプ送信はバーストしないため、サーバーサイドで気付くことが出来ず • 「あけおめLINE」のタイミングでバーストしてElasticsearchが過負荷へ... 2021年元旦のスタンプ過負荷

    下までスクロール 現在は、このデータが取得できなくても、 スタンプ送信に影響がないように修正済み。 20
  21. 2022年のあけおめLINEに向けて 21

  22. あけおめLINEの難しさ = 把握・予測の難しさ • アクセス見積もり • 前年・前々年の障害によるアクセス需要データの不足 • 新規機能はそもそもデータがない •

    様々なキャンペーンにより、ユーザー行動も平時とは大きく異なる • パフォーマンスキャパシティの変化 • 1年間に蓄積された全ての変更の影響度を把握するのは難しい 2022年のあけおめLINEに向けて 22
  23. 備えたこと 2022年のあけおめLINEに向けて 23 予防 検知 対処 • 以前の過負荷に対する個別対処 • 複数の方法を併用したアクセス数予測

    • ボトルネックと1nodeあたりのキャパシティ確認 • トラフィックの削減 • サービスのコンテキストごとに担当者をアサイン • 専用のダッシュボード作成 • Playbook準備 • Priority load sheddingの運用の準備
  24. 備えたこと 2022年のあけおめLINEに向けて 24 予防 検知 対処 • 以前の過負荷に対する個別対処 • 複数の方法を併用したアクセス数予測

    • ボトルネックと1nodeあたりのキャパシティ確認 • トラフィックの削減 • サービスのコンテキストごとに担当者をアサイン • 専用のダッシュボード作成 • Playbook準備 • Priority load sheddingの運用の準備
  25. Elasticsearch dual cluster • 2021年のElasticsearchの過負荷への予防策 • もちろん、キャッシュ追加やクライアントサイドの変更も実施済み • コストのため、「あけおめLINE」が終わり次第、スケールインしたい 予防

    - 以前の過負荷に対する個別対処 MongoDB MySQL indexer Search-server select indexing search 25
  26. Elasticsearch dual cluster • バッチでElasticsearchにindexingしているアーキテクチャだった • クラスタレベルでスケールアウトすることに 予防 - 以前の過負荷に対する個別対処

    MongoDB MySQL indexer Search-server select indexing search w/ round robin indexer 26
  27. Gateway serverの過負荷分析 • 2021年の「あけおめLINE」時、Elasticsearchだけでなく、Gateway serverも過負荷になった • Async-profilerを使って、ボトルネックを分析 • 原因はJWT local

    verificationだったため、Session storeを利用したremote verificationへ変更 予防 - 以前の過負荷に対する個別対処 27
  28. 備えたこと 2022年のあけおめLINEに向けて 28 予防 検知 対処 • 以前の過負荷に対する個別対処 • 複数の方法を併用したアクセス数予測

    • ボトルネックと1nodeあたりのキャパシティ確認 • トラフィックの削減 • サービスのコンテキストごとに担当者をアサイン • 専用のダッシュボード作成 • Playbook準備 • Priority load sheddingの運用の準備
  29. 2つの予測方法の最大値利用 データが不十分だったり、信頼できないものがあったため、2つの予測方法を併用 「予測を当てること」ではなく、「過負荷を防ぐこと」が目的なため、最大値を予測値として利用。 予防 - 複数の方法を併用したアクセス数予測 CAGR(年平均成⻑率) 売上の予測などでしばしば使われる。キャンペーンや障害などで上振れや下振れがあっても、多少吸収できる。 最低2年分の元旦のデータがあれば良く、その場合は元旦のアクセス数の等⽐数列の⼀般項の計算結果と同じ。 通常時のアクセス数の前年⽐を成⻑率とみなす

    前年と今年の10⽉第⼆⽔曜⽇のアクセス数の⽐率を、去年の元旦のアクセス数に掛ける。 元旦に障害やキャンペーンで⼤きな上振れや下振れがないことが前提。 29
  30. CAGR(年平均成長率)の説明 CAGR(年平均成長率)compound average growth rate. CAGR(年平均成長率)とは、複数年にわたる成長率から、1年あたりの幾何平均を求めたもの。 毎年の成長率に上振れ・下振れがあっても、多少吸収してくれる。 予防 - 複数の方法を併用したアクセス数予測

    30 CAGR: +44% +74% +46% +17%
  31. 通常時のアクセス数の前年比を成長率とする 前年と今年の10月第二水曜日のピークアクセス数の比率を計算。 この比率を成長率とみなし、前年の元旦のアクセス数に掛ける。 前年のアクセス数が信頼できないと、予測不可。 予防 - 複数の方法を併用したアクセス数予測 31 2020年 2021年

    2022年 1000rps 2500rps 5000rps 2000rps 4500rps ???rps x2.5 x2 Weekday on Oct NY’s Day
  32. アクセス数予測値の決定 予防 - 複数の方法を併用したアクセス数予測 32 予測値あり 予測不可 予測値あり MAX(A,B) B

    予測不可 A コンテキストの近いマイクロサービス の 予測値を参考 (B). CAGR (A). 通常時アクセス数の前年比
  33. 安全マージンの積み方を調整 予測精度に自信があるサービス • CPU使用率が最大70%になるように増設 • 基準の例: • CAGRと通常時比での予測誤差が5%以内 • その他懸念がない

    予測精度に不安があるサービス • CPU使用率が最大50%になるように増設 • 基準の例: • 前年に障害があって不安 • なんか「匂う」 33 予防 - 複数の方法を併用したアクセス数予測
  34. 備えたこと 2022年のあけおめLINEに向けて 34 予防 検知 対処 • 以前の過負荷に対する個別対処 • 複数の方法を併用したアクセス数予測

    • ボトルネックと1nodeあたりのキャパシティ確認 • トラフィックの削減 • サービスのコンテキストごとに担当者をアサイン • 専用のダッシュボード作成 • Playbook準備 • Priority load sheddingの運用の準備
  35. ボトルネックを確認するのではなく、デザインする 予防 - ボトルネックと1nodeあたりのキャパシティ確認 35 CPUをボトルネックにする • CPUがボトルネックであれば、スケールアウトで線形に拡張できる • エンジニアリソース的に、すべてのマイクロサービスを分析しきれない...

    スミルノフ・グラブス検定で、CPU利用率の外れ値を探す 外れ値のマイクロサービス から優先して深堀調査 正規分布を前提に、再帰的に実施して複数の外れ値を見つけることができる スミルノフ・グラブス検定を利用した。 ※正規性の確認には注意が必要 今回の用途では、仮に正規性がなく、外れ値が多く検出されたとしても 深堀調査する対象マイクロサービスが増えるだけで、全量調査よりマシなため利用
  36. 統計的な処理で外れ値のマイクロサービスを探す 予防 - ボトルネックと1nodeあたりのキャパシティ確認 36 ϦΫΤετ਺૿Ճྔ NBYNJO $16ར༻཰૿Ճྔ NBYNJO ϦΫΤετ૿Ճྔ

     $16૿Ճྔ 4FSWJDF"    4FSWJDF#    4FSWJDF$    4FSWJDF%    4FSWJDF ʜ ʜ ʜ この数値を使って、スミルノフ・グラブス検定 各サービスごとにリクエスト の最大と最小の比率を計算 リクエスト最大と最小時の CPU利用率の比率を計算 Heap memoryが枯渇して、GC頻度が高くなり、 リクエスト増加率以上に、CPU利用率が高くなるService Bが見つかった Heap memoryをscale-upして解決
  37. 実際のユーザーアクセスを利用した負荷試験 37 LB Server 1 Server 2 Server 3 Server

    4 Server 5 Server 6 重要なサービスでは負荷試験も実施 • 負荷試験の準備が⼤変で、複数のマイクロサービス をやるリソースがない • サーバーをScale-inして、負荷を特定のノードに偏らせる⽅法で実施 • エラー率やレイテンシを確認 • CPUが70%以上使い切れていればOK • 簡単にできるチューニング箇所が⾒つかれば、"ついで”に実施 予防 - ボトルネックと1nodeあたりのキャパシティ確認
  38. 備えたこと 2022年のあけおめLINEに向けて 38 予防 検知 対処 • 以前の過負荷に対する個別対処 • 複数の方法を併用したアクセス数予測

    • ボトルネックと1nodeあたりのキャパシティ確認 • トラフィックの削減 • サービスのコンテキストごとに担当者をアサイン • 専用のダッシュボード作成 • Playbook準備 • Priority load sheddingの運用の準備
  39. マイクロサービス化に伴う無駄なトラフィックの削減 予防 - トラフィックの削減 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. どのように無駄なトラフィックを探すか? 予防 - トラフィックの削減 40 Codeを読む or Code ownerに聞いていくしかない •

    増設規模が⼤きいサービスのCode ownerに対して、重点的にダメ元で確認していく この変更のおかげで、250VM以上の増設を回避 Service A Service C 3. 切り離し完了
  41. 備えたこと 2022年のあけおめLINEに向けて 41 予防 検知 対処 • 以前の過負荷に対する個別対処 • 複数の方法を併用したアクセス数予測

    • ボトルネックと1nodeあたりのキャパシティ確認 • トラフィックの削減 • サービスのコンテキストごとに担当者をアサイン • 専用のダッシュボード作成 • Playbook準備 • Priority load sheddingの運用の準備
  42. モニタリング待機の人員をコンテキストごとに配置 検知 – サービスのコンテキストごとに担当者をアサイン ελϯϓܥ -*/&4503&ܥ ը૾഑৴ܥ 42 サービスのコンテキストごとに待機⼈員をアサイン 1.過負荷はコンテキスト内に影響が波及する

    2.ひとつの過負荷で、全待機⼈員の稼働が奪われないようにする • 発⽣する障害は⼀つとは限らないため
  43. 備えたこと 2022年のあけおめLINEに向けて 43 予防 検知 対処 • 以前の過負荷に対する個別対処 • 複数の方法を併用したアクセス数予測

    • ボトルネックと1nodeあたりのキャパシティ確認 • トラフィックの削減 • サービスのコンテキストごとに担当者をアサイン • 専用のダッシュボード作成 • Playbook準備 • Priority load sheddingの運用の準備
  44. サービスのコンテキストを意識した専用ダッシュボードの作成 • サービスのコンテキストを意識し、近いマイクロサービス をダッシュボード的にも近くに配置 • スタンプの送信関連 • リスティング関連 • 画像配信関連

    • その他 検知 – 専用ダッシュボードの作成 44
  45. Prometheusに負荷をかけすぎないように 検知 – 専用ダッシュボードの作成 45 GrafanaのPanel機能をサービスごとに利⽤ 1. パネルを閉じていれば、PrometheusにGrafanaからクエリを投げない 2. パネルの開閉を⾏えば、そのサービスだけリロード可能

    安定してモニタリングできるように、 共有Prometheusに負荷をかけすぎないようにする
  46. サービスのコンテキストを意識した専用ダッシュボードの作成 検知 – 専用ダッシュボードの作成 46 Requests /sec / nodeグラフ 1.

    スケールアウトできるシステムにおいて、total rpsはそこまで意味がない 2. すべてのノードに偏りなくアクセスされていることが確認できる
  47. 備えたこと 2022年のあけおめLINEに向けて 47 予防 検知 対処 • 以前の過負荷に対する個別対処 • 複数の方法を併用したアクセス数予測

    • ボトルネックと1nodeあたりのキャパシティ確認 • トラフィックの削減 • サービスのコンテキストごとに担当者をアサイン • 専用のダッシュボード作成 • Playbook準備 • Priority load sheddingの運用の準備
  48. Playbookの事前準備 異常が起きた際に、何をするのかを記載したPlaybookを用意 検知 – Playbook準備 48 予測したアクセス数を超えた 安定して処理できるアクセス数を超えた 1. チーム内で状況共有

    2. 安全マージンでカバーできるか注視 1. 社内の緊急連絡チャンネルで状況共有 2. 予定していた即時対処(後述)を実施
  49. 備えたこと 2022年のあけおめLINEに向けて 49 予防 検知 対処 • 以前の過負荷に対する個別対処 • 複数の方法を併用したアクセス数予測

    • ボトルネックと1nodeあたりのキャパシティ確認 • トラフィックの削減 • サービスのコンテキストごとに担当者をアサイン • 専用のダッシュボード作成 • Playbook準備 • Priority load sheddingの運用の準備
  50. Priority load sheddingの運用準備 対処 – Priority load sheddingの運用の準備 50 ⾼度なドメイン知識がないと即座に運⽤できなかった

    1.どの機能・どのviewで、このAPIが利⽤されているか︖ 2.エラーにした際、どのようなUXになるか︖ • 別の機能にフォールバックする︖ • エラーメッセージが表⽰される︖ • リトライアブルになっている︖ Gateway serverでAPI単位のThrottling機能は存在する 効果的な運用のハードルが高かった
  51. 開発環境でThrottlingするワークショップ • ステークホルダーが集まり、1時間のワークショップを実施 • APIをアクセス数が多い順に列挙 • 実際に開発環境でThrottlingして、動作確認 51 企画 開発

    UIT 開発 Client- side QA こういうエラーハンドリング ができるかもしれない こういうエッジケースで問題 になると思います 最悪この機能は諦めましょう こっちは死守しましょう 対処 – Priority load sheddingの運用の準備
  52. 開発環境でThrottlingするワークショップ • ステークホルダーが集まり、1時間のワークショップを実施 • APIをアクセス数が多い順に列挙 • 実際に開発環境でThrottlingして、動作確認 52 企画 開発

    UIT 開発 Client- side QA こういうエラーハンドリング ができるかもしれない こういうエッジケースで問題 になると思います 最悪この機能は諦めましょう こっちは死守しましょう 時間内にすべてのAPIを試す必要はなし アクセス数が多い順に確認して、できるところまで 対処 – Priority load sheddingの運用の準備
  53. APIをLoad sheddingの優先度ごとに分類 対処 – Priority load sheddingの運用の準備 ユーザー影響\アクセス数 ্Ґ ্Ґ

    ະຬ Ϣʔβʔ͕ؾ͔ͮͳ͍ ༏ઌ౓ɿߴ ༏ઌ౓ɿߴ ༏ઌ౓ɿߴ ؾ෇͕͘ɺக໋తͰ͸ͳ͍ ༏ઌ౓ɿத ༏ઌ౓ɿ௿ ༏ઌ౓ɿ௿ க໋తͳӨڹ /" /" /" 53
  54. 全体の振り返り 54

  55. それぞれにかかったエンジニアリソース ֓ཁ ΤϯδχΞਓ਺ ظؒ &MBTUJDTFBSDIEVBMDMVTUFS ʮ͚͓͋Ί-*/&ʯ͕ऴྃޙɺ͙͢ʹεέʔϧΠϯ͠΍͢ ͍Α͏ʹɺ$MVTUFSMFWFMͰεέʔϧΞ΢τ͢Δ ਓ 4%& िؒ

    (BUFXBZTFSWFSͷ+85 WFSJGJDBUJPOվળ MPDBMWFSJGJDBUJPOͰ$16ෛՙ͕ඇৗʹߴ͔ͬͨͨΊɺ 4FTTJPOTUPSFΛར༻ͨ͠SFNPUFWFSJGJDBUJPOʹมߋ ਓ 4%& $MJFOU िؒ ΞΫηε਺༧ଌ աڈͷσʔλ͔Βɺ೥ฏۉ੒௕཰ $"(3 ͱฏ࣌ͷΞΫ ηε਺ͷൺ཰Λར༻ͯ͠ɺ༧ଌΛߦͬͨ ਓ 43& ೔ؒ ແବͳτϥϑΟοΫͷ࡟ݮ ϚΠΫϩαʔϏεԽͷྲྀΕͰɺͨͩϓϩΩγ͢Δ͚ͩʹ ͳ͍ͬͯͨॲཧΛ࡟আ ਓ 43& िؒ 55 全体の振り返り
  56. それぞれにかかったエンジニアリソース ֓ཁ ΤϯδχΞਓ਺ ظؒ ϘτϧωοΫΛ$16ʹ͢Δ େྔʹ͋ΔϚΠΫϩαʔϏε ͷத͔ΒɺϘτϧωοΫ͕ $16ʹͳ͍ͬͯͳ͍αʔϏεΛ౷ܭతख๏Ͱൃݟͨ͠ ਓ 43&

    ೔ؒ ෛՙࢼݧʹΑΔΩϟύγςΟ֬ೝ ࣮ࡍʹϢʔβʔͷϦΫΤετΛར༻ͨ͠ΩϟύγςΟ֬ ೝͷͨΊͷෛՙࢼݧΛ࣮ࢪͨ͠ ਓ 43& िؒ 1SJPSJUZMPBETIFEEJOHͷ४උ "1*͝ͱʹϢʔβʔΠϯύΫτͱෛՙ΁ͷΠϯύΫτΛ ֬ೝ͠ɺ5ISPUUMJOH͢ΔͨΊͷ༏ઌॱҐΛܾΊΔϫʔΫ γϣοϓΛ։࠵ͨ͠ ਓ 43& 4%& ೔ؒ ઐ༻μογϡϘʔυͷ࡞੒ͱ଴ػ ਓһͷΞαΠϯ αʔϏεͷίϯςΩετΛҙࣝͨ͠μογϡϘʔυΛ࡞ ੒͠ɺίϯςΩετ͝ͱʹ଴ػਓһΛΞαΠϯͨ͠ ਓ 43& ೔ؒ 56 全体の振り返り
  57. 特に実施してよかった準備 1. Priority load sheddingのためのワークショップ • 障害発生を前提とした対策ができて、非常に有意義でした • 好評だったため、今後も半期や四半期ごとに定期開催する予定です 2.

    統計的処理を用いたチューニング余地のあるマイクロサービス検出 • マイクロサービスの数が増えてもスケールする手法で、リーズナブルでした 3. Elasticsearch dual cluster • 負荷対策だけでなく、バージョンアップなどにも今後利用していく予定です 上記は特に「あけおめLINE」を契機でしたが、それ以外にも役に立つ準備でした。 また、来年の「あけおめLINE」もユーザーの信頼を損なわないように準備していきます。 全体の振り返り 57
  58. Thank you!! 58