Update Blog

This commit is contained in:
Raven Scott 2024-09-16 08:12:06 -04:00
parent c483e8f079
commit e75dca0bb1

View File

@ -3,11 +3,15 @@ Finding an efficient way to cache data into memory.
# Building a Fast and Efficient Minecraft Server Cache Manager in Node.js # Building a Fast and Efficient Minecraft Server Cache Manager in Node.js
In this article, we will take an in-depth look at how to build a cache manager in Node.js to drastically improve the performance of your application, specifically for listing Minecraft servers. Without caching, the response time for listing all the servers was over 2 minutes due to multiple heavy computations and I/O operations. With the introduction of a caching mechanism, this time was reduced to an impressive 2 milliseconds. Lets dive into the code and understand how this was achieved. In this article, we will take an in-depth look at how to build a cache manager in Node.js to drastically improve the performance of your application, specifically for listing Minecraft servers. Without caching, the response time for listing all the servers was over 2 minutes due to multiple heavy computations and I/O operations.
With the introduction of a caching mechanism, this time was reduced to an impressive 2 milliseconds. Lets dive into the code and understand how this was achieved.
## Overview of the System ## Overview of the System
The purpose of this system is to manage a list of Minecraft servers efficiently. The core functionality includes fetching server information, such as the server's MOTD (Message of the Day), online status, game version, and operational details (e.g., ops, whitelist, banned players). The data is sourced from Docker containers, local file systems, and remote authentication services. The purpose of this system is to manage a list of Minecraft servers efficiently. The core functionality includes fetching server information, such as the server's MOTD (Message of the Day), online status, game version, and operational details (e.g., ops, whitelist, banned players).
The data is sourced from Docker containers, local file systems, and remote authentication services.
### Problem Statement ### Problem Statement
@ -18,7 +22,9 @@ When youre dealing with numerous Minecraft servers, querying real-time server
- Fetching MOTD and other server metadata. - Fetching MOTD and other server metadata.
- Interacting with the file system to fetch or generate tokens. - Interacting with the file system to fetch or generate tokens.
These operations, especially when scaled to multiple servers, can significantly slow down the response time. Without caching, the requests took over 2 minutes to process. This system mitigates those delays by introducing an efficient in-memory cache. These operations, especially when scaled to multiple servers, can significantly slow down the response time. Without caching, the requests took over 2 minutes to process.
This system mitigates those delays by introducing an efficient in-memory cache.
## The Caching Mechanism ## The Caching Mechanism
@ -38,7 +44,9 @@ These caches are refreshed periodically and stored in an in-memory object, reduc
### Directory and File Structure ### Directory and File Structure
- **Cache Directory:** The `cacheDir` (in this case, `/home/cache`) stores JSON files that provide metadata for each Minecraft server. Each file corresponds to a specific server and includes connection details and server-specific configuration data. - **Cache Directory:** The `cacheDir` (in this case, `/home/cache`) stores JSON files that provide metadata for each Minecraft server.
Each file corresponds to a specific server and includes connection details and server-specific configuration data.
```javascript ```javascript
const cacheDir = "/home/cache"; const cacheDir = "/home/cache";
@ -122,13 +130,17 @@ exports.list_all_servers = async function (req, res) {
}; };
``` ```
This function first checks the secret key for authentication. If the secret key is valid, it proceeds to list all servers. The server data is retrieved from the in-memory cache, avoiding the need to re-fetch the data from slow external sources like Docker, network connections, and the file system. This function first checks the secret key for authentication. If the secret key is valid, it proceeds to list all servers.
The server data is retrieved from the in-memory cache, avoiding the need to re-fetch the data from slow external sources like Docker, network connections, and the file system.
### Caching Core Functions ### Caching Core Functions
#### Fetching MOTD #### Fetching MOTD
The function `fetchMOTD` sends a custom status request packet to the server and waits for its response. The result is cached, so future requests can serve the MOTD immediately without querying the server again. The function `fetchMOTD` sends a custom status request packet to the server and waits for its response.
The result is cached, so future requests can serve the MOTD immediately without querying the server again.
```javascript ```javascript
async function fetchMOTD(connectString) { async function fetchMOTD(connectString) {
@ -154,7 +166,9 @@ async function fetchMOTD(connectString) {
#### Fetching Container Info #### Fetching Container Info
The `fetchContainerInfo` function interacts with Docker to fetch container details for each Minecraft server. Dockerode is used to communicate with the Docker API. The result is cached in memory to avoid repeatedly querying Docker for container data. The `fetchContainerInfo` function interacts with Docker to fetch container details for each Minecraft server.
Dockerode is used to communicate with the Docker API. The result is cached in memory to avoid repeatedly querying Docker for container data.
```javascript ```javascript
async function fetchContainerInfo(serverName) { async function fetchContainerInfo(serverName) {
@ -176,10 +190,14 @@ The cache is updated by periodically calling the `updateCache` function, which r
setInterval(updateCache, 60000); setInterval(updateCache, 60000);
``` ```
This ensures that the cache is kept relatively up-to-date while still providing the performance benefits of avoiding repeated heavy I/O operations. The cache holds both the value and a timestamp, allowing future improvements like time-based cache invalidation if needed. This ensures that the cache is kept relatively up-to-date while still providing the performance benefits of avoiding repeated heavy I/O operations.
## Conclusion The cache holds both the value and a timestamp, allowing future improvements like time-based cache invalidation if needed.
By introducing an in-memory caching system, this application was able to reduce request times from over 2 minutes to just 2 milliseconds. This system efficiently caches key server data, eliminating the need to repeatedly query external services like Docker, network services, and file systems. This approach is especially useful in applications with high I/O overhead and network latency, allowing for faster and more responsive interactions. ## Findings
By introducing an in-memory caching system, this application was able to reduce request times from over 2 minutes to just 2 milliseconds. This system efficiently caches key server data, eliminating the need to repeatedly query external services like Docker, network services, and file systems.
This approach is especially useful in applications with high I/O overhead and network latency, allowing for faster and more responsive interactions.
This caching strategy could be adapted and extended further, for instance by adding cache expiration policies or integrating Redis for distributed caching in a multi-node architecture. This caching strategy could be adapted and extended further, for instance by adding cache expiration policies or integrating Redis for distributed caching in a multi-node architecture.