Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

チーム構成 3

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

Pure SRE と Embedded SRE チーム構成 ༧๷ ࣏ྍ ࣾ಺ඪ४ͷ πʔϧఏڙ 0O$BMMରԠ ಠࣗπʔϧ։ൃ νϡʔχϯά શࣾԣஅ αʔϏεݻ༗ Use Feedback PR 開発 Server-side 約25名 Embedded SRE Pure SRE 6

Slide 7

Slide 7 text

システム概要 7

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

検索 & レコメンド システム概要 API gateway Web site rendering Home Contents Server Recommend system Search server 9 SSG rest api to thrift rpc

Slide 10

Slide 10 text

スタンプ送信 システム概要 Talk server Capability server Open Chat MySQL MongoDB 10

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

システム全体 システム概要 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 検索やレコメンド スタンプ送信 スタンプ画像取得

Slide 13

Slide 13 text

基本的な負荷対策の紹介 「あけおめLINE」対策の紹介の前に パフォーマンスのために⽇頃から⾏っていることを紹介 13

Slide 14

Slide 14 text

各マイクロサービスでの基本的な実装 基本的な高負荷対応の実装 • RxJavaとArmeriaを使って、ノンブロッキングな実装 • 特定の処理が遅くなっても、他のAPIが影響を受けにくくする • システム間通信はThrift RPC + Client-side LB • Client-side LBでサーキットブレイカー、モニタリングなどの機能を注入 • ローカルとリモートでの多段キャッシュ • Hot keyによるRedis高負荷対策や低レイテンシのために • Caffeine(Javaライブラリ)を利用したローカルキャッシュ • Redisを用いたリモートキャッシュ 14

Slide 15

Slide 15 text

Gateway serverでの実装 基本的な高負荷対応の実装 • API単位のThrottling機能 • 特定のAPIの成功/失敗を割合で設定可能 • 各マイクロサービス で安易に実施すると、リトライによる連鎖障害リスクがあるため、Gatewayで実施 API gateway Service A Service B Service C 15

Slide 16

Slide 16 text

あけおめLINEについて 16

Slide 17

Slide 17 text

あけおめLINE自体の特徴 • 短時間で一気にスパイクする • スタンプの送信数が1分前の約9倍になる • 数時間の売上が急伸する • 年に1回きりのイベント • 今年ローンチした新機能は十分なデータの蓄積がない • 実装やアーキテクチャの変更に伴う負荷の変化を把握するのは難しい あけおめLINEについて 17

Slide 18

Slide 18 text

あけおめLINE自体の特徴 • 1時間ごとにピークがある • LINEはアジア圏を中心に複数の国と地域でサービスを提供している • 日本(UTC+9)→台湾(UTC+8)→タイ(UTC+7)と負荷が累積する あけおめLINEについて UTC+7 UTC+8 UTC+9 18

Slide 19

Slide 19 text

2021年(前年)元旦のスタンプ過負荷 19

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

2022年のあけおめLINEに向けて 21

Slide 22

Slide 22 text

あけおめLINEの難しさ = 把握・予測の難しさ • アクセス見積もり • 前年・前々年の障害によるアクセス需要データの不足 • 新規機能はそもそもデータがない • 様々なキャンペーンにより、ユーザー行動も平時とは大きく異なる • パフォーマンスキャパシティの変化 • 1年間に蓄積された全ての変更の影響度を把握するのは難しい 2022年のあけおめLINEに向けて 22

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

Elasticsearch dual cluster • 2021年のElasticsearchの過負荷への予防策 • もちろん、キャッシュ追加やクライアントサイドの変更も実施済み • コストのため、「あけおめLINE」が終わり次第、スケールインしたい 予防 - 以前の過負荷に対する個別対処 MongoDB MySQL indexer Search-server select indexing search 25

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

Gateway serverの過負荷分析 • 2021年の「あけおめLINE」時、Elasticsearchだけでなく、Gateway serverも過負荷になった • Async-profilerを使って、ボトルネックを分析 • 原因はJWT local verificationだったため、Session storeを利用したremote verificationへ変更 予防 - 以前の過負荷に対する個別対処 27

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

2つの予測方法の最大値利用 データが不十分だったり、信頼できないものがあったため、2つの予測方法を併用 「予測を当てること」ではなく、「過負荷を防ぐこと」が目的なため、最大値を予測値として利用。 予防 - 複数の方法を併用したアクセス数予測 CAGR(年平均成⻑率) 売上の予測などでしばしば使われる。キャンペーンや障害などで上振れや下振れがあっても、多少吸収できる。 最低2年分の元旦のデータがあれば良く、その場合は元旦のアクセス数の等⽐数列の⼀般項の計算結果と同じ。 通常時のアクセス数の前年⽐を成⻑率とみなす 前年と今年の10⽉第⼆⽔曜⽇のアクセス数の⽐率を、去年の元旦のアクセス数に掛ける。 元旦に障害やキャンペーンで⼤きな上振れや下振れがないことが前提。 29

