ドーモ、はじめまして。 WEBアプリケーションエンジニアの@Moyashipanです。 毛糸を触ると手がかゆくなる体質なのに、趣味は編みぐるみです。
さて、前編の記事では@ykskがアクセス解析機能の UI について解説しましたが、 後編ではアクセス解析機能のリリースまでの流れについてご紹介します。
まず初めに、アクセス解析機能の開発はプロトタイピングを行うことから始められました。
プロトタイピングを行うねらいは以下の通りです。
- どのような方法で実装するのかを検討する
- 集計結果から、ユーザにとって有益な情報が得られるのかを調査する
実際に行われた複数のプロトタイピングについて、時系列に沿って以下に紹介します。
プロトタイピング : ログファイルから
初期のプロトタイピングでは、既存のpixivのアプリケーションに処理を追加しなくて良いように、すでに存在しているログファイルを利用してグラフ描画が行われました。 利用されたのはフロントサーバのログファイルです。
当初はログファイルを直接読んで集計を行なっていましたが、 そのままではグラフに必要ない情報を含んでいたため以下のように中間データを作成して集計を行いました。
- グラフに必要な情報のみ抽出
- Ruby の Marshal データに変換
- 以降はその中間データから並列処理で集計を行う
それをもとに集計されたのが以下の2種類のグラフです。
全イラストに対する反応数グラフ
1つ目は、全イラストに対する反応(ブックマーク、評価、タグ編集)の回数で、 今後処理する必要のあるデータの総量をざっくりと把握するために集計されました。
特定作品の1分ごとの閲覧数グラフ
2つ目は、特定の作品が閲覧された結果だけを抽出し、1分ごとの閲覧数をグラフとして描画しました。 得られたグラフを実際に見てみると、ユーザの人気度の違いによってグラフの見え方に大きく違いが出る事や、 1分ごとという細かい粒度のデータは必要無い事がわかりました。
プロトタイピング : 反応があった順
次に、ブックマークや評価といった反応のあった作品を、反応があった順に並べる画面が試作されました。 そこでは前回のプロトタイピングのようにログファイルから集計を行うのではなく、 pixiv のアプリケーションに処理を追加し、特定のユーザ(絵を書いているピクシブ社員)の作品に対して反応があった場合に Redis にデータを書き込むという方法が取られました。 (もしそのままのシステム構成で運用していた場合に、全プレミアムユーザの全投稿作品に対する処理をさばけていたかは不明です)
そうして作成されたプロトタイプでは、アクセス解析のページを開くとまず反応のあった作品が並んでおり、 各リンクから詳細なグラフへ飛べるというページ構成が取られていました。
ですが、作品に対する反応が少ないユーザがアクセスした場合、 このページ構成では最初に見える画面が代わり映えしないため、 あまり有益な情報のあるページに見えず「テンションが上がらない」ページになってしまう事がわかりました。
プロトタイピング : 折れ線グラフ
反応があった順の試作と並行して、閲覧数などの折れ線(累積)グラフも試作が行われていました。 ここでは前述したログファイルからの集計ではなく、 イラストの閲覧数や評価数などが格納されているテーブルを定期的に参照して、その時その時の値をアクセス解析用のテーブルに保存する方法が取られました。
またこの頃は Google Charts の利用についても検討されており、 Geomap を利用して作品の閲覧数を閲覧者の国籍別に地図上にプロットする機能なども検討されていました。
プロトタイピング : 男女別閲覧数
プロトタイピングが進行する中で、ページデザインのモックアップも出来上がりつつありました。 モックアップには閲覧数を男女別に表示する機能が描かれており、それについてもプロトタイプを作成する事になりました。
丁度その頃、 Google Summer of Code に採用された経験のある学生エンジニアがインターンシップに来てくれたので、このプロトタイピングを任せる事になりました。
これまでのプロトタイピングと違い、あいにく閲覧数に関する既存のテーブルには、男女別のグラフを表示するために都合の良いデータは含まれていませんでした。 そこで今回のプロトタイピングでは「特定のユーザのイラストが見られた場合にアクセス解析用のテーブルにインクリメントクエリを発行する」という処理を、pixivのアプリケーションに追加する方法が取られました。
この方法を全プレミアムユーザの全投稿作品に対して適用することは処理量的に現実的ではありませんが、 今回のように対象となるユーザ数をごく一部に絞れば、処理数が巨大になることも無く、既存のアプリケーションへの影響を最小限に抑えられるだろうという判断のもと行われました。
そうしてデータが得られた後、 担当してくれた学生エンジニアは JavaScript を書いた経験が無いながらも、グラフ表示部分も爆速で作ってくれました。 Google Charts の使いやすさもあったでしょうが、爆速という言葉を会社のスローガンにしてTシャツを作りたくなるほどに爆速でした。
今回のプロトタイピングでは、そうして得られたグラフを社員であれば pixiv 上で閲覧できる状態にしました。 アクセスしやすい場所にグラフを設置した事で、開発の人間以外からもフィードバックが得られるようになり、社内でのアクセス解析に対するテンションも上がったように感じます。
リリースされたバージョン
プロトタイピングによって用意すべきグラフがわかってきて、ページデザインのモックアップもできてから、開発が本格的に始まりました。
MySQL へ格納
前述の「反応があった順」のプロトタイプでは Redis を利用していましたが、最終的には利用しませんでした。 理由は、以下のような懸念点があったためです。
- Redis でどこまでさばけるのかといった動作検証を十分に出来ていない
- 目標となるリリース日までに予想外の問題点が出てくる可能性がある
結果的に、反応があった順や各種グラフのデータの格納には、運用経験や開発速度の見積もりやすさなども考慮して MySQL を選択しました。
Fluentd で集計
また前述の「男女別閲覧数」のプロトタイプでは、作品閲覧時に直接アクセス解析用のテーブルにデータを挿入することで目的のデータを用意していましたが、 最終的には Fluentd を利用して、ログファイルを中継した形でアクセス解析用のデータを用意することにしました。
処理の流れとしては以下のようになります。
- 作品が閲覧されたり反応があった際に、閲覧者の性別やリファラなどを含んだJSONを各アプリケーションサーバのログファイルに保存
- 各アプリケーションサーバの Fluentd がログファイルを tail し、集計用サーバに転送する
- 集計用サーバで動作する Fluentd がそれらをまとめて、1分ごとのファイルに保存
- その1分ごとのログファイルを元に、同じく集計用サーバで動作するバッチ処理がアクセス解析用テーブルへデータをまとめてインサート
こうしてアクセス解析機能のほぼ全ての表示要素は、同じログ集計処理を利用して構築されています。
まとめ
アクセス解析機能をリリースするまでの流れと、仕組みについてご紹介しました。
ピクシブではニュービー、タツジンを問わず優秀なエンジニアを募集しています。
リリースに関わった以下の人達と仕事がしてみたい方は採用情報を御覧ください。
- edvakf (Application, DB-Schema, Manage)
- ksu (Application, DB-Schema)
- yksk (UI, UX, Markup, JS)
- ysp (UI, UX, Design)
- atsumu (DB-Schema, Logging, Benchmark)
- harukasan (Server, Logging)
- mido (Prototype)
- kovensky (Prototype)
- norio (Manage)
- susan (Press Release)
- ALL pixiv STAFF (Review)
- tarbrick (SHACHOU)
- moyashipan (Application, DB-Schema)
(太字は主要メンバー)