Redis as atomic distributed cache system

In a high available high throughput distributed system, atomicity of any of the CRUD operation is extremely critical. Any inconsistency could easily propagate and extremely difficult to trace when we are talking about 1m transactions per second.

While it is hard to imagine a single server can handle 1m transactions per second, it is not so hard when it comes to highly clustered microservices. Then the question arise how do we maintain awareness between each microservices. Ideally a microservice should be independent to another instance of itself, but there are edge cases whereby there is a need for all instances to be aware or share information to one another.

This sharing can be achieved using database, or MQ, or Redis. In this post I will be talking about Redis and how the Transaction in Redis works, and provide example of high throughput concurrent test that Redis manage to handle easily

Redis Transction

Transaction is rather unique in Redis and takes time to understand, Redis guarantees atomicity for all comamnds running in between MULTI and EXEC, but it doesn't give any output. Output is returned only after EXEC is run. Therefore when handling transaction in Redis, we will need to think about how to and when to execute commands differently, for example below is a POP function for HASH, since redis does not return values while in transaction, we need to GET and then DELETE to emulate a POP.


The Concurrency Test

The concurrency test is rather simple, 2 Spring Boot application looping 10,000 times sending a request of fakeId between fakeId0 to fakeId10. Once received in the server, the server will store the fakeId and its count of occurences in redis HASH.


After the loop, the test will sleep for 30s to give time for each other (2 Spring Boot apps) to complete their iterations before calling processRequest() which will POP the HASH set.


The Result


As we can see below, the result from both apps, one of them will print exactly 20000 entries while the other will have nothing. The most important take away here is that since both apps are executing the for loop at roughly the same time and as fast as the CPU can go, it creates a heaven like environment for concurrency problem. The fact that the final output is still 20000 instead of some other number suggested that Redis is extremely resillient when it comes to concurrency handling






Source code: https://github.com/overtakerx/redistransactiondemo

Comments

Popular posts from this blog

Spring Boot 2: Parallelism with Spring WebFlux

Cucumber + Junit5 + Localstack