Dynamically Manage and Update Cache Target API Lists of ARCUS Application

JaM2in
7 min readMay 26, 2021

The ARCUS Common Module makes use of Spring AOP technology to easily apply ARCUS Cache in Java Applications. There are two ways to apply ARCUS Cache, (1) attach Annotation to the cache target API and (2) specify cache target APIs and their cache attributes in the Property file. More details on the ARCUS Common Module are described in the ARCUS Common Cache Module Use with Basic Pattern Caching in Java Environment article.

When updates of cache target API or cache attributes are required from the caching methods (Annotation method, Property file method) of ARCUS Common Module, Application redeployment was needed to modify and reflect these changes. Due to the need to make updates without Application redeployment, the dynamic Property management method was developed.

We have used ZooKeeper as ARCUS metadata storage, to keep the cache target API data(cache target API + cache attributes) and have made it possible to update them when it’s necessary. ARCUS Common Module detects and retrieves the real-time changes of cache target APIs with the ZooKeeper’s Watcher feature and dynamically applies the changes to ARCUS applications.

Management of Cache Target API Data in ZooKeeper

ZooKeeper has a directory structure of key-value items called znode (ZooKeeper Node) that stores and manages desired data in it. Below-shown ZooKeeper’s directory structure describes how to store and manage cache target API data of the ARCUS Application. At the top of the structure, there come /arcus_app and /cache_target_list directories followed by /service-code/ znodes of ARCUS Cache Cluster. The cache target API list and their attributes of each ARCUS Application are stored to sub znodes of the service code that the Application access.

ZooKeeper directory structure

The key of the znode can solely identify the cache target API by using a target name consisting of the ‘package-name.class-name.method-name’ and the value of the znode stores the JSON property as shown in the below example.

/* 
JSON Property of Cache Target
*/
{
/*
It is consisting of ‘package-name.class-name.method-name’ as a signature of Cache Target API.
*/
"target":"com.service.BoardService.getBoard",
/*
Assigns the ARCUS Cache Key's prefix generated from Cache Target API.
*/
"prefix":"BOARD",
/*
Assigns the ARCUS Cache Item's TTL (Time to Live) generated from Cache Target API.
*/
"expireTime":60,
/*
Specifies the key parameters (separated by commas) that will be used as ARCUS Cache Key generated from Cache Target API.
*/
"keyParams":["bno"],
/*
Automatic creation of ARCUS Cache Keys generated from Cache Target API: if true automatically create a cache key using all parameters; if false keyParams must be specified.
*/
"keyAutoGeneration":false,
/*
Condition of whether to apply Arcus Cache on the Cache Target API.
*/
"enable":true,
/*
Append the Arcus Cache Key creation time information after the Arcus Cache Key string. This is intended for to create different cache keys.
*/
"keyDate":"KEY_DATE_NONE"
}

All arcus_apps, cache_target_list and service_code znodes that store cache target APIs are all generated in persistent type and the znodes that store the cache target APIs data are created in persistent and sequence types. The reason why we use the sequence type is, to easily determine creation, deletion, and other cache target API property updates. The cache target API property Update operation removes the existing znode and generates a new znode of the same key with updated property details. Thereby causes the corresponding znode’s sequence value to be increased.

For instance, let’s say when we want to update API’s cache property where the znode of com.service.BoardService.getBoard-0000000000 key already exists. On the update operation, an existing znode will be removed, and a new znode with com.service.BoardService.getBoard-0000000001 key will be created at the same time. Thereby, the ARCUS Application looks up only the child nodes in /arcus_apps/cache_target_list/service-code znode and allows you to check creation, deletion, and update with the sequence value in its own cache target API list.

The ARCUS’s Cache Common Module Lookups the Latest Cache Target API List from ZooKeeper (using ZooKeeper Watcher)

ARCUS Common Module uses a cache item map to store and manage the cache target API list of the corresponding service code which the Application access.

In order to receive real-time notifications, we register the ZooKeeper Watcher to the corresponding znode of service code. When the changes occur in the corresponding cache target API list, ZooKeeper Watcher notifies any occurred updates to ARCUS Common Module. Then, ARCUS Common Module reads the latest cache target API list. It looks up the updated cache target API list by comparing the sequence values of previous and latest cache target APIs. ARCUS Common Module also reads the property details of the updated cache target API as a JSON file from ZooKeeper and updates them on the cache item map.

Creation, Deletion, and Update of Cache Target API Properties

By directly using the ZooKeeper Command Line Interface tool — zkCli, you can create, delete and update cache target API property details as shown below. In the below example, the -s option is given to create a znode of sequence type. But it would be much efficient to make and use a script that executes the corresponding operations than operating directly with a zkCli tool.

// CREATION of Cache Target API
[ZK: localhost:2180(CONNECTED)]
create -s /arcus_apps/cache_target_list/service-code/com.service.BoardService.getBoard
{
"target":"com.service.BoardService.getBoard",
"prefix":"BOARD",
"expireTime":60,
"keyParams":["bno"],
"keyAutoGeneration":false,
"enable":true,
"keyDate":"KEY_DATE_NONE"
}
// DELETION of Cache Target API
[ZK: localhost:2180(CONNECTED)]
delete /arcus_apps/cache_target_list/service-code/com.service.BoardService.getBoard-0000000000
// UPDATE of Cache Target API
[ZK: localhost:2180(CONNECTED)]
create -s /arcus_apps/cache_target_list/service-code/com.service.BoardService.getBoard
{
"target":"com.service.BoardService.getBoard",
"prefix":"BOARD",
"expireTime":60,
"keyParams":["bno"],
"keyAutoGeneration":false,
"enable":true,
"keyDate":"KEY_DATE_NONE"
}
[ZK: localhost:2180(CONNECTED)]
delete /arcus_apps/cache_target_list/service-code/com.service.BoardService.getBoard-0000000000

Performing creation, deletion, and update operations of cache target API directly using a zkCli tool can be uncomfortable for an operator. On the webpage, to efficiently operate and manage ARCUS Cache Cluster (including ZooKeeper Ensemble) JaM2in currently developing ARCUS Admin Tool. On the ARCUS Admin Tool, we have developed a cache target feature to manage the Application’s cache target APIs, as shown in the below example.

Below web page shows the cache targe API list of a specific service code. In this page, our service code’s name is a test, by clicking on a particularcache target API, you can check the details of JSON property.

The below image displays how to create a new cache target API. A user enters the property details that will be made as a JSON property and creates the corresponding cache target API. Relatively, delete and update operations of cache target API can be performed in the same manner on the ARCUS Admin Tool.

To recap briefly what has been discussed so far, when a user creates, deletes, or updates the cache target APIs through cache target feature on the ARCUS Admin Tool, these changes are stored and managed by ZooKeeper Ensemble, where ZooKeeper Watcher monitors these change events and passes them to the ARCUS Common Module which is attached to the Application. As explained earlier, ARCUS Common Module looks up for updates on cache target API and manages them with a cache item map. ARCUS Cache will be automatically applied only to cache target APIs that stored on the cache item map.

Application Method of the ARCUS Common Module

ARCUS Common Module itself is described in the ARCUS Common Cache Module Use with Basic Pattern Caching in Java Environment article, but here as well, I will give you a brief introduction on how to apply the ARCUS Common Module to the Java Application.

In order to apply ARCUS Common Module to the Java Application first, add the ARCUS Common Module dependency to the pom.xml file of the Java Application.

<dependencies>
...
<dependency>
<groupId>com.jam2in.arcus</groupId>
<artifactId>arcus-app-common</artifactId>
<version>1.4.0</version>
</dependency>
...
</dependencies>

Then, create the ARCUS property file (arcus.properties) as shown below.

# ZooKeeper Ensemble Address 
# Used to Connect ARCUS and Renew Cache Target List

arcus.address=1.2.3.4:2181,1.2.3.4:2182,1.2.3.4:2183
# Arcus service code
arcus.serviceCode=test
# Connection Pool size of Arcus Client
arcus.poolSize=8
# Operation timeout (milliseconds)
arcus.asyncOperationTimeout=700
# Global Prefix of Arcus Cache Key
arcus.globalPrefix=RELEASE

Lastly, if you set up the Spring as shown below, the ARCUS Common Module application will be completed. The ARCUS Common Module makes it very easy for a user to apply ARCUS Cache and dynamically manage a cache target API list.

@Configuration
// Arcus Property Loading
@PropertySource("classpath:arcus.properties")
// @Aspect Use
@EnableAspectJAutoProxy(proxyTargetClass = true)
@Import(ArcusBeans.class)
public class ArcusConfiguration {
@Autowired
private ArcusBeans arcusBeans;

@Bean
public static PropertySourcesPlaceholderConfigurer
propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}

@Bean
public ArcusStarter arcusStarter() {
return new ArcusStarter(arcusBeans);
}

@Bean
public ArcusCacheAspect arcusAdvice() {
return new ArcusCacheAspect(arcusBeans);
}
}

Conclusion

In summary, I’ve introduced and explained how to dynamically create, delete and update cache target APIs without restart of the ARCUS Application, and how to store and manage cache target APIs using ZooKeeper. ARCUS Common Module through ZooKeeper Watcher detects real-time updates in the cache target API list and always maintains the latest updated list of cache target APIs. In the future, to improve the management feature of a cache target API, the following works will be processed:

  • HIT, MISS, RATIO indication of cache target API,
  • HISTORY feature of cache target API e.g. records of by whom and when the cache target API property details were updated,
  • A parser feature to view cache target API as a JSON string or JSON file.

--

--