UUUM攻殻機動隊(エンジニアブログ)

UUUMのエンジニアによる技術ブログです

4000以上のチャンネルを支えるデータ解析基盤をBigQuery, Go, embulk等で整備した話

nazoです。

UUUMでは2017年3月時点で4000チャンネルを抱えており、日本最大のマルチチャンネルネットワーク(MCN)となっております。

これだけのチャンネル数があり、さらに多くのチャンネルは毎日のように動画を投稿しており、1日に増える動画の数だけでも相当な数になっています。

以前はこれらのデータの取得をPHPで行っていたのですが、最近Goによる新システムの運用を少しずつ始めており、大きな変化が生まれています。 今回はそのあたりについて解説したいと思います。

現在の構成

それまで動いていたPHPによる解析システム(こちらは今回は話しません)があるのですが、これはUIとデータ取得部分が、そもそも他のシステムと同居しており、改修が難しくなっていました。また、PHPは並列処理が苦手で、やろうと思えばいくつか手段はありますが、並列化に対して大きくリソースを割いていませんでした。そのため、データ量の多い処理では24時間近く処理時間がかかっていました。

これを解決するために、新たに高速かつ独立したデータ収集システムを用意しようと動き始めました。

この時に決めた要件は

  • Goを使う
  • データ取得部分で、データ取得に関すること以外を行わない

というものでした。

ざっくりと、現在は以下のような構成で動いています。

f:id:nazone:20170629134341p:plain

なぜGoか

Goに関するメリットに関しては詳細な解説が各所に存在しますが、改めて簡単に説明すると以下のような感じです。

そもそも言語自体の実行速度が高速

Goは最初から高速と言われていた上に、バージョンが上がる毎による度重なる最適化により、さらなる速度を手に入れています。ここ最近は特にGCに関する高速化が多いように見えます。GCが最適化されると、長時間動作するアプリケーションでの効率が特に上昇します。

手軽かつ強力な並列処理

goroutineによる並列処理は、特にAPIのようなネットワーク処理が多発する場合の制御に有効です。Goの並列処理は、複数のカーネルスレッド(プロセス)と複数のユーザースレッドを制御するM:Nスレッドモデルで動作します。最近は GOMAXPROCS もコア数で自動設定されるので、CPUのコア数をフルに使用しつつ、スレッドによる並列性をユーザーが意識せずに扱うことができます。

強力な標準ネットワークライブラリ

ネットワーク系のライブラリが言語に標準搭載されていることにより、ネットワーク系の処理を書くのに特別な知識を必要とせず、ノンブロッキングIOや並列処理は言語・ライブラリ側で吸収されているので、余計なことを考えずに高速なプログラムを簡単に書くことができます。今回のような大量のAPIを叩いたりするような用途には最適と言えます。

Goで書かれたデータ収集システムで動いている内容

後述するData Apiによる情報の取得がメインになっております。速報性の高い情報を確実に取得するためのものとして書かれております。また、業務上の必要に応じて、所属していないチャンネルの情報も取得できるようになっております。所属外チャンネルに関しては公開されている情報のみを取得しております。

Goで書いたことによって、以前は最大24時間近くかかっていた処理が、なんと2分程度で終わるようになりました。元の書き方が良くなかったところはあるにしても、劇的な改善に成功しました。

embulkとdigdag

データ収集システムで取得したデータを他システムから利用する際に、DBを直接繋いでしまう方法もありますが、アプリケーションからそちらのDBへの接続も張ってしまうと可用性が下がってしまうので、embulkで必要なデータのみ取得しています。embulkにより、必要なデータのみを高速に転送することが可能です。

また、データ収集システムでの各種ワークフローや、embulkの定期実行などに、digdagを使っています。以前はRundeck等も使用していたのですが、ワークフローの書きやすさ、メンテナンスのしやすさといったところでdigdagのほうが利便性が高いと判断し、最近はdigdagを主に使用しています。

どちらも、シンプルかつ高機能という使いやすさがあり、重宝しております。

BigQuery

まず前提の話として、YouTube APIには、速報値の正確を持つData Apiと、正確な値を取得するためのAnalytics and Reporting Apiの二種類があります。簡単に説明すると、Data Apiのほうは一般ユーザーでも取れる情報の取得と、チャンネルや動画の一般的な操作が利用できます。

一般ユーザーでも取れる情報というのは、「再生数」や「チャンネル登録者数」といった、画面上にも表示されている情報のことですが、YouTubeの再生数の表示は、不正な方法によって水増しされた場合などに、後で修正を入れたりすることがあります。そのため、現在表示されている数値が正確な数値(つまり、収入に関わる数値)かどうかはわからないということになっております。また、そもそも「表示したタイミングの数値」なため、特定の日の中での正確な値は取得することができません。

一般の利用ではData Apiで十分ではありますが、我々のようなクリエイターを管理する立場がその数値では何かと不便ですので、正確な値を取得するためにAnalytics and Reporting Apiも併用します。このデータは、速報性がなく数日遅れでデータが作成されるものの、その日の確定値を正確に取得することができます。

Analytics and Reporting Apiには、「指定したチャンネルまたは動画の指定範囲を取得する」Analytics Apiと、「指定のチャンネルまたは動画のCSVデータをまとめて取得する」Reporting Apiの二種類が存在します。

個人利用であれば前者で十分ですが、我々のような4000チャンネルの動画を全て取得しようとすると、Api利用回数があっという間に尽きてしまいます。そこで後者を利用するのですが、どちらにしてもデータ量が膨大なので、BigQueryに入れて解析するのが相性が良いです。

Reporting ApiからBigQueryにデータを入れる処理は自作しても良いのですが、Google側でBigQuery Data Transfer Serviceという、そのものが用意されています。これはYouTube以外にも、Google AdWords等に対応していますので、YouTubeは使っていないけどAdWordsはヘビーユーザーであるという場合には試してみると良いのではないでしょうか。

というわけで、ノンプログラミングで、YouTubeのデータをBigQueryに入れることが可能です。

まとめ

Goによるデータ収集部の切り出し、embulkやdigdagの利用により、適切な粒度によるサービスの分離を行うことができ、実行速度の向上と可用性の向上の両方を得ることができました。

取得したデータはre:dashを使用しモニタリングをしています。データ部分だけを切り出して流用することも簡単になったため、今後は分析も効率的に行うことができそうです。

UUUMでは、4000を超えるチャンネルを分析して活かすことのできるエンジニアも募集しています。詳しくは以下をご覧下さい。