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

3周年に突入するAbemaTVの挑戦と苦悩 / The challenge and anguish of AbemaTV celebrating the third anniversary

646a01801bac1886ddf86aee2de913ed?s=47 Yusei Yamanaka
February 15, 2019

3周年に突入するAbemaTVの挑戦と苦悩 / The challenge and anguish of AbemaTV celebrating the third anniversary

646a01801bac1886ddf86aee2de913ed?s=128

Yusei Yamanaka

February 15, 2019
Tweet

Transcript

  1. 3周年に突⼊する AbemaTVの挑戦と苦悩 @Developers Summit -A- #devsumiA

  2. ⼭中 勇成 a.k.a みゆっき • ೥4݄ גࣜձࣾαΠόʔΤʔδΣϯτೖࣾ גࣜձࣾAbemaTV ίϯςϯπ഑৴νʔϜ Streaming

    Reliability Engineer toriimiyukki miyukki
  3. AbemaTVとは 24時間365⽇のリニア型放送を⾏う、インターネットテレビ局 ニュース番組やアニメをはじめとした多彩な番組が楽しめる約20チャンネルを提供 PC、タブレット、スマホ、テレビデバイスなど様々なデバイスで楽しめます

  4. 無 料 会員登録なし 24時間編成

  5. ຊ ֨ త ͳ ։ ൃ ։ ࢝  

    Ծ ։ ہ   ُ ా ڵ ؽ ʹ উ ͬ ͨ Β     ສ ԁ ࢹ ௌ ऀ ͕ ࡴ ౸ ͠  ࣌ ؒ ൒ μ ΢ ϯ  ։ ہ  प ೥  Ϗ σ Φ ػ ೳ ɾ ॎ ը ໘ Ϧ Ϧ ɹ ε ʔ ։ ہ  प ೥  μ ΢ ϯ ϩ ɹ υ ɾ ௥ ͬ ͔ ͚ ࠶ ੜ Ϧ Ϧ ɹ ε ʔ ʔ ೥ ຤ ೥ ࢝ ಛ ൪   ແ ࣄ ೥ ຤ ೥ ࢝ Λ ৐ Γ ੾ Δ ೥ ຤ ೥ ࢝ ಛ ൪   ϐ ɹ Ϋ ଳ ͷ $ . ࣌ ʹ ࢹ ௌ ো ֐ ʔ ຊ ։ ہ  ཌ ೔ ʹ ( $ 1 ͷ શ Ϧ ɹ δ ϣ ϯ ো ֐ ʔ   ࣌ ؒ ϗ ϯ ω ς Ϩ Ϗ ແ ࣄ ഑ ৴ Λ ߦ ͍ ա ڈ ࠷ ߴ ࢹ ௌ Λ ه ࿥  ʮ ʯ
  6. 今⽇の内容 • 今⽇話すこと AbemaTVが今までどう開発してきたか、なぜその技術を選んだか(挑戦) 今困っていることは何か、今だったらどうするのか(課題)を技術レイヤーごとに紹介 映像配信サービスに限らない⼀般的なWebサービス開発にも関わる話 • 今⽇話さないこと 映像配信に関するアーキテクチャ 番組表などサービス特有のアーキテクチャ

  7. 技術レイヤー チーム体制 アプリケーション ネットワーク 開発⽀援 モニタリング プロジェクト プロジェクト管理 ⾔語 構成管理

    通信プロトコル CDN 広告 CI/CD テスト デプロイ 監視 ログ メトリクス ミドルウェア プラットフォーム 仮想化 勤務体制
  8. 最近の登壇 • 今⽇の話はAbemaTV Developer Conference から⼀部抜粋 https://speakerdeck.com/miyukki/the-history-of-abematvs-architecture https://logmi.jp/tech/articles/

  9. プロジェクト

  10. チーム⼈数 開発当初 2019年1⽉ 超

  11. 開発チーム体制 Web Android 新デバイス iOS 基盤開発 プロダクト開発 コンテンツエンジニアリング コンテンツ配信 SRE

    データマネジメント Streaming Client デザイナー ディレクター QA
  12. Android iOS Web New Device Streaming Client Developer Infrastructure Product

    Content Engineering Content Delivery Data Management SRE Direction Design QA CTO VPoE BOARD
  13. プロジェクト管理 • チームごとにプロジェクト管理はやりやすい⽅法を選択 JIRA、GitHub Projects、物理ボードなどさまざま • サーバのリリースは不定 • クライアントは2週間のスプリントで開発とリリースを 回している

    機能リリースの仕様やQAなどのスケジュールをディレクターが管理
  14. 勤務体制 • 週に1度のリモート勤務が推奨 • AbemaTVはCA社内でも年齢層が⾼く(シニアエンジニアが多い)、
 家庭事情でスライド勤務などが許可されていたり柔軟な対応をしている

  15. アプリケーション

  16. 開発着⼿前 • 当時としては、挑戦的な構成で挑むことを検討していた 当時のCTO

  17. プラットフォーム • オンプレはコスト以外のメリットがなく却下 • 既に知⾒のあるAWSかGCPの選択肢へ

  18. なぜGCPを選んだか ⾼機能L ロードバランサ Stackdriver Logging / BigQueryなどの
 ログ収集や集計サービスの充実 ネットワーク帯域に対するコストの安さ GKE

    / Kubernetes
  19. GCPの課題 • 開発当初に東京リージョンはなかったが、台湾リージョンを使⽤しているこ とでいくつかの課題が浮上 ⽇本と台湾間のネットワーク 遅延と安定性が国内のリージョンに⽐べて劣る 東京リージョンや国内の別のプラットフォームに移動したい Legacy Network(VPC) 開発当初はLegacy

    Networkしかなかったため、Legacy Networkを使⽤しているが、
 Lagacy Network上ではリージョン間でサブネットを作成することができないなど、
 リージョン移⾏ やネットワーク移⾏を⾏う負担が⼤きい
  20. ⾔語 • CyberAgentのバックエンドにおける開発⾔語は、Java→Node.js→Go Ameba OwndやAWAなどがGoを使⽤し、当時のCTOがAWAから来たこともあり、Goを採⽤

  21. アーキテクチャ • Microservicesアーキテクチャを採⽤ 機能単位でのリリースやスケールが可能 コンテナ化によるリソースの有効活⽤が可能 AbemaTVには、約80のサービスがある • 各サービス間の通信は gRPC+Protocol Buffers

    • Gateway系/Backend系に分けたGateway Pattern (BUFXBZ 4FSWJDF #BDLFOE 4FSWJDF %BUBCBTF
  22. Go/Microservicesの課題 • パッケージ管理 開発当初はGodepを使⽤してvendor管理をしていた 新しい⼀部のサービスからはdepを使い始めている • Goのバージョン管理 Goは約半年にメジャーバージョンリリースされ、最新2つしかサポートしない 基本的にビルドするGoバージョンを上げれば済むが、サービス古いバージョンを使⽤してい たり…ということもある

  23. Go/Microservicesの課題 • 共通ロジックをどこにまとめるか AbemaTVの開発当初はMonorepoで1つのリポジトリに複数サービスのコードが存在した その後、サービスごとにリポジトリを分解してからは、共通ロジックをまとめるリポジトリを 作成して、そこを集約 → 最新の共通ロジックに追従しているサービスとそうでないサービスがバラバラになる 全てのサーバの共通したロジックをどこに置き、どう⼀⻫に管理するかが課題 •

    役割の負担が⼤きいマイクロサービス 開発を続けていると1つのサービスの責務が⼤きくなってくるので、良きタイミングで分解する
  24. 仮想化/コンテナ • GKE / Kubernetes GCPを使った最⼤のアドバンテージ Googleの豊富な経験に基づいて構築された、マネジメントなKubenetes Engine環境

  25. データベース • MongoDB 開発当初はGCPで提供している、Cloud BigtableかCloud Datastoreにしたかった 先⾏して編成ツールを完成する必要があり、クエリ要件やスキーマの柔軟な変更が求められ る開発状況の為、MongoDBを採⽤ MongoDB Cloud

    Managerを使⽤して管理 各種メトリクスの表⽰、スナップショットの管理など シャーディングによる分散とレプリカセットによる冗⻑化構成 vCPU core、RAM GBのmongodインスタンスが約60台稼働 ドメインに応じてクラスタを⽤意 過去にデータベースのコネクションが枯渇してサービス影響が出たことがあったため
 負荷分散と障害影響の最⼩化を⽬的として、ユーザー⽤、コメント⽤、配信⽤とクラスタを分散
  26. MongoDBの課題 • Mongosの管理、コネクションプールの管理 • スキーマは柔軟だが複雑なビジネス要件をそのまま処理すると即死する • イケてるGoのライブラリが無い

  27. キャッシュ • In-Memory Goのアプリケーション側でのキャッシュ 使⽤頻度が⾼く、すべてのインスタンスが持っているべきデータであれば、In-Memoryで キャッシュする事が多い

  28. キャッシュ • Redis 開発当初はGCPでマネージドなキャッシュサービスが提供していなかった → 現在はCloud Memorystore for Redisがリリースされている 主にセッション管理、ロック⽬的、ネットワーク的な負荷を減らす⽬的で使⽤される

    ネットワーク的な負荷…GCSへのファイルへのキャッシュ MongoDBと同様、ドメインに応じてRedis Clusterを構築
  29. 構成管理 • Terraform クラウド環境上のインフラ構築や設定を、コードを使って⾃動化するためのツール AbemaTVでは、GCPの構成管理に使⽤ DNS、GCEインスタンス、ディスクなど… • Packer 複数の仮想化環境、クラウド環境に対応した マシンイメージを作成、起動するためのツール

    AbemaTVでは、GCEインスタンスのディスクイメージを作成するために使⽤ Redis、MongoDB、Varnish、Wowzaなど…
  30. ネットワーク

  31. クライアント間通信 • gRPCも検討したが… 開発当初は、GCLB(Google Cloud Load Balancing)がHTTPの負荷分散ではHTTP/ . や gRPCでのバックエンドとの通信に対応していなかった

    → 現在はgRPCでのバックエンドとの通信をサポート • クライアントとの通信フォーマットとしてProtocol Buffersを使⽤
  32. CDN • Akamai Media Deliveryを使⽤ 開発当初に、HLSなどのメディアデリバリーに特化した製品が少なく、
 サービスの規模を鑑みてAkamaiを採⽤ • APIのCDNとしてはCloud CDNを使⽤

    GCLBの設定にチェックを加えるだけで設定完了する容易さから採⽤
  33. 広告 • リニア型配信ではSSAI(Server-Side Ad Insertion)で広告を挿⼊ 開発当初では、社内で開発している広告サーバと独⾃⽅式で通信をしていたが、
 汎⽤的な規格であるVASTに統⼀ • VOD型配信ではCSAI(Client-Side Ad

    Insertion)で広告を挿⼊ サーバで挿⼊するとシーク制御が難しいため、クライアント側で挿⼊ Google IMA(Interactive Media Ads)のSDKをクライアントに⼊れて、VASTで通信を⾏う
  34. 開発⽀援

  35. CI/CD • Codeship バックエンドのテストやイメージの作成を⾏うCI(継続的インテグレーション)サービス Dockerコンテナを並列に可動させてパイプラインを組むことが可能 • Deploykun 社内製のCD(継続的デリバリ)を⾏うためのChatOps⽤のボット

  36. Deploykun • ChatOpsでサービスのバージョン作成、デプロイ、ロールバック、スケール をサポート

  37. リリース時のフロー Apply Deploykun Developer GitHub Codeship Create release Create tag

    Hook Run test Return result GKE Push image Create ops PR Merge ops PR Deploy バージョン 作成 リリース
  38. モニタリング

  39. 監視 • サービスのスパイク‧エラー監視はBugsnagを使⽤ ライブラリをインポートして、呼び出すとエラーを集計 リリース後の新規エラーやスパイクなどを検知することが可能 • Google Cloud MonitoringにてGCE/GKEの挙動を監視 •

    これらの異常を検知すると、Slackに投稿&バックエンドエンジニアにコール ⾃分の担当以外のサービスのコールが掛かってくる エンジニア以外が対応ステータスがわかりにくい PagerDutyを使ったオンコール体制の⾒直し 課題
  40. PagerDutyを使ったオンコール体制の⾒直し • PagerDuty インシデント管理ソリューション 監視元の連携が豊富であり、スケジューリング‧エスカレーションなどの設定が可能 SREチームで1次対応 アラートに対するマニュアルが作成されていてれば、その対処を実施 マニュアルがない場合は、可能な対応と2次対応者を呼び出し、その後マニュアルを作成 インシデントのNoteに書き込むことにより、インシデントの状況を記録&展開 画像が貼れないのがネック…

  41. ログ • アプリケーションログ Goの標準出⼒にJSON形式で出⼒ → GKEのfluentdがログを収集、StackDriver Loggingで表⽰ • アクセスログ 開発当初はfluentdを使って収集していたが、Goでの扱いづらさとfluentdの運⽤が必要

    だったため、Cloud PubSubとBigQueryを使った形に置き換え Cloud PubSub BigQuery App Stream Inserter
  42. アクセスログの課題 Streaming Inserterの運⽤と管理 BigQueryのStreaming Insertのキャパシティ サービスごとのカスタムカラムの追加がし難い 常にBigQueryにデータを⼊れ続けるコスト • 新ログシステムに求める要件 フルマネージド

    柔軟なスキーマ Cloud DataflowとApache Avroを使⽤したログシステムへ 課題
  43. Cloud Dataflowを使⽤したログシステム • Apache Avroを利⽤するメリット BigQueryがGCSからのAvroファイルの取り込みをサポート スキーマがファイルに含まれているので、展開時に管理する必要がない Cloud Dataflow Cloud

    Storage Cloud PubSub BigQuery Cloud Storage App Cloud DataflowでPubSubからのデータを⼀定の間隔(数⼗秒)ごとに区切られたAvroをGCSへ保存 ログが必要なときに、GCSからAvroファイルをインポート app- .avro
  44. メトリクス • Redis / MongoDBなどのインスタンスメトリクスはStackdriverで視覚化 • 各アプリケーションメトリクスはPrometheusで収集‧集計、
 Grafanaで視覚化 Prometheusは負荷分散のために、ドメインごとに作成 複数のPrometheusのデプロイを簡略化するためHelmで管理

    • 各サービスはメトリクス⽤のポートが開いており、Goの基本的なメトリクス (ヒープやGorutine数など)とサービス固有のメトリクスを出⼒
  45. Prometheus + Grafana QSPNFUIFVTHSQD (SBGBOB QSPNFUIFVT NPOHPEC QSPNFUIFVTIUUQ QSPNFUIFVTLT QSPNFUIFVTSFEJT

    QSPNFUIFVTOPEF HDF QSPNFUIFVTOPEF LT QSPNFUIFVTOPEF NJTD 4FSWJDF .POJUPS QSPNFUIFVTTFSWFST 1SPNFUIFVT 0QFSBUPS FYQPSUFST BMFSUNBOBHFS 4MBDL RVFSZ FYFD NBOBHF pOE UBSHFUT QVMM NFUSJDT QVTI BMFSUT OPUJGZ
  46. 今後の展望

  47. なぜ挑戦と苦悩を続けるのか サービス規模の拡⼤ サービスが成⻑するに従い、ユーザーの増加や新たな機能追加などによるキャパシティの確保 マネジメントコストの抑制 さらなる安定化の追求 サービスの品質向上のため、より安定したアーキテクチャへの移⾏ 既存システムの⽼朽化 ミドルウェアなどのEOLや古いアーキテクチャによる開発‧保守コストの抑制

  48. ⽬指すべきアーキテクチャ 配信レイヤーの全⼆重化 チャンネル別リソース 実績と予測に基づいたオートスケール

  49. 配信レイヤーの全⼆重化 • 映像配信関わる全てのレイヤー(サーバや回線など)をユーザーの直前まで
 ⼆重化する Encoder Transcoder Proxy CDN Encoder Transcoder

    Proxy CDN Encoder 現在 理想 User User Encoder Transcoder Proxy CDN
  50. チャンネル別リソース • コンポーネントのリソースをチャンネル別に確保することにより、
 リソースの効率化(容易なスケール)と障害時の影響の最⼩化を図る 現在 理想 Channel A Channel B

    Channel A Channel B 1つのコンポーネントの障害により 全チャンネル障害となる 障害は1つのチャンネルに限られる
  51. 実績と予測に基づいたオートスケール • 現時点だとCPU使⽤率に応じたオートスケールをすることしかできないが、
 視聴数などの過去の実績や時間帯の予測などに基づいたオートスケールをし て、コストとオペレーションを削減する

  52. ご清聴ありがとうございました