My goal is to make about 80% CPU usage on Redis server, this can benifit our backend server designing.
While using Redis itself's benchmark, it's very easy to reach about 100% CPU usage:
$ redis-benchmark -h 192.168.1.6 -n 1000000 -c 50
On this benchmark, we assigned 50 client to push 1,000,000 request on our redis server(192.168.1.6)
But while using some other client tools(such as redis-lua or webdis), the most CPU usage is less than 60%.
I browsed some code in webdis and reids-lua. webdis depend on hiredis, redis-lua implemented in Lua, which based on socket(lua-socket). Does these fatctors affect the test result?
I also browsed some code in redis-benchmark.c, the benchmark's main work done in aeMain
, seems like that
the redis-benchmark used the code in Redis, and my test clients(webdis and redis-lua) do not.
Currently my client have two choices, use redis-lua or do something like webdis, but this two do not make a good use of Redis (less than 60%), is there any more choice? Or how to make a good usage on redis-server except the redis-benchmark itself?
I doubt maximizing CPU usage of Redis will benefit your backend design. The right question is rather whether Redis is efficient enough to sustain your throughput at a given latency. Redis is a single-threaded server: at 80% CPU consumption, the latency will likely be very bad.
I suggest you measure latency while redis-benchmark is working to see if it is acceptable for your needs before trying to increase Redis CPU consumption. The --latency option of redis-cli can be used for this:
Now, if you really want to increase Redis CPU consumption, you need either an efficient client program (like redis-benchmark), able to handle multiple connections concurrently, either multiple instances of your client program.
Lua is a fast interpreted language, but it is still an interpreted language. It will be one or two orders of magnitude slower than C code. Redis is much faster at parsing/generating its protocol than lua-redis, so you will not be able to saturate Redis with a unique Lua client (except if you use O(n) Redis commands - see later).
webdis is implemented in C, with an efficient client library, but has to parse the http/json protocols which happen to be more verbose and complex than Redis protocol. It likely consumes more CPU than Redis itself for most operations. So again, you will not saturate Redis with a single webdis instance.
Here are some examples to saturate Redis with multiple Lua clients.
If it is not already done, I suggest you had a look at the Redis benchmark page first.
If you run your benchmark on the same box as Redis:
The key point is to dedicate a core to Redis, and run the client programs on the other cores. On Linux, you can use the taskset command for this.
The Lua program should use pipelining to maximize throughput and reduce system activity.
On my system, the Lua program takes more than 4 times the CPU of Redis, so you need more than 4 cores to saturate Redis with this method (a 6 cores box should be fine).
If you run your benchmark on a different box than Redis:
Except if you run on CPU starved virtual machines, the bottleneck will likely be the network in that case. I don't think you can saturate Redis with anything less than a 1 GbE link.
Be sure to pipeline your queries as far as you can (see the previous Lua program) to avoid the network latency bottleneck, and reduce the cost of network interrupts on the CPU (filling ethernet packets). Try to run Redis on a core which is not bound to the network card (and processes network interrupts). You can use tools like htop to check this last point.
Try to run your Lua clients on various other machines of the network if you can. Again you will need a good number of Lua clients to saturate Redis (6-10 should be fine).
In some cases, a unique Lua process is enough:
Now, it is possible to saturate Redis with a single Lua client if each query is expensive enough. Here is an example:
This program populates a list with 1M items, and then uses lrange commands to fetch 10 items from the middle of the list (worst case for Redis). So each time a query is executed, 500K items are scanned by the server. Because only 10 items are returned, they are fast to parse by lua-redis which will not consume CPU. In this situation, all the CPU consumption will be on server side.
Final words
There are probably faster Redis clients than redis-lua:
You may want to try them.