Slide 1

Slide 1 text

1

Slide 2

Slide 2 text

2 山中勇成 a.k.a みゆっき
 株式会社サイバーエージェント 2017年 新卒入社 
 株式会社AbemaTV 開発局 コンテンツ配信Div. 
 未踏スーパークリエータ
 最近の 買い 欲しい物
 自己紹介 Panasonic 4Kリモートカメラ 
 AW-UE150


Slide 3

Slide 3 text

今回の話は、配信システムの大規模刷新プロジェクトであるSUPERBIRDに関連する。 
 詳しくは、CA BASE NEXTでの以下の発表を参考。 
 前置き 3 "新しい未来のテレビ"を目指すABEMA配信システムの再設計 https://ca-base-next.cyberagent.co.jp/sessions/abema-live-streaming-re-architecture/

Slide 4

Slide 4 text

SUPERBIRDについて 4 中央集約(ハブ化) エンコーダーリプレイス 監視設備強化 新配信管理画面 各スタジオとデータセンターを専用線で、 データセンターとクラウドをプライベートピアで接続 品質の高いアプライアンス型の 専用エンコーダーの導入 電源や回線が冗長化され、 レガシーな監視から脱却された 新しい監視設備を構築 現場の意見をヒアリングした上 で、現場が使いやすい管理画面を 新たに開発

Slide 5

Slide 5 text

SUPERBIRDにより、配信用のオペレーションツールのバックエンドを作り直す必要があった。 
 今回話す内容について 5 課題
 Streaming Server Encoder Manifest Decorator この辺りのステータス表示や制御を行うためのツール 
 ● コンテンツ配信チームでは、現状2人でABEMAの配信を見ているため、 
 できるだけメンテナンスコストを減らしたい
 ● 他の新規案件や改修タスクもあるため、 できるだけ短時間で構築したい
 ● スキルアップを目的に流行りのツールを使ってみたい


Slide 6

Slide 6 text

6 AWS AppSync


Slide 7

Slide 7 text

GraphQLとは 
 
 
 Facebookにより開発された、WebAPIのためのクエリ言語とそのランタイム
 https://graphql.org/
 
 ● 少ないリクエストで複数のリソースにアクセス可能 
 ● クライアントに必要な最小限のデータだけを取得可能 
 
 ● エンドポイントがリソースやアクションを表していないため、 
 キャッシュやモニタリングなど、HTTPのエコシステムを活用しにくい 
 7 Pros
 Cons


Slide 8

Slide 8 text

8 schema { query: Query } type Query { getUser(id: Int!): Person } type Person { id: Int! name: String! age: Int! job: String children: [Person!]! } Schema { "getUser": { "name": "Luke Skywalker", "job": "driver", "age": 56, "children": [ { "name": "Giselle Skywalker", "age": 24, "job": "engineer" }, { "name": "Sania Calhoun", "age": 12, "job": null } ] } } Response { getUser(id: 1) { name age job children { name age job } } } Request GraphQLのスキーマとリクエストの流れ

Slide 9

Slide 9 text


 
 
 完全マネージド型のGraphQLサーバー
 https://aws.amazon.com/jp/appsync/
 ● DynamoDBやLambdaなどのデータソースと接続し、リクエストを処理可能 
 ● 認証やキャッシュ、リアルタイムのサブスクリプション、クライアントSDKと 
 連携すればオフラインでの利用なども可能 
 ● APIリクエストのボリュームに合わせた GraphQL API 実行エンジンの自動的なスケールアッ プとダウンが行われる
 AWS AppSyncとは 9 AWS AppSync


Slide 10

Slide 10 text

AWS AppSyncのアーキテクチャ AppSyncでは、予め設定されたスキーマとリゾルバーを元にデータソースへアクセスを行い、クライ アントにデータを返却する。
 10 DynamoDB Aurora Lambda AppSync Client Schema Resolver Cognito Data Source 現時点で対応しているデータソース 
 ● DynamoDB
 ● AWS Lambda
 ● Amazon OpenSearch Service 
 ● HTTP
 ● Aurora Serverless
 HTTP

Slide 11

Slide 11 text


 スキーマのフィールドを解決するための設定 
 データソースとマッピングテンプレートを指定する。 
 
 データソースとのリクエストとレスポンスをどう処理するか を記述する。
 テンプレートは、ApacheVTLで記述する。 
 リクエストテンプレートは、JSON形式で出力することが多 い。
 11 GraphQL Request Resolver Request Mapping Template Response Mapping Template Data Source GraphQL Response リゾルバーとマッピングテンプレート リゾルバー
 マッピングテンプレート 


