Scaling a Node.js Application with Distributed Caching: Part 2 - Memcached
Shankar
Posted on June 30, 2023
In the first part of this series, we explored how to scale a Node.js application using distributed caching with Redis. Now, let's take a look at another popular caching solution - Memcached.
Introduction to Memcached
Memcached is an open-source, high-performance, distributed memory object caching system. It is an in-memory key-value store for small chunks of arbitrary data (strings, objects) from results of database calls, API calls, or page rendering.
Why Choose Memcached?
Memcached's simple design promotes quick deployment, ease of development, and solves many problems facing large data caches. Its API is available for most popular languages, making it a versatile choice for developers.
Setting Up Memcached
First, you need to install Memcached on your machine. You can do this using the following commands:
# For Ubuntu
sudo apt-get install memcached
# For MacOS
brew install memcached
Integrating Memcached in Node.js
To use Memcached in a Node.js application, you need to install the memcached package. You can do this using the following command:
npm install memcached
After installing the memcached package, you can use it in your application like this:
const Memcached = require('memcached');
const memcached = new Memcached('localhost:11211');
memcached.set('key', 'value', 10, function (err) { /* handle error */ });
memcached.get('key', function (err, data) {
console.log(data);
});
In the above code, we first require the memcached package and then create a new Memcached instance. We then set a key-value pair in Memcached with a lifetime of 10 seconds. After that, we retrieve the value of the key from Memcached.
Scaling with Memcached
When scaling a Node.js application with Memcached, you can use multiple Memcached servers. The memcached package allows you to pass an array of server locations when creating a new Memcached instance:
const memcached = new Memcached(['localhost:11211', 'localhost:11212']);
In the above code, we create a new Memcached instance with two Memcached servers. The memcached package will automatically distribute the keys among the servers.
Implementing Memcached
Let's dive into the implementation of distributed caching in a Node.js application using Memcached. Like Part1, we'll use an example of caching the results of a database query.
const Memcached = require('memcached');
const memcached = new Memcached('localhost:11211');
// Example route handler in an Express.js application
app.get('/users/:id', async (req, res) => {
const userId = req.params.id;
const cacheKey = `user:${userId}`;
// Check if the data exists in the cache
memcached.get(cacheKey, async (err, cachedData) => {
if (cachedData) {
// Data found in the cache, return it
const user = JSON.parse(cachedData);
res.json(user);
} else {
// Fetch data from the database
const user = await fetchUserFromDatabase(userId);
// Store the data in the cache with an expiration time (e.g., 1 hour)
memcached.set(cacheKey, JSON.stringify(user), 3600, function (err) { /* handle error */ });
// Return the data to the client
res.json(user);
}
});
});
// Function to fetch user data from the database
async function fetchUserFromDatabase(userId) {
// Code to query the database and retrieve user data
// ...
// Simulating a delay in fetching data from the database
await new Promise((resolve) => setTimeout(resolve, 1000));
// Return the fetched user data
const user = { id: userId, name: 'John Doe', email: 'john@example.com' };
return user;
}
Conclusion
In this part, we explored how Memcached can be a powerful tool for scaling a Node.js application. It allows you to cache data in memory, which can significantly speed up your application. In the next part of this series, we will compare the performance of Redis and Memcached to help you choose the best tool for your needs.
Posted on June 30, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.