Tranquilizer Performance (0.7.3)

Hi,

We were pushing data using Tranquility 0.5.x and is working fine, the problem is we cannot get number of failed messages. With 0.7.3 and Tranquilizer, I’m planning to do the following code. My question is, how does the performance of Tranquilizer compared with the old way of sending data?(javaService.apply(List<Map<String, Object>>). My concern is that we send ~100K rows with every flush(), we are pushing ~1.5M rows every minute, will the calling send() method too many time along with the added listeners introduce extra performance overhead and memory stress? We’d like to understand this question before moving to the newer version. From the doc, looks like Tranquilizer handles batch internally, can someone help me understand that with our data size, what would be the performance expectation here?

 public PushResult pushMessages(List<Map<String, Object>> messages) {
        final AtomicLong sentCounter = new AtomicLong();
        final AtomicLong failedCounter = new AtomicLong();
        for (Map<String, Object> message : messages) {
            tranquilizer.send(message).addEventListener(
                new FutureEventListener<BoxedUnit>() {
                    @Override
                    public void onSuccess(BoxedUnit value) {
                        sentCounter.incrementAndGet();
                    }

                    @Override
                    public void onFailure(Throwable e) {
                        failedCounter.incrementAndGet();
                    }
                });
        }
        tranquilizer.flush();
        return new PushResult(sentCounter.get() + failedCounter.get(),
            sentCounter.get(), failedCounter.get());
    }

Thanks in advance
Shuai

Hey Shuai,

I benchmarked the tranquilizers at 150k messages/sec (simple messages) from a single thread on my laptop, and there’s code in a PR that pushes that up to 300k messages/sec. It’s thread safe so you can also send from multiple threads.

Although calling flush() very often will likely hurt performance, since it forces you to wait for all pending messages to send, so if you can live with calling it less often (bigger batches) then that’d be good. You could also send multiple batches simultaneously if that works for your app (this is what Tranquility Server does).

Thanks for the clarification. I’ve started to move to 0.7.3, so far looks promising.

Can you go over very roughly how Tranquilizer deals with batching when is the best time to call flush()? My understanding is that without calling flush(), Tranquilizer still sends out batches “at its own pace”, however, if the flush() is called, current batch will be forced to push to Druid. Is this right, or flush() is mandatory?

Thanks again for your quick and helpful response

Hey Shuai,

Sure, basically whenever you call “send” your message is added to a pending batch. That batch is sent to Druid either when it’s full (maxBatchSize) or when there’s room in the outgoing batch queue (# pending batches < maxPendingBatches). lingerMillis is a tuning that forces not-yet-full batches to wait a certain amount of time before being sent.

This all happens without you ever calling “flush”. What “flush” does is force all pending batches to be sent to Druid, and blocks until they are confirmed sent.

Great to know, thank a lot!