I have a crazy idea : use Redis as hibernate second cache level. Redis is an in-memory datastore, it supports replication, pipeline, etc.. The goal is to share the hibernate cache between many tomcat nodes. The basic implementation should be to serailize Hibernate cache object key and value and store all into a Redis database. What do you think about that idea ?
Best regards,
Julius
I made Hibernate 2nd level cache with Redis
check it!
https://github.com/debop/hibernate-redis
Just found a github project on it. https://github.com/debop/hibernate-redis
I think it's already done. It's missing some documentation.
EDIT: Just found a better repository, with better documentation. https://github.com/Jongtae/hibernate-redis
After building and importing the library into your project, it's as simple as any second level cache.
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.use_query_cache">true</property>
<property name="hibernate.cache.region.factory_class">net.daum.clix.hibernate.redis.RedisRegionFactory
</property>
<property name="redis.host">"redis.host"</property>
I'm thinking in using redis in some functionalities in the website I'm working on. Other interesting possibilities: distributed Locking, tomcat session manager.
Redisson framework implements Redis based Hibernate Cache. It supports Hibernate 5.3 and 5.4.
Please refer to documentation for more details.
I think it's a cool idea. Here is some code to get you started
In Grails, for example, Redis is a plugginable backend instead of Hibernate, and unless you really need that Hibernate complexity, I think instead
would be the right way to go.
But having an ability to keep those Hibernate entities in Redis ( e.g. via JRedis ) would also be nice in case that (Hibernate) complexity is truly needed.
I think your idea is great.
I saw a hibernate 2nd level cache provider for memcached. Maybe it can help you also (i.e - get some ideas from it for working with redis?)
I would appreciate if you can open source this work on github or googlecode or any other place.
I used Redisson with Springboot and it's very easy to configure.
Just add the following:
implementation 'org.redisson:redisson-spring-boot-starter:3.10.2'
implementation 'org.redisson:redisson-hibernate-53:3.10.2'
application.yml
jpa:
generate-ddl: false
show-sql: false
properties:
hibernate:
ddl-auto: create
dialect: com.codefish.model.hibernate.MySqlDialect
generate_statistics: false
show_sql: false
use_sql_comments: false
format_sql: true
cache:
use_second_level_cache: true
use_query_cache: false
region.factory_class: com.eddress.config.RegionFactory
RedisConfig
@Configuration
public class RedisConfig {
@Value("${spring.redis.master:#{null}}")
public String redisMaster;
@Value("${spring.redis.slave:#{null}}")
public String redisSlave;
@Value("${spring.redis.password:#{null}}")
public String redisPassword;
@Bean
public RedissonConnectionFactory redissonConnectionFactory(RedissonClient redisson) {
return new RedissonConnectionFactory(redisson);
}
@Bean(destroyMethod = "shutdown")
public RedissonClient redisson() {
return Redisson.create(buildConfigFile(redisMaster,redisSlave, redisPassword));
}
public static Config buildConfigFile(String redisMaster,String redisSlave, String password){
if (Preconditions.isEmpty(redisMaster)) redisMaster = "localhost";
if (Preconditions.isEmpty(password)) password = null;
Config config = new Config().setTransportMode(TransportMode.NIO).setCodec(new SnappyCodecV2());
if (Preconditions.notBlank(redisSlave)){
config.useMasterSlaveServers()
.setMasterAddress("redis://"+redisMaster+":6379")
.addSlaveAddress("redis://"+redisSlave+":6379")
.setPassword(password)
.setIdleConnectionTimeout(10000)
.setTimeout(10000);
}
else{
config.useSingleServer()
.setAddress("redis://"+redisMaster+":6379")
.setPassword(password)
.setIdleConnectionTimeout(10000)
.setTimeout(10000);
}
return config;
}
@Bean
CacheManager cacheManager(RedissonClient redissonClient) {
Map<String, CacheConfig> config = new HashMap<>();
// create "testMap" cache with ttl = 24 minutes and maxIdleTime = 12 minutes
CacheConfig configItem = new CacheConfig(TimeUnit.MINUTES.toMillis(60), TimeUnit.MINUTES.toMillis(30));
config.put("domainCache",configItem);
return new RedissonSpringCacheManager(redissonClient, config);
}
RegionFactory
public class RegionFactory extends org.redisson.hibernate.RedissonRegionFactory {
@Override
protected RedissonClient createRedissonClient(Map properties) {
String master = System.getProperty("REDIS_MASTER");
String slave = System.getProperty("REDIS_SLAVE");
String password = System.getProperty("REDIS_PASSWORD");
Config config = RedisConfig.buildConfigFile(master,slave, password);
return Redisson.create(config);
}
}