Slide 30

Slide 30 text

CAGR(年平均成長率)の説明 CAGR(年平均成長率)compound average growth rate. CAGR(年平均成長率)とは、複数年にわたる成長率から、1年あたりの幾何平均を求めたもの。 毎年の成長率に上振れ・下振れがあっても、多少吸収してくれる。 予防 - 複数の方法を併用したアクセス数予測 30 CAGR: +44% +74% +46% +17%

Slide 31

Slide 31 text

通常時のアクセス数の前年比を成長率とする 前年と今年の10月第二水曜日のピークアクセス数の比率を計算。 この比率を成長率とみなし、前年の元旦のアクセス数に掛ける。 前年のアクセス数が信頼できないと、予測不可。 予防 - 複数の方法を併用したアクセス数予測 31 2020年 2021年 2022年 1000rps 2500rps 5000rps 2000rps 4500rps ???rps x2.5 x2 Weekday on Oct NY’s Day

Slide 32

Slide 32 text

アクセス数予測値の決定 予防 - 複数の方法を併用したアクセス数予測 32 予測値あり 予測不可 予測値あり MAX(A,B) B 予測不可 A コンテキストの近いマイクロサービス の 予測値を参考 (B). CAGR (A). 通常時アクセス数の前年比

Slide 33

Slide 33 text

安全マージンの積み方を調整 予測精度に自信があるサービス • CPU使用率が最大70%になるように増設 • 基準の例: • CAGRと通常時比での予測誤差が5%以内 • その他懸念がない 予測精度に不安があるサービス • CPU使用率が最大50%になるように増設 • 基準の例: • 前年に障害があって不安 • なんか「匂う」 33 予防 - 複数の方法を併用したアクセス数予測

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

ボトルネックを確認するのではなく、デザインする 予防 - ボトルネックと1nodeあたりのキャパシティ確認 35 CPUをボトルネックにする • CPUがボトルネックであれば、スケールアウトで線形に拡張できる • エンジニアリソース的に、すべてのマイクロサービスを分析しきれない... スミルノフ・グラブス検定で、CPU利用率の外れ値を探す 外れ値のマイクロサービス から優先して深堀調査 正規分布を前提に、再帰的に実施して複数の外れ値を見つけることができる スミルノフ・グラブス検定を利用した。 ※正規性の確認には注意が必要 今回の用途では、仮に正規性がなく、外れ値が多く検出されたとしても 深堀調査する対象マイクロサービスが増えるだけで、全量調査よりマシなため利用

Slide 36

Slide 36 text

統計的な処理で外れ値のマイクロサービスを探す 予防 - ボトルネックと1nodeあたりのキャパシティ確認 36 ϦΫΤετ਺૿Ճྔ NBYNJO $16ར༻཰૿Ճྔ NBYNJO ϦΫΤετ૿Ճྔ $16૿Ճྔ 4FSWJDF" 4FSWJDF# 4FSWJDF$ 4FSWJDF% 4FSWJDF ʜ ʜ ʜ この数値を使って、スミルノフ・グラブス検定 各サービスごとにリクエスト の最大と最小の比率を計算 リクエスト最大と最小時の CPU利用率の比率を計算 Heap memoryが枯渇して、GC頻度が高くなり、 リクエスト増加率以上に、CPU利用率が高くなるService Bが見つかった Heap memoryをscale-upして解決

Slide 37

Slide 37 text

実際のユーザーアクセスを利用した負荷試験 37 LB Server 1 Server 2 Server 3 Server 4 Server 5 Server 6 重要なサービスでは負荷試験も実施 • 負荷試験の準備が⼤変で、複数のマイクロサービス をやるリソースがない • サーバーをScale-inして、負荷を特定のノードに偏らせる⽅法で実施 • エラー率やレイテンシを確認 • CPUが70%以上使い切れていればOK • 簡単にできるチューニング箇所が⾒つかれば、"ついで”に実施 予防 - ボトルネックと1nodeあたりのキャパシティ確認

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

マイクロサービス化に伴う無駄なトラフィックの削減 予防 - トラフィックの削減 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. 切り離し完了 この切り離しだけ後回しに されていることがある

Slide 40

Slide 40 text

どのように無駄なトラフィックを探すか? 予防 - トラフィックの削減 40 Codeを読む or Code ownerに聞いていくしかない • 増設規模が⼤きいサービスのCode ownerに対して、重点的にダメ元で確認していく この変更のおかげで、250VM以上の増設を回避 Service A Service C 3. 切り離し完了

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

