In this page listing the redis clients, I counted 8 asynchronous libraries. My understanding is that frameworks like as node.js or tornado only make sense when the asynchro
The single-threaded nature of Redis is irrelevant regarding the potential benefits of an asynchronous client. Despite its unique event loop, Redis is able to concurrently manage a good number of client connections. I have seen benchmarks with up to 30000 connections on a single Redis instance.
Just consider that with in-memory key/value stores like Redis or memcached, the performance and latencies are dominated by the network roundtrips rather than server-side CPU consumption. Granted, the latency of network roundtrips increases when the network links are saturated, but it does not mean it becomes negligible when the network is far from saturation. For instance, on a very lightly loaded 1 GbE network, it is not uncommon to see the RTT latency close to 200 us.
The consequence is, except when the network links are close to saturation, client connections (or asynchronous callback functions) are rarely competing with each other for I/Os. Sockets are associated to buffers which amortize the cost of read and write operations on the network. Most of the time, the wait states are not due to I/O competition, but to the latency of the network.
There are various ways to decrease the impact of network latency:
pipelining: grouping multiple commands together so that network roundtrips are payed once per group of commands (actually, this is synchronous pipelining).
non blocking I/Os: while it does not reduce the number of roundtrips (or their individual cost), an asynchronous client can manage them concurrently. The consequence is the network latency has less (or no) impact on the application throughput.
multiple client connections: each client connection has its own socket, and therefore its own buffer. More buffers often means better throughput. More connections increases the opportunity to process things concurrently and/or asynchronously, with positive impacts on the overall performance.
These solutions are all supported by the Redis ecosystem, and can be combined to maximize the performance. Asynchronous clients typically allows this kind of combinations. What are the use cases of an asynchronous client? Here are a few examples:
implementing asynchronous pipelining, to minimize the wait states on a single connection.
integrating Redis connection(s) with an existing event loop (such as libevent, Node.js, Tornado, Twisted, etc ...) without relying on an extra thread pool.
supporting data sharding with multiple Redis instances. In that case, the client application will probably want to parallelize the accesses to the various instances. With an asynchronous client, it can be conveniently done from a unique thread.
supporting the HA resiliency models based on the pre-connection of the client application to the various master/slaves instances.
Event loops, asynchronous libraries, and/or coroutine-like mechanisms are one of the corner stones of a majority of the efficient NoSQL engines out there.