Slide 1

Slide 1 text

pixivを支える技術 2014

Slide 2

Slide 2 text

自己紹介 ● 高山温 ○ @edvakf ● 2012年の3月に入社しました ● pixivチームのリーダーをしています ● 最近はグロースチームでpixivのプレミアムやア クティブユーザーまわりの数字を追いかける 他、難しい事をプラットフォームチームにお願い するお仕事をしています

Slide 3

Slide 3 text

pixivという会社 の事業の1つとしてpixivという ウェブサービスがある 他にはピクシブ百科事典、pixiv comic、BOOTH、 Cure、World Cosplayなど

Slide 4

Slide 4 text

ウェブサービスとは HTTPを通じて ● 情報を格納したり ● 情報を取り出すこと を特定のロジックに基づいて行うシステムのこと

Slide 5

Slide 5 text

ウェブサービスに必要なもの ● 情報の格納場所 ● 情報を格納したり取り出すロジック ● HTTPでやりとりする仕組み

Slide 6

Slide 6 text

つまりウェブサービスは ● ストレージ ● アプリケーション ● HTTPサーバー で成り立っている

Slide 7

Slide 7 text

pixivというウェブサービス ● ストレージ ○ MySQL ○ KyotoTycoon ○ WebDav (ファイルシステム) ○ Apache Solr ○ Apache Traffic Server ○ (Redis) ○ (MongoDB) ● HTTPサーバー ○ Apache ○ nginx ● サーバーサイドアプリケーション ○ PHP ○ (Go) ● クライアントサイドアプリケーション ○ HTML+JavaScript ○ iOSアプリ ○ Androidアプリ ● バッチ ○ PHP ○ (C++) ○ (Scala)

Slide 8

Slide 8 text

pixivというアプリケーション には 1. サーバーサイドウェブアプリケーション 2. クライアントサイドアプリケーション 3. バッチ があり、1と3はほぼすべてPHP 「バッチもpixivというアプリケーションの重要な一 部」

Slide 9

Slide 9 text

ここまでで質問?

Slide 10

Slide 10 text

Question: ● pixivの平均レスポンスタイムは? ● MySQLの1 SELECTの時間は? ● 1ページにMySQLのクエリは何個? ● 100ms ● 5ms ● 20個

Slide 11

Slide 11 text

コネクションの確立の時間 MySQLへのリクエスト1回だけなら5msぐらいだ が、同じコネクションで10回リクエストすれば2回目 からは1〜2msぐらいになる →TCPコネクションは少ないほどよい

Slide 12

Slide 12 text

Question: ● 1リクエスト内でCPUを一番使う処理は 何? ● それはどのぐらい時間がかかってる? ● テンプレートエン ジン ● レスポンスタイ ムの30%〜40%

Slide 13

Slide 13 text

つまり pixivのサーバーサイドウェブアプリケーションは ● MySQLが50% ● テンプレートエンジンが40% ● KTが5% ● その他のCPU処理が5%

Slide 14

Slide 14 text

フレームワークは? pixivはPHPのフレーワークを採用していない。 最大の理由は、最初に作られたときに フレームワークを使ってなかったから。 フレームワークを使ったらあと50msぐらい は増えるし、今からの全面導入は微妙かも。

Slide 15

Slide 15 text

