Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

load tests and number of concurrent connections #22

Closed
loicdescotte opened this issue Nov 25, 2013 · 11 comments
Closed

load tests and number of concurrent connections #22

loicdescotte opened this issue Nov 25, 2013 · 11 comments
Labels

Comments

@loicdescotte
Copy link

Hi,

I'm trying to find the best way to use redis from a play framework application, to support a great number of connections and have a good request/second and response time ratio.

I made a few gatling tests : redisscala with async play features, redis-scala in blocking mode (with 'Await') and a bigger play thread pool, and finally Jedis/Sedis (synchronous and blocking).

My results are surprising : I reach the best scalability with the Jedis driver.
With Jedis I can easily reach 500 connected users (500 threads) but with redisscala if I use more than 100 threads to stress the app, it becomes very slow.

My code is very simple :

def asyncRedisQuery(q: String) = Action.async {
    val redis = RedisClient()
    redis.get(q).map(_.get).map(_.utf8String).map( result =>   
        Ok(result)
      )
  }

N.B : I've tried several execution context and thread pool configuration.

Did I miss something?

Thanks

@etaty
Copy link
Owner

etaty commented Nov 25, 2013

Yep you should put val redis = RedisClient() outside of your main loop (here Action)

RedisClient() does a lot of thing (initialise a connection to redis server, pop 2 actors ...)

@loicdescotte
Copy link
Author

Thanks for your reply, as the jedis client is not threadsafe, I put it at method level, and I did the same for your driver!
Trying now :)

@loicdescotte
Copy link
Author

Now its works perfectly, and it's very fast!

My conclusions now are that the fastest test is redisscala with blocking code and a big thread pool (but the nb ofthreads will not be infinite...) , then the async redisscala, and then Jedis.

Thanks for your help!

@etaty
Copy link
Owner

etaty commented Nov 25, 2013

Do you have numbers ?

Could you show the "redisscala with blocking code" ?

@loicdescotte
Copy link
Author

Yep,

In fact I've relunched the load test and it's quite similar in blocking or not blocking mode (I hope it's readable on github) :

blockingredissimulation :

STATISTICS
Requests Executions Response Time (ms)
Total OK KO Min Max Mean Std Dev 95th pct 99th pct Req/s
Global Information 10000 10000 0 0 80 1 5 10 30 906
request_blocking_redis 10000 10000 0 0 80 1 5 10 30 906

async redissimulation :

STATISTICS
Requests Executions Response Time (ms)
Total OK KO Min Max Mean Std Dev 95th pct 99th pct Req/s
Global Information 10000 10000 0 0 120 2 6 10 30 929
request_redis 10000 10000 0 0 120 2 6 10 30 929

The blocking redis code is very simple :

def blockingRedisQuery(q: String) = Action { 
    val result = Await.result(redis.get(q), 10 seconds).map(_.utf8String).getOrElse("not found")
    Ok(result) 
  }

It uses the default thread pool with 500 threads

@etaty
Copy link
Owner

etaty commented Nov 25, 2013

Thanks.
If you are going for async, you can reduce the thread pool size.

What was the number with Jedis?

@etaty
Copy link
Owner

etaty commented Nov 25, 2013

Also you should avoid doing many map on a Future when you can write it in one map :

.map(_.get).map(_.utf8String).map( result =>   
        Ok(result)
      )

.map(r => Ok(r.get.utf8String))

Each time you map, you add a Future to threadpool which will have to be scheduled

@loicdescotte
Copy link
Author

Thanks for the tip, I'll try like this
For the thread pools, I have 500 threads for Jedis and "blocking redisscala", but for the async redisscala test, I have only 1 thread by cpu

@loicdescotte
Copy link
Author

I've removed the useless map operation
Now I have EXACTLY the same performance with async and blockign simulations : 997 request/sec and 84% of requests <= 1ms

I can put the benchmark on github if you wish

@etaty
Copy link
Owner

etaty commented Nov 25, 2013

Yep good idea, it might help other.

@loicdescotte
Copy link
Author

I've pushed everything here : https://github.com/loicdescotte/play-redis-benchmarks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants