Skip to main content

External Server Cache

tip

This section is an extension related to the external server.

This document is not required reading, but it introduces a performance optimization technique and is recommended when you have time.

Introduction

When caching business data, common approaches use professional caching libraries such as Caffeine, cache2k, ehcache, JetCache, and cache data inside logic servers.

External server cache allows some hot business data to be cached directly in the external server. When users access related routes, data is returned directly from external-server memory. This avoids repeatedly requesting logic servers and reduces data serialization (encoding), resulting in major performance gains.

When external-server cache is combined with professional cache libraries, performance can improve further. Hot data can be cached at the external layer, so subsequent accesses no longer need to fetch from logic servers, and can be completed directly at the external-server layer.


External server cache significantly improves performance in several ways:

  1. Faster response for cached data because the request chain is shorter.
  2. Direct read at external server, with no request forwarding to logic servers and no business-data serialization.
  3. Less request forwarding to logic servers, saving system resources.

Features

  1. Zero learning cost.
  2. Fast response to user requests.
  3. Simplifies caching usage. Even without caching those data in logic servers, route cache configured in external server can still achieve caching effect.
  4. Reduced request forwarding. Cached business data can be handled at external-server layer without passing through logic servers.
  5. Avoids serialization operations. Route business data is cached as byte[] in external server, so data read from cache no longer needs serialization (encoding). In simple terms, business objects do not need to be converted into byte[] repeatedly.
  6. Supports conditional cache (same action with different request parameters).
  7. Supports route-scope cache configuration.

Comparing Solutions

To help developers better understand the advantages of external-server cache, this section first compares it with two commonly used third-party solutions.


Compared with Hazelcast, Redis, and other third-party solutions

  • Redis has extra overhead, such as data serialization/deserialization, compression/decompression, network IO, network fluctuation, and so on. Using external-server cache can effectively avoid these issues, and performance can be hundreds of times that of Redis in suitable scenarios.
  • Hazelcast also has additional overhead. Memory usage is almost equal across nodes, regardless of whether all data is useful for each node. If one node uses 1 GB memory, other nodes may also consume similar memory. When data changes, serialization across N nodes and network IO across N nodes are required. For developers unfamiliar with Hazelcast, installation, configuration, and cluster debugging can also be complex and time-consuming.

Using Hazelcast, Redis, and similar third-party solutions - drawbacks

  • Requires additional installation (installation cost and machine resource cost).
  • After introducing third-party components, you need to learn related APIs (learning cost).
  • Requires extra work such as data storage and updates (usage and maintenance cost).

Comparison summary

Most importantly, developers can use external-server cache with minimal awareness (zero learning cost).

External CacheHazelcastRedisDescription
High performanceBoth can be hundreds of times faster than Redis
Zero installation cost
Zero learning cost
Zero usage cost
Zero maintenance cost
Memory usageOn demandEqualized across nodesLoad all in memory
Serialization count00NPer cache access
Network IO count00NPer cache access

Usage Scenarios

Example scenarios

  • Configuration data, such as equipment config, item config, etc.
  • Leaderboards with low timeliness requirements, for example accepting sync delay every 1/5/10/N minutes, and with small data volume (hundreds of records).
  • More examples will be added later.

Suitable scenarios for external-server cache

  • Hot data.
  • Frequently requested data with low change frequency.
tip

You can treat the external server as an alternative "Nginx/OpenResty"-like layer, which can serve pre-shielding and feature-extension responsibilities in the overall architecture.

External-server cache is not intended to replace Hazelcast/Redis. It has stronger advantages in specific business scenarios.

Cache Processing Flowchart

external_cache

Flowchart explanation

  • Player: user.
  • ExternalServer: external server.
  • request: user request.
  • response: response from external server.
  • cacheData: cached data. If matching cache exists, response is returned from cache; otherwise data is fetched from logic server.

How to Use

Using external-server cache is similar to route access permission control. If you already know that section, you can get started in minutes.

  • code 3: configure cache for route 3-1.
PresentKit.ifPresent(ExternalGlobalConfig.externalCmdCache, externalCmdCache -> {
// cache config
externalCmdCache.addCmd(3, 1);
});

When user requests 3-1, if cached data exists in external server, response is returned directly at external layer.

If cache is not found, request is forwarded to logic server for processing. After processing, logic server returns result to external server and stores result into cache. When another user requests 3-1 later, result can be returned from cache for fast response.

More Configurations

CmdCacheOption

CmdCacheOption is the cache configuration object for external server and enables finer control.

  • code 3: cache expiration 1 hour.
  • code 4: expiration check interval 5 minutes.
  • code 5: cache limit per action set to 256 entries.
CmdCacheOption createCmdCacheOption() {
return CmdCacheOption.builder()
.setExpireTime(Duration.ofHours(1))
.setExpireCheckTime(Duration.ofMinutes(5))
.setCacheLimit(256)
.build();
}
tip

Even without explicit configuration, these are also the framework defaults. This section only demonstrates how to create cache options.

Configuring Different CmdCacheOption

  • code 4~5: create and set default cache option; subsequent added route caches use this default.
  • code 6: add route cache 22-1, using default option.
  • code 8~14: create a new cache option object and apply it to routes 22-2 and 22-3. (these routes will use optionCustom, not the default option)
...
void extractedExternalCache() {
PresentKit.ifPresent(ExternalGlobalConfig.externalCmdCache, externalCmdCache -> {
var defaultOption = createCmdCacheOption()
externalCmdCache.setCmdCacheOption(defaultOption);
externalCmdCache.addCmd(22, 1);

var optionCustom = CmdCacheOption.builder()
.setExpireTime(Duration.ofSeconds(30))
.setExpireCheckTime(Duration.ofSeconds(5))
.build();

externalCmdCache.addCmd(22, 2, optionCustom);
externalCmdCache.addCmd(22, 3, optionCustom);
});
}

CmdCacheOption createCmdCacheOption() {
return CmdCacheOption.builder()
.setExpireTime(Duration.ofHours(2))
.setExpireCheckTime(Duration.ofMinutes(10))
.setCacheLimit(128)
.build();
}

Route Scope Cache Configuration

Here, we add main route 2, so external server caches data for all sub-routes under main route 2. With route-scope caching, you avoid configuring each route individually.

For example, for sub-routes 2-1, 2-2, 2-N, cache still works even if those sub-routes are not configured separately. Sub-routes use the same cache option as the main route.

PresentKit.ifPresent(ExternalGlobalConfig.externalCmdCache, externalCmdCache -> {
externalCmdCache.addCmd(2);
});

Enterprise Features

warning

This is an enterprise-level feature.