Stefan
Stefan

Reputation: 2068

RabbitMQ - Many queues or one with routing keys?

i'm running a distributed application (running on multiple servers) that fetch messages from our main backend server(s) running a RabbitMQ cluster.

However, the messages are almost all the same kind, but i use one queue for each of our customers. I notice that our load & memory usage is pretty high - Could using only one queue with routing keys as customer IDs solve the problem?

Currently, i'm using one channel per one consumer and max 20 channels per connection - so one server accessing the rabbitmq server can have multiple connections. Around 500-800 connections are not unusual.

UPDATE

Here are some metrics:

Connections: 748
Channels: 6577
Exchanges: 8
Queues: 1590
Consumers: 1098
Messages Total: 153.394
Messages unacked: 152.848
Acknowledge: 2674/s
Publish: 704/s
Deliver: 586/s

And rabbitmqctl status output:

Status of node rabbit@masternode ...
[{pid,10814},
 {running_applications,
     [{rabbitmq_management,"RabbitMQ Management Console","3.5.6"},
      {rabbitmq_web_dispatch,"RabbitMQ Web Dispatcher","3.5.6"},
      {webmachine,"webmachine","1.10.3-rmq3.5.6-gite9359c7"},
      {mochiweb,"MochiMedia Web Server","2.7.0-rmq3.5.6-git680dba8"},
      {rabbitmq_management_agent,"RabbitMQ Management Agent","3.5.6"},
      {rabbit,"RabbitMQ","3.5.6"},
      {os_mon,"CPO  CXC 138 46","2.2.14"},
      {inets,"INETS  CXC 138 49","5.9.7"},
      {mnesia,"MNESIA  CXC 138 12","4.11"},
      {amqp_client,"RabbitMQ AMQP Client","3.5.6"},
      {xmerl,"XML parser","1.3.5"},
      {sasl,"SASL  CXC 138 11","2.3.4"},
      {stdlib,"ERTS  CXC 138 10","1.19.4"},
      {kernel,"ERTS  CXC 138 10","2.16.4"}]},
 {os,{unix,linux}},
 {erlang_version,
     "Erlang R16B03 (erts-5.10.4) [source] [64-bit] [smp:32:32] [async-threads:64] [kernel-poll:true]\n"},
 {memory,
     [{total,1093604792},
      {connection_readers,8069400},
      {connection_writers,6168304},
      {connection_channels,115667448},
      {connection_other,20448952},
      {queue_procs,526134000},
      {queue_slave_procs,3045928},
      {plugins,1638160},
      {other_proc,20891248},
      {mnesia,5975616},
      {mgmt_db,63193376},
      {msg_index,2245016},
      {other_ets,3895632},
      {binary,214973160},
      {code,20000582},
      {atom,703377},
      {other_system,80554593}]},
 {alarms,[]},
 {listeners,[]},
 {vm_memory_high_watermark,0.4},
 {vm_memory_limit,54036645478},
 {disk_free_limit,50000000},
 {disk_free,100918980608},
 {file_descriptors,
     [{total_limit,49900},
      {total_used,1231},
      {sockets_limit,44908},
      {sockets_used,243}]},
 {processes,[{limit,1048576},{used,15377}]},
 {run_queue,1},
 {uptime,2241834}]

Publish and deliver sometimes stall (go very low)

UPDATE 2

There's nothing showing in the logs and the java driver doesn't call the callback when something is blocked.

I have several use cases, for example for batching documents that i load into our search server (solr). Many producers (>50) generate around 50.000 messages per minute and the consumer(s) use that queue without autoack.

After the messages have been successfully sent (or retried up to 5 times), the messages will be acked. Maybe this could block everything? I set it to autoack and everything runs a lot smoother now.

What my initial question was about: Every of our customers has a single queue which is currently on autoack. It can happen that one of those customers suddenly doesn't have a customer, but that's no problem at all. So, would using a single queue with routing keys improve performance?

Currently i'm just sending to an empty exchange (default exchange) without routing key (or empty routing key) directly to the customer-queue. The messages are gzipped json, so pretty small, a few kb in average.

Upvotes: 2

Views: 1980

Answers (1)

theMayer
theMayer

Reputation: 16177

As far as it goes, connections and channels are both lightweight objects, though there is additional process and overhead involved in creating a connection as opposed to a channel, which is simply a single-packet command. I would not expect 800 connections to even begin to stretch RabbitMQ. Memory use and disk use is primarily driven by the number of messages sitting in the queues, and to some extent by the number of queues. Without details on your application throughput, it is difficult to surmise further, but I would start by ensuring that your producers and consumers are roughly matched from a volume standpoint.

To find out more about what is using memory, invoke rabbitmqctl status (see documentation here).

Upvotes: 1

Related Questions