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

大規模イベントを支えるクラウドアーキテクチャの実現 / ABEMA Cloud Platform Architecture for Large-scale Events

大規模イベントを支えるクラウドアーキテクチャの実現 / ABEMA Cloud Platform Architecture for Large-scale Events

FIFA ワールドカップ カタール 2022 に向けて、我々のクラウドアーキテクチャに対して、どのような懸念があったのか、どのような対応を行って懸念を解消したのか、キャパシティ戦略・スケール戦略・サービスメッシュ・モニタリングシステムなどを紹介します。

https://developer.abema.io/2023/sessions/zonrtHzFiY/?utm_medium=social&utm_source=speakerdeck

CyberAgent
PRO

April 19, 2023
Tweet

More Decks by CyberAgent

Other Decks in Technology

Transcript

  1. View Slide

  2. Software Engineer / Manager, Cloud Platform Group, AbemaTV, inc.
    2011 年株式会社サイバーエージェント入社
    2017 年より ABEMA に参画。プロダクト開発のテックリードを経て、
    2019 年より Cloud Platform Group のマネージャーとして ABEMA のクラウ
    ドソリューション全般を担当。
    永岡 克利
    Katsutoshi Nagaoka
    Twitter @na_ga GitHub @na-ga
    発表者紹介

    View Slide

  3. 1 従来構成と課題
    Index
    FIFA ワールドカップ カタール
    2022、(以後 ワールドカッ
    プ)Cloud Architecture
    2 どのように構成変更を進めたか
    3 キャパシティ戦略
    4 スケール戦略
    5 サービスメッシュの適用と効果
    6 期間中の対応

    View Slide

  4. 従来構成と課題

    View Slide

  5. 2022 年前半のクラウドアーキテクチャ
    Micro Services
    Micro Services
    Micro Services
    Ingress Micro Services
    API Gateways
    Micro Services
      Cloud Bigtable
    Micro Services
      Cloud Trace
    Micro Services
      Pub/Sub Micro Services
      Cloud Spanner
    Micro Services
      Momerystore
    Micro Services
      Cloud Storage
    Micro Services
      BigQuery Micro Services
      MongoDB
    Micro Services
    Micro Services
    Micro Services
    Ingress Micro Services
    API Gateways
    Micro Services
    DynamoDB
    Micro Services
    SQS
    Micro Services
    SNS Micro Services
    Aurora
    Micro Services
    Lambda
    Micro Services
    S3
    Micro Services
    Redshift Micro Services
    Kinesis
    Micro Services
      Cloud CDN
    Region: 東京 & 台湾
    Region: 東京
    AWS Cloud
    Micro Services
    CloudFront
    Micro Services
    Edge Proxies
    Micro Services
    Edge Proxies
    Kubernetes Cluster
    Kubernetes Cluster
    App Mesh
    Anthos Service Mesh
    … etc
    … etc
    Client
    2021 年12 月に開催した ABEMA Developer Conference 2021
    300 以上のマイクロサービスを支えるクラウドアーキテクチャ戦略 より転載
    使用割合: 東京 1 : 台湾 9
    Plain mTLS

    View Slide

  6. 従来のクラウドアーキテクチャの課題
    通信遅延
    限定的な
    サービスメッシュ
    耐障害性

    View Slide

  7. 大部分は
    台湾リージョンで稼働し、
    東京リージョンの利用は
    一部に限られている
    従来のクラウドアーキテクチャの課題
    通信遅延
    限定的な
    サービスメッシュ
    耐障害性

    View Slide

  8. 大部分は
    台湾リージョンで稼働し、
    東京リージョンの利用は
    一部に限られている
    従来のクラウドアーキテクチャの課題
    通信遅延
    限定的な
    サービスメッシュ
    耐障害性
    構成上の理由により
    台湾リージョンで
    サービスメッシュを
    活用できていない

    View Slide

  9. 大部分は
    台湾リージョンで稼働し、
    東京リージョンの利用は
    一部に限られている
    従来のクラウドアーキテクチャの課題
    通信遅延
    限定的な
    サービスメッシュ
    耐障害性
    ワールドカップ向けの
    ライブ配信システムは
    リージョン障害への耐久性を必
    須とする
    構成上の理由により
    台湾リージョンで
    サービスメッシュを
    活用できていない

    View Slide

  10. どのように構成変更を進めたか

    View Slide

  11. Google Cloud 東京リージョンへの移設 & プロジェクトの分離
    目的
    ○ 通信遅延の短縮と、 ASM を全面的に活用できる構成に変更する
    方針
    ○ リージョン障害への耐久性は目的としない
    ○ ユーザーへのレスポンスに関わるサービスを東京に配置する
    ○ 上記以外はコスト単価の低い台湾リージョンを、新しい構成で配置する

    View Slide

  12. 従来の構成

    View Slide

  13. 移設期間中の構成

    View Slide

  14. 移設期間中の構成

    View Slide

  15. 移設期間中の構成

    View Slide

  16. 移設期間中の構成

    View Slide

  17. 移設期間中の構成

    View Slide

  18. 移設対応後の構成

    View Slide

  19. 通信遅延の削減効果
     例) 東京から台湾リージョンに通信していた API
     Request Duration 99 percentile を 150ms 削減
    Baseline 400ms
    Baseline 250ms
    7/06 7/12 7/14 7/18
    7/08 7/10 7/16

    View Slide

  20. AWS ソウルリージョンの立て付け
    目的
    ○ ワールドカップ向けライブ配信システムのリージョン障害耐久性
    方針
    ○ AWS Media Services に対応しているソウルリージョン環境を構築する
    ○ EKS 東京リージョンと同じ構成を行えるように EKS ソウルリージョンを提供する
    ○ 原則リージョンに閉じた設計とするが、例外的なクロスリージョン通信を許容する

    View Slide

  21. 従来の構成

    View Slide

  22. 耐障害性を目的としたソウルリージョン整備

    View Slide

  23. リージョン毎にサービスメッシュを設計

    View Slide

  24. 例外的なクロスリージョン通信

    View Slide

  25. ワールドカップに向けた構成
    Micro Services
    Micro Services
    Micro Services
    Ingress Micro Services
    API Gateways
    Micro Services
    Micro Services
    Micro Services
    Ingress Micro Services
    API Gateways
    Micro Services
    Cloud CDN
    Region: 東京 & 台湾
    Region: 東京 & ソウル
    AWS Cloud
    Micro Services
    CloudFront
    Micro Services
    Edge Proxies
    Micro Services
    Edge Proxies
    Kubernetes Cluster: 台湾
    Kubernetes Cluster: ソウル
    App Mesh
    Anthos Service Mesh
    Client
    使用割合: 東京 9 : 台湾 1
    使用割合: 東京 5 : ソウル 5
    Micro Services
    Micro Services
    Micro Services
    API Gateways Micro Services
    Edge Proxies
    Kubernetes Cluster: 東京
    Micro Services
    Micro Services
    Micro Services
    API Gateways Micro Services
    Edge Proxies
    Kubernetes Cluster: 東京
    App Mesh
    Internal ALB
    Plain mTLS

    View Slide

  26. キャパシティ戦略

    View Slide

  27. Google Cloud を主軸としたキャパシティプランニング
    AWS
    ○ ワールドカップ向けライブ配信システムを展開している
    ○ CDN 帯域の確保は必須であったが Origin への負荷は限定的となる
    ○ Security Group を用いて CDN Layer 以外の Origin アクセスを遮断
    Google Cloud
    ○ ワーストケースを想定したシナリオによる負荷試験で大枠を捉える
    ○ 並行してアプリケーションの効率化を実施し、最終的なキャパシティを算出する
    ○ キャパシティプラニングは SRE セッションで触れられている為、ここでは割愛とする

    View Slide

  28. Google Cloud を主軸としたキャパシティプランニング
    AWS
    ○ ワールドカップ向けライブ配信システムを展開している
    ○ CDN 帯域の確保は必須であったが Origin への負荷は限定的となる
    ○ Security Group を用いて CDN Layer 以外の Origin アクセスを遮断
    Google Cloud
    ○ ワーストケースを想定したシナリオによる負荷試験で大枠を捉える
    ○ 並行してアプリケーションの効率化を実施し、最終的なキャパシティを算出する
    ○ キャパシティプラニングは SRE セッションで触れられている為、ここでは割愛とする

    View Slide

  29. Google Cloud を主軸としたキャパシティプランニング
    AWS
    ○ ワールドカップ向けライブ配信システムを展開している
    ○ CDN 帯域の確保は必須であったが Origin への負荷は限定的となる
    ○ Security Group を用いて CDN Layer 以外の Origin アクセスを遮断
    Google Cloud
    ○ ワーストケースを想定したシナリオによる負荷試験で大枠を捉える
    ○ 並行してアプリケーションの効率化を実施し、最終的なキャパシティを算出する
    ○ キャパシティプラニングは SRE セッションで触れられている為、ここでは割愛とする

    View Slide

  30. マルチリージョンによるキャパシティ確保
    キャパシティ懸念
    Google Cloud 東京リージョンで
    必要とするキャパシティを満たせない
    可能性が生じた
    コンピュートからデータベースに
    繋ぐパスにあるコンポーネントに
    キャパシティ上の懸念があった

    View Slide

  31. 台湾リージョン活用
    Request Volume が大きく
    ユーザー体験に関わらない API を
    集約したマイクロサービスを作成
    台湾リージョンに配置し
    懸念のあるコンポーネントに
    大きな負荷を回避した構成に変更
    マルチリージョンによるキャパシティ確保
    強制アップデート後

    View Slide

  32. マルチリージョンによるキャパシティ確保
    強制アップデート後
    クロスリージョン通信
    東京リージョンに
    依存しているサービス間通信は
    ASM の Multi Cluster Mesh を活用

    View Slide

  33. ● 準決勝
    ストックアウト対策
    11/20 12/18
    12/13
    12/03
    11/24
    ● 開幕
    ● BEST16
    12/09
    ● 準々決勝
    ● 決勝
    11/23
    ● 日本 vs ドイツ
    11/27
    ● 日本 vs コスタリカ
    12/01
    ● 日本 vs スペイン
    12/05
    ● 日本 vs クロアチア
    12/17
    ● 三位決定戦
    11/22
    ● アルゼンチン vs サウジアラビア
    ● スペイン vs ドイツ
    ● オランダ vs アルゼンチン
    12/10
    ● イングランド vs フランス
    ● フランス
    vs アルゼンチン
    ● カタール vs エクアドル
    ワールドカップの全 64 試合
    ● オランダ vs アメリカ

    View Slide

  34. ● 準決勝
    ストックアウト対策
    11/20 12/18
    12/13
    12/03
    11/24
    ● 開幕
    ● BEST16
    12/09
    ● 準々決勝
    ● 決勝
    11/23
    ● 日本 vs ドイツ
    11/27
    ● 日本 vs コスタリカ
    12/01
    ● 日本 vs スペイン
    12/05
    ● 日本 vs クロアチア
    12/17
    ● 三位決定戦
    11/22
    ● アルゼンチン vs サウジアラビア
    ● スペイン vs ドイツ
    ● オランダ vs アルゼンチン
    12/10
    ● イングランド vs フランス
    ● フランス
    vs アルゼンチン
    ● カタール vs エクアドル
    期間中はアメリカの感謝祭 & ブラックフライデーと重なっている
       クォータが緩和されていたとしても、ストックアウトが発生するリスクがある
    ● オランダ vs アメリカ
    ● 感謝祭 & ブラックフライデー

    View Slide

  35. ● 準決勝
    ストックアウト対策
    11/20 12/18
    12/13
    12/03
    11/24
    ● 開幕
    ● BEST16
    12/09
    ● 準々決勝
    ● 決勝
    11/23
    ● 日本 vs ドイツ
    11/27
    ● 日本 vs コスタリカ
    12/01
    ● 日本 vs スペイン
    12/05
    ● 日本 vs クロアチア
    12/17
    ● 三位決定戦
    11/22
    ● アルゼンチン vs サウジアラビア
    ● スペイン vs ドイツ
    ● オランダ vs アルゼンチン
    12/10
    ● イングランド vs フランス
    ● フランス
    vs アルゼンチン
    ● カタール vs エクアドル
    Future Reservations ※ を利用して、指定期間中のキャパシティを事前に確約した
       各ゾーン毎に Machine Type と台数を指定し、Google Cloud の承認を得る
    ● オランダ vs アメリカ
    Future Reservations
    ※ 当時 Private Preview として利用しましたが 2023 年内に一般提供 (GA) が計画されています
    ● 感謝祭 & ブラックフライデー

    View Slide

  36. ストックアウト対策
    Future Reservations ※ を利用して、指定期間中のキャパシティを事前に確約した
       単一ゾーン障害が発生しても影響がないように、必要なキャパシティの 1.5 倍を確保
    Zone A 空き 33 Node
    使用 100 Node
    Zone B 空き 33 Node
    使用 100 Node
    Zone C 空き 33 Node
    使用 100 Node
    合計 300 Node

    View Slide

  37. ストックアウト対策
    Future Reservations ※ を利用して、指定期間中のキャパシティを事前に確約した
       単一ゾーン障害が発生しても影響がないように、必要なキャパシティの 1.5 倍を確保
    Zone A 空き 50 Node
    使用 100 Node
    Zone B 空き 50 Node
    使用 100 Node
    Zone C 空き 50 Node
    使用 100 Node
    合計 300 Node + 空き 150 Node

    View Slide

  38. ストックアウト対策
    Future Reservations ※ を利用して、指定期間中のキャパシティを事前に確約した
       単一ゾーン障害が発生しても影響がないように、必要なキャパシティの 1.5 倍を確保
    Zone A 空き 50 Node
    使用 100 Node
    Zone B 空き 50 Node
    使用 100 Node
    Zone C 空き 50 Node
    使用 100 Node
    Zone A 使用 150 Node
    Zone B 使用 150 Node
    Zone C ゾーン障害
    合計 300 Node
    合計 300 Node + 空き 150 Node

    View Slide

  39. スケール戦略

    View Slide

  40. ❶ Kubernetes のスケール戦略

    View Slide

  41. 固定サイズの Fixed と、リクエストに応じて動的に変動する Auto Scale
    想定を超える負荷に備えた Node Pool 設計
     Kubernetes Cluster (GKE/EKS 共通) 
     Node Pool 
    Future Reservations で確保した Capacity を常
    時稼働し、通常時は 33% の空きがある
     Fixed (固定サイズ) 
    Priority Class の低い Balloon Pod のみを配置
    し、通常時は最小構成で稼働する
     Auto Scale (動的サイズ) 

    View Slide

  42. Pod Disruption Budget (PDB) による割合制御と Priority Class & Node Affinity を設定
    Workload の特性に合わせた配置
     Kubernetes Cluster (GKE/EKS 共通) 
     Node Pool 
    Future Reservations で確保した Capacity を常
    時稼働し、通常時は 33% の空きがある
     Fixed (固定サイズ) 
    Priority Class の低い Balloon Pod のみを配置
    し、通常時は最小構成で稼働する
     Auto Scale (動的サイズ) 
     Kubernetes Workload (GKE/EKS 共通) 
    利用不能状態を許容する割合を指定
     PDB 
    apiVersion: policy/v1beta1
    kind: PodDisruptionBudget
    spec:
    maxUnavailable: 30%
    selector:
    matchLabels:
    name: xxx

    View Slide

  43. Pod Disruption Budget (PDB) による割合制御と Priority Class & Node Affinity を設定
    Workload の特性に合わせた配置
     Kubernetes Cluster (GKE/EKS 共通) 
     Node Pool 
    Future Reservations で確保した Capacity を常
    時稼働し、通常時は 33% の空きがある
     Fixed (固定サイズ) 
    Priority Class の低い Balloon Pod のみを配置
    し、通常時は最小構成で稼働する
     Auto Scale (動的サイズ) 
     Kubernetes Workload (GKE/EKS 共通) 
    Priority Class High として Fixed に配置
     Evict を避けたい Workload 

    View Slide

  44. Pod Disruption Budget (PDB) による割合制御と Priority Class & Node Affinity を設定
    Workload の特性に合わせた配置
     Kubernetes Cluster (GKE/EKS 共通) 
     Node Pool 
    Future Reservations で確保した Capacity を常
    時稼働し、通常時は 33% の空きがある
     Fixed (固定サイズ) 
    Priority Class の低い Balloon Pod のみを配置
    し、通常時は最小構成で稼働する
     Auto Scale (動的サイズ) 
     Kubernetes Workload (GKE/EKS 共通) 
    Priority Class High として Fixed に配置
    Priority Class Middle として Fixed に配置
    もし空きがない場合は Auto Scale に配置
     Evict を許容できる Workload 
     Evict を避けたい Workload 

    View Slide

  45. Pod Disruption Budget (PDB) による割合制御と Priority Class & Node Affinity を設定
    Workload の特性に合わせた配置
     Kubernetes Cluster (GKE/EKS 共通) 
     Node Pool 
    Future Reservations で確保した Capacity を常
    時稼働し、通常時は 33% の空きがある
     Fixed (固定サイズ) 
    Priority Class の低い Balloon Pod のみを配置
    し、通常時は最小構成で稼働する
     Auto Scale (動的サイズ) 
     Kubernetes Workload (GKE/EKS 共通) 
    Priority Class High として Fixed に配置
    Priority Class Middle として Fixed に配置
    もし空きがない場合は Auto Scale に配置
     Evict を許容できる Workload 
     Evict を避けたい Workload 

    View Slide

  46. ❷ Kubernetes Workload のスケール戦略

    View Slide

  47. Workload 特性に合わせた HPA
    ○ CPU や Memory 等の Resource Metrics
    ○ Workload の負荷係数に対応した Custom Metrics
    Custom Metrics は正常に取得できない状況が発生しうる
    ○ Custom Metrics のみは設定しない
    ○ セーフガードとして Resource Metrics を必ず設定する
    Kubernetes Workload のスケール戦略

    View Slide

  48. apiVersion: autoscaling/v2beta2
    spec:
    metrics:
    - type: Resource
    resource:
    name: cpu
    target:
    type: Utilization
    averageUtilization: 25
    - type: External
    external:
    metric:
    name: "prometheus.googleapis.com|ccu_scale|gauge"
    target:
    type: AverageValue
    averageValue: "20000"
    Resource Metrics と Custom Metrics の設定例
    Resource Metrics
    CPU 使用率 25% を設定
    セーフガードとして必ず併用する
    Custom Metrics
    CCU 平均値 20,000 を設定
    予想される局所的な負荷に備える

    View Slide

  49. Custom Metrics
    有効時は 1 を返却
    最大 Replicas までスケールアウト
    apiVersion: autoscaling/v2beta2
    spec:
    metrics:
    ...
    - type: External
    external:
    metric:
    name: "prometheus.googleapis.com|bulk_scale|gauge"
    target:
    type: Value
    value: "1"
    Custom Metrics による一括スケールアウト機構の設定例

    View Slide

  50. ❸ Monitoring System のスケール戦略

    View Slide

  51. 基本構成
    Workload Metrics は Prometheus の Remote Write によって Victria Metrics Cluster に永続化

    View Slide

  52. 従来のスケール戦略
    Metrics の種類毎に Prometheus を分離し、必要なリソースを割り当てる

    View Slide

  53. 従来のスケール戦略
    対象 Workload のスケールアウトによって Promethues のキャパシティを超過する懸念

    View Slide

  54. 全ての Workload に重要度を制定
    クリティカルパスとなる API に関わっているかを判断基準とする

    View Slide

  55. 重要度に応じて担当する Prometheus を分離
    重要度の低い Workload による影響が全体に連鎖することを回避

    View Slide

  56. Victoria Metrics キャパシティ超過時の防衛策
    想定負荷を大きく超過した場合は、重要度の低い Workload の Scraping を停止

    View Slide

  57. Google Managed Prometheus による可用性担保
    HPA として使用するカスタムメトリクスは GMP を併用することで可用性を担保
    ※ Managed Service for Prometheus が属する Cloud Monitoring は SLA 99.95% (月間 21 分のダウンタイム ) が適用される

    View Slide

  58. Google Managed Prometheus 障害時の防衛策
    GMP に障害が発生した場合は Victria Metrics Cluster に切り替える機構を整備
    ※ 各種 HPA に設定するメトリクスキーを変更することで Stackdriver Adapter から Prometheus Adapter に切り替える

    View Slide

  59. サービスメッシュの適用と効果

    View Slide

  60. AWS
    ○ App Mesh は、従来から利用できる状態になっていた
    ○ リージョンに閉じた通信は App Mesh によるサービス間通信を適用した
    Google Cloud
    ○ ASM は、Google Cloud プロジェクト分離によって利用できる状態になった
    ○ 従来クライアント SDK で行っていた処理を ASM に置き換えを実施した
    App Mesh と Anthos Service Mesh を全体的に適用

    View Slide

  61. サービスメッシュによる効果
    自動回復性 障害の局所化 影響箇所の確認

    View Slide

  62. レスポンスコード等による
    指数 Backoff 再試行によって一
    時的な異常を自動回復
    サービスメッシュによる効果
    自動回復性 障害の局所化 影響箇所の確認

    View Slide

  63. レスポンスコード等による
    指数 Backoff 再試行によって一
    時的な異常を自動回復
    サービスメッシュによる効果
    自動回復性 障害の局所化 影響箇所の確認
    障害影響を最小化し、障害が連
    鎖しない仕組みとしてCircuit
    Breaker を随所に活用

    View Slide

  64. レスポンスコード等による
    指数 Backoff 再試行によって一
    時的な異常を自動回復
    サービスメッシュによる効果
    自動回復性 障害の局所化 影響箇所の確認
    Fault Injection による疑似的なエ
    ラーを発生させ、
    障害が連鎖しないことを確認
    障害影響を最小化し、障害が連
    鎖しない仕組みとしてCircuit
    Breaker を随所に活用

    View Slide

  65. サービスメッシュによる分散トレーシング活用
    課題
    ○ 統合負荷試験によって、ボトルネック箇所の特定に時間がかかっていた
    方針
    ○ ASM と Cloud Trace 連携による分散トレーシングを実現する
    ○ TraceId の伝搬を行う SDK を実装し Workload に適用する
    ○ オーバーヘッドを避けるために分散トレーシングの適用箇所は Workload 側で制御する

    View Slide

  66. ASM と Cloud Trace 連携による分散トレーシング
    Head based Sampling Algorithm は呼び出し元の判定に従う

    View Slide

  67. ASM と Cloud Trace 連携による分散トレーシング
    Global Setting で Sampling Rate を 0% に設定する

    View Slide

  68. ASM と Cloud Trace 連携による分散トレーシング
    リクエストの起因となる Workload で Sampling Rate を上書き

    View Slide

  69. ASM と Cloud Trace 連携による分散トレーシング
    本番環境でも導入を進め、リアルトラフィックを用いた分析・改善を可能とした

    View Slide

  70. 期間中の対応

    View Slide

  71. Grafana Dashboard の整備
    ○ 想定範囲内の負荷傾向であることを随時確認
    ○ 全体俯瞰用の Dashboard に加えて、重要システムの専用 Dashboard を整備
    特別体制によるモニタリング

    View Slide

  72. Grafana Dashboard の整備
    ○ 想定範囲内の負荷傾向であることを随時確認
    ○ 全体俯瞰用の Dashboard に加えて、重要システムの専用 Dashboard を整備
    Grafana Unified Alert の活用
    ○ Dashboard に紐づいた主要メトリクスに対する Alert を整備
    ○ 紐づいている Dashboard のスクリーンショットを自動投稿し、即座に調査に取り掛かる
    特別体制によるモニタリング

    View Slide

  73. Grafana Dashboard の整備
    ○ 想定範囲内の負荷傾向であることを随時確認
    ○ 全体俯瞰用の Dashboard に加えて、重要システムの専用 Dashboard を整備
    Grafana Unified Alert の活用
    ○ Dashboard に紐づいた主要メトリクスに対する Alert を整備
    ○ 紐づいている Dashboard のスクリーンショットを自動投稿し、即座に調査に取り掛かる
    関連各所と連携したコミュニケーション
    ○ CyberAgent グループ管轄の関連システムと共同の監視体制
    ○ Google Cloud / AWS / Akamai / MongoDB 社と密に連携した監視体制
    特別体制によるモニタリング

    View Slide

  74. Kubernetes のキャパシティ監視

    View Slide

  75. Kubernetes Workload の HPA 可視化

    View Slide

  76. 重要システムの関連メトリクスを集約

    View Slide

  77. まとめ

    View Slide

  78. まとめ
    ワールドカップに向けたクラウドアーキテクチャの構成変更
    マルチリージョンによるキャパシティ確保とストックアウト対策
    Kubernetes および Monitoring System のスケール戦略
    サービスメッシュの全体的な適用による恩恵を最大限に活用
    社内外との連携や、重要コンポーネントの専用ダッシュボードによるモニタリング体制

    View Slide

  79. View Slide