Upload
akitsukada
View
1.767
Download
1
Embed Size (px)
DESCRIPTION
スタディプラスで使っている AWS 上の worker、画像変換サーバの話
Citation preview
スタディプラスのworkerと画像処理周り
2014.08.07 @akitsukada
はじめに
自己紹介塚田 朗弘 @akitsukada 2歳の娘持ち からあげや二郎が好き
糖質セーブ中 スタディプラスCTO
職歴的には中規模金融系SIer→ドワンゴ iOS、Rails、AWS、MySQL、Haskell スケーラブルなシステムを適切な設計で作りたい
はじめに
会社とサービス紹介スタディプラス株式会社
教育系スタートアップ、 EdTech エンジニア6名デザイナ1名(募集中!)
サービス スタディプラス
学習を支援するSNS/プラットフォーム 高校生の 1/4 が利用
ラーニングドラゴン 英単語学習の教材アプリ スタディプラスAPIを利用するモデルケース
スタディラウンジ 会員制の有料自習室
はじめに
スタディプラス、インフラの規模感
会員数 70万人弱、年内に100万到達見込み
はじめに
50万人のときのプレスリリースですが…
スタディプラス、インフラの規模感
APIサーバリクエスト数 420/sec @ peak 1500万/day 4億5000万/month
はじめに
これリクエスト数じゃなくて PV ですが…
スタディプラス、インフラの規模感
サーバ台数 EC2インスタンス80-90台くらい @ peak(スタディプラス以外のサーバ含む)
はじめにこれ台数じゃなくてインスタンス時間ですが…
晩御飯たべて勉強し終わった頃がピーク
はじめに
SumRequests
HealthyInstances
SumRequests
HealthyInstances
晩御飯たべて勉強し終わった頃がピーク
はじめに
だいたい22:30-25:00
本日のアジェンダ
!
振幅10倍のオートスケールなworker とか !
サイズ不問の画像処理とか
振幅10倍のオートスケールな
worker とか
みなさん worker
どうしてますか
振幅10倍のオートスケールな worker とか
worker
振幅10倍のオートスケールな worker とか
誰かがキューイングした時間がかかる処理(job)をどんどん捌くプロセス Webアプリのパフォーマンスを確保する上で基本的なテクニック 実装例
SQS Q4M RabbitMQ WebSphere MQ Resque
worker
振幅10倍のオートスケールな worker とか
誰かがキューイングした時間がかかる処理(job)をどんどん捌くプロセス Webアプリのパフォーマンスを確保する上で基本的なテクニック 実装例
SQS Q4M RabbitMQ WebSphere MQ Resque
Resque を使ってますResque https://github.com/resque/resque
GitHub 製 OSS Rails との親和性大、カンタン、Webコンソールが気に入った 構成概要
Redis は c3.large を EC2 に立ててます 自分で立てた翌週くらいにElastiCacheがRedisに対応した…
worker daemon-spawn で daemon 化 monit でプロセス監視 インスタンスタイプは c1.medium
1台につき10プロセスの worker
振幅10倍のオートスケールな worker とか
スタディプラスのworker は
front/batchの二種類
振幅10倍のオートスケールな worker とか
front_workerAPI サーバがキューイングした job をさばく
メール送信 プッシュ通知送信 外部 API 処理 その他リアルタイム性が求められない処理
ピークタイムは28台・280プロセス、アイドルタイムは2台・20プロセス
振幅10倍のオートスケールな worker とか
batch_workerいわゆるバッチ処理も worker でやる。
メールの一斉配信や日次処理など resque-scheduler利用
cron 的に job をキューイングする スケールしやすいようにバッチを設計するといい感じに
「スケールしやすい」= worker 数を増やすことでリニアに処理時間が短縮できるといった意味
例:worker 数を2倍に増やすとメール一斉配信の所要時間が半分になる。わかりやすい!
ピークタイムは20台・200プロセス、アイドルタイムは1台・10プロセス
振幅10倍のオートスケールな worker とか
スケールしやすい batch_worker の設計
kicker と processor に分ける kicker
resque-scheduler によりキューイングされる job を見張り、並列可能な processor の job を多数作ってキューイングする
processor kicker によってキューイングされる job を見張り、とにかく次から次へと物量作戦で処理する
振幅10倍のオートスケールな worker とか
スケールしやすい batch_worker の設計
振幅10倍のオートスケールな worker とか
Resque-scheduler
①kickerのjobを登録
kicker
②kickerのjobを処理
③processorのjobをたくさん登録
processor
④processorのjobを物量作戦で処理
processorauto scaling
spot インスタンスおいしいです(^q^)
front/batch共に spot使いまくりです
振幅10倍のオートスケールな worker とか
front_worker での spot 活用1/2
spot が先にスケールアウトするように仕向ける 1. spot インスタンスの worker 群と
レギュラーインスタンスの worker 群とで Auto Scaling Policy を分ける
2. spot の方がちょっとだけ先にスケールアウトし、ちょっとだけ後でスケールインするようにする
3. spot が優先的に増えていってくれて大幅にお得に!もはやスポットで使っている感じではない
振幅10倍のオートスケールな worker とか
front_worker での spot 活用2/2
spot が買えなくても困らないように作る 仮に spot の価格が高騰して突然 spot インスタンス群が落ちても…
一時的に job が貯まるだけで、数分-20分もすればスケールアウトしたレギュラーインスタンスの worker 群が問題なくjobを捌いてくれる もともとリアルタイム性の低いjobなのでまぁ許容できる(ユーザはほぼ気づかない)
振幅10倍のオートスケールな worker とか
batch_worker での spot 活用
front_worker と同様のことはやっている spot が先にスケールアウトするように仕向ける spot が買えなくても困らないように作る
scheduled action で、大量の job がキューイングされる10分前に大量のspot インスタンスを起動しておく
メール一斉配信とか
振幅10倍のオートスケールな worker とか
結局どのくらい spot使ってるの
振幅10倍のオートスケールな worker とか
SumRequests
HealthyInstances
晩御飯たべて勉強し終わった頃がピーク
はじめに
だいたい22:30-25:00
spot使用比率まとめ、価格換算
振幅10倍のオートスケールな worker とか
稼働時間(単位:時間)
0時
1時
2時
3時
4時
5時
6時
7時
8時
9時
10時
11時
12時
13時
14時
15時
16時
17時
18時
19時
20時
21時
22時
23時
計
spot 20 10 3 1 1 1 3 5 3 5 5 4 7 7 6 6 7 8 9 12 15 18 20 21 197
res. 4 3 1 1 1 1 1 1 1 1 1 1 3 3 2 2 3 4 4 5 5 5 5 5 63
reg. 2 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 2 2 3 3 3 3 3 25
計 26 14 4 2 2 2 4 6 4 6 6 5 11 11 8 8 11 14 15 20 23 26 28 29 285
課金額(単位:$)
0時
1時
2時
3時
4時
5時
6時
7時
8時
9時
10時
11時
12時
13時
14時
15時
16時
17時
18時
19時
20時
21時
22時
23時
計
spot 0.40 0.20 0.06 0.02 0.02 0.02 0.06 0.10 0.06 0.10 0.10 0.08 0.14 0.14 0.12 0.12 0.14 0.16 0.18 0.24 0.30 0.36 0.40 0.42 3.94
res. 0.20 0.15 0.05 0.05 0.05 0.05 0.05 0.05 0.05 0.05 0.05 0.05 0.15 0.15 0.10 0.10 0.15 0.20 0.20 0.25 0.25 0.25 0.25 0.25 3.09
reg. 0.32 0.16 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.16 0.16 0.00 0.00 0.16 0.32 0.32 0.47 0.47 0.47 0.47 0.47 3.95
計 0.91 0.51 0.11 0.07 0.07 0.07 0.11 0.15 0.11 0.15 0.15 0.13 0.45 0.45 0.22 0.22 0.45 0.67 0.69 0.96 1.02 1.08 1.12 1.14 10.98
spot:spot res.=reserved reg.=regular
worker で困ったりしたところ突然 worker -> Redis で接続エラー多発
Redis の timeout 設定やulimitにも問題なし http://d.conma.me/entry/2013/03/21/114044 1aのworkerだけで起きていることが判明1cは問題なし
原因わからないけどとにかく全workerを1cに振って回避、気持ち悪い
スケールインするときのworkerプロセス後始末 インスタンス terminate 時にworkerをshutdownしたい(何もしないとworking中のjobがworkingのままに…)
/etc/rc.d/ に worker_shutdown スクリプトを配置して対応
振幅10倍のオートスケールな worker とか
about 5 hours ago
worker まとめ
振幅10倍のオートスケールな worker とか
オートスケール *
spotおいしいです
サイズ不問の画像処理とか
みなさん 画像
どうしてますか
サイズ不問の画像処理とか
みなさん画像どうしてますか
アプリケーション要件として ユーザによって様々なサイズの画像がアップロードされる 箇所によって様々な表示サイズをとりうる(サムネイルとか)
サイズ不問の画像処理とか
自動リサイズ機構はもはや必須では
柔軟に表示したい 画像のサイズを数種類に固定するとかしたくない
デザイン、実装の制約を作りたくない(絶対気にしてられない、精神が死ぬ)
デザイナがレイアウト変更を検討するとき 開発者がレイアウトの変更に対応するとき
画像枚数370万枚をいちいち各サイズ用意してられない
レイアウト変更のたびに全部リサイズとか
サイズ不問の画像処理とか
resizerを自前で作って使っています
httpリクエスト時のパラメータによって任意の画像を任意のサイズで返す。
ElasticBeanstalk 上で稼働する Java アプリ CloudFront - CDN RDS - 元画像のURIを管理 S3 - 画像ファイル置き場
cf. クックパッドさん mod_tofu
http://www.slideshare.net/mirakui/ss-8150494 クラスメソッドさん Rudess
http://dev.classmethod.jp/cloud/aws/rudess-image-server/
サイズ不問の画像処理とか
resizerリクエスト例
http://resizer/1?w=50&h=50&m=speed&e=truehttp://resizer/1?w=512&h=512&m=balanced&e=true http://resizer/1?w=512&h=512&m=ultra_quality
{quality} 部分は、利用しているライブラリ imgscalr に依存しているもの。 http://www.thebuzzmedia.com/software/imgscalr-java-image-scaling-library/ ほんとは依存してないほうがいいですね。
サイズ不問の画像処理とか
http://resizer/{image_id}?w={width}&h={height}&m={quality}&e={enlargement}
resizer構成図
サイズ不問の画像処理とか
AWS cloud
Elastic Beanstalk container
bucket with objects
Amazon RDS
Auto Scaling group
Availability Zone
Availability Zone
Auto Scaling
instances
instances
Elastic LoadBalancing
download distribution
edge location
edge location
edge location
edge location
Internet
CloudFront
users
users
users
users client
mobile client
client
mobile client
resizer規模感EC2インスタンス
インスタンスタイプ: m1.medium オートスケールで2-8台
画像数 370万枚 リクエスト数(クライアント側でキャッシュしてるところも大きい)
ELB 80/sec @ peak 200万/day 6000万/month
CloudFront(最大ヒット率 84%) 450/sec @ peak 1100万/day 3億3100万/month
内 98% はTokyo Region
サイズ不問の画像処理とか
resizerで困ったりしたところ
ある月、突然 CloudFront の請求額が3倍に…!
resizer や CloudFront 弄ってない ユーザ数もreq数も3倍になんてなってない
iOS アプリで「ユーザ画像サムネイルの画質を向上してほしい」という要望に応えたアップデートをかました結果だった
考慮漏れではあったがまぁしゃーなし
サイズ不問の画像処理とか
運用してみてる所感とはいえだいたい安定してる
改修、修正、保守の必要がほぼない origin側のインスタンスがかなり低負荷 クライアント側からも使いやすい
サイズ不問の画像処理とか
画像処理まとめ
サイズ不問の画像処理とか
AWS からマネージドサービス出して欲しい!
(絶対使うと思うんですけど)
最後に
色々言いましたが、ただいまシステムのフルリプレイスを
推進中であるため全部作り変える予定です。 Scala でスケーラブルなシステムを
作ることに興味がある方、 Swift で E2E テスト書くことに興味がある方
いらっしゃったらお手伝いください>< @akitsukada
劇 終 THE END
2014.08.07 @akitsukada