Creating and Configuring Azure Redis Cache and use in Spring Boot Application
Prerequisite
- Azure Subscription
- Java Development Kit (JDK)
- Apache Maven
Introduction: Azure Cache for Redis
In today’s fast pacing world, the need for high performing, efficient and user-friendly application is highly desired. To achieve these, the software’s architectures have become more complex and the data it has to handle also becomes huge which led to challenge the performance of an application.
Finding a smarter way to counter the performance issues becomes critical. Depends on the scenario one way to address this issue can be, reducing data retrieval and processing time. This is where caching comes to the rescue.
Cache
Caching is the process of storing data or files in a temporary location (Cache) so that it can be accessed faster by the application when needed instead of making an expensive data retrieval from the application’s storage layer.
There are few types of caches available such as,
- In-memory caching
- Database caching
- Web caching
- CDN caching
Azure Cache for Redis
Azure Cache for Redis provides an in-memory cache based on Redis software. Data in in-memory caching commonly uses key-value pair so each data can be identified with a unique key identifier. Redis improves the performance of an application which heavily uses the backend data.
As per Microsoft documentation, the Azure Cache for Redis offers both the Redis open-source (OSS Redis) and a commercial product from Redis Labs (Redis Enterprise) as a managed service. It provides secure and dedicated Redis server instances and full Redis API compatibility. The service is operated by Microsoft, hosted on Azure, and usable by any application within or outside of Azure.
Azure Cache for Redis can be used as a distributed data or content cache, a session store, a message broker, and more. It can be deployed as a standalone. Or, it can be deployed along with other Azure database services, such as Azure SQL or Cosmos DB.
Create and Configure Azure Cache for Redis in Portal
Step1: Login to Azure portal https://portal.azure.com and search for Azure Cache for Redis in search resource section
Step2: Click on Create to create a new instance of Redis cache.
Step3: In the Basics tab, provide the details such as
Subscription
Resource Group: create new or select existing resource group
DNS Name: Host name for the Redis cache instance
Location: Location desired to create Redis cache instance
Cache type: Basic (only for Dev/Test), Standard, Premium, Enterprise types are available. In this article, Standard C1 with 1GB cache is used
Step4: The Network and Advanced tab is left to default. If the user wants to create Redis cache with non-TLS port, then in Advanced tab, select the Non-TLS Port option.
Step5: Once all values are provided, click on Review + Create button to review the creation and once the validation is passed, click Create button to create the resource
The deployment will take some time and once it is completed, navigate to Azure Cache for Redis resource. The newly created instance can be viewed
Step6: Make a note of the host name and port of the instance by navigating to Overview section.
Step7: From the Access Keys which is under the Settings section, get the Primary key for this instance
Note: In the later part of this article, the hostname, port and access key will be used to make the Spring Boot and Azure cache for Redis integration
Create Spring Boot application to use with Azure Cache for Redis
Step8: Navigate to https://start.spring.io/ to create a demo application. Add Spring Web dependency and generate the application. The application will gets downloaded as a zip file to your local
Step9: Once downloaded, extract and open the project in IDE of choice.
Step10: Add the Jedis dependency to the pom.xml. The Jedis is one of the Redis Java Client
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.2.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
Step11: In application.properties file, enter the hostname, port, ssl, access key of the created Azure Redis cache instance
# Specify the DNS URI of your Redis cache.
spring.redis.host=demo-labs.redis.cache.windows.net
# Specify the access key for your Redis cache.
spring.redis.password=<access_key>
# Specify that you want to use SSL.
spring.redis.ssl=true
# Specify the SSL port for your Redis cache.
spring.redis.port=6380
Step12: Creating a Jedis client in configuration class
@Configuration
public class ConfigJedis {
@Value("${spring.redis.host}")
private String hostName;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.ssl}")
private boolean ssl;
@Value("${spring.redis.password}")
private String accessKey;
@Bean
public Jedis config() {
JedisShardInfo jedisInfo = new JedisShardInfo(hostName, port, ssl);
jedisInfo.setPassword(accessKey);
Jedis jedis = new Jedis(jedisInfo);
return jedis;
}
}
Step13: The Spring Boot service exposes three endpoints as mentioned below
Endpoint.1 ) Add new product information to Azure Redis Cache
Endpoint: /addProductCatalogue
Method: POST
Description: A POST API which accepts list of products in a request body. This endpoint is used to insert product name and price of the respective product in Redis cache as a key value pair.
<productName>:<productPrice>
Once the insertion to cache is successful, a success message is returned with 200 OK response. If not, relevant exception is returned as a response.
@PostMapping("/addProductCatalogue")
public String addProductCatalogue(@RequestBody List<ProductCatalogue> productList) {
return demoService.addProductCatalogue(productList);
}
Endpoint.2 ) Get total price of the products from Azure Cache for Redis
Endpoint: /getPurchaseAmount
Method: GET
Description: This GET API is used to fetch the total price of the list of products sent via request body. This endpoint retrieves the price of the individual product by accessing Redis cache and sums it and returns as a response. If the product requested is not available in the cache storage, then HTTP 404 error code is returned with relevant message as a response
@GetMapping("/getPurchaseAmount")
public String getPurchaseAmount(@RequestBody List<String> products) {
return demoService.getPurchaseAmount(products);
}
Endpoint.3 ) Delete product information from Azure Cache for Redis
Endpoint: /deleteproducts
Method: DELETE
Description: DELETE API to delete the products which is sent via request body from Azure cache for Redis. Once the product information is deleted, success message is returned as a response
@DeleteMapping("/deleteProducts")
public String deleteProducts(@RequestBody List<String> products) {
return demoService.deleteProducts(products);
}
Step14: Creating a service component to implement the above mentioned functionality
@Service
public class DemoServiceImpl implements DemoService {
@Autowired
Jedis config;
private static final String ADD_PRODUCT_RESPONSE_MESSAGE = "Successfully Added Products to Cache";
private static final String GET_PURCHASE_AMOUNT_RESPONSE_MESSAGE = "Total Purchase amount ";
private static final String DELETE_PRODUCT_RESPONSE_MESSAGE = "Successfully deleted products ";
private static final String PRODUCT_MISSING_RESPONSE_MESSAGE = "Product information is not available in cache storage for product ";
//Method to add Product info
public String addProductCatalogue(List<ProductCatalogue> productList) {
try {
// Setting the incoming catalogue items to cache
for (ProductCatalogue product : productList) {
config.set(product.getItemName(), product.getPrice());
}
} catch (JedisException jException) {
return jException.getMessage();
} catch (Exception exception) {
return exception.getMessage();
}
return ADD_PRODUCT_RESPONSE_MESSAGE;
}
//Method to fetch the total price of the supplied products
public String getPurchaseAmount(List<String> products) {
int totalPurchaseAmount=0;
try {
for(String product: products) {
if(config.exists(product)) {
totalPurchaseAmount+= Integer.parseInt(config.get(product));
}else {
return PRODUCT_MISSING_RESPONSE_MESSAGE+product;
}
}
}catch (JedisException jException) {
return jException.getMessage();
} catch (Exception exception) {
return exception.getMessage();
}
return GET_PURCHASE_AMOUNT_RESPONSE_MESSAGE+totalPurchaseAmount;
}
//Method to delete product info
public String deleteProducts(List<String> products) {
try {
for(String product: products) {
config.del(product);
}
}catch (JedisException jException) {
return jException.getMessage();
} catch (Exception exception) {
return exception.getMessage();
}
return DELETE_PRODUCT_RESPONSE_MESSAGE+products;
}
}
Here the Jedis client is used to set product information to the cache storage, get the value of the product, delete the product from the cache storage using config.get(Key)
, config.set(Key)
, config.del(Key)
Step15: Product Catalogue Entity Class
@Component
public class ProductCatalogue {
private String itemName;
private String price;
//Getters...
//Setters...
}
Test the Integration
To test the Spring Boot service and Azure cache for Redis integration, POSTMAN tool is used.
Step16: Run the service locally. The service is running in localhost:8080
Step17: In POSTMAN, three endpoints for POST, GET, DELETE is tested
- POST request to add the XYZ_TV and ABC_Refrigerator to the cache storage
- GET request to fetch the total price of XYZ_TV and ABC_Refrigerator products
- DELETE request to delete the XYZ_TV product from cache product
References
Azure Redis Cache Overview - docs.microsoft.com/en-us/azure/azure-cache-..
Azure Redis Cache with Java - docs.microsoft.com/en-us/azure/azure-cache-..
Jedis Client - github.com/redis/jedis