Slide 12

Slide 12 text

12 schema { query: Query } type Query { getUser(id: Int!): Person } type Person { id: Int! name: String! age: Int! job: String children: [Person!]! } Schema Resolver { "version": "2017-02-28", "operation": "GetItem", "key": { "id": $util.dynamodb.toDynamoDBJson($ctx.args.id), } } DataSource UserTable Request Mapping Template - DataSourceにどういうクエリを送るか Response Mapping Template - DataSourceから返ってきたデータをどうクライアントに返すか $util.toJson($ctx.result) {"N": "1234"} Query.getUserにリゾルバーを紐付け
 リゾルバーとマッピングテンプレートの紐付け

Slide 13

Slide 13 text

AWS AppSyncをどの様に使うか 13 Lambda DynamoDB AppSync S3 Operators Cognito ● AppSyncは、GraphQLのゲートウェイ (認証とフィールドの解決) 、DynamoDBへの取得系クエリ の処理を行う様に設定
 ● 上記以外の更新系などの処理は、AppSyncからLambdaを呼び出している 
 ➡ 更新時には、バリデーションや外部APIの呼び出しなどを行う可能性が高いため、 
 処理の柔軟性が高いLambdaを前提として構築した 


Slide 14

Slide 14 text

AWS AppSyncのデバッグ方法 14 リクエスト毎にリゾルバーがどう処理され たかをログとして出力 
 CloudWatch
 リクエスト毎にリクエストの詳細やデータ ソースへのアクセスを分析 
 X-Ray
 ブラウザ上で簡単にGraphQLクエリを実 行可能(Cognitoの認証も可能) 
 コンソール


Slide 15

Slide 15 text

AWS AppSyncの良い点・悪い点 
 ● スケーラブルなマネージドGraphQLサーバが簡単に作れる 
 ● クライアントSDKを使用すれば認証やオフラインキャッシュなども利用可能 
 
 ● 細かいことをやろうとするとLambdaが必要になる 
 ● テストがしにくい
 ● マッピングテンプレート(Apache VTL)を覚える必要がある 
 ● バリデーションや認可などをマッピングテンプレートに書くことができるが、 
 管理が複雑になる
 15 Pros
 Cons


Slide 16

Slide 16 text

社内では、Terraformを用いてAWSリソースを管理することが一般的。 
 ただし、それではAppSyncのスキーマ変更やLambdaのコード変更の度にTerraformの反映が必要 になってしまう。
 AWS AppSyncをどのように構築するか 16 CodeBuild Cognito DynamoDB S3 SQS IAM Roles Terraformで生成されるリソース 
 Serverlessで生成されるリソース 
 Lambda AppSync ➡ 基本はTerraform、開発利便性が必要なリソースはServerlessで管理するように 


Slide 17

Slide 17 text


 
 
 サーバレスコンポーネントのために開発された構成管理ツール
 https://www.serverless.com/ 
 ● AWS Lambdaなどのサーバレスコンポーネントが簡単に構築、管理可能 
 ● 様々なProvider(AWS, GCP, Azure, etc...)に対応している
 ● CloudFormationのテンプレートを記述すれば対応外のものも管理可能 
 ● プラグインを開発することにより、ビルドや更新時の挙動を変更可能 
 Serverless Frameworkとは 17

Slide 18

Slide 18 text

Serverlessの実行環境には、CodeBuildを使用。 
 ➡ AWS内のリソースを管理するため、IAM Roleベースで権限を管理したいため 
 Serverlessの実行環境 18 CodeBuild GitHub コードリポジトリ Post Webhook Lambda AppSync dependent go modules... GitHub Token Run Setup Webhook Goの依存モジュールなどのアクセスについては、GitHubのTokenをParameter Storeで管理。


Slide 19

Slide 19 text

GitHub Flowを採用し、開発環境ではdevelopブランチを自動的に反映、本番環境はmasterブランチ を自動的に反映する様にCodeBuildで設定を行っている。 
 
 
 
 
 
 
 ➡ 検証したい場合は、開発環境などでブランチを指定して ビルドすることにより構成が反映される 
 ServerlessのCD 19

Slide 20

Slide 20 text

