背景
之前做日志收集模块时,用到flume。另外也有的方案,集成kafaka来提升系统可扩展性,其中涉及到消息队列
当时自己并不清楚为什么要使用消息队列。
而在我自己提出的原始日志采集方案中不适用消息队列
时,有几个基本问题:1. 日志文件上传过程,有个基本的生产者-消费者
问题;2. 另外系统崩溃时,数据丢失的处理问题。
今天,几位同事再次谈到消息队列
这么个东西,很NB的样子,我也想弄清楚,OK,搞起。
什么是消息队列
消息队列(Message Queue,简称MQ),从字面意思上看,本质是个队列,FIFO先入先出,只不过队列中存放的内容是message
而已。其主要用途:不同进程Process/线程Thread之间通信。为什么会产生消息队列
?这个问题问的好,我大概查了一下,没有查到最初产生消息队列的背景,但我猜测可能几个原因:
- 不同进程(process)之间传递消息时,两个进程之间耦合程度过高,改动一个进程,引发必须修改另一个进程,为了隔离这两个进程,在两进程间抽离出一层(一个模块),所有两进程之间传递的消息,都必须通过
消息队列
来传递,单独修改某一个进程,不会影响另一个; - 不同进程(process)之间传递消息时,为了实现标准化,将消息的格式规范化了,并且,某一个进程接受的消息太多,一下子无法处理完,并且也有先后顺序,必须对收到的消息进行排队,因此诞生了事实上的
消息队列
;
不管到底是什么原因催生了消息队列
,总之,上面两个猜测是其实际应用的典型场景。
为什么要用
切合前一部分猜测的消息队列
产生背景,其主要解决两个问题:
- 系统解耦:项目开始时,无法确定最终需求,不同进程间,添加一层,实现解耦,方便今后的扩展。
- 消息缓存:系统中,不同进程处理消息速度不同,MQ,可以实现不同Process之间的缓冲,即,写入MQ的速度可以尽可能地快,而处理消息的速度可以适当调整(或快、或慢)。
下面针对系统解耦、消息缓存两点,来分析实际应用消息队列
过程中,可能遇到的问题。虚拟场景:Process_A通过消息队列MQ_1向Process_B传递消息,几个问题:
- 针对MQ_1中一条消息message_1,如何确保Process_B从MQ_1中只取一次message_1,不会重复多次取出message_1?
- 如果MQ_1中message_1已经被Process_B取出,正在处理的关键时刻,Process_B崩溃了,哭啊,我的问题是,如果重启Process_B,是否会丢失message_1?
不要着急,阅读了下面的简要介绍后,水到渠成,上面几个问题就可以解决了。 消息队列有如下几个好处,这大都是由其系统解耦和消息缓存两点扩展而来的:
- 提升系统可靠性:
- 冗余:Process_B崩溃之后,数据并不会丢失,因为MQ多采用
put-get-delete
模式,即,仅当确认message被完成处理之后,才从MQ中移除message; - 可恢复:MQ实现解耦,部分进程崩溃,不会拖累整个系统瘫痪,例,Process_B崩溃之后,Process_A仍可向MQ中添加message,并等待Process_B恢复;
- 可伸缩:有较强的峰值处理能力,通常应用会有突发的访问流量上升情况,使用足够的硬件资源时刻待命,空闲时刻较长,资源浪费,而
消息队列
却能够平滑峰值流量,缓解系统组件的峰值压力;
- 冗余:Process_B崩溃之后,数据并不会丢失,因为MQ多采用
- 提升系统可扩展性:
- 调整模块:由于实现解耦,可以很容易调整,消息入队速率、消息处理速率、增加新的Process;
- 其他:
- 单次送达:保证MQ中一个message被处理一次,并且只被处理一次。本质:get获取一个message后,这一message即被预定,同一进程不会再次获取这一message;当且仅当进程处理完这一message后,MQ中会delete这个message。否则,过一段时间后,这一message自动解除被预订状态,进程能够重新预定这个message;
- 排序保证:即,满足队列的FIFO,先入先出策略;
- 异步通信:很多场景下,不会立即处理消息,这是,可以在MQ中存储message,并在某一时刻再进行处理;
- 数据流的阶段性能定位:获取用户某一操作的各个阶段(通过message来标识),捕获不同阶段的耗时,可用于定位系统瓶颈。
参考来源
- top 10 uses for message queue:英文原文、pdf版本、中文译文
- Message Queue wiki
- http://bbs.csdn.net/topics/110160741
- http://www.cnblogs.com/yuanyi_wang/archive/2009/12/30/1636178.html
- http://www.php1.cn/article/9865.html
http://kb.cnblogs.com/page/537914/
We’ve been working with, building, and evangelising message queues for the last year, and it’s no secret that we think they’re awesome. We believe message queues are a vital component to any architecture or application, and here are ten reasons why:
- Decoupling It’s extremely difficult to predict, at the start of a project, what the future needs of the project will be. By introducing a layer in between processes, message queues create an implicit, data-based interface that both processes implement. This allows you to extend and modify these processes independently, by simply ensuring they adhere to the same interface requirements.
- Redundancy Sometimes processes fail when processing data. Unless that data is persisted, it’s lost forever. Queues mitigate this by persisting data until it has been fully processed. The put-get-delete paradigm, which many message queues use, requires a process to explicitly indicate that it has finished processing a message before the message is removed from the queue, ensuring your data is kept safe until you’re done with it.
- Scalability Because message queues decouple your processes, it’s easy to scale up the rate with which messages are added to the queue or processed; simply add another process. No code needs to be changed, no configurations need to be tweaked. Scaling is as simple as adding more power.
- Elasticity & Spikability When your application hits the front page of Hacker News, you’re going to see unusual levels of traffic. Your application needs to be able to keep functioning with this increased load, but the traffic is anomaly, not the standard; it’s wasteful to have enough resources on standby to handle these spikes. Message queues will allow beleaguered components to struggle through the increased load, instead of getting overloaded with requests and failing completely. Check out our Spikability blog post for more information about this.
- Resiliency When part of your architecture fails, it doesn’t need to take the entire system down with it. Message queues decouple processes, so if a process that is processing messages from the queue fails, messages can still be added to the queue to be processed when the system recovers. This ability to accept requests that will be retried or processed at a later date is often the difference between an inconvenienced customer and a frustrated customer.
- Delivery Guarantees
The redundancy provided by message queues guarantees that a message will be processed eventually, so long as a process is reading the queue. On top of that, IronMQ provides an only-delivered-once guarantee. No matter how many processes are pulling data from the queue, each message will only be processed a single time. This is made possible because retrieving a message “reserves” that message, temporarily removing it from the queue. Unless the client specifically states that it’s finished with that message, the message will be placed back on the queue to be processed after a configurable amount of time. - Ordering Guarantees
In a lot of situations, the order with which data is processed is important. Message queues are inherently ordered, and capable of providing guarantees that data will be processed in a specific order. IronMQ guarantees that messages will be processed using FIFO (first in, first out), so the order in which messages are placed on a queue is the order in which they’ll be retrieved from it. - Buffering In any non-trivial system, there are going to be components that require different processing times. For example, it takes less time to upload an image than it does to apply a filter to it. Message queues help these tasks operate at peak efficiency by offering a buffer layer–the process writing to the queue can write as fast as it’s able to, instead of being constrained by the readiness of the process reading from the queue. This buffer helps control and optimise the speed with which data flows through your system.
- Understanding Data Flow
In a distributed system, getting an overall sense of how long user actions take to complete and why is a huge problem. Message queues, through the rate with which they are processed, help to easily identify under-performing processes or areas where the data flow is not optimal. - Asynchronous Communication
A lot of times, you don’t want to or need to process a message immediately. Message queues enable asynchronous processing, which allows you to put a message on the queue without processing it immediately. Queue up as many messages as you like, then process them at your leisure.
If you’d like to get started with an efficient, reliable, and hosted message queue today, check out IronMQ. If you’d like to connect with our engineers about how queues could fit into your application, they’re always available atget.iron.io/chat.
UPDATE: We posted a related article recently on the uses of a worker system titled Top 10 Uses of IronWorker(although the uses can apply to any worker system/task queue). They often work in concert with message queues and are used for background processing, schedule jobs, event processing, as a mobile compute cloud, and for many other uses.
过去几年中,我们一直在使用、构建和宣传消息队列,我们认为它们是很令人敬畏的,这也不是什么秘密。我们相信对任何架构或应用来说,消息队列都是一个至关重要的组件,下面是十个理由: 1. 解耦 在项目启动之初来预测将来项目会碰到什么需求,是极其困难的。消息队列在处理过程中间插入了一个隐含的、基于数据的接口层,两边的处理过程都要实现这一接口。这允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。 |
lwei
|
其它翻译版本(1) |
2. 冗余 有时在处理数据的时候处理过程会失败。除非数据被持久化,否则将永远丢失。消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险。在被许多消息队列所采用的"插入-获取-删除"范式中,在把一个消息从队列中删除之前,需要你的处理过程明确的指出该消息已经被处理完毕,确保你的数据被安全的保存直到你使用完毕。 3. 扩展性 因为消息队列解耦了你的处理过程,所以增大消息入队和处理的频率是很容易的;只要另外增加处理过程即可。不需要改变代码、不需要调节参数。扩展就像调大电力按钮一样简单。 |
lwei
|
其它翻译版本(1) |
4. 灵活性 & 峰值处理能力 当你的应用上了Hacker News的首页,你将发现访问流量攀升到一个不同寻常的水平。在访问量剧增的情况下,你的应用仍然需要继续发挥作用,但是这样的突发流量并不常见;如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列能够使关键组件顶住增长的访问压力,而不是因为超出负荷的请求而完全崩溃。请查看我们关于峰值处理能力的博客文章了解更多此方面的信息。 5. 可恢复性 当体系的一部分组件失效,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。而这种允许重试或者延后处理请求的能力通常是造就一个略感不便的用户和一个沮丧透顶的用户之间的区别。 |
wang7x
|
6. 送达保证 消息队列提供的冗余机制保证了消息能被实际的处理,只要一个进程读取了该队列即可。在此基础上,IronMQ提供了一个"只送达一次"保证。无论有多少进程在从队列中领取数据,每一个消息只能被处理一次。这之所以成为可能,是因为获取一个消息只是"预定"了这个消息,暂时把它移出了队列。除非客户端明确的表示已经处理完了这个消息,否则这个消息会被放回队列中去,在一段可配置的时间之后可再次被处理。 |
lwei
|
7.排序保证 在许多情况下,数据处理的顺序都很重要。消息队列本来就是排序的,并且能保证数据会按照特定的顺序来处理。IronMO保证消息浆糊通过FIFO(先进先出)的顺序来处理,因此消息在队列中的位置就是从队列中检索他们的位置。 8.缓冲 在任何重要的系统中,都会有需要不同的处理时间的元素。例如,加载一张图片比应用过滤器花费更少的时间。消息队列通过一个缓冲层来帮助任务最高效率的执行--写入队列的处理会尽可能的快速,而不受从队列读的预备处理的约束。该缓冲有助于控制和优化数据流经过系统的速度。 |
Holiday_
|
9. 理解数据流 在一个分布式系统里,要得到一个关于用户操作会用多长时间及其原因的总体印象,是个巨大的挑战。消息系列通过消息被处理的频率,来方便的辅助确定那些表现不佳的处理过程或领域,这些地方的数据流都不够优化。 10. 异步通信 很多时候,你不想也不需要立即处理消息。消息队列提供了异步处理机制,允许你把一个消息放入队列,但并不立即处理它。你想向队列中放入多少消息就放多少,然后在你乐意的时候再去处理它们。 |
lwei
|
我们相信上述十个原因,使得消息队列成为在进程或应用之间进行通信的最好形式。我们已经花费了一年时间来创建和学习IronMQ,我们的客户也通过消息队列完成了许多不可思议的事情。队列是创建强大的分布式应用的关键,它可以利用云技术所提供的所有强大能量。 如果现在你想要开始使用一个高效的、可靠的、托管的消息队列,下载IronMQ吧。如果你想联系我们的工程师,咨询如何把队列集成到你的应用中去,他们随时欢迎你的访问:get.iron.io/chat。 |
http://www.oschina.net/translate/top-10-uses-for-message-queue?