pixivの画像アップロードシステム
DESCRIPTION
pixivの画像アップロードシステムTRANSCRIPT
自己紹介•氏名:久保 達彦• H.N:bokko / @cubicdaiya• pixivのインフラ兼ソフトウェアエンジニア• 2010年10月入社• HP:http://cccis.jp
普段はC++でdiffのライブラリとか作ってます
http://code.google.com/p/dtl-cpp
今日お話すること
入社して最初の仕事
画像アップロードの高速化
従来のアップロードの問題点
• 大量のサムネイル生成処理• 全部同期的に処理される• アップロードが集中すると全体的に重くなる• とにかく遅い・重い
従来のアップロードの問題点
• 大量のサムネイル生成処理• 全部同期的に処理される• アップロードが集中すると全体的に重くなる• とにかく遅い・重い
手元にあった2MBのJPG画像をアップロードしようとしたら20秒弱かかった
これはいけない
新しいアップロードシステムの設計・開発に取りかかることに
制作:bokko監修:kamipoさん
冗談抜きで、当時僕が書いたアップロードまわりのコードの8~9割ぐらいはkamipoさんにレビューされてます。
pixivの画像アップロードフロー
ファイル選択画面 情報入力画面 完了画面
pixivの画像アップロードフロー
ファイル選択画面 情報入力画面 完了画面
pixivの画像アップロードフロー
ファイル選択画面 情報入力画面 完了画面
全てのサムネイル生成はここの画面遷移時に同期的に行われる
pixivの画像アップロードフロー
ファイル選択画面 情報入力画面 完了画面
全てのサムネイル生成はここの画面遷移時に同期的に行われるユーザにはとても遅く感じる(そして実際遅い)
pixivの画像アップロードフロー
ファイル選択画面 情報入力画面 完了画面
pixivの画像アップロードフロー
ファイル選択画面 情報入力画面 完了画面
pixivの画像アップロードフロー
ファイル選択画面 情報入力画面 完了画面
pixivの画像アップロードフロー
ファイル選択画面 情報入力画面 完了画面
実はユーザが一番時間を使う箇所
情報入力画面
情報入力画面
キャプションやタグを一生懸命入力する傾向が強い
サムネイル生成はユーザが情報を入力している間に非同期で行う
なので、
ファイル選択画面 情報入力画面 完了画面
・サムネイル生成に必要な情報をエンキュー・ロックファイル作成
ロックファイルが削除されるまでポーリング
サムネイル生成ジョブをデキュー サムネイル生成 ロックファイルを削除
サムネイル生成ジョブをデキュー
サムネイル生成ジョブをデキュー
サムネイル生成
サムネイル生成
ロックファイルを削除
ロックファイルを削除
サムネイル生成プロセスをひたすらフォーク最大同時実行プロセス数:5
・・・
・・・
・・・
プロセス終了
プロセス終了
プロセス終了
バックエンドの処理
フロントエンドの処理こんな感じ
続いて、システム構成について
アップロード処理の特徴
•CPUバウンド•メモリバウンド
サムネイル生成は非常に重いタスク
Load Balancer ・・・
APサーバ APサーバ APサーバ・・・ ・・・
従来はアップロード処理もAP(アプリケーション)サーバが担当
Load Balancer
Load Balancer ・・・
APサーバ APサーバ APサーバ・・・ ・・・
Load Balancer
Load Balancer ・・・
APサーバ APサーバ APサーバAP(upload only)
Q4Mworker_upload
・・・ ・・・
Load Balancer
Load Balancer ・・・
APサーバ APサーバ APサーバAP(upload only)
Q4Mworker_upload
・・・ ・・・ ・・・
Load Balancer
Load Balancer ・・・
APサーバ APサーバ APサーバAP(upload only)
Q4Mworker_upload
・・・ ・・・ ・・・
Load Balancer
AP(upload only)Q4M
worker_upload
Load Balancer ・・・
APサーバ APサーバ APサーバAP(upload only)
Q4Mworker_upload
・・・ ・・・ ・・・
Load Balancer
AP(upload only)Q4M
worker_upload
Load Balancer ・・・
APサーバ APサーバ APサーバAP(upload only)
Q4Mworker_upload
・・・ ・・・ ・・・
Load Balancer
AP(upload only)Q4M
worker_upload
Load Balancer ・・・
APサーバ APサーバ APサーバAP(upload only)
Q4Mworker_upload
アップロード処理専用のAPサーバを用意
・・・ ・・・ ・・・
Load Balancer
AP(upload only)Q4M
worker_upload
アップロード専用サーバの構成
AP(upload_only) ・アップロード関連のリクエストを処理・アップロードデータの情報をQ4Mにエンキュー
Q4M ・アップロードデータの情報を格納するキュー
worker_upload ・Q4Mからアップロードデータの情報をデキュー・デキューした情報を元にサムネイル生成
AP(upload only)
AP(upload only)
• PHP5.3• ImageMagick6.6.0• imagick3.0.0
Q4M
Q4M
• MySQLのストレージエンジン• MySQLのテーブルがキューになる• SQLでエンキュー・デキューができる• サイボウズ・ラボの奥一穂氏が開発
worker_upload
worker_upload
• Q4Mと通信してサムネイル生成を行うマルチプロセスデーモン
•所謂ジョブワーカー• daemontoolsでデーモン化• Python製
worker_uploadを構成するPythonモジュール
•python-prefork• python-q4m• python-worker
後々のことを考えてとっととdebパッケージ化python-prefork以外は自作
workerがpreforkするjob数を決定する
• preforkするjob数毎にサムネイル生成にかかる時間を計測
• 小さい画像(50KB)と大きい画像(2MB)の合計49枚に対して一斉にサムネイル生成処理を実行
• CPU :Athlon II X4 2.3GHz(4コア)• メモリ:8GB
すべてのジョブ(サムネイル生成)を実行するのにかかる時間
prefork
prefork
すべてのジョブ(サムネイル生成)を実行するのにかかる時間
prefork数が5を越えたあたりからスケールしなくなった
prefork
prefork
各々のジョブ(サムネイル生成)実行にかかる時間
prefork
■ prefork数:1■ prefork数:5■ prefork数:10
各々のジョブ(サムネイル生成)実行にかかる時間
prefork
prefork数が多すぎるとかえって性能低下
■ prefork数:1■ prefork数:5■ prefork数:10
workerがpreforkするジョブ数は4~5が適切と判断
そんな感じでアップロード高速化完了
さらに、
libjpeg-turboによる高速化
libjpeg-turbo
• x86とx86_64用に最適化されたlibjpeg• SIMD命令(MMX, SSE2)を活用• libjpegと簡単に差し替えることが可能• ImageMagickはlibjpegを使ってる
各々のジョブ(サムネイル生成)実行にかかる時間prefork数:5
■ use libjpeg■ use libjpeg-turbo
各々のジョブ(サムネイル生成)実行にかかる時間prefork数:5
ライブラリ差し替えるだけで一割以上速くなった
■ use libjpeg■ use libjpeg-turbo
まとめ
• サムネイル生成処理を非同期化することによってユーザの体感速度を向上させることに成功
• 実際のスピードについても専用サーバやlibjpeg-turboを使うことで高速化できた
ご静聴ありがとうございました