2

I have a middleware based on Apache Camel which does a transaction like this:

from("amq:job-input")
  to("inOut:businessInvoker-one") // Into business processor
  to("inOut:businessInvoker-two")
  to("amq:job-out");

Currently it works perfectly. But I can't scale it up, let say from 100 TPS to 500 TPS. I already

  1. Raised the concurrent consumers settings and used empty businessProcessor
  2. Configured JAVA_XMX and PERMGEN

to speed up the transaction.

According to Active MQ web Console, there are so many messages waiting for being processed on scenario 500TPS. I guess, one of the solution is scale the ActiveMQ up. So I want to use multiple brokers in cluster.

According to http://fuse.fusesource.org/mq/docs/mq-fabric.html (Section "Topologies"), configuring ActiveMQ in clustering mode is suitable for non-persistent message. IMHO, it is true that it's not suitable, because all running brokers use the same store file. But, what about separating the store file? Now it's possible right?

Could anybody explain this? If it's not possible, what is the best way to load balance persistent message?

Thanks

sancho21
  • 3,511
  • 1
  • 39
  • 45

5 Answers5

1

You can share the load of persistent messages by creating 2 master/slave pairs. The master and slave share their state either though a database or a shared filesystem so you need to duplicate that setup.

Create 2 master slave pairs, and configure so called "network connectors" between the 2 pairs. This will double your performance without risk of loosing messages.

See http://activemq.apache.org/networks-of-brokers.html

Geert Schuring
  • 2,060
  • 1
  • 18
  • 28
0

If all running brokers use the same store file or tx-supported database for persistence, then only the first broker to start will be active, while others are in standby mode until the first one loses its lock.

If you want to loadbalance your persistence, there were two way that we could try to do:

  1. configure several brokers in network-bridge mode, then send messages to any one and consumer messages from more than one of them. it can loadbalance the brokers and loadbalance the persistences.
  2. override the persistenceAdapter and use the database-sharding middleware (such as tddl:https://github.com/alibaba/tb_tddl) to store the messages by partitions.
Hans.Loven.work
  • 108
  • 1
  • 6
kimmking
  • 1
  • 3
0

This answer relates to an version of the question before the Camel details were added.

It is not immediately clear what exactly it is that you want to load balance and why. Messages across consumers? Producers across brokers? What sort of concern are you trying to address?

In general you should avoid using networks of brokers unless you are trying to address some sort of geographical use case, have too many connections for a signle broker to handle, or if a single broker (which could be a pair of brokers configured in HA) is not giving you the throughput that you require (in 90% of cases it will).

In a broker network, each node has its own store and passes messages around by way of a mechanism called store-and-forward. Have a read of Understanding broker networks for an explanation of how this works.

ActiveMQ already works as a kind of load balancer by distributing messages evenly in a round-robin fashion among the subscribers on a queue. So if you have 2 subscribers on a queue, and send it a stream of messages A,B,C,D; one subcriber will receive A & C, while the other receives B & D.

If you want to take this a step further and group related messages on a queue so that they are processed consistently by only one subscriber, you should consider Message Groups.

Jakub Korab
  • 4,974
  • 2
  • 24
  • 34
0

Adding consumers might help to a point (depends on the number of cores/cpus your server has). Adding threads beyond the point your "Camel server" is utilizing all available CPU for the business processing makes no sense and can be conter productive.

Adding more ActiveMQ machines is probably needed. You can use an ActiveMQ "network" to communicate between instances that has separated persistence files. It should be straight forward to add more brokers and put them into a network.

Make sure you performance test along the road to make sure what kind of load the broker can handle and what load the camel processor can handle (if at different machines).

When you do persistent messaging - you likely also want transactions. Make sure you are using them.

Petter Nordlander
  • 22,053
  • 5
  • 50
  • 84
-1

Your first step is to increase the number of workers that are processing from ActiveMQ. The way to do this is to add the ?concurrentConsumers=10 attribute to the starting URI. The default behaviour is that only one thread consumes from that endpoint, leading to a pile up of messages in ActiveMQ. Adding more brokers won't help.

Secondly what you appear to be doing could benefit from a Staged Event-Driven Architecture (SEDA). In a SEDA, processing is broken down into a number of stages which can have different numbers of consumer on them to even out throughput. Your threads consuming from ActiveMQ only do one step of the process, hand off the Exchange to the next phase and go back to pulling messages from the input queue.

You route can therefore be rewritten as 2 smaller routes:

from("activemq:input?concurrentConsumers=10").id("FirstPhase")
    .process(businessInvokerOne)
    .to("seda:invokeSecondProcess");

from("seda:invokeSecondProcess?concurentConsumers=20").id("SecondPhase")
    .process(businessInvokerTwo)
    .to("activemq:output");

The two stages can have different numbers of concurrent consumers so that the rate of message consumption from the input queue matches the rate of output. This is useful if one of the invokers is much slower than another.

The seda: endpoint can be replaced with another intermediate activemq: endpoint if you want message persistence.

Finally to increase throughput, you can focus on making the processing itself faster, by profiling the invokers themselves and optimising that code.

Jakub Korab
  • 4,974
  • 2
  • 24
  • 34
  • Thanks for the inputs. IMHO, I think they just speed up the transaction, but do not scale the number of the transaction (increasing the throughput). What if I want to make it handle 5000 messages / sec. I think I should buy other machines to make up a cluster so that they can do load balancing. – sancho21 Aug 14 '13 at 11:01
  • Speed of processing and throughput are directly related - 1 thread processing 1000 msg/s gives the same throughput as 1000 threads processing 1 msg/s. If you want to scale to beyond what a single machine will give you, you should test whether it's ActiveMQ that's the bottleneck (easily checked through http://activemq.apache.org/activemq-performance-module-users-manual.html), or the Camel route. If it's the latter, keep tuning the number of consumers until you find the upper limit, then add a second instance of the routing process onto another box to read from the same ActiveMQ instance. – Jakub Korab Aug 14 '13 at 11:18
  • I would not assume these processing steps always could be broken down into a seda architecture since the actual processing is unknown. – Petter Nordlander Aug 14 '13 at 22:14
  • You'll notice that's why I used the phrase "could" :) It doesn't change the fundamental answer that throughput is a function of the processing time and the number of concurrent consumers. – Jakub Korab Aug 15 '13 at 10:48