@RedisHash with TTL (spring-data)

·

2 min read

Long story short: it's not working yet :)

So what is wrong?

An open issue was opened in 2016. (Actually, a workaround was added in September 2021 to clean up on the application startup)

What effects you might get:

  • findAll returns null values
  • pages have the wrong size
  • Memory leaks as described in detail here

it's happening because expired records indexes and shadow copies are not cleaned up automatically

How to do the right thing?

It means you should use @RedishHash with TTL very carefully:

  1. Make sure your Redis server allows your app to 'CONFIGURE' keyspace events from the app. So the app might enable it and subscribe to it.
  2. Enable keyspace events in your app. But keep in mind that configuring keyspace events from app annotation is still not recommended as a production-ready solution (see Jira ticket). Think about configuring it on Redis and subscribing from the app.
  3. Disable shadow copies if you don't use them.
  4. Make sure you have a workaround from the Jira issue above to handle records that were expired and your app hasn't handled them (was offline or not responding)
  5. Filter null values on findAll (and probably some other wide queries)
  6. Have a scheduler to double-check Redis is in good shape. (and reduce TTL to an absolute required minimum) (optional)

Also in the article above, there is a manual solution on how to use RedisTemplate and manually implement only what you really need.

How to do it right?

To do it right consider using Redis hash without TTL and instead move responsibility to remove records to some application use case or flow (scheduler?). Another option would be to use a regular cache if that fits your needs.