ActiveMQ prefetch机制
每次consumer连接至 broker 时,broker 预先获取许多message到消费者(前提是broker 中存在大量消息),预先存放message的数量取决于prefetchSize(默认为1000)。
此机制的目的很显然,是想让客户端代码用一个consumer反复进行receive操作,这样能够大量提高出队性能。
prefetch预取,即push,而不用pull,pull拉会造成消息一定程度的延迟;
预取的消息数量必须合理限制:
太大了会大量消耗客户端资源,并被一个客户端占用,而其他客户端无法消费;
太小了会造成客户端频繁获取消息,如果获取消息的速度赶不上消费的速度,则会降低客户端的消费能力;
针对某客户端,broker一旦分发了指定预取数量 N 的消息后,就不会再分发消息了,直到该客户端中针对预取消息N的50%回馈后才会考虑再分发;
One of the design goals of ActiveMQ is to be a highly performant message bus. This means using a SEDA architecture to perform as much work as possible asynchronously. To make efficient use of network resources the broker utilizes a 'push' model to dispatch messages to consumers. This ensures that a consumer always has a local buffer of messages ready to process. The alternative would be for consumers to explicitly pull messages from the broker. Pulling messages individually is not very efficient and can increase the per message latency significantly.
However, there is a danger that without limiting the number of messages that are pushed to a consumer its client-side resources could become exhausted. This is the natural consequence of message consumption typically being much slower than message delivery. To avoid this situation ActiveMQ therefore employs a prefetch limit to limit the maximum number of messages that can be dispatched to an individual consumer at once. The consumer in turn uses the prefetch limit to size its prefetch message buffer.
Once the broker has dispatched a prefetch limit number of messages to a consumer it will not dispatch any more messages to that consumer until the consumer has acknowledged at least 50% of the prefetched messages, e.g., prefetch/2, that it received. When the broker has received said acknowledgements it will dispatch a further prefetch/2 number of messages to the consumer to 'top-up', as it were, its prefetch buffer. Note that it's possible to specify a prefetch limit on a per consumer basis (see below).
Large prefetch values are recommended for high performance with high message volumes. However, for lower message volumes, where each message takes a long time to process, the prefetch should be set to 1. This ensures that a consumer is only processing one message at a time. Specifying a prefetch limit of zero, however, will cause the consumer to poll for messages, one at a time, instead of the message being pushed to the consumer.
ActiveMQ的一个主要的设计目标是:提供一个高性能的消息中间件。它使用了SEDA(Staged Event Driven Architecture)架构及异步传输。为了提供更高的性能,很重要的一点是 尽快地将消息传送给消费者,这样消费者利用消息缓冲区等待处理,而不是等待消息。 然后,这样也有很大风险:不断地向 消费者 传送消息可能使得其消息缓冲溢出,因为传送的速度比消费者真正“消费”消息更快,这是很可能。 因此,ActiveMQ使用了 消息”预取限制“(prefetch limit):表示在某个时间段内,可能向消费者传输的最大消息量,如果达到该上限,那么停止发送,直到ActiveMQ收到消费者的acknowledgements(确认,表示已经处理了该消息)。prefetch limit可以针对每个不同的consumer来设置。 为了获取更高的性能,prefetch limit当然是越大越好,只要consumer有足够大的消息缓冲区(messagevolume)。如果消息的总量非常少,而且每个消息的处理时间非常的长,那么,可以将prefetch设置为1,这样,每次向consumer发送一个消息,等其确认已经处理完毕后,再发送第二个。 特别地,如果prefetch设置为0,表示consumer每次 主动向activeMQ要求传输最大的数据量,而不是被动地接收消息。
What is the Prefetch Limit For?
http://activemq.apache.org/what-is-the-prefetch-limit-for.html