Slide 1

Slide 1 text

佐藤 琢斗 Pocochaを支えるバックエンド 〜アーキテクチャとDBシャーディング〜

Slide 2

Slide 2 text

この発表を聞くとわかること 1. ソーシャルライブサービスを支える   バックエンドの技術構成がわかる 2. リソースの限られた新規事業で   何を重視して開発してきたかわかる 3. DB書き込み負荷対策のために  どのようにシャーディングを行ったかわかる

Slide 3

Slide 3 text

アジェンダ 1章. 自己紹介 2章. Pocochaとは? 3章. Pocochaのバックエンド構成 4章. Pocochaのはじまり 〜限られたリソースとユーザー価値〜 5章. 急成長とDB負荷とシャーディング 6章. まとめとPocochaのこれから

Slide 4

Slide 4 text

アジェンダ 1章. 自己紹介 2章. Pocochaとは? 3章. Pocochaのバックエンド構成 4章. Pocochaのはじまり 〜限られたリソースとユーザー価値〜 5章. 急成長とDB負荷とシャーディング 6章. まとめとPocochaのこれから

Slide 5

Slide 5 text

自己紹介 佐藤 琢斗 / Takuto Sato (tockn) ・2020年DeNA新卒入社(1年目) ・Pocochaシステム部 ・Pocochaのイベント開発・運用を担当 Twitter: @tockn_s GitHub : tockn #Go #Vue.js #Firebase #GCP

Slide 6

Slide 6 text

今年度新卒入社したエンジニアが キャッチアップしてきたPocochaの裏側をお話します

Slide 7

Slide 7 text

アジェンダ 1章. 自己紹介 2章. Pocochaとは? 3章. Pocochaのバックエンド構成 4章. Pocochaのはじまり 〜限られたリソースとユーザー価値〜 5章. 急成長とDB負荷とシャーディング 6章. まとめとPocochaのこれから

Slide 8

Slide 8 text

Pocochaとは ・2017年に始まったソーシャルライブサービス ・誰でも気軽にライブ配信、視聴が可能  ・ライバー、リスナー ・チャットやアイテムによるコミュニケーション ・ランキング、イベントで上位を目指す仕組み

Slide 9

Slide 9 text

Pocochaとは ・絶賛急成長中  ・190万DL突破!  ・ライバー、リスナーMAU   前年比3倍! 2021年3月期第2四半期 決算説明会資料より抜粋

Slide 10

Slide 10 text

Pocochaの主要な機能(配信中) ・コメント  ・ライバーや他リスナーと会話 ・いいね  ・画面タップで送信。連投可能 ・アイテム  ・コインを消費してライバーを応援 ライバー、リスナー間 双方向コミュニケーション ⚠イメージです

Slide 11

Slide 11 text

Pocochaの主要な機能 ・イベント  ・開催期間中にライバー間でスコアを競う  ・入賞者には賞品贈呈  ・イベント終了直前の盛り上がり  ・毎月約100本のイベントを開催 リアルタイムスコア計算で 盛り上がりを演出 ⚠イメージです

Slide 12

Slide 12 text

ここまでを振り返る ・Pocochaというサービスの重要な要素  ・ライバー、リスナー間の双方向コミュニケーション   ・コメント、アイテム等  ・リアルタイム性   ・配信、イベントの盛り上がり →どのような構成でこれらを実現しているか?

Slide 13

Slide 13 text

アジェンダ 1章. 自己紹介 2章. Pocochaとは? 3章. Pocochaのバックエンド構成 4章. Pocochaのはじまり 〜限られたリソースとユーザー価値〜 5章. 急成長とDB負荷とシャーディング 6章. まとめとPocochaのこれから

Slide 14

Slide 14 text

Pocochaのバックエンド構成全体像

Slide 15

Slide 15 text

アプリケーションレイヤ ・Ruby on Rails  ・モノリシック  ・クライアントと通信するほぼ全てのAPI  ・配信審査、運用を行う管理画面  ・EC2 with Auto Scaling ・ランキング周りはRedisで管理  ・Sorted set  ・リアルタイム性

Slide 16

Slide 16 text

ユーザー間リアルタイム通信とbcsvr ・ユーザー間のリアルタイム通信が必要  ・コメント  ・アイテム  ・いいね等 ・bcsvr  ・DeNA内製WebSocket Server  ・Pub/Sub  ・モバゲーでの利用実績

