I just added $redis->get('key') where the key is just A but I only get 40% increase in throughput vs mysql database query of the whole table for a data that is about 1000x more than that retrieved by redis.
Comment From: funny-falcon
How much CPU uses MySQL when you do it? And how much CPU uses Redis?
I claim, Redis uses single core at most (and, probably, even lesser), while MySQL uses at lease four cores (ie 400% CPU).
Comment From: dev-lyr
mysql also has query cache in memory.
Comment From: jobs-git
Hi, your claim is almost correct. Actually, Redis does not even register cpu usage while MySQL consumes almost the whole cpu core.
But despite this, throughput is just 40% better. Query cache was disable in config file of mysql. If it helps I use centos 7.4 sclo redis 3.2.4.
Comment From: funny-falcon
Throughput for singe threaded usage? How many concurrent requests you do? One? Then your bottleneck is networking round-trip (it is not negligible even on the localhost). You don't measure "throughput of Redis". You measure overhead of system calls and networking.
Until your Redis will eat at least 80% CPU there is nothing to talk about.
BTW, try pipelining.
Comment From: tong3jie
@funny-falcon 👍
Comment From: filipecosta90
Asking the core team to close this given there seems to be no issue reported above.
Comment From: jobs-git
Did you already check on this?
What is unusual is it was a localhost, yet its just 40% better than mysql considering for a fact that Redis is in-memory db. I hope u guys first look into it then close if its not the case.
Comment From: funny-falcon
@jobs-git if I understand you correctly:
- query were sent to redis and to mysql one-by-one in a single thread
- redis almost didn't use CPU, while MySQL eats almost core
- redis were faster than MySQL by 40%.
If that is what you mean then there is no issue here. You hit limits of OPERATING SYSTEM, not redis.
Comment From: jobs-git
@funny-falcon
Yes, you did listed all points correctly. If its the SYSTEM, then there is an opportunity for Redis to improve in performance, that is overcome the limits of system calls without modifying the system.
Thank you for supporting the issue regarding Redis and SYSTEM communication problem. Should we file a different issue for that?
Comment From: funny-falcon
If its the SYSTEM, then there is an opportunity for Redis to improve in performance
There is almost no way to significantly improve performance without huge complication. Yes, there is io_uring in modern Linux kernels that could be used, but it will fix only Redis side, but not client side.
Your test is slow because it doesn't utilize any kind of parallelism. Even if one introduce io_uring both into redis and into client library you use, you will not see 10x improvement in your test. I bet it will be 2.5-4x at most and only if stars converge in a right way.
But if you use pipelining with today's Redis and today's client libraries, you will easily see 20-50x improvement.
Yep, io_uring in the Redis will be great improvement, but for very other reasons: io_uring will allow to reduce Sys CPU usage when a lot of client connections simultaneously sends requests. But it will not improve your test significantly.
What is broken is your test. Believe me.
Comment From: jobs-git
That pipelining is interesting if we have series of commands.
But what if commands coming from N-individual clients?
Say
Client 1 -
|
Client 2 ---> Redis server
|
Client N -
Can redis pipeline requests by itself?
I would love to hear a php library that does this. Better yet, should be internally implemented in Redis.
Comment From: funny-falcon
Case of N independent clients is unfixable.
In the environment with embedded concurrency (NodeJS, Go, .Net, Java) there is possibility to transparently use pipelining for concurrent activities in the same process. Go libraries that implements transparent pipelining are https://github.com/joomcode/redispipe and https://github.com/mediocregopher/radix (v3 and v4). And there is list of other language connectors in redispipe's README that also implements transparent pipelining.
But transparent pipelining also could improve only overall performance. It doesn't improve each individual client separately. Unfortunately "single thread single query at at time" performance has very low (<50krps at max, but usually <25krps) limit and it could not be improved significantly.
And another bad side: pipelining is incompatible with blocking calls. Unfortunately Redis does no asynchronous request processing internally. RESP2 protocol completely serial, and it could not respond requests out of order. And even for RESP3 they missed ability to adopt RequestID field :-( it were so pity.
If you use PHP, there is no possibility to achieve transparent pipelining because most common PHP setup is process-per-request, and I believe you don't use any of PHP event loops (reactphp, evloop).
There is https://github.com/RedisLabs/redis-cluster-proxy that can be used with Redis Cluster. It has ability to muliplex requests from many client connections to lower count of connections to Redis. Therefore it brings some benefits of pipelining (less Redis CPU usage). I didn't test it though.
Comment From: jobs-git
This is very much welcomed information.
Yes you are correct, I dont use these php event loops, its too complicated to handle. So this falls into the framework I use that is not able to handle this stuff. By the concept you discussed, enabling this compatibility will result to re-working of redis, that I dont recommend in this issue. Closing now.