Q4Mを試す

ようやくインストールが終わったので、試してみる
まずはチュートリアルに沿ってやってみる。
http://q4m.31tools.com/tutorial.php

テーブル作成

CREATE TABLE my_queue (v1 int not null, v2 varchar(255)) ENGINE=queue;
desc my_queue;

+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| v1    | int(11)      | NO   |     | NULL    |       |
| v2    | varchar(255) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+

キューに送る

INSERT INTO my_queue (v1, v2) VALUES (1, "hello");
INSERT INTO my_queue (v1, v2) VALUES (2, "hello!");
INSERT INTO my_queue (v1, v2) VALUES (3, "hello!!");
INSERT INTO my_queue (v1, v2) VALUES (4, "hello!!!");

試してみる!

ふつうにselectする
select * from my_queue;
+----+--------------+
| v1 | v2           |
+----+--------------+
|  1 | hello        |
|  2 | hello!       |
|  3 | hello!!      |
|  4 | hello!!!     |
+----+--------------+

すべてのメッセージが見える

キューから取り出す
select queue_wait('my_queue');
+------------------------+
| queue_wait('my_queue') |
+------------------------+
|                      1 |
+------------------------+

select * from my_queue;
+----+-------+
| v1 | v2    |
+----+-------+
|  1 | hello |
+----+-------+

select queue_end();
+-------------+
| queue_end() |
+-------------+
|           1 |
+-------------+
もう一度、ふつうにselect
select * from my_queue;
----+----------+
| v1 | v2       |
+----+----------+
|  2 | hello!   |
|  3 | hello!!  |
|  4 | hello!!! |
+----+----------+

減ってる!!!!

他のコネクションからはどう見える?

  • コネクション1
select queue_wait('my_queue');
select * from my_queue;
+----+--------+
| v1 | v2     |
+----+--------+
|  2 | hello! |
+----+--------+
  • コネクション2
mysql> select * from my_queue;
+----+----------+
| v1 | v2       |
+----+----------+
|  3 | hello!!  |
|  4 | hello!!! |
+----+----------+
2 rows in set (0.01 sec)

コネクション1で取り出したキュー以外のものが見えた!
チュートリアルに書いてあるとおりだ。

By calling the queue_wait function, Q4M table enters OWNER mode. Once entering the OWNER mode, only one row (at maximum) becomes SELECTable, exclusively from the connection, i.e. a row owned by a connection becomes invisible to other connections
(http://q4m.31tools.com/tutorial.php)

  • queue_wait関数を呼ぶとOWNER modeになる
  • OWNERのコネクションは1行のみselect可
  • NON-OWNERのコネクションはOWNERのselect行が見えなくなる

ってことね。

複数Web -> Q4M -> 複数daemonという構成を意識してこうなってるのかな。
実際試してみると、複数のコネクションからqueue_waitが呼べて、適切にdequeueできたので、そうなんだろう。

事例

http://alpha.mixi.co.jp/blog/?cat=19
にも書かれているように、オンラインからの書き込みを非同期化してIOを時間で均すのに使える。

ふむー、なるほど。
うまいことサービスで使えそう。