11

I have a code in which i have implemented cache mechanism. Previously it was Guava based caching now i am shifting to Redis considering the needs of centralized cache.

But I am concerned about its performance as i have seen drastically low performance with redis when compared to guave.

I have measured performance for an api which gets a class object from cache In case of Guava it was 5ms, whereas in Redis it gets 200ms.
This is average response in case of load test , in case of single request response does not differ much.
I have implemented Spring data Redis with cache abstraction.

Below is the sample Redis configuration:

 @Bean
 public RedisConnectionFactory redisConnectionFactory(@Value("${redis.host}") String redisHost,
            @Value("${redis.port}") Integer redisPort) {
        JedisConnectionFactory cf = new JedisConnectionFactory();
        cf.setHostName(redisHost);
        cf.setPort(redisPort);
        cf.setUsePool(true);
        JedisPoolConfig jedisPool = new JedisPoolConfig();
        jedisPool.setMaxTotal(500);
        cf.setPoolConfig(jedisPool);
        return cf;
    }

    @Bean(name = "redisTemplate")
    RedisTemplate<Object,Object> redisTemplate() {
        final RedisTemplate<Object,Object> template = new RedisTemplate<Object,Object>();
        template.setConnectionFactory(applicationContext.getBean(RedisConnectionFactory.class));
        return template;
    }

    @Bean
    public CacheManager cacheManager() {
        if(isRedisEnabled)
        {
            RedisTemplate<?,?> template = (RedisTemplate<?, ?>) applicationContext.getBean("redisTemplate");
            RedisCacheManager redisCacheManager = new PieRedisCacheManager(template);
            redisCacheManager.setUsePrefix(true);
           
                try
                {
                    template.getConnectionFactory().getConnection();
                }
                catch(Exception e)
                {
                    LOG.error("Unable to connect to redis Server ,closing application : "+e);
                    SpringApplication.exit(applicationContext);
                }
            return redisCacheManager;
        }
        else
        {
            GuavaCacheManager guavaCacheManager = new GuavaCacheManager();
            guavaCacheManager.setCacheBuilder(CacheBuilder.newBuilder());
            return guavaCacheManager;
        }
    }

Apart from that, For redis server configuration i have tried disabling all persistence as i don't need it. But still low performance.

My main query is that is it the configuration which is causing this or Redis is very low performing compared to Guava?
Can by more configuration tuning redis performance be compared to that of guava?
Please Suggest.

GP007
  • 691
  • 2
  • 9
  • 24
  • Are you making numerous redundant calls per request? Are you making calls sequentially in a loop that could be retrieved as a batch (multi-get)? – Ben Manes Aug 19 '15 at 03:27
  • @Ben : Yes for one api request we are requesting data from redis multiple times. I am not sure about your second question. – GP007 Aug 19 '15 at 10:20
  • 1
    Since you are making network requests, when possible you want to avoid redundant calls. For that use a request scoped cache in front of redis. Similarly if you make calls in a loop those are N sequential requests instead of 1 multi-get retrieving N entries. For example loading the popular items in an e-commerce site or last 10 blog entries. You can trace which keys are requested and see what refactorings can be used to reduce the number of calls. By switching to redis you now need to optimize to reduce latencies. – Ben Manes Aug 19 '15 at 16:30

1 Answers1

20

Disclaimer: I'm by no means an expert in using either Guava or Redis, though I have used both.

Obvious Performance Losses are Obvious

For starters, it would appear to me that it is perfectly normal that you encounter a performance decrease when switching from Guava to Redis.

Mostly because:

  • Guava provides caches that are in-memory and local to your application's running JVM. So your application can readily query without resorting to any inter-process communication.

  • Redis is a separate key-value store application, running in its own process. As a result, you have to communicate with it in some way to establish a connection and send requests.

So even if you were on the same machine, and even if Redis inherent performance was better than Guava's caches (which is probably the case, to be honest, for the general case), you would definitely see a performance hit anyways.

Possible Improvements

That being said, you could probably improve your performance by way of configuration and architectural choices:

  • Make sure you connect to Redis by using a local IP. This would help to avoid any address resolving when attempting to establish connections.

  • Make sure to connect to Redis over a protocol that's as lightweight as possible. As I assume you are using a local Redis server, and that you abide to the previous point, you won't need any bells-and-whistles, secure protocol, etc...

  • Any other usual Redis configuration tweaks that may apply to your scenario.

therealrootuser
  • 10,215
  • 7
  • 31
  • 46
haylem
  • 22,460
  • 3
  • 67
  • 96