百度空间 | 百度首页 
 
查看文章
 
Web应用中的轻量级消息队列
2009年11月07日 星期六 下午 03:45
作者:老王

Web应用中为什么会需要消息队列?主要原因是由于在高并发环境下,由于来不及同步处理,请求往往会发生堵塞,比如说,大量的insert,update之类的请求同时到达mysql,直接导致无数的行锁表锁,甚至最后请求会堆积过多,从而触发too many connections错误。通过使用消息队列,我们可以异步处理请求,从而缓解系统的压力。在Web2.0的时代,高并发的情况越来越常见,从而使消息队列有成为居家必备的趋势,相应的也涌现出了很多实现方案,像Twitter以前就使用RabbitMQ实现消息队列服务,现在又转而使用Kestrel来实现消息队列服务,此外还有很多其他的选择,比如说:ActiveMQZeroMQ等。

上述消息队列的软件中,大多为了实现AMQP,STOMP,XMPP之类的协议,变得极其重量级,但在很多Web应用中的实际情况是:我们只是想找到一个缓解高并发请求的解决方案,不需要杂七杂八的功能,一个轻量级的消息队列实现方式才是我们真正需要的。

第一感觉是能不能使用memcached来实现消息队列?稍加考虑后就会发现它不合适,因为memcached仅仅支持键值方式的操作,没有排序之类的功能,所以如果要用它来实现消息队列,则必须自己通过某个键来保存数组形式的队列,不过这样的话,在操作队列的时候很容易丢失数据,比如说我们要添加一个消息,则需先取出现有队列,然后把消息保存到队列尾部,最后保存队列,单纯使用memcached的话,由于我们无法保证整个过程的原子性,所以当处理若干个并发请求时,各个请求间可能会互相覆盖,丢失数据就在所难免。另外,memcached只是内存键值缓存而已,一旦宕机,数据就消失了。

memcacheq的出现解决了上面的问题,它在memcached的基础上实现了消息队列,以php客户端为例:

消息从尾部入栈:memcache_set
消息从头部出栈:memcache_get

memcacheq依附于memcached之上,所以你可以通过现有的memcached工具来操作它,这无疑是它的一大优势,但它也有一个很大的缺点,那就是memcacheq本身的开发维护似乎并不活跃,如果遇到问题的话,你很可能需要自己动手解决。

目前看来,我更推荐下面这种解决方案,那就是redis,如果不了解,可以参考我以前的文章,表面上看,redis和memcached差不多,也是键值操作,但是redis本身实现了list,相关操作也可以保证是原子的,所以可以很自然的通过list来实现消息队列:

消息从尾部入栈:RPUSH
消息从头部出栈:LPOP

redis本身虽然是一个新项目,但很有朝气,开发维护也很活跃,如果你的下一个Web应用里需要使用轻量级的消息队列,不妨使用它。

此外,还有不少其他的选择可供尝试,比如说MySQL第三方的Q4M引擎,通过扩展SQL语法来操作消息队列,也是一个不错的选择。

套用网络流行语:那些重量级软件实现的不是你要的功能,而只是独在高处不胜寒的寂寞,所以不必迷恋其中,它们只是传说而已。

类别:Database | 添加到搜藏 | 浏览() | 评论 (9)
 
网友评论:
1
2009年11月08日 星期日 上午 11:03 | 回复
好文章,转载到 deving.cn,希望可以和更多的人分享
 
2
2009年11月08日 星期日 上午 11:17 | 回复
估计Redis还是比较好的选择。
 
3
2009年11月08日 星期日 下午 06:06 | 回复
rabbitmq stompserver zeromq morbid apachemq starling beanstalk kestrel memcacheq
 
4
2009年11月09日 星期一 上午 09:45 | 回复
好文,收藏至20ju.com
 
5
2009年11月09日 星期一 上午 11:48 | 回复
很久没看过技术文章了,来看看!
 
6
2009年11月09日 星期一 下午 01:14 | 回复
很精彩
 
7
2009年11月09日 星期一 下午 08:26 | 回复
key‐value‐cache memcached, repcached, coherence, infinispan, eXtreme scale, jboss cache, velocity, terracoqa key‐value‐store keyspace, flare, schema‐free, RAMCloud eventually‐consistent key‐value‐store dynamo, voldemort, Dynomite, SubRecord, Mo8onDb, Dovetaildb ordered‐key‐value‐store tokyo tyrant, lightcloud, NMDB, luxio, memcachedb, actord data‐structures server redis tuple‐store gigaspaces, coord, apache river object database ZopeDB, db4o, Shoal document store CouchDB, Mongo, Jackrabbit, XML Databases, ThruDB, CloudKit, Perservere, Riak Basho, Scalaris wide columnar store BigTable, Hbase, Cassandra, Hypertable, KAI, OpenNeptune, Qbase, KDI
 
8
2009年11月12日 星期四 下午 02:07 | 回复
消息从尾部入栈:RPUSH
消息从头部出栈:LPOP

这里其实是队列,不能说是栈了。

而且想知道list的实现方式如何,对于普通的 vector LPOP 操作有可能导致后续元素O(n)次位置移动,效率不高。
 
9
2009年11月12日 星期四 下午 02:57 | 回复
看了看代码,list用的是双向链表,效率应该没问题了。
 
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu