2

Architecture

Producer looks at each message type and routes to any ArrayBlockingQueue based on availability of space in that Queue. There are only two types of messages Type 1 or Type 2. A given queue can contain only one type of message. I want to build a system which can have 'm' queues where some of them will contain Type 1 messages, and the rest will contain Type 2 messages. Now each queue can have one or more consumers reading from it. Mapping of Queue to consumer is 1:n. Each consumer will consume from exactly 1 queue.

Now, the functionality I want is this:

  1. If there is even one queue with space in it, the producer should put() a message into that queue. Producer should block on put() only if all queues are full.
  2. As long as there is a message in a queue, all consumers that are waiting on a given queue should be able to take() from the queue and get a message of their own.
  3. No message should be processed by multiple consumer threads.

Is this possible and elegant with ArrayBlockingQueue? Or is there a better solution for this problem?

user2116243
  • 303
  • 2
  • 10
  • Why use n queues rather than one queue with n times the capacity? – Jim Rogers Apr 23 '20 at 23:06
  • We'd want several queues so that the system can be more and more scalable. End goal is to consume as many messages as possible. So, I want to have 100s of consumer threads. If there was only one queue, each thread will have to synchronize behind the "take()" method of the BlockingQueue. – user2116243 Apr 24 '20 at 00:51
  • Did you execute two simple tests given 1000 consumers and either (a) 1 queue of 100000 objects or (b) 2 queues of 50000 objects? Which test finishes earlier and is the extra throughput worth the added complexity? – Jeff Holt Apr 24 '20 at 01:00
  • You have a single producer. No matter how many consumers you scale up to they will never be able to process data from the queue or queues any faster than the producer writes to the queue or queues. Forcing the producer to handle many queues rather than one for each message type results in overhead for the producer. – Jim Rogers Apr 24 '20 at 05:24
  • 1
    @JeffHolt, I just did, and with a 1000 consumers, just one queue, the simulation didn't really expose much contention, actually. I had each producer produce messages every 10 ms. Each consumer takes 200 ms to process a message. Overall in 10 seconds, there were 894 produced and 878 consumed. That performance is quite sufficient for us, to be honest. Interesting, I really thought reading from one queue will prove to be a bottleneck that will significantly slow down the rate of consumption. – user2116243 Apr 24 '20 at 20:55

0 Answers0