Enterprise Java

Redis in Microservices Architecture Example

This post features a comprehensive tutorial with code examples on Redis in Microservices Architecture.

1. Redis – A brief overview

Redis is an open source, in-memory data structure store, used as a database, cache and message broker.

Redis in Microservices
Fig. 1. Redis in Microservices

It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes with radius queries and streams.

2. Redis in Microservices Architecture

Redis can be leveraged as a database, cache, message broker in a microservices architecture depending on the requirement.

It supports built-in replication, Lua scripting, LRU(Least Recently Used) eviction, transactions and different levels of on-disk persistence, provides high availability via Redis Sentinel and automatic partitioning with Redis Cluster.

The above mentioned architectural, design and performance aspects of redis make it ideal for various use cases in a scalable and robust microservices architecture. We will understand the various use cases of redis in microservices architecture in the sections below.

2.1 Redis as In-memory data store

We will understand how redis can be used as an in-memory data store in this section through a simple event store micro-service built using spring boot and maven.

We will be using spring data redis for the easy configuration and access from the spring applications and spring-boot-starter-data-redis is the dependency which needs to be added to the pom.xml

The entity of the application, the Event object, is defined like below.

Event

@Data
@RedisHash("event")
public class Event implements Serializable {
	private static final long serialVersionUID = 1L;
	@Id
	private Long id;
	private Date date;
	private EventStatus status;

	public enum EventStatus {
		NEW, IN_PROGRESS, DONE;
	}
	@Override
	public String toString() {
		return this.id + "::" + this.date + ":" + this.status;
	}
}

It is important to note that it is annotated with RedisHash so as to be used with Event repository which is defined like below.

EventRepository

public interface EventRepository extends CrudRepository {
}

The REST APIs corresponding to the manipulation of Event entity is defined as part of the EventController like below.

EventController

@RestController
@RequestMapping("/events")
public class EventController {

	@Autowired
	EventPublisher publisher;
	
	@Autowired
	EventRepository repository;

	@PostMapping
	public Event create(@RequestBody Event event) {
		event = repository.save(event);
		try {
			publisher.publish(event);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
		return event;
	}


	@GetMapping("/{id}")
	public Event findById(@PathVariable("id") Long id) {
		Optional optEvent = repository.findById(id);
		if (optEvent.isPresent()) {
			return optEvent.get();
		} else {
			return null;
		}
	}

	@GetMapping
	public List findAll() {
		return (List) repository.findAll();
	}
}

When an event is created using the POST API in the above controller, the event data gets stored as key value pairs in a redis hash like shown in the screenshot below

Redis in Microservices - Redis as In memory store
Fig. 2. Redis as In memory store

2.2 Redis as Message broker

In microservices architecture, Redis can as well be used as a message broker. According to its official documentation, publish/subscribe messaging paradigm is implemented by Subscribe, Unsubscribe and Publish commands. The published messages are characterized into channels and subscribers express interest in one or more channels to only receive those messages

In the below sections, we will understand how redis is used as a message broker in our event store application.

Below is the publisher code to publish an event to a channel.

EventPublisher

public class EventPublisher {

	private static final Logger LOGGER = LoggerFactory.getLogger(EventPublisher.class);

	RedisTemplate redisTemplate;
	ChannelTopic topic;

	@SuppressWarnings("unchecked")
	public EventPublisher(RedisTemplate redisTemplate, ChannelTopic topic) {
		this.redisTemplate = redisTemplate;
		this.redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer(Event.class));
		this.topic = topic;
	}

	public void publish(Event trip) throws JsonProcessingException {
		LOGGER.info("Sending: {}", trip);
		redisTemplate.convertAndSend(topic.getTopic(), trip);
	}
}

The publish method converts Event Object to json using Jackson2JsonRedisSerializer which is defined as part of RedisTemplate instantiation.

The event subscriber needs to implement the MessageListener interface overriding the onMessage method like shown in the code below

EventSubscriber

@Service
public class EventSubscriber implements MessageListener {

	private final Logger LOGGER = LoggerFactory.getLogger(EventSubscriber.class);

	@Autowired
	EventRepository repository;
	
	ObjectMapper mapper = new ObjectMapper();

	@Override
	public void onMessage(Message message, byte[] bytes) {
		try {
			Event event = mapper.readValue(message.getBody(), Event.class);
			LOGGER.info("Message received: {}", event.toString());
		} catch (IOException e) {
			LOGGER.error("Error reading message", e);
		}
	}
}

Both the publisher and subscriber configurations are defined as part of EventConfiguration like shown in the code below.

EventConfiguration

@Configuration
@EnableRedisRepositories
public class EventConfiguration {

	@Autowired
	RedisTemplate redisTemplate;

	@Bean
	EventPublisher redisPublisher() {
		return new EventPublisher(redisTemplate, topic());
	}

	@Bean
	ChannelTopic topic() {
		return new ChannelTopic("events");
	}

	@Autowired
	RedisConnectionFactory redisConnectionFactory;

	@Bean
	RedisMessageListenerContainer container() {
		RedisMessageListenerContainer container = new RedisMessageListenerContainer();
		container.addMessageListener(messageListener(), topic());
		container.setConnectionFactory(redisConnectionFactory);
		return container;
	}

	@Bean
	MessageListenerAdapter messageListener() {
		return new MessageListenerAdapter(new EventSubscriber());
	}
}

In the above configuration, EventSubscriber is added as the message listener to the RedisMessageListenerContainer bean instance which is responsible for subscribing EventSubscriber to the created event channel

When the spring boot application is run and an event is created using the create REST API, we can note that the message is published and is being consumed by the EventSubscriber from the logs printed in the figure below

Redis in Microservices - Redis as message broker
Fig. 3. Redis as message broker

2.3 Redis as Caching layer

One of the most common use cases of Redis is the caching capability. LRU(Least Recently Used) eviction policy, performance, high availability and built in replication capabilities make Redis the go-to data store for caching use case in microservice architecture.

2.4 Redis as Database

Redis comes about as a robust solution for database in microservices given the numerous persistence options it supports along with its inherent architectural and design capabilities.

The various persistence mechanisms it supports are below

  • RDB – snapshots your dataset at specified intervals
  • AOF – persists log of every write operation received by the server

3. Conclusion

In this article, we have understood the various use cases of redis in microservices architecture. We have illustrated how redis can be used as in- memory datastore and message broker through an example microservice application. Towards the end of the article, we have also understood the other use case of how redis can be used as cache and as a persistent database. Thus, we can realise the power of redis from the variety of use cases it supports and how instrumental it is in the design of microservices architecture applications.

4. Download the Source Code

This source contains the example code snippets used in this article to illustrate use cases of Redis in Microservices Architecture.

Download
You can download the full source code of this example here: Redis in Microservices Architecture Example

Aarish Ramesh

He is a polyglot developer with great experience designing, building highly scalable and robust software. He holds a Master’s degree in Software Systems from BITS, Pilani, India and Bachelor’s degree in Electronics and Communication from SSN College of Engineering, Chennai, India . He has been associated earlier with engineering roles in e-commerce and productivity software companies like Cleartrip and Zoho. During his professional career and studies, he has been majorly involved in software projects involving Java, Big data technologies and ecosystem
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button