モニタリング待機の人員をコンテキストごとに配置 検知 – サービスのコンテキストごとに担当者をアサイン ελϯϓܥ -*/&4503&ܥ ը૾഑৴ܥ 42 サービスのコンテキストごとに待機⼈員をアサイン 1.過負荷はコンテキスト内に影響が波及する 2.ひとつの過負荷で、全待機⼈員の稼働が奪われないようにする • 発⽣する障害は⼀つとは限らないため

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

サービスのコンテキストを意識した専用ダッシュボードの作成 • サービスのコンテキストを意識し、近いマイクロサービス をダッシュボード的にも近くに配置 • スタンプの送信関連 • リスティング関連 • 画像配信関連 • その他 検知 – 専用ダッシュボードの作成 44

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

サービスのコンテキストを意識した専用ダッシュボードの作成 検知 – 専用ダッシュボードの作成 46 Requests /sec / nodeグラフ 1. スケールアウトできるシステムにおいて、total rpsはそこまで意味がない 2. すべてのノードに偏りなくアクセスされていることが確認できる

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

Playbookの事前準備 異常が起きた際に、何をするのかを記載したPlaybookを用意 検知 – Playbook準備 48 予測したアクセス数を超えた 安定して処理できるアクセス数を超えた 1. チーム内で状況共有 2. 安全マージンでカバーできるか注視 1. 社内の緊急連絡チャンネルで状況共有 2. 予定していた即時対処(後述)を実施

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

Priority load sheddingの運用準備 対処 – Priority load sheddingの運用の準備 50 ⾼度なドメイン知識がないと即座に運⽤できなかった 1.どの機能・どのviewで、このAPIが利⽤されているか︖ 2.エラーにした際、どのようなUXになるか︖ • 別の機能にフォールバックする︖ • エラーメッセージが表⽰される︖ • リトライアブルになっている︖ Gateway serverでAPI単位のThrottling機能は存在する 効果的な運用のハードルが高かった

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

APIをLoad sheddingの優先度ごとに分類 対処 – Priority load sheddingの運用の準備 ユーザー影響\アクセス数 ্Ґ ্Ґ ະຬ Ϣʔβʔ͕ؾ͔ͮͳ͍ ༏ઌ౓ɿߴ ༏ઌ౓ɿߴ ༏ઌ౓ɿߴ ؾ෇͕͘ɺக໋తͰ͸ͳ͍ ༏ઌ౓ɿத ༏ઌ౓ɿ௿ ༏ઌ౓ɿ௿ க໋తͳӨڹ /" /" /" 53

Slide 54

Slide 54 text

全体の振り返り 54

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

それぞれにかかったエンジニアリソース ֓ཁ ΤϯδχΞਓ਺ ظؒ ϘτϧωοΫΛ$16ʹ͢Δ େྔʹ͋ΔϚΠΫϩαʔϏε ͷத͔ΒɺϘτϧωοΫ͕ $16ʹͳ͍ͬͯͳ͍αʔϏεΛ౷ܭతख๏Ͱൃݟͨ͠ ਓ 43& ೔ؒ ෛՙࢼݧʹΑΔΩϟύγςΟ֬ೝ ࣮ࡍʹϢʔβʔͷϦΫΤετΛར༻ͨ͠ΩϟύγςΟ֬ ೝͷͨΊͷෛՙࢼݧΛ࣮ࢪͨ͠ ਓ 43& िؒ 1SJPSJUZMPBETIFEEJOHͷ४උ "1*͝ͱʹϢʔβʔΠϯύΫτͱෛՙ΁ͷΠϯύΫτΛ ֬ೝ͠ɺ5ISPUUMJOH͢ΔͨΊͷ༏ઌॱҐΛܾΊΔϫʔΫ γϣοϓΛ։࠵ͨ͠ ਓ 43&4%& ೔ؒ ઐ༻μογϡϘʔυͷ࡞੒ͱ଴ػ ਓһͷΞαΠϯ αʔϏεͷίϯςΩετΛҙࣝͨ͠μογϡϘʔυΛ࡞ ੒͠ɺίϯςΩετ͝ͱʹ଴ػਓһΛΞαΠϯͨ͠ ਓ 43& ೔ؒ 56 全体の振り返り

Slide 57

Slide 57 text

特に実施してよかった準備 1. Priority load sheddingのためのワークショップ • 障害発生を前提とした対策ができて、非常に有意義でした • 好評だったため、今後も半期や四半期ごとに定期開催する予定です 2. 統計的処理を用いたチューニング余地のあるマイクロサービス検出 • マイクロサービスの数が増えてもスケールする手法で、リーズナブルでした 3. Elasticsearch dual cluster • 負荷対策だけでなく、バージョンアップなどにも今後利用していく予定です 上記は特に「あけおめLINE」を契機でしたが、それ以外にも役に立つ準備でした。 また、来年の「あけおめLINE」もユーザーの信頼を損なわないように準備していきます。 全体の振り返り 57

Slide 58

Slide 58 text

Thank you!! 58