Fillmoreadvisory,Inc. Yusuke Hata
Q4MとFlareを使って スケーラブルなサービスを作る!
2009.9.5 1 Fillmoreadvisory,Inc.
Building High-Scalable Web Applications Using Q4M and Flare
Fillmore Advisory
自己紹介
• Yusuke Hata (漢祐介) ▫ blog: http://blog.xole.net/
• Committer in Seasar.org for PHP framework development ▫ DI container and AOP Framework: S2Container.PHP5 ▫ DAO (Data-Access-Object) ORM Framework: S2Dao.PHP5 ▫ Port to PHP5 from Java http://www.seasar.org/#php
• Working at Fillmore advisory since 2008 ▫ http://www.fillmoreadvisory.jp/
• 最近、本を書きました(宣伝) ▫ published from Shoeisha in Jan 2009
2009.9.5 2 Fillmoreadvisory,Inc.
About me
Fillmore Advisory
最近 vizoo というサービスを作りました
2009.9.5 3 Fillmoreadvisory,Inc.
We released “vizoo”
h t t p : / / w w w. v i s u a l z o o . c o m /
Fillmore Advisory
About vizoo • グラフ作成 & 共有サイト • 経済データなどが豊富 ▫ 豊富なデータを元に簡単にグラフを 作成できる
• データ版YouTube • グラフをブログに貼ろう! • 開発はPHP5.2.x + symfony もちろん、グラフは Flash (flex)
2009.9.5 4 Fillmoreadvisory,Inc.
Fillmore Advisory
今日は vizoo で利用している Q4M と Flare について
お話します
2009.9.5 5 Fillmoreadvisory,Inc.
Talk about: Q4M and Flare Using in “vizoo”
Fillmore Advisory
Agenda
• Q4MとFlareについて ▫ About Q4M and Flare
• Webアプリケーションにおける 高負荷になりやすい(であろう)ポイントと解決方法 ▫ How to improve: High-load to Web Applications
• Webアプリケーションにける スケールアウトしにくい(であろう)ポイントと解決方法 ▫ How to improve: Difficult to scaling in Web Applications
• Symfony での実装について ▫ Implementation in Symfony
• 少し凝った Q4M と Flare の使い道 ▫ (few) Advanced usage of Q4M and Flare
2009.9.5 6 Fillmoreadvisory,Inc.
Fillmore Advisory
Q4Mとは
• Message Queue for MySQL ▫ MySQLをつかったメッセージキュー
• MySQL Pluggable Storage Engine ▫ MySQL 5.1以降でPluginとしてインストールできる
• サイボウズ ラボの奥一穂氏が開発 ▫ http://q4m.31tools.com/
• 高速!柔軟なAPI!便利! • MySQLに接続できるならどんな言語からでも利用できる!
2009.9.5 7 Fillmoreadvisory,Inc.
Fillmore Advisory
SQLで書けるQueue
• Q4MのメッセージはSQLを使う • データはTableに格納される • CREATE TABLE でメッセージの作成
2009.9.5 8 Fillmoreadvisory,Inc.
CREATE TABLE phpcon_queue ( param_a int unsigned not null, param_b varchar(200), priority tinyint not null ) ENGINE=queue;
Message 名
Messageのパラメータ
エンジンの種類は queue
MySQL Q4M
Fillmore Advisory
SQLで書けるQueue
• Queueの追加は INSERT を使う
2009.9.5 9 Fillmoreadvisory,Inc.
INSERT INTO phpcon_queue ( param_a, param_b, priority ) VALUES ( 2009, ‘hello’, 9 );
INSERT INTO phpcon_queue ( param_a, param_b, priority ) VALUES ( 2009, ‘world’, 5 );
param_a param_b priority
2009 hello 9
2009 world 5
enqueue
enqueue
Fillmore Advisory
SQLで書けるQueue • Queueの取り出しは、Q4MのAPIを通して行う • Queueの参照はSELECTを使う
2009.9.5 10 Fillmoreadvisory,Inc.
SELECT queue_wait(‘phpcon_queue’, 2);
param_a param_b priority
2009 hello 9
2009 world 5 param_a param_b priority
2009 hello 9
queue_wait SELECT * FROM phpcon_queue;
param_a param_b priority
2009 world 5
queue_end
SELECT queue_end();
Fillmore Advisory
SQLで書けるQueue • queue_wait はキューの取得までブロックする時間(秒)を指定できる
• queue_end で取得したキューを削除できる
• queue_abort は取得したキューを消さずに取り消せる
2009.9.5 11 Fillmoreadvisory,Inc.
SELECT queue_wait(‘phpcon_queue’, 2);
SELECT queue_end();
SELECT queue_abort();
これ
Fillmore Advisory
Q4Mの動作イメージ
2009.9.5 12 Fillmoreadvisory,Inc.
Q4M
task1
task2
task3
task4
: :
insert (enqueue)
insert (enqueue)
insert (enqueue)
Fillmore Advisory
Q4Mの動作イメージ
2009.9.5 13 Fillmoreadvisory,Inc.
Q4M task2
task3
task4
:
:
task1 job
queue_wait
hit
queue_end
job
job
select
queue_wait
queue_wait
Fillmore Advisory
導入が楽!
• MySQL 5.1 さえあれば導入できる ▫ MySQL のプラグインとしてインストール
• 言語問わず利用できる • APIの細かいドキュメントは >< ▫ 覚えやすく、簡単なAPIなので OKかも
2009.9.5 14 Fillmoreadvisory,Inc.
Fillmore Advisory
Flareとは
• Memcached compatible KVS (key-value storage) • Persistent storage (Tokyo Cabinet) • Data Replication • Dynamic re-construction • Node monitoring • GREE 開発 ▫ http://labs.gree.jp/Top/OpenSource/Flare.html ▫ http://labs.gree.jp/Top/OpenSource/Flare-en.html
2009.9.5 15 Fillmoreadvisory,Inc.
Fillmore Advisory
インデックスサーバが便利
2009.9.5 16 Fillmoreadvisory,Inc.
master server
slave servers
• checking node status • switch master • switch proxy
index server
node monitoring
telnet
Fillmore Advisory
memcache message
Memcached互換なので導入が楽!
2009.9.5 17 Fillmoreadvisory,Inc.
set
get
flared apps
Fillmore Advisory
Webアプリケーションにおける 高負荷になりやすいであろうポイント
• Databaseに対してのread/writeが多い系
2009.9.5 19 Fillmoreadvisory,Inc.
App Servers Database
writes
reads
Fillmore Advisory
Webアプリケーションにおける 高負荷になりやすいであろうポイント
• Databaseに対してのread/writeが多い系
2009.9.5 20 Fillmoreadvisory,Inc.
アプローチ
App Servers
Database
writes
reads
Fillmore Advisory
Webアプリケーションにおける 高負荷になりやすいであろうポイント • よくある解決方法: ▫ Master / Slave 構成にする
2009.9.5 21 Fillmoreadvisory,Inc.
writes
reads
replication
Master
Slave
Fillmore Advisory
Webアプリケーションにおける 高負荷になりやすいであろうポイント
2009.9.5 22 Fillmoreadvisory,Inc.
write
ロックなどが発生して、DBからの レスポンスが遅くなると、クライアントへのレスポンスも遅くなる
: :
: :
request
response reply
synchronous!
waits...
Fillmore Advisory
Webアプリケーションにおける 高負荷になりやすいであろうポイント
• これからは: ▫ Q4Mも使う
2009.9.5 23 Fillmoreadvisory,Inc.
enqueue
asynchronous!
write クライアントにはさっさと レスポンスを返してしまう。 たぶん、ユーザが何かしらの操作を 行っている間にwriteは終わっている
Q4M
workers
Fillmore Advisory
Webアプリケーションにおける 高負荷になりやすいであろうポイント
• Webサーバが頑張っちゃう系
2009.9.5 24 Fillmoreadvisory,Inc.
App server
SMTP
Fillmore Advisory
Webアプリケーションにおける 高負荷になりやすいであろうポイント
• よくある解決方法:
2009.9.5 25 Fillmoreadvisory,Inc.
SMTP backend
every 5 min
mail data database
app server
cron
Fillmore Advisory
Webアプリケーションにおける 高負荷になりやすいであろうポイント
• これからは: ▫ Q4Mを使う
2009.9.5 26 Fillmoreadvisory,Inc.
notify send mail
notify excel download
event
backend
backend
event
request Q4M
Q4M
Fillmore Advisory
Webアプリケーションにおける 高負荷になりやすいであろうポイント
• SQL的に重たいクエリを頑張っちゃう系
2009.9.5 27 Fillmoreadvisory,Inc.
Slave app server
heavy queries...
Fillmore Advisory
Webアプリケーションにおける 高負荷になりやすいであろうポイント
• よくある解決方法:
2009.9.5 28 Fillmoreadvisory,Inc.
backend
every 6 hours
replication
read
summary
read
read
Slave
app server
Fillmore Advisory
Webアプリケーションにおける 高負荷になりやすいであろうポイント
• これからは: ▫ Q4Mを使う
2009.9.5 29 Fillmoreadvisory,Inc.
summary
Q4M
enqueue
read only write only
notify event
backend insert/update once row
app server
Fillmore Advisory
Webアプリケーションにおける スケールアウトしにくいであろうポイント
セッション! Session!
2009.9.5 31 Fillmoreadvisory,Inc.
それは....
Fillmore Advisory
Webアプリケーションにおける スケールアウトしにくいであろうポイント
• よくある解決方法: ▫ DBに格納する
2009.9.5 32 Fillmoreadvisory,Inc.
read/write
master/slave構成には masterとslave間での
同期問題が あるため
なかなか難しい そのため1台構成になりやすい
Fillmore Advisory
Webアプリケーションにおける スケールアウトしにくいであろうポイント
• これからは: ▫ Flareを使う
2009.9.5 33 Fillmoreadvisory,Inc.
set xxxx (protocol : memcache)
get xxxx (protocol : memcache)
replication
Slave
Flare storage
Master
Fillmore Advisory
Webアプリケーションにおける スケールアウトしにくいであろうポイント
• Flareにしたことでここまで変わった:
2009.9.5 34 Fillmoreadvisory,Inc.
0 50000 100000 150000 200000
db-100
db-1000
memcache-1000
flare-1000
トランザクション 成功
Fillmore Advisory
Webアプリケーションにおける スケールアウトしにくいであろうポイント
• Flareにしたことでここまで変わった:
2009.9.5 35 Fillmoreadvisory,Inc.
0
20
40
60
80
100 100 1000 10000
db memcache flare
(session数) (成功tx %)
Fillmore Advisory
Q4Mをsymfonyのtaskとして実装する
2009.9.5 37 Fillmoreadvisory,Inc.
<?php
class MyQueueTask extends sfTask { protected function execute($arguments = array(), $parameters = array()){ $iterator = new HermitQueue(‘MyQueueDao’, $timeout); foreach($iterator as $queue){ // infinite loop $row = $queue->get();
// // {{{ execute queue }}} //
$queue->complete(); // or $queue->abort(); } } }
shell> php symfony job:MyQueueTask –env=batch
HermitQueue is Q4M wrapper; http://coderepos.org/share/wiki/Hermit
Fillmore Advisory
Flareをsymfonyのstorageとして実装する
2009.9.5 38 Fillmoreadvisory,Inc.
<?php class fmFlareSessionStorage extends sfSessionStorage { public function initialize($opts = array(){ parent::initialize($opts); session_save_handler(array(.....)); } public function sessionRead($id){ $slave = fmMemcache::getInstance(‘slave’); if($slave->has($id)){ return $slave->get($id); } $master = fmMemcache::getInstance(‘master’); $master->set($id, ‘’); return ‘’; } public function sessionWrite($id, $data){ $master = fmMemcache::getInstance(‘master’); $master->set($id, $data); return true; } public function sessionDestory($id){ return fmMemcache::getInstance(‘master’)->remove($id); } }
Fillmore Advisory
Flareをsymfonyのstorageとして実装する
2009.9.5 39 Fillmoreadvisory,Inc.
dev: master: host: memcache.local port: 11211 slave: host: memcache.local port: 11211 prod: master: host: flare.master port: 12121 slave: host: flare.slare port: 1212
storage.yml
開発時はmemcachedをそのまま利用し、本番の設定では flaredを指定するようにしている
Fillmore Advisory
Q4Mではpriorityを使う
• Priorityでjobを分離する
2009.9.5 41 Fillmoreadvisory,Inc.
param_1 param_2 priority
.... .... 1
.... .... 2
.... .... 1
.... .... 5
.... .... 9
Low Priority Workers
queue_wait(‘tbl:priority>=5’, 10)
High Priority Workers
queue_wait(‘tbl:priority<=2’, 5)
tbl
condition
Fillmore Advisory
Q4Mではmulti queueを使う
• Multi queue で色んな Queue を一元化
2009.9.5 42 Fillmoreadvisory,Inc.
param
....
....
....
param
....
....
....
param
....
....
....
a_event_queue b_event_queue c_event_queue
Event Workers
queue_wait(‘a_event_queue’, ‘b_event_queue’, ‘c_event_queue’, 5)
Fillmore Advisory
Q4Mではqueueをバラまく
• 大きくなったら細かくして分散
2009.9.5 43 Fillmoreadvisory,Inc.
big_task_1
big_task_2
big_task_3
event_queue
Map Workers
....
....
....
....
....
....
....
....
....
hoge_queue
foo_queue
bar_queue
Hoge Workers
Foo Workers
Bar Workers
small_task
small_task
small_task
Fillmore Advisory
Cronの代わりにQ4M
• 好きな時間にbatchを回したいこともあります
2009.9.5 44 Fillmoreadvisory,Inc.
task_id next_tstmp
8 123456789
5 123331231
11 124534556
scheduled_queue
Scheduled Workers
queue_wait( ‘scheduled_queue:task_id=8&&next_tstmp<=123456789’, 5 )
<?php $id = 8; $tstmp = time() + 86400; $timeout = 5; $stmt = $conn->prepare( ‘select queue_wait(?,?)’ ); $stmt->bind(1, ‘scheduled_queue:task_id=‘ . $id . ‘&&next_tstmp=‘ . $tstmp ); $stmt->bind(2, $timeout); $stmt->execute();
?>
Fillmore Advisory
Q4Mではtimeoutを 最大でも60秒にする
• Jobのshutdownを行う(=メンテ)などのときに、 timeoutが長すぎると MySQL が shutdown できなくなる。
• 最大でも60秒にする。それ以上にならないようにする
2009.9.5 45 Fillmoreadvisory,Inc.
Fillmore Advisory
小さくて共有するデータはflareに • キャッシュみたいに消えてもいいものはmemcache
2009.9.5 46 Fillmoreadvisory,Inc.
replication
Slave
Flare storage
Master
Fillmore Advisory
まとめ:
Q4Mを使うことで、DBへのアプローチに 幅がでてきた。
Flareはセッションストレージの大本命。 (期限付き+比較的小さい+読み書きが多い) セッション以外でも充分使えそう。
Q4MもFlareも大好きです。
2009.9.5 47 Fillmoreadvisory,Inc.