Slide 1

Slide 1 text

Go Tech Talk 動画配信サービスを支える 基盤の内部 2022-11-30 ミラティブ事業本部 基盤開発技術部 インフラ・ストリーミング 漢 祐介 © 2022 Mirrativ, Inc.

Slide 2

Slide 2 text

1. 自己紹介 2. Mirrativのマルチクラウド構成について 3. Mirrativのライブ配信基盤について 4. CPU/メモリとGoとcgo 5. (おまけ)マイクロアーキテクチャサポート 「Go x スケーラビリティ」 Mirrativではバックエンド・基盤開発・インフラ管理の幅広い範囲でGoを利用して いるのでその紹介と Goそのものもつスケーラビリティの高さ以外にインフラ的な視点から工夫している ところなどを紹介できればと思っています アジェンダ 2

Slide 3

Slide 3 text

自己紹介 ■ 漢 祐介(Hata Yusuke) ⁃ twitter: twitter.com/octu0 ⁃ github: github.com/octu0 ■ 2018年10月 Mirrativ に Join ⁃ OSS活動、スタートアップを経てDeNAへ入社し、ゲームの大規模トラ フィックやSHOWROOMのライブ配信サービスの基盤設計・運用に携わ る。2018年にミラティブへ入社し、インフラ・ストリーミング領域のマ ネージャーとしてライブ配信基盤/インフラ基盤に携わる。 ■ ミラティブでの役割 ⁃ インフラ・ストリーミング部門のMGR ⁃ インフラ基盤・ストリーミング基盤の設計開発 ⁃ ミドルウェアおよびもろもろ整備 3

Slide 4

Slide 4 text

Mirrativのマルチクラウド構成

Slide 5

Slide 5 text

Mirrativのマルチクラウド構成 ■ ミラティブのインフラは複数のクラウドで構成 している ⁃ Mirrativ本体のインフラ基盤はGCP ⁃ ストリーミング配信基盤はIDCF ⁃ どちらもIaaS管理+コンテナ化された環境 ■ Mirrativ本体は 大小さまざまなサイズのVMが数百単位で稼働 ■ ストリーミング配信基盤はベアメタルサーバと VMサーバの組み合わせで稼働 5

Slide 6

Slide 6 text

Mirrativのマルチクラウド構成と開発チーム ■ Mirrativ本体はAPI/Batchプロセスの集合 ⁃ PerlからGoに移行しているところ ⁃ バックエンドチームが本体の機能開発 ⁃ 基盤開発チームおよびインフラチームが 基盤となる部分の設計開発 ■ CI/CDなどは Cloud Build + α WAF は Cloud Armorを使ってたりする ■ 構成管理ツールや監視は開発環境でテストし たバイナリをそのまま本番に持っていってる 6

Slide 7

Slide 7 text

Mirrativのマルチクラウド構成と開発チーム ■ 映像/音声のライブ配信はIDCFクラウドで受けてい る ⁃ iOS/Androidのライブラリおよび配信サーバは ストリーミングチームが設計開発 ⁃ ベアメタルなサーバと VMなサーバのハイブリッドな環境 ■ ハードウェアロードバランサを使用していたり、ク ラウド<->物理サーバ間のL2/L3接続などネット ワーキングに特徴がある → 今回紹介するのはこのストリーミング周辺です 余談 配信サーバは長年Wowzaという製品を使っていたが Goに移行した 7

Slide 8

Slide 8 text

Mirrativのマルチクラウド構成 ■ マルチクラウドで構成 ⁃ より最適なところで稼働させるため ⁃ 拠点単位での動作/複数拠点による相互監視 ⁃ コスト最適化 • オートスケーリング • トラフィックコントロール • ベアメタルの活用 ■ ベンダーロックインを避けるために ⁃ コンポーネント間の依存関係を薄く小さく ⁃ 密結合を避ける ⁃ シンプルを保つ 8

Slide 9

Slide 9 text

Mirrativのライブ配信基盤 (Goの話までもう少しあります)

Slide 10

Slide 10 text

Mirrativのライブ配信基盤 ■ Origin/Edge 構成 ⁃ ストリーミング版Pub/Subのイメージ ⁃ 以前はPolling方式だった 今はPush方式になっている ⁃ 水平分散(sharding)している ■ Originは配信者さんから映像/音声を 最初に受けるところ ■ Edgeは視聴者さんに映像/音声を届 けるところ 10

Slide 11

Slide 11 text

Mirrativのライブ配信基盤 - Origin ■ OriginはハードウェアLBにて冗長化 ⁃ Active/Standby構成 ⁃ LB自体も冗長化されてる ■ Originで処理すること(*1)が増えてきたので ベアメタルサーバを利用 ⁃ 基本的にCPU処理だけで完結するように設 計しているので、VMでもベアメタルでも 可搬性のあるプログラムである必要がある ⁃ GPU搭載マシンは使っておらず汎用サーバ で構成しているので調達はしやすい • とはいえ突発的な受け皿として利用するよ うなキャパシティ確保には不利 *1 サーバサイド通知ぼかし(画像処理)や 直近では音量解析(音声処理)をサーバサイドで行ってる 11

Slide 12

Slide 12 text

Mirrativのライブ配信基盤 - Edge ■ EdgeはActiveとStandbyに接続 ⁃ OriginのFailoverの影響を受けない ⁃ Push方式なのでEdgeはtopicを待ち続け るだけ ■ EdgeはOriginへのOffloading用途 ⁃ Originへの接続を束ねて大量の視聴者接 続を受け持つのが役目 ⁃ そのため複雑な機能はなく Clientに映像/音声のPushくらい ■ キャパシティ面やコスト面からクラウド上に オートスケールするようにしている 12

Slide 13

Slide 13 text

CPU/メモリとGoとcgo

Slide 14

Slide 14 text

CPU/メモリとGoとcgo ■ ライブ配信基盤のサーバミドルウェアはGoにて記述 ⁃ GPUなどを搭載しない汎用サーバを利用しているのでCPU処理が主体 ⁃ Goはメインロジックの他、通信関連、Pub/Subのロジックを書いている ■ 画像のトランスコーディングや音声処理を扱う場面では cgo を経由して、 C/C++のロジックが走る ⁃ 高いリアルタイム性が求められる場面 ⁃ SIMD化したい箇所をOSSなライブラリを使えばGoでもできるが アルゴリズムとスケジューリング分離を行うためにHalide 言語(C++のDSL)で書いてる ⁃ 音声処理もHalideで書いたりしている => 続く 14

Slide 15

Slide 15 text

CPU/メモリとGoとcgo - CPU ←Halideで書いたコード ↓Goで呼び出すとき(抜粋) 15

Slide 16

Slide 16 text

CPU/メモリとGoとcgo - CPU ■ 普通にGoのコードを書いていればマルチコアなサーバでスケールできる ⁃ vCPU 8のサーバでも vCPU 64 のサーバでも同じバイナリでスケールする ⁃ VMでもベアメタルなサーバでも同じ ■ Halideでナイーブにチューニングをしてしまうとスケールしない ⁃ 並列数や L2,L3 cacheサイズの違いを意識しないといけない ⁃ 実行環境毎にバイナリを用意することになるので少しイケてない ⁃ とはいえ高速な処理を書きやすいので、使い所は限定的に 16

Slide 17

Slide 17 text

CPU/メモリとGoとcgo - メモリ ■ ライブ配信ではメディアデータ(映像/音声)を扱うため、テキストデータと比 べてメモリ管理がシビア ⁃ 30fpsの映像だと1秒間に30枚の画像がパラパラ漫画のように送られてくる ⁃ 一度どこかで allocate したものは、コピーを作らず最後まで使い回す 17

Slide 18

Slide 18 text

CPU/メモリとGoとcgo - メモリ ■ allocateしたものは基本的に使いまわし ⁃ leaky bufferな実装で必要な分だけbufferする(sync.Poolでも良いがコントロールしずらい) ⁃ 大きな値は mmap を使用することもある ←Pool ↓使うとき 18

Slide 19

Slide 19 text

■ 非同期処理ではgoroutineを “直接”使わずワーカプール ⁃ メモリ管理 / goroutine leak を検出するため ⁃ 一度起動した goroutine の再利用で起動コスト低減も CPU/メモリとGoとcgo - メモリ 余談 ■ goroutine leakの検出はとても難しい... ⁃ 予期せぬところで刺さって閉じられないまま だったり ⁃ 空っぽの channel を待ち続けていたり ⁃ capが埋まってる channel に書き込もうとしてた り 19

Slide 20

Slide 20 text

(おまけ)マイクロアーキテクチャサポート

Slide 21

Slide 21 text

(おまけ)マイクロアーキテクチャサポート ■ Go1.18 からGOAMD64フラグを使ってビルドすることで、より最適化したバイナリを 作ることができるようになった ⁃ GOOS=linux GOARCH=amd64 GOAMD64=v3 go build -o a.out cmd/main.go ⁃ 例えば • v1 では math/bits.OnceCount(popcnt) や math.FMA 等は最適化されないが • v2 では popcnt は最適化 / math.FMA は最適化されない • v3 では popcnt / math.FMA などが最適化される ⁃ GOARCH=amd64 GOAMD64=v3 go tool compile -S main.go しながら runtime.x86HasXXX の 最適化具合で追いかけれる • (v4はAVX512系なので省略) ■ 試しに、前述の音声処理を GOAMD64=v2, v3 でそれぞれでベンチマークを取ると ⁃ GOAMD64=v2版 46.978µs ⁃ GOAMD64=v3版 31.94µs ⁃ とちょっと早くなる。ちなみに(慣れているので)Halideで書いたものが 1.87us になるのでHalideを使っている 21

Slide 22

Slide 22 text

まとめ

Slide 23

Slide 23 text

まとめ ■ Goはバックエンド・インフラ・ストリーミングのどの領域でも活用している ■ システム全体としてスケーラビリティがある状態を作っていく ⁃ マシンの調達も性能もスケーラビリティがある状態は重要 ⁃ スケールできるようにシステムアーキテクチャの設計は大事 ■ 一緒に作ってくれる仲間を募集しています! 23

Slide 24

Slide 24 text

ありがとうございました