RabbitMQ内存管理

之前一直有个疑问:如果一个exchange关联n个queue,那么一份消息会不会需要拷贝n份呢?这个问题十分关键。如果真的会有n个拷贝,那么queue的数量就必须严格限制了。庆幸的是RabbitMQ官方文档的确完整,于是看摘抄如下(完整文章在此):

A bit of background
First of all we need to understand how Erlang manages memory. Erlang is a bit different from most garbage-collected languages in that it does not have a global heap. Instead, each process has a separate heap that’s private to it. In RabbitMQ terms process might be queues, channels, connections and so on. This means that the entire system does not have to come to a halt every time garbage collection needs to happen; instead each process collects garbage on its own schedule.

That’s fine, but as a message passes through RabbitMQ, it will pass through several different processes. We’d like to avoid doing too much copying as this happens. Therefore Erlang gives us a different memory management scheme for binaries, which are used for a number of things inside RabbitMQ, of which the most interesting is message bodies. Binaries are shared between processes and reference-counted (with references being held by processes and garbage-collected along with everything else).

How this applies to RabbitMQ
This means that memory used by message bodies is shared among processes in RabbitMQ. And this sharing also happens between queues too: if an exchange routes a message to many queues, the message body is only stored in memory once.

由此可见,RabbitMQ在内存处理上还是考虑周到的,每个消息无论在内存还是disk都只会保留一个拷贝,队列里只保存对消息的引用。因此,在设计系统时,队列数量可以作为一个相对比较廉价的开销。