Aside: DRYにするべきところ ● DRY(don't repeat yourself)するかしないか、 その判断基準について ● DRYにしない選択肢もあることを意識している ○ DRYにするべきところがDRYになっていないこともある のが課題

Slide 16

Slide 16 text

ここまでで質問?

Slide 17

Slide 17 text

Question: ウェブアプリケーションのレスポンスを 速く返すのに最も効果的な方法は?

Slide 18

Slide 18 text

Question: ウェブアプリケーションのレスポンスを 速く返すのに最も効果的な方法は? ● インデックスの使われないクエリをなくす ● キャッシュする

Slide 19

Slide 19 text

ウェブアプリのキャッシュ戦略 キャッシュと言ってもレイヤーも方法も色々 ● 304 Not Modified ● LocalStorage (JavaScript) ● KVS (memcached / redis) ● Shared Memory Cache ● Fragment Cache (Rails) ● Proxy Cache (Apache, nginx)

Slide 20

Slide 20 text

pixivのキャッシュ戦略 サーバーサイドウェブアプリのレイヤーでは ● KyotoTycoon (KT) ○ memcachedプロトコルのキャッシュサーバー ● APC ○ PHPのShared Memory Cache ○ アプリケーションサーバーのローカルキャッシュ pixiv engineering blog: pixivのデータストア/キャッシュ戦略

Slide 21

Slide 21 text

その他のpixivのキャッシュ ● 304はPHPのリクエストでは返していない ○ 投稿画像やCSSなどの静的ファイルには多用 ● AjaxリクエストをLocalStorageにキャッシュ ○ pixivポップボードのキャッシュの仕組みとFacebookのUIの話 ● MySQLのクエリキャッシュ ○ テーブルに更新クエリがあるたびに破棄される ○ 更新の多いテーブルでは意図的にオフにしてる ● Solrへのリクエストをnginxでキャッシュ

Slide 22

Slide 22 text

Aside: Solrについて ● オープンソースの検索エンジン ● MySQLからバッチでSolrに流し込んでいる ○ pixivでは唯一Scalaで書かれたコード ● PHPからはHTTPで通信 ○ HTTPはインターネットとのやりとりの他にもミドルウェア とのやりとりにも使われる ○ HTTPであることで、nginxのような普通のプロキシが使 える

Slide 23

Slide 23 text

Question: pixivというサービスがキャッシュと相性が悪い理由 は何?

Slide 24

Slide 24 text

Question: pixivというサービスがキャッシュと相性が悪い理由 は何? ● ロングテールなアクセス ● R18見る設定やマイピク限定画像など、1つの ビューでも出る要素の組み合わせが複雑 ● アクセスが多すぎてキャッシュが無くなると一気 にMySQL(など)にクエリが流れる

Slide 25

Slide 25 text

ロングテール(80:20の法則) 全データの20%が80%のアクセスを占める →キャッシュのヒット率がとても悪い pixivではロングテールなデータは最小限しか キャッシュせずにMySQLを直接参照する キャッシュしてもKTだけで、APCは使わない

Slide 26

Slide 26 text

バッチによるキャッシュ(?)生成 バッチで生成してKTに入れてるデータがある ランキング, レコメンデーション, BloomFilter, コンテストデータ, 人気タグ, etc. 計算量が多い場合や、pixiv本体とは疎結合にした い別アプリケーションで、KTのデータだけでpixivと つながっているなど KTはあくまでもキャッシュなので、いつ消えても全 部作り直せることに気をつけている

Slide 27

Slide 27 text

ここまでで質問?

Slide 28

Slide 28 text

バッチについて 「バッチもpixivというアプリケーションの重要な一 部」 一般に: ● 定期的に実行される (cron job) ● 無限ループで常に動いている (daemon) がある

Slide 29

Slide 29 text

Question: cronの問題点は?

Slide 30

Slide 30 text

Question: cronの問題点は? ● rootでないと更新できない ● コマンドが失敗したかわかりにくい ● コマンドのログが見れない ● コマンドの実行履歴が見れない ● とにかく面倒!! ○ /etc/cron.d/ 以下のファイル名に制約があるとか ○ パーミッションに制約があるとか

Slide 31

Slide 31 text

Jenkins 元は継続的インテグレーションのためのツールだ が、cronの代替としてとても優秀 ● 登録されているジョブが一覧できる ● 現在走っているジョブが一覧できる ● ジョブの実行中の標準出力が見られる ● ジョブの過去の失敗履歴やログが見られる ● ウェブ画面ですべて操作できる

Slide 32

Slide 32 text

pixivでのJenkins CI用途でしか使ってなかったが、今年からcronの 代替として全面導入 daemon的な処理もJenkinsで1分おきに実行 ● 1分したらwhileループを抜ける ● デーモンの管理にJenkinsほどの良いツールが 無いのが理由(の1つ)

Slide 33

Slide 33 text

ここまでで質問?

Slide 34

Slide 34 text

MySQL サイトの規模が大きくなると必ず行わなければい けないこと、それは 「データベースの系統を分ける」 ユーザーIDで分割したりデータの日付で分けたり することもあるが、pixivではテーブルのアクセス頻 度や機能ごとに分割している

Slide 35

Slide 35 text

データベース系統 ● ユーザー、イラストデータ ● 小説 ● プレミアム関係 ● ブックマーク ● グループ機能 ● プレミアム向けアクセス解析 などなど、それぞれにMasterが1台とSlaveが複数 ある

Slide 36

Slide 36 text

Question: サービスのデータベースが1系統のみであることが 望ましい理由は?

Slide 37

Slide 37 text

Question: サービスのデータベースが1系統のみであることが 望ましい理由は? ● JOINが使える ● トランザクションが使える ● ウェブアプリケーションから複数のDBに接続し なくてよい

Slide 38

Slide 38 text

DBまわりで特に意識していること ● 最近はJOINはあまりしない方針 ○ アプリケーションレベルのJOINを多用 ● ORMは使わない ○ 流れるクエリを意識するためにSQLを手書き ○ ガチガチにチューニングしたクエリがたくさん ● MySQLにアクセスする層とアプリケーションロ ジックの層を分離

Slide 39

Slide 39 text

Aside: pixiv最大のデータベース ブックマーク ● 12億レコード ○ uint32max = 42億 ● 1年で倍増弱ぐらい 今後、市販のメモリで収まりきらなくなれば、期間 で分割なども考える必要があり、更にカオスに…

Slide 40

Slide 40 text

ここまでで質問?

Slide 41

Slide 41 text

Question: pixivではほぼすべてのユーザーデータはMySQL に入れているが、MySQLに入っていないデータは 何?

Slide 42

Slide 42 text

Question: pixivではほぼすべてのユーザーデータはMySQL に入れているが、MySQLに入っていないデータは 何? 投稿された画像

Slide 43

Slide 43 text

画像ストレージ リレーショナルデータベースに入らないファイル は、どのサービスもそれぞれの要件に合わせて頭 をひねる部分 pixivではWebDAVを採用している ● HTTPのGETやPOSTでファイルシステムにア クセスするプロトコル ● Apacheやnginxのプラグインとして使える

Slide 44

Slide 44 text

Question: 画像をMySQLに保存しない理由は?

Slide 45

Slide 45 text

Question: 画像をMySQLに保存しない理由は? ● ファイルあたりのサイズが大きい ● 総容量も多い(40TB) ● 配信するときにApacheやnginxが直接読める ファイル単位としてある方が便利 ● 管理上もファイルとしてあるほうがSQLを書いて 取り出すよりラク

Slide 46

Slide 46 text

pixivの画像の特徴 ● 1つ1つが手作りなので写真と違って増えるスピードは速くな い ● PC、スマホ、ガラケーなどがあり、生成するサムネイルの種 類が多い ● 漫画の枠や、正方形クロップ時の特殊な変換 ● 変換後も同じファイルフォーマット ○ なんでそうしてしまったのか… ● 数々の歴史的経緯… ● 最近ではうごイラも

Slide 47

Slide 47 text

pixivの画像変換 ● 昔はすべてのサムネイルを投稿時に変換して保存 ● 非同期アップロード化(2009) ○ pixivの画像アップロードシステム ● mod_small_lightで配信時に動的変換 ○ ただしリクエストの多いサムネイルは静的サムネイルのまま ○ YAPC::Asia 2012「pixivのサムネイル事情」 ● サムネイルマスター(2014) ○ サムネイル生成元となる大きめのサムネイルをJPEGで用意 ● サムネイル変換クラスター (2014) ○ https://github.com/pixiv/go-thumber ○ 近日稼働予定!

Slide 48

Slide 48 text

画像配信 pixivというウェブアプリケーションと pixivの画像ストレージ、配信はまあまあ疎結合 →今後はもっと疎結合にしていきたい 理想はAmazon S3のように、ファイルをPOSTする とURLが返ってくるぐらいのブラックボックスにして いきたい 詳しくはインフラのところで話されるかも?

Slide 49

Slide 49 text

ここまでで質問?

Slide 50

Slide 50 text

そろそろまとめ 主にpixivのサーバーサイドアプリケーションを、ス トレージとキャッシュに注目して見ていきました。 pixivならではのパフォーマンス上の問題や アプリケーションの制約について いくつか紹介しました。

Slide 51

Slide 51 text

今日話さなかったこと ● 個別機能にまつわる話 ● クライアントサイドの話 ● デプロイの話 ● テストの話 ● グロースチームのエンジニアとしての話 その他いっぱい →興味があればあとで質問歓迎