简体   繁体   中英

Redis as Hibernate second level cache

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 ( eg 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 (ie - 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);

    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM