Why is Redis so fast?

Tiffany Hsu
6 min readSep 9, 2023

--

Introduction

One day, your manager asked you a technical question: “Can you provide a reason why Redis works faster than MySQL?” You promptly responded that Redis operates in-memory, whereas MySQL relies on disk storage. There was a moment of silence, and your manager appeared contemplative before finally saying, “Go get me a coffee at Starbucks.”

As you walked into Starbucks, you couldn’t shake the question from your manager out of your mind: “Did I misunderstand the concept?” Inside, you noticed that Starbucks operated with a single clerk behind the counter.

The clerk smiled hospitably and asked, “Hey, sir, what would you like today?”.

You replied, “I’ll have an Americano to go, please.”

With a warm smile, the clerk recorded your order on the list. Behind the scenes, the barista got to work, carefully preparing your Americano according to the order list. After finishing the task, the barista informed the clerk that the coffee was ready.

The clerk collected your Americano from the barista and handed it to you. You left Starbucks with the coffee in hand, ready to provide an answer to your manager’s question.

So, why is Redis faster than MySQL?

Single thread multiplex I/O in Redis

Let’s revisit the Starbucks example. At Starbucks, there’s just one clerk who must be attentive to clients walking into the shop, responding with a warm smile and a welcoming greeting.

In the world of Redis, this clerk is analogous to the single thread responsible for serving incoming socket connections. The clerk initiates an alarm system, which signifies that when there are no clients, the clerk takes a nap. However, when a client enters the shop, the clerk awakens immediately to serve them. Think of the event loop as the clerk calling the select or epoll system call and then going to sleep. When a socket becomes ready for reading or writing, the event loop wakes up and initiates the process of serving the client.

This single thread efficiently monitors and handles multiple socket connections, much like the Starbucks clerk welcoming and attending to arriving clients. However, there’s an important distinction: the Starbucks clerk isn’t the one making the coffee; that task falls to the barista. In the realm of Redis, the baristas are dynamically created. If more clients enter Starbucks, the clerk can seamlessly hire additional baristas to make coffee. This means that the clerk doesn’t have to wait for previous clients’ coffee orders to be completed; it can promptly serve the next client.

  • Clerk: Represents the event loop in Redis. This is the single thread responsible for managing incoming client (socket) connections.
  • Clients: Analogous to socket connections in Redis. These are the clients sending requests to the Redis server.
  • Order: Corresponds to tasks or requests in Redis. These are the operations that clients request Redis to perform.
  • Order List: Similar to the task queue in Redis, where pending tasks or requests are stored.
  • Barista: Represents the query thread in Redis. These are the worker threads responsible for executing tasks or requests.
  • Dynamically Hiring Baristas: Reflects Redis’s ability to create query threads dynamically to handle multiple tasks in parallel.
  • Using the alarm system to wake itself up: The event loop uses select or epoll in Linux to notify itself when a socket is ready for reading or writing.

Multithreading in Mysql

In the MySQL world, imagine Starbucks hiring more than one clerk. There’s a pool of clerks available(connection pool), and each client is assigned to a clerk, which is akin to the connection thread. However, the number of baristas and clerks is predefined in the store’s contract, just as MySQL’s thread management is constrained by parameters like max_connections and thread_pool_size.

Here’s a scenario: Picture yourself entering Starbucks, and you see many clerks ready to take orders. You approach one clerk, and they handle your order, similar to how a connection thread works in MySQL. The clerk, much like MySQL’s thread model, then delegates your order to a specific barista.

Now, let’s highlight the difference. While the barista is preparing your coffee, they can’t tend to other orders, illustrating the concept of blocking I/O. Once your coffee is ready, the barista returns it to the initial clerk who took your order.

If that clerk is currently assisting another client, you’ll have to wait. This situation demonstrates the context switching that occurs in MySQL’s thread management.

In addition, MySQL employs a connection pool, which means there’s a predefined limit to the number of clients that can be served simultaneously. It’s akin to Starbucks having a maximum occupancy limit. If all the clerks are busy and the connection pool is full, new clients must wait until a clerk becomes available.

  • Clerks: Represent the connection threads in MySQL. There are multiple clerks available to handle incoming client requests. Each clerk can serve many client requests, necessitating context switching. This means the clerks must juggle between different client requests.
  • Baristas: Represent the query threads in MySQL. These are responsible for executing queries or tasks.
  • In MySQL’s multithreading model, there are indeed multiple clerks and multiple baristas (connection threads and query threads).
  • When a barista is busy (executing a query), others cannot assist, demonstrating blocking I/O in MySQL. This means the thread is occupied and cannot serve other clients until the current task is completed.

Comparison

Single Thread vs. Multithreading

Redis employs a single-threaded event loop to efficiently manage multiple socket connections. It operates with a single clerk who keeps an eye out for incoming clients, eliminating the need for context switching or the complexities of handling multiple threads. Think of it as having just one clerk who watches for new customers.

Dynamic Thread Creation

In Redis, “baristas” are dynamically created as needed. This dynamic thread creation makes Redis highly scalable, enabling it to handle an increasing number of clients seamlessly. It’s like hiring additional baristas on-demand when the coffee shop gets busier.

Non-Blocking I/O

Redis excels in non-blocking I/O operations. Imagine a coffee shop where the clerk efficiently manages incoming orders without getting stuck. Each new client is served promptly, and the clerk doesn’t need to wait for the coffee to brew before attending to the next customer.

Efficient Event Handling

Redis uses efficient event handling mechanisms, including the “alarm system” mentioned earlier. Redis’s event loop proactively responds to incoming requests. It’s like having a clerk who occasionally takes a short nap but immediately springs into action when a client enters the shop. In contrast, the MySQL shop requires clerks to be present at all times, actively watching for clients to arrive.

Conclusion

Redis and MySQL have distinct approaches to handling client requests, which significantly impact their speed and scalability. Redis’s single-threaded event loop, dynamic thread creation, and non-blocking I/O operations contribute to its exceptional speed and efficiency. In contrast, MySQL’s multithreading model, with predefined connection pools and context switching, introduces complexities that can affect its performance. Understanding these architectural differences helps explain why Redis is often faster than MySQL, especially for tasks that require rapid data retrieval and response.

Your support is greatly appreciated and motivates me to keep sharing insights with you. Thanks for reading! 👏 👏 👏

--

--

Tiffany Hsu

Graduated from NYCU CS Master: From Code to Cuisine, Loving Tech and Taste