Q4m使用手册
q4m是基于mysql存储引擎的轻量级消息队列,通过扩展SQL语法来操作消息队列,使用简单,容易上手,开发人员基本不用再进行学习和熟悉。Q4M支持多发送方,多接收方,接收方相互不影响,php项目中异步信息机制可以使用q4m。
1,安装q4m,这个不细讲;
2,q4m学习,参考以下文档http://blog.csdn.net/tianjing_1983/article/details/7418833
一、概述
1. Q4M模型
是基于MySQL存储引擎的轻量级消息队列,通过扩展SQL语法来操作消息队列,使用简单,容易上手,开发人员基本不用再进行学习和熟悉。
Q4M支持多发送方,多接收方,接收方相互不影响,支持可靠获取,支持多队列,宕机后数据可恢复,可用SQL方便查看队列状态,实测单队列单线程的入队性能上限为7405QPS (单消息10b),出队列性能上限在9375QPS,单队列50线程的入队列性能上限为81632QPS,出队列性能上限为62500QPS。
2. 属主状态(OWNER MODE)说明
为了保证可靠获取,Q4M引入了属主状态(OWNER MODE)和无属主状态(NON-OWNER MODE)概念,此为Q4M最大的特性。当消息出队列后,则该消息先进入属主状态(OWNER MODE),即该消息只对属主所在线程可见,对其它线程不可见。
通过调用queue_wait()取消息出队并进入属主状态,每次获取消息最多不超过一条(队列为空返回零条),调用queue_end()结束属主状态,并删除已出队消息;调用queue_abort(),放弃属主状态,已出队消息重新回收到队列中;若在属主状态中连接中断,则已出队消息重新回收到队列中;若连续调用queue_wait(),则会自动删除上次出队消息并获取下一条信息,即可理解为在第两次queue_wait()前自动执行了queue_end()。详细可见下文示例。
3. 使用限制及注意点
Ø 没有主键或索引支持;
Ø 不支持AUTO_INCREMENT自增列,默认按插入顺序排序;
Ø 不支持update,可支持insert和delete;
Ø 属主状态(owner mode)的消息获取超时时间默认为60秒,注意此为获取时间,不是消息使用时间。如队列为空时,queue_wait()会等待直至超时后返回;
Ø 若连接异常断开,消息自动回收到队列中,因此建议将MYSQL 参数interactive_timeout、 wait_timeout调短到10分钟以内,连接超时断开后可自动回收消息;
Ø 一条消息上限为512MB,表上限为2^63 bytes,即1048576 TB;
Ø 内存不足时可能会导致MySQL Crash;
Ø 若压缩数据时宕机,内存中的消息可能会丢失;
Ø 不支持主从复制,可通过搭建多套Q4M进行容灾
二.使用示例
1. 创建队列
一个表就是一个队列,每一行记录是一条消息。若需创建一队列,只需建一queue引擎的table即可,若需要多队列,则创建多个表即可。
MySQL> CREATE TABLE my_queue (v1 int not null, v2 varchar(255)) ENGINE=queue;
2. 消息入队
只需用正常的sql语法insert记录即可将消息添加到队列。
MySQL> INSERT INTO my_queue (v1, v2) VALUES (1, "Tian"); INSERT INTO my_queue (v1, v2) VALUES (2, "Jing"); INSERT INTO my_queue (v1, v2) VALUES (3, "1983"); INSERT INTO my_queue (v1, v2) VALUES (4, "IN"); INSERT INTO my_queue (v1, v2) VALUES (5, "GANJI"); INSERT INTO my_queue (v1, v2) VALUES (6, "HAPPY"); MySQL> select * from my_queue; +----+-------+ | v1 | v2 | +----+-------+ | 1 | Tian | | 2 | Jing | | 3 | 1983 | | 4 | IN | | 5 | GANJI | | 6 | HAPPY | +----+-------+ 6 rows in set (0.00 sec)
3. 消息出队
调用queue_wait()使消息出队,获取的消息进入属主状态(可见1.2解释),在本线程内,只能查到已出队消息。
MySQL>SELECT * FROM my_queue WHERE queue_wait('my_queue');
+----+------+
| v1 | v2 |
+----+------+
| 1 | Tian |
+----+------+
1 row in set (0.00 sec)
MySQL>SELECT * FROM my_queue;
+----+------+
| v1 | v2 |
+----+------+
| 1 | Tian |
+----+------+
1 row in set (0.00 sec)
调用queue_end()结束属主状态,自动删除上次出队的消息。这时select * 可查到队列中所有消息了。
MySQL>select queue_end(); +-------------+ | queue_end() | +-------------+ | 1 | +-------------+ 1 row in set (0.00 sec) MySQL>SELECT * FROM my_queue; +----+-------+ | v1 | v2 | +----+-------+ | 2 | Jing | | 3 | 1983 | | 4 | IN | | 5 | GANJI | | 6 | HAPPY | +----+-------+ 5 rows in set (0.00 sec)
若调用queue_abort()则放弃属主状态,已出队消息自动回收到原队列中。
MySQL>SELECT * FROM my_queue WHERE queue_wait('my_queue');
+----+------+
| v1 | v2 |
+----+------+
| 1 | Tian |
+----+------+
1 row in set (0.00 sec)
MySQL>SELECT * FROM my_queue ;
+----+------+
| v1 | v2 |
+----+------+
| 1 | Tian |
+----+------+
1 row in set (0.00 sec)
MySQL>select queue_abort();
+---------------+
| queue_abort() |
+---------------+
| 1 |
+---------------+
1 row in set (0.00 sec)
MySQL>SELECT * FROM my_queue ;
+----+-------+
| v1 | v2 |
+----+-------+
| 1 | Tian | # queue_abort()该消息重新回收到队列中
| 2 | Jing |
| 3 | 1983 |
| 4 | IN |
| 5 | GANJI |
| 6 | HAPPY |
+----+-------+
6 rows in set (0.00 sec)
若连续调用queue_wait(),则会自动删除上次出队消息并获取下一条信息,即可理解为在第两次queue_wait()前自动执行了queue_end()
MySQL>SELECT * FROM my_queue WHERE queue_wait('my_queue');
+----+------+
| v1 | v2 |
+----+------+
| 1 | Tian |
+----+------+
1 row in set (0.00 sec)
MySQL>SELECT * FROM my_queue WHERE queue_wait('my_queue');
+----+------+
| v1 | v2 |
+----+------+
| 2 | Jing |
+----+------+
1 row in set (0.02 sec)
MySQL>SELECT * FROM my_queue WHERE queue_wait('my_queue');
+----+------+
| v1 | v2 |
+----+------+
| 3 | 1983 |
+----+------+
1 row in set (0.01 sec)
MySQL>select queue_end();
+-------------+
| queue_end() |
+-------------+
| 1 |
+-------------+
1 row in set (0.00 sec)
MySQL>SELECT * FROM my_queue ; #前三条消息都已被取出
+----+-------+
| v1 | v2 |
+----+-------+
| 4 | IN |
| 5 | GANJI |
| 6 | HAPPY |
+----+-------+
3 rows in set (0.00 sec)
4. 按条件进行消息出队
Q4M也支持按某条件获取消息并出队,使用方法为queue_wait('table:col>N'):
MySQL>SELECT * FROM my_queue ;
+----+-------+
| v1 | v2 |
+----+-------+
| 1 | Tian |
| 2 | Jing |
| 3 | 1983 |
| 4 | IN |
| 5 | GANJI |
| 6 | HAPPY |
+----+-------+
6 rows in set (0.00 sec)
MySQL>SELECT * FROM my_queue WHERE queue_wait('my_queue:v1>=5');
+----+-------+
| v1 | v2 |
+----+-------+
| 5 | GANJI | #取出的值为v1>=5的第一条消息
+----+-------+
1 row in set (0.01 sec)
目前Q4M支持如下运算符:
- ~ () * div % mod + - << >> & | = != <= < >= > not && and xor || or
5. 消息出队的伪代码实现
如下是消息出队的伪代码实现:
while (true) {
rows := SELECT * FROM my_queue
WHERE queue_wait('my_queue'); # 消息出队并进入属主状态
if (count(rows) != 0) # 如果有消息,则
handle_row(rows[0]); # 进行消息处理
SELECT queue_end(); # 结束属主状态
}
Q4m使用手册的更多相关文章
- FREERTOS 手册阅读笔记
郑重声明,版权所有! 转载需说明. FREERTOS堆栈大小的单位是word,不是byte. 根据处理器架构优化系统的任务优先级不能超过32,If the architecture optimized ...
- JS魔法堂:不完全国际化&本地化手册 之 理論篇
前言 最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求--国际化&本地化.熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已. ...
- 转职成为TypeScript程序员的参考手册
写在前面 作者并没有任何可以作为背书的履历来证明自己写作这份手册的分量. 其内容大都来自于TypeScript官方资料或者搜索引擎获得,期间掺杂少量作者的私见,并会标明. 大部分内容来自于http:/ ...
- Redis学习手册(目录)
为什么自己当初要选择Redis作为数据存储解决方案中的一员呢?现在能想到的原因主要有三.其一,Redis不仅性能高效,而且完全免费.其二,是基于C/C++开发的服务器,这里应该有一定的感情因素吧.最后 ...
- JS魔法堂:不完全国际化&本地化手册 之 实战篇
前言 最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求--国际化&本地化.熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已. ...
- Windows API 函数列表 附帮助手册
所有Windows API函数列表,为了方便查询,也为了大家查找,所以整理一下贡献出来了. 帮助手册:700多个Windows API的函数手册 免费下载 API之网络函数 API之消息函数 API之 ...
- linux命令在线手册
下面几个网址有一些 Linux命令的在线手册,而且还是中文的,还可以搜索.非常方便 Linux命令手册 Linux命令大全 Linux中文man在线手册 每日一linux命令
- Mysql完全手册(笔记二,使用数据与性能优化)
一.使用数据 1.使用变量 MySQL也可以让我们以用户自定义的变量来存储select查询的结果,以便在将来select查询中使用.它们只会在客户会话期间存在,但是它们提供一个方便有效的方法来连接查询 ...
- html javascript css3 php3.2.3离线手册
各位新年快乐! 愿大家"愿有前程可奔赴,也有岁月可回头"! 发现个离线手册很全的网站,分享大家,也mark自用. http://www.shouce.ren/ 手册网
随机推荐
- Redis 发布/定阅
[Redis 发布/定阅] 1.SUBSCRIBE channel [channel ...] 订阅给定的一个或多个频道的信息. 2.PSUBSCRIBE pattern [pattern ...] ...
- 使用heroku创建应用时报错 heroku does not appear to be a git repository
在跟着heroku的官方教程创建python应用时,到deploy-the-app这一步,要上传代码到heroku 的git仓库时,报的这个错误: 网上一搜,相关的答案居然极少,首页只出现一篇(还好这 ...
- IT项目经理岗位职责(转)
一. 项目经理岗位职责 1. 项目经理为整个项目的第一责任人. 2. 项目经理对<质量检查报告>中的所有细则负首要责任. 3. 项目经理必须有效掌控项目开发的各个环节,协助.指导项 ...
- leetcode 62 不同的路径
描述: m*n的矩阵,从左上角走到右下角,只能向下或向右走. 解决: 简单dp,dp[i][j]表示到i,j这点总共多少种路径. dp[i][j] = dp[i][j - 1] + dp[i - 1] ...
- Yii2 windows 安装步骤
安装 Yii2 高级版应用 基础版可以看官方文档 今天安装了YII2高级版应用 写下步骤 留个记号,以备查询! 在 Windows 中,你首先需要下载并运行 Composer-Setup.exe 查看 ...
- 解压*.tar.bz2的坑
下了一个压缩包,tar -xf 解压不了 解决办法: 装了bzip2工具 bzip2 -d **.tar.bz2 //将文件解压成**.tar tar -xf **.tar //解包 听说可以 tar ...
- [Selenium] 怎样判断是否适合自动化测试
实施自动化测试前需要对软件开发过程进行分析,以观察其是否适合使用自动化测试.通常需要满足以下条件: 1)需求变动不频繁 2)项目周期足够长 3)自动化测试脚本可重复使用 4)手工测试无法完成或者需要大 ...
- W-D-S-链接地址
1.程序一开始是烧写到nandflash上,设置为nandflash启动,6410片内有8K的内存,设为nandflash启动时,是从片内内存0地址开始,一上电,nandflash前面8K的内容会原原 ...
- 基于Web Service的客户端框架搭建四:终结篇
前言 这是这个系列的终结篇,前面3个博客介绍了一下内容: 1.使用Http Post方式调用Web Service 2.客户端框架之数据转换层 3.客户端框架之代理层 框架结构 框架是基于C#的,在V ...
- Redis通用命令(七)
Keys的通用操作: (1)获得所有的keyskeys *(2)查看my开头的keykeys my?(3)删除keydel key1 key2(4)key是否存在exists key1 exists ...