Parallel Thread Contention At High Load

Viewed 250

I have a four core machine. At high load, the response times are pretty bad. This is pretty obvious as the work queue grows at high loads, and 4 parallel threads can only consume so fast.

Mono.just(stream)
    .flatMap(handler::handleRequest)
    .subscribeOn(Schedulers.parallel())
    .subscribe(this::response) 

Similarly, when I get a response for an I/O call, I do a .publishOn(Schedulers.parallel()) so that the response is processed on a CPU tuned thread.

I am thinking of using a bounded elastic scheduler to initiate my pipeline and use the parallel threads only for highly CPU intensive tasks (POJO manipulation and hash calculation). So basically, I start my pipeline on an elastic threads and process the response on an elastic thread as well.

I benchmarked my application using an infinite elastic scheduler and the heap size blew up. However, the wait times were definitely lower. However, if I create too many threads, the scheduling overhead would at some point overshadow the lower wait times.

How do I optimise my application? I am aiming for around 800 TPS per JVM. Is creating those many threads recommended?

1 Answers

Similarly, when I get a response for an I/O call, I do a .publishOn(Schedulers.parallel()) so that the response is processed on a CPU tuned thread.

That's the problem. You should never do blocking calls in threads started by Schedulers.parallel() (you can use http://github.com/reactor/BlockHound that will throw and error when you do so).

So basically, I start my pipeline on an elastic threads and process the response on an elastic thread as well.

There is no need to "start the pipeline on the elastic threads". Just start it "normally", and offload blocking calls to Schedulers.boundedElastic().

Related