Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

ຊ ֨ త ͳ ։ ൃ ։ ࢝ Ծ ։ ہ ُ ా ڵ ؽ ʹ উ ͬ ͨ Β ສ ԁ ࢹ ௌ ऀ ͕ ࡴ ౸ ͠ ࣌ ؒ ൒ μ ΢ ϯ ։ ہ प ೥ Ϗ σ Φ ػ ೳ ɾ ॎ ը ໘ Ϧ Ϧ ɹ ε ʔ ։ ہ प ೥ μ ΢ ϯ ϩ ɹ υ ɾ ௥ ͬ ͔ ͚ ࠶ ੜ Ϧ Ϧ ɹ ε ʔ ʔ ೥ ຤ ೥ ࢝ ಛ ൪ ແ ࣄ ೥ ຤ ೥ ࢝ Λ ৐ Γ ੾ Δ ೥ ຤ ೥ ࢝ ಛ ൪ ϐ ɹ Ϋ ଳ ͷ $ . ࣌ ʹ ࢹ ௌ ো ֐ ʔ ຊ ։ ہ ཌ ೔ ʹ ( $ 1 ͷ શ Ϧ ɹ δ ϣ ϯ ো ֐ ʔ ࣌ ؒ ϗ ϯ ω ς Ϩ Ϗ ແ ࣄ ഑ ৴ Λ ߦ ͍ ա ڈ ࠷ ߴ ࢹ ௌ Λ ه ࿥ ʮ ʯ

Slide 6

Slide 6 text

今⽇の内容 • 今⽇話すこと AbemaTVが今までどう開発してきたか、なぜその技術を選んだか(挑戦) 今困っていることは何か、今だったらどうするのか(課題)を技術レイヤーごとに紹介 映像配信サービスに限らない⼀般的なWebサービス開発にも関わる話 • 今⽇話さないこと 映像配信に関するアーキテクチャ 番組表などサービス特有のアーキテクチャ

Slide 7

Slide 7 text

技術レイヤー チーム体制 アプリケーション ネットワーク 開発⽀援 モニタリング プロジェクト プロジェクト管理 ⾔語 構成管理 通信プロトコル CDN 広告 CI/CD テスト デプロイ 監視 ログ メトリクス ミドルウェア プラットフォーム 仮想化 勤務体制

Slide 8

Slide 8 text

最近の登壇 • 今⽇の話はAbemaTV Developer Conference から⼀部抜粋 https://speakerdeck.com/miyukki/the-history-of-abematvs-architecture https://logmi.jp/tech/articles/

Slide 9

Slide 9 text

プロジェクト

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

開発チーム体制 Web Android 新デバイス iOS 基盤開発 プロダクト開発 コンテンツエンジニアリング コンテンツ配信 SRE データマネジメント Streaming Client デザイナー ディレクター QA

Slide 12

Slide 12 text

Android iOS Web New Device Streaming Client Developer Infrastructure Product Content Engineering Content Delivery Data Management SRE Direction Design QA CTO VPoE BOARD

Slide 13

Slide 13 text

プロジェクト管理 • チームごとにプロジェクト管理はやりやすい⽅法を選択 JIRA、GitHub Projects、物理ボードなどさまざま • サーバのリリースは不定 • クライアントは2週間のスプリントで開発とリリースを 回している 機能リリースの仕様やQAなどのスケジュールをディレクターが管理

Slide 14

Slide 14 text

勤務体制 • 週に1度のリモート勤務が推奨 • AbemaTVはCA社内でも年齢層が⾼く(シニアエンジニアが多い)、
 家庭事情でスライド勤務などが許可されていたり柔軟な対応をしている

Slide 15

Slide 15 text

アプリケーション

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

⾔語 • CyberAgentのバックエンドにおける開発⾔語は、Java→Node.js→Go Ameba OwndやAWAなどがGoを使⽤し、当時のCTOがAWAから来たこともあり、Goを採⽤

Slide 21

Slide 21 text

アーキテクチャ • Microservicesアーキテクチャを採⽤ 機能単位でのリリースやスケールが可能 コンテナ化によるリソースの有効活⽤が可能 AbemaTVには、約80のサービスがある • 各サービス間の通信は gRPC+Protocol Buffers • Gateway系/Backend系に分けたGateway Pattern (BUFXBZ 4FSWJDF #BDLFOE 4FSWJDF %BUBCBTF

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

Go/Microservicesの課題 • 共通ロジックをどこにまとめるか AbemaTVの開発当初はMonorepoで1つのリポジトリに複数サービスのコードが存在した その後、サービスごとにリポジトリを分解してからは、共通ロジックをまとめるリポジトリを 作成して、そこを集約 → 最新の共通ロジックに追従しているサービスとそうでないサービスがバラバラになる 全てのサーバの共通したロジックをどこに置き、どう⼀⻫に管理するかが課題 • 役割の負担が⼤きいマイクロサービス 開発を続けていると1つのサービスの責務が⼤きくなってくるので、良きタイミングで分解する

Slide 24

Slide 24 text

仮想化/コンテナ • GKE / Kubernetes GCPを使った最⼤のアドバンテージ Googleの豊富な経験に基づいて構築された、マネジメントなKubenetes Engine環境

Slide 25

Slide 25 text

データベース • MongoDB 開発当初はGCPで提供している、Cloud BigtableかCloud Datastoreにしたかった 先⾏して編成ツールを完成する必要があり、クエリ要件やスキーマの柔軟な変更が求められ る開発状況の為、MongoDBを採⽤ MongoDB Cloud Managerを使⽤して管理 各種メトリクスの表⽰、スナップショットの管理など シャーディングによる分散とレプリカセットによる冗⻑化構成 vCPU core、RAM GBのmongodインスタンスが約60台稼働 ドメインに応じてクラスタを⽤意 過去にデータベースのコネクションが枯渇してサービス影響が出たことがあったため
 負荷分散と障害影響の最⼩化を⽬的として、ユーザー⽤、コメント⽤、配信⽤とクラスタを分散

Slide 26

Slide 26 text

MongoDBの課題 • Mongosの管理、コネクションプールの管理 • スキーマは柔軟だが複雑なビジネス要件をそのまま処理すると即死する • イケてるGoのライブラリが無い

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

キャッシュ • Redis 開発当初はGCPでマネージドなキャッシュサービスが提供していなかった → 現在はCloud Memorystore for Redisがリリースされている 主にセッション管理、ロック⽬的、ネットワーク的な負荷を減らす⽬的で使⽤される ネットワーク的な負荷…GCSへのファイルへのキャッシュ MongoDBと同様、ドメインに応じてRedis Clusterを構築

Slide 29

Slide 29 text

構成管理 • Terraform クラウド環境上のインフラ構築や設定を、コードを使って⾃動化するためのツール AbemaTVでは、GCPの構成管理に使⽤ DNS、GCEインスタンス、ディスクなど… • Packer 複数の仮想化環境、クラウド環境に対応した マシンイメージを作成、起動するためのツール AbemaTVでは、GCEインスタンスのディスクイメージを作成するために使⽤ Redis、MongoDB、Varnish、Wowzaなど…

Slide 30

Slide 30 text

ネットワーク

Slide 31

Slide 31 text

クライアント間通信 • gRPCも検討したが… 開発当初は、GCLB(Google Cloud Load Balancing)がHTTPの負荷分散ではHTTP/ . や gRPCでのバックエンドとの通信に対応していなかった → 現在はgRPCでのバックエンドとの通信をサポート • クライアントとの通信フォーマットとしてProtocol Buffersを使⽤

Slide 32

Slide 32 text

CDN • Akamai Media Deliveryを使⽤ 開発当初に、HLSなどのメディアデリバリーに特化した製品が少なく、
 サービスの規模を鑑みてAkamaiを採⽤ • APIのCDNとしてはCloud CDNを使⽤ GCLBの設定にチェックを加えるだけで設定完了する容易さから採⽤

Slide 33

Slide 33 text

広告 • リニア型配信ではSSAI(Server-Side Ad Insertion)で広告を挿⼊ 開発当初では、社内で開発している広告サーバと独⾃⽅式で通信をしていたが、
 汎⽤的な規格であるVASTに統⼀ • VOD型配信ではCSAI(Client-Side Ad Insertion)で広告を挿⼊ サーバで挿⼊するとシーク制御が難しいため、クライアント側で挿⼊ Google IMA(Interactive Media Ads)のSDKをクライアントに⼊れて、VASTで通信を⾏う

Slide 34

Slide 34 text

開発⽀援

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

リリース時のフロー Apply Deploykun Developer GitHub Codeship Create release Create tag Hook Run test Return result GKE Push image Create ops PR Merge ops PR Deploy バージョン 作成 リリース

Slide 38

Slide 38 text

モニタリング

Slide 39

Slide 39 text

監視 • サービスのスパイク‧エラー監視はBugsnagを使⽤ ライブラリをインポートして、呼び出すとエラーを集計 リリース後の新規エラーやスパイクなどを検知することが可能 • Google Cloud MonitoringにてGCE/GKEの挙動を監視 • これらの異常を検知すると、Slackに投稿&バックエンドエンジニアにコール ⾃分の担当以外のサービスのコールが掛かってくる エンジニア以外が対応ステータスがわかりにくい PagerDutyを使ったオンコール体制の⾒直し 課題

Slide 40

Slide 40 text

PagerDutyを使ったオンコール体制の⾒直し • PagerDuty インシデント管理ソリューション 監視元の連携が豊富であり、スケジューリング‧エスカレーションなどの設定が可能 SREチームで1次対応 アラートに対するマニュアルが作成されていてれば、その対処を実施 マニュアルがない場合は、可能な対応と2次対応者を呼び出し、その後マニュアルを作成 インシデントのNoteに書き込むことにより、インシデントの状況を記録&展開 画像が貼れないのがネック…

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

アクセスログの課題 Streaming Inserterの運⽤と管理 BigQueryのStreaming Insertのキャパシティ サービスごとのカスタムカラムの追加がし難い 常にBigQueryにデータを⼊れ続けるコスト • 新ログシステムに求める要件 フルマネージド 柔軟なスキーマ Cloud DataflowとApache Avroを使⽤したログシステムへ 課題

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

メトリクス • Redis / MongoDBなどのインスタンスメトリクスはStackdriverで視覚化 • 各アプリケーションメトリクスはPrometheusで収集‧集計、
 Grafanaで視覚化 Prometheusは負荷分散のために、ドメインごとに作成 複数のPrometheusのデプロイを簡略化するためHelmで管理 • 各サービスはメトリクス⽤のポートが開いており、Goの基本的なメトリクス (ヒープやGorutine数など)とサービス固有のメトリクスを出⼒

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

今後の展望

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

チャンネル別リソース • コンポーネントのリソースをチャンネル別に確保することにより、
 リソースの効率化(容易なスケール)と障害時の影響の最⼩化を図る 現在 理想 Channel A Channel B Channel A Channel B 1つのコンポーネントの障害により 全チャンネル障害となる 障害は1つのチャンネルに限られる

Slide 51

Slide 51 text

実績と予測に基づいたオートスケール • 現時点だとCPU使⽤率に応じたオートスケールをすることしかできないが、
 視聴数などの過去の実績や時間帯の予測などに基づいたオートスケールをし て、コストとオペレーションを削減する

Slide 52

Slide 52 text

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