forked from snxraven/ravenscott-blog
Update Blog
This commit is contained in:
parent
c483e8f079
commit
e75dca0bb1
@ -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
|
||||
|
||||
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. Let’s 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. Let’s dive into the code and understand how this was achieved.
|
||||
|
||||
## 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
|
||||
|
||||
@ -18,7 +22,9 @@ When you’re dealing with numerous Minecraft servers, querying real-time server
|
||||
- Fetching MOTD and other server metadata.
|
||||
- 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
|
||||
|
||||
@ -38,7 +44,9 @@ These caches are refreshed periodically and stored in an in-memory object, reduc
|
||||
|
||||
### 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
|
||||
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
|
||||
|
||||
#### 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
|
||||
async function fetchMOTD(connectString) {
|
||||
@ -154,7 +166,9 @@ async function fetchMOTD(connectString) {
|
||||
|
||||
#### 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
|
||||
async function fetchContainerInfo(serverName) {
|
||||
@ -176,10 +190,14 @@ The cache is updated by periodically calling the `updateCache` function, which r
|
||||
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.
|
Loading…
Reference in New Issue
Block a user