● Serverlessのテンプレートは、TypeScriptで記述 
 ● Lambdaは、単一のバイナリではなく、GraphQLのフィー ルド毎にバイナリを生成
 ● ServerlessでAppSyncを管理するために、 serverless-appsync-pluginを使用 
 ● ServerlessでGoのLambdaデプロイをするのに、 serverless-go-pluginを使用
 ○ 右の様なモノレポなプロジェクトをデプロイ可能 
 
 Serverlessの構成 20 ├── serverless.ts ├── functions │ ├── core │ │ ├── hoge │ │ │ └── hoge.go │ │ ├── foo │ │ │ └── foo.go │ │ ├── go.mod │ │ └── go.sum │ ├── update-live-stream │ │ ├── main.go │ │ ├── go.mod │ │ └── go.sum │ ├── update-encoder │ │ ├── main.go │ │ ├── go.mod │ │ └── go.sum │ │── update-pipeline │ │ ├── main.go │ │ ├── go.mod │ │ └── go.sum プロジェクトのディレクトリ構成 共通ロジック 関数A 関数B 関数C

Slide 21

Slide 21 text

バックエンドアーキテクチャ 21 CodeBuild GitHub コードリポジトリ Post Webhook Lambda DynamoDB AppSync GitHub Terraformリポジトリ Push IAM Roles For CodeBuild / AppSync / Lambda / SQS S3 Manage&Deploy Request Other services in EKS Push Other services in GKE Service A Service B Service D Service C dependent go modules... Release GitHub Token SQS Operators Developers Put Run Setup Webhook Appliance Datacenter Cognito

Slide 22

Slide 22 text

● Lambdaの起動時間が許容できない 
 ○ リクエスト時間がシビアな処理(=CM挿入処理)をLambdaで捌こうと思ったが、AppSync経由で Lambdaからの応答が返ってくる時間が許容できなかった 
 ○ Provisioned ConcurrencyなLambdaを設定したが、Provisionedでない呼び出しの 
 タイミングが許容できない 
 ○ Lambda自体の起動というより、アプリケーションの初期化 (DnyamoDBへのTLS接続など) に
 時間を要していた
 AWS AppSyncを使って直面した課題1 22 ➡ EKS上にCM挿入処理を切り出したアプリケーションを用意し、AppSyncからHTTPを データソー スとして呼び出すようにした
 


Slide 23

Slide 23 text

➡ AppSyncへのリクエストに用いられる Authorization ヘッダーをバイパスして、HTTP側で Cognito のJWTを検証するようにした 
 ● HTTPデータソースの呼び出し元がAppSyncであることを検証できない 
 ○ HTTP側でAppSyncから呼び出した事が保証できないと、セキュリティ上の懸念がある 
 AWS AppSyncを使って直面した課題2 23 Lambda AppSync Operators HTTP Server on EKS Authorization: ... Authorization: ...

Slide 24

Slide 24 text

AWS AppSyncを使って直面した課題3 ● 障害や問題発生時に、CloudWatchのログのみだと切り分けが難しい 
 ○ AppSyncへのリクエスト時にCloudWatchに保存されるログは、事象ベースからの検索のハードル が高い
 ○ 問い合わせがあった時間から、AWS AppSyncへのリクエストを検索し、判明したRequestIdや X-Amzn-Trace-Idなどを元に、各種コンポーネントの調査を行う 
 24 ➡ トレースを行いやすくするツール開発の検討、クライアント側への情報表示の検討 


Slide 25

Slide 25 text

Serverlessを使って直面した課題 ● Lambdaが増えるごとにビルド時間が増加する 
 ○ 前述の通り、GraphQLのフィールド毎にバイナリを生成しており、デプロイ時に毎回ビル ドを行っている
 
 
 ➡ シングルバイナリの検討、前回のデプロイと差分がある関数のみビルドを行うようなプラグイン 開発の検討
 25

Slide 26

Slide 26 text

まとめ ● AWS AppSyncとServerless Frameworkを使うことで、マネージドなGraphQLサーバーを短時間 で構築することができた
 ○ 実際、構築と開発にかかった期間は、ロジック部分も含めて3ヶ月ほど 
 ● AWS AppSyncでは、取得系はDynamoDB、更新系はLambdaをデータソースにしている 
 ○ 一部、Lambdaで許容できない処理はHTTPを呼び出すことで解決 
 ● 構成はGitHub Flowで管理していて、ブランチへのpushをトリガーに自動的に構成が反映され る
 
 26

Slide 27

Slide 27 text

27 この後は... このセッションで話したツールのフロントエンドの実装については、 
 この後、同トラックで発表予定。 
 生配信管理システムのフロントエンド〜配信現場に合わせたアジャイル開発〜 https://developer.abema.io/2021/sessions/skvMoyXlQM/

Slide 28

Slide 28 text

28