Slide 17

Slide 17 text

ユーザー間リアルタイム通信とbcsvr ・ユーザー間のリアルタイム通信が必要  ・コメント  ・アイテム  ・いいね等 ・bcsvr  ・DeNA内製WebSocket Server  ・Pub/Sub  ・モバゲーでの利用実績

Slide 18

Slide 18 text

ユーザー間リアルタイム通信とbcsvr ・ユーザー間のリアルタイム通信が必要  ・コメント  ・アイテム  ・いいね等 ・bcsvr  ・DeNA内製WebSocket Server  ・Pub/Sub  ・モバゲーでの利用実績

Slide 19

Slide 19 text

ユーザー間リアルタイム通信とbcsvr ・ユーザー間のリアルタイム通信が必要  ・コメント  ・アイテム  ・いいね等 ・bcsvr  ・DeNA内製WebSocket Server  ・Pub/Sub  ・モバゲーでの利用実績

Slide 20

Slide 20 text

配信基盤 ・Amazon IVS (Interactive Video Service)  ・2020年に誕生  ・マネージドライブ配信ソリューション  ・オートスケールによるスケーラビリティ ・以前はwowzaを使用  ・メディアサーバソフトウェア  ・オンプレで管理  ・スケーラビリティ、品質管理コストが課題

Slide 21

Slide 21 text

ここまでを振り返る ・以上がPocochaの大まかなバックエンド構成 ・手堅い構成であり、モダンな構成ではない?  ・マイクロサービス  ・Docker, Kubernetes等 ・なぜこのような構成を選択してきたのか? → Pocochaのはじまりを覗いてみる

Slide 22

Slide 22 text

アジェンダ 1章. 自己紹介 2章. Pocochaとは? 3章. Pocochaのバックエンド構成 4章. Pocochaのはじまり 〜限られたリソースとユーザー価値〜 5章. 急成長とDB負荷とシャーディング 6章. まとめとPocochaのこれから

Slide 23

Slide 23 text

インキュベーションプログラムとPococha ・Pocochaはインキュベーションプログラムの1つとして誕生 ・インキュベーションプログラムとは?  ・DeNA社内で行われた職種、所属にかかわらず   新規事業の立ち上げができるプロジェクト (現在は終了)  ・4年間で40の新規事業を立ち上げ ・1つの事業に対して少額投資  ・新規事業の数を増やす  ・継続、クローズのフットワークを軽く 4年間で40の新規事業を生んだDeNA流 リーンインキュベーションの秘訣| 私の所信表明 千條 吉基 https://fullswing.dena.com/archives/2925

Slide 24

Slide 24 text

Pocochaの初期 ・リソースは限られていた  ・予算1000万 + α (人件費込み)  ・エンジニアは2人   ・iOS, バックエンド1人ずつ  ・3ヶ月程でリリース、高速検証する必要があった →限られたリソースで如何にして価値を生むか?

Slide 25

Slide 25 text

ここでいう「価値」とは何か ・仮説検証段階では…  ・高速に機能をリリースし、分析して次の手を決めることが重要  ・「短期的なスピード」が価値  ・それがユーザー価値に直結 ・エンジニアの視点で…  ・機能のリリース、クローズを可能な限り早くすること  ・リリースした機能を即座に分析できる基盤を作ること

Slide 26

Slide 26 text

限られたリソースで価値を生む ・初期Pocochaの場合、リソースは多いとは言えなかった  (リソースが潤沢なスタートアップは少ないのでは?) ・技術の学習コストは事業の負担  ・例えば無理にモダンな技術を採用すると悪手になることも ・そこで堅実な技術選定が求められる  ・密結合であるRailsで開発スピードを出す  ・開発者本人が「既に持っている経験」を活用

Slide 27

Slide 27 text

ユーザー価値最大化に努めた結果 ・高速な機能開発、分析、意思決定に注力し、  とにかくユーザー価値最大化に努めた ・結果、Pocochaは大きく成長 リスナーMAU 2021年3月期第2四半期 決算説明会資料より抜粋

Slide 28

Slide 28 text

ここまでを振り返る ・以上がPocochaが手堅い構成を取ってきた理由 ・その結果Pocochaは着実に成長 ・「短期的なスピード」が価値だった中の成長で  浮き彫りになった課題もあった → どのような課題が浮き彫りになったのか?

Slide 29

Slide 29 text

アジェンダ 1章. 自己紹介 2章. Pocochaとは? 3章. Pocochaのバックエンド構成 4章. Pocochaのはじまり 〜限られたリソースとユーザー価値〜 5章. 急成長とDB負荷とシャーディング 6章. まとめとPocochaのこれから

Slide 30

Slide 30 text

急成長と浮かび上がる課題 ・巣ごもり需要もありPocochaは急成長  ・成長スピードが一段階加速 ・想定より早く課題解決を迫られることに  ・その1つが「DB(MySQL)負荷」 リスナーMAU 2021年3月期第2四半期 決算説明会資料より抜粋

Slide 31

Slide 31 text

DB負荷と向き合う(読み込み負荷) ・読み込み負荷に関して  ・元々DBはレプリケーション済み   ・読み込みはリードレプリカから行う ・読み込みと書き込みの分割 ・複数レプリカによる負荷分散 ・読み込み負荷は大きな問題にはならず

Slide 32

Slide 32 text

DB負荷と向き合う(書きこみ負荷) ・書き込み負荷に関して  ・シャーディングされていなかった  ・今まではスケールアップで解決していた   ・限界があるが、まだ先のはずだった…  ・成長スピードが上がったことで、限界が早く来た   ・db.r5.12xlargeまでスケールアップ、残り2段階…

Slide 33

Slide 33 text

シャーディング対応 ・書き込み起因の負荷を減らすためにシャーディング  ・特に負荷の大きいテーブル ・そもそもシャーディングとは  ・水平分割  ・独立した複数DBに    同一テーブルのレコードを分散配置  

Slide 34

Slide 34 text

シャーディング対応で考えること ・レコード分散方法  ・どのレコードをどのシャードに置くか? ・id採番方法  ・どのように複数DBで一意なidを持つか? ・アプリケーション側実装方法  ・どのようにApp側から複数DBを操作するか?

Slide 35

Slide 35 text

シャーディング対応で考えること ・レコード分散方法  ・どのレコードをどのシャードに置くか? ・id採番方法  ・どのように複数DBで一意なidを持つか? ・アプリケーション側実装方法  ・どのようにApp側から複数DBを操作するか?

Slide 36

Slide 36 text

レコード分散方法 ・どのレコードをどのシャードに割り当てるか ・idを元に一意に決定する方法  ・id範囲   ・例: idが1~100はシャード1へ、101~200はシャード2へ等  ・idとシャード数との剰余   ・例: シャード数が2の時、id: 100はシャード1へ、id: 101はシャード2へ等 ・シンプルで高速だが、シャード増設への対応が困難

Slide 37

Slide 37 text

レコード分散方法 ・そこでPocochaでは… ・割り当て先を重み付きランダムで決定する方法  ・INSERT時に割り当て   ・割り当て先管理テーブルにINSERT ・シャード増設に対応可能 ・重みを変更し割り当て先の工夫が可能 割当先管理テーブル

Slide 38

Slide 38 text

レコード分散方法 ・そこでPocochaでは… ・割り当て先を重み付きランダムで決定する方法  ・INSERT時に割り当て   ・割り当て先管理テーブルにINSERT ・シャード増設に対応可能 ・重みを変更し割り当て先の工夫が可能 割当先管理テーブル

Slide 39

Slide 39 text

シャーディング対応で考えること ・レコード分散方法  ・どのレコードをどのシャードに置くか? ・id採番方法  ・どのように複数DBで一意なidを持つか? ・アプリケーション側実装方法  ・どのようにApp側から複数DBを操作するか?

Slide 40

Slide 40 text

id採番方法 ・シャーディングすると1テーブルが複数DBに跨る ・複数DB間で一意なidを担保する必要 ・Pocochaでは2つの方式を採用  ・既存のテーブル   ・採番テーブル方式  ・新規作成するテーブル   ・ULID方式

Slide 41

Slide 41 text

・Pocochaの場合、既存のテーブルのidはAUTO_INCREMENT  ・このままでは複数DB間で一意なidにならない ・そこで採番テーブルを作成  ・idのみを保持するテーブル ・実際のテーブルには  採番テーブルで採番したidをINSERT ・既存のテーブルをシャーディング可能に id採番方法 - 採番テーブル方式 採番テーブル

Slide 42

Slide 42 text

・Pocochaの場合、既存のテーブルのidはAUTO_INCREMENT  ・このままでは複数DB間で一意なidにならない ・そこで採番テーブルを作成  ・idのみを保持するテーブル ・実際のテーブルには  採番テーブルで採番したidをINSERT ・既存のテーブルをシャーディング可能に id採番方法 - 採番テーブル方式 採番テーブル

Slide 43

Slide 43 text

・Pocochaの場合、既存のテーブルのidはAUTO_INCREMENT  ・このままでは複数DB間で一意なidにならない ・そこで採番テーブルを作成  ・idのみを保持するテーブル ・実際のテーブルには  採番テーブルで採番したidをINSERT ・既存のテーブルをシャーディング可能に id採番方法 - 採番テーブル方式 採番テーブル

Slide 44

Slide 44 text

・Pocochaの場合、既存のテーブルのidはAUTO_INCREMENT  ・このままでは複数DB間で一意なidにならない ・そこで採番テーブルを作成  ・idのみを保持するテーブル ・実際のテーブルには  採番テーブルで採番したidをINSERT ・既存のテーブルをシャーディング可能に id採番方法 - 採番テーブル方式 採番テーブル

Slide 45

Slide 45 text

id採番方法 - ULID方式 ・ULIDとは  ・一意に識別できるソート可能な識別子  ・生成順に辞書順でソート可能  ・ソート可能なUUIDのようなもの ・新規テーブルのidはULIDを使用  ・複数DBのテーブル間で一意 & 順序も担保 01EVXNGW7BASK7B1G92DQ8BW1K 01EVXNGW7BWZK8TF16EWF2PSW7 01EVXNGW7BQPHMETNBMMZ6GD0C ︙ ULIDの生成例

Slide 46

Slide 46 text

シャーディング対応で考えること ・レコード分散方法  ・どのレコードをどのシャードに置くか? ・id採番方法  ・どのように複数DBで一意なidを持つか? ・アプリケーション側実装方法  ・どのようにApp側から複数DBを操作するか?

Slide 47

Slide 47 text

アプリケーション側実装方法 ・Pocochaでは現在Rails5を使用 ・Rails 5.x単体ではシャーディング非対応  (Rails 6.1では対応しているが、当時未リリース) ・そこでOctopusを使用  ・Rails (Active Record) でシャーディングするためのgem  ・メジャーであること、社内の利用実績が選定理由

Slide 48

Slide 48 text

ここまでを振り返る ・急成長で特に大きかった課題は「DB書き込み負荷」  ・シャーディング対応 ・「短期的なスピード」が価値のフェーズから  「長期的な品質」も価値となるフェーズになった → 今後Pocochaはどうなっていくのか?

Slide 49

Slide 49 text

アジェンダ 1章. 自己紹介 2章. Pocochaとは? 3章. Pocochaのバックエンド構成 4章. Pocochaのはじまり 〜限られたリソースとユーザー価値〜 5章. 急成長とDB負荷とシャーディング 6章. まとめとPocochaのこれから

Slide 50

Slide 50 text

Pocochaのこれから ・グローバル版の開発  ・多言語対応 etc... ・新機能開発  ・コラボ配信  ・新規イベント etc... 「守りつつ攻める体制」でグロースさせる! ・さらなる品質向上の追求  ・パフォーマンス   ・遅延時間短縮   ・通信プロトコル最適化  ・組織拡大に対応する    アーキテクチャ模索

Slide 51

Slide 51 text

発表まとめ ・システム構成  ・「双方向通信」と「リアルタイム性」がキーワード  ・Ruby on Rails, MySQL, Redis, bcsvr, Amazon IVS ・Pocochaはミニマムに始まった事業  ・高速仮説検証を重視し、技術選定は堅実に! ・シャーディングで急成長によるDB負荷対策  ・ランダム分散, 採番テーブル, ULID, Octopus

Slide 52

Slide 52 text

We are hiring! Pocochaではエンジニアを絶賛募集中!  話を聞いて興味を持った方!  グロースフェーズの事業でサービスの成長にコミットしたい方!

Slide 53

Slide 53 text

No content