Spring Boot+Redisのno such key異常について



Spring Boot 2を使用しています.xとRedisが統合されたとき、次のような異常に遭遇し、この問題を解決するのに時間を費やし、いくつかの回り道をしました.
org.springframework.data.redis.RedisSystemException: Error in execution; nested exception is io.lettuce.core.RedisCommandExecutionException: ERR no such key

org.springframework.data.redis.RedisSystemException: Error in execution; nested exception is io.lettuce.core.RedisCommandExecutionException: ERR no such key
at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:54)
at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:52)\
at org.springframework.data.redis.connection.lettuce.LettuceExceptionConverter.convert(LettuceExceptionConverter.java:41)
at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:44)
at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:42)
at org.springframework.data.redis.connection.lettuce.LettuceConnection.convertLettuceAccessException(LettuceConnection.java:257)
at org.springframework.data.redis.connection.lettuce.LettuceKeyCommands.convertLettuceAccessException(LettuceKeyCommands.java:650)
at org.springframework.data.redis.connection.lettuce.LettuceKeyCommands.rename(LettuceKeyCommands.java:249)
at org.springframework.data.redis.connection.lettuce.LettuceClusterKeyCommands.rename(LettuceClusterKeyCommands.java:119)
at org.springframework.data.redis.connection.DefaultedRedisConnection.rename(DefaultedRedisConnection.java:96)
at org.springframework.data.redis.core.RedisTemplate.lambda$rename$13(RedisTemplate.java:889)
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:224)
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:184)
at org.springframework.data.redis.core.RedisTemplate.rename(RedisTemplate.java:888)
at org.springframework.session.data.redis.RedisOperationsSessionRepository$RedisSession.saveChangeSessionId(RedisOperationsSessionRepository.java:815)
at org.springframework.session.data.redis.RedisOperationsSessionRepository$RedisSession.saveDelta(RedisOperationsSessionRepository.java:772)
at org.springframework.session.data.redis.RedisOperationsSessionRepository$RedisSession.access$000(RedisOperationsSessionRepository.java:649)
at org.springframework.session.data.redis.RedisOperationsSessionRepository.save(RedisOperationsSessionRepository.java:384)
at org.springframework.session.data.redis.RedisOperationsSessionRepository.save(RedisOperationsSessionRepository.java:245)
at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.commitSession(SessionRepositoryFilter.java:234)
at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper.access$100(SessionRepositoryFilter.java:197)
at org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryResponseWrapper.onResponseCommitted(SessionRepositoryFilter.java:185)
at org.springframework.session.web.http.OnCommittedResponseWrapper.doOnResponseCommitted(OnCommittedResponseWrapper.java:227)
at org.springframework.session.web.http.OnCommittedResponseWrapper.access$000(OnCommittedResponseWrapper.java:38)
at org.springframework.session.web.http.OnCommittedResponseWrapper$SaveContextServletOutputStream.flush(OnCommittedResponseWrapper.java:494)
at org.springframework.security.web.util.OnCommittedResponseWrapper$SaveContextServletOutputStream.flush(OnCommittedResponseWrapper.java:514)
at com.fasterxml.jackson.core.json.UTF8JsonGenerator.flush(UTF8JsonGenerator.java:1100)
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:915)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:286)
at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:102)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:271)
at org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:218)
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:82)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:119)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:870)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:776)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
at ....
 
ネット上で言った解決方法以外は、試しても私の現実的な問題を解決していません.
このようなソリューションには、次のような方法があります.
1.Spring boot RedisとSpring Sessionサポート、pomを追加xmlは以下の通り

            org.springframework.boot
            spring-boot-starter-data-redis
        

		
			org.springframework.session
			spring-session-data-redis
		
 
2.バージョンの問題に注意してください.私が使っているSpring Boot 2.0は、それに一致するRedisバージョンを使用します.
3.Springが提供するStringRedisTemplateとRedisTempateの2つのクラスの使用は、spring sessionにかかわらず、次のエラーコードもno such keyの異常を報告します.
public boolean setString(String key,String value ){
        try {
            stringRedisTemplate.opsForList().set(key,value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
だからネット上のCopyツール類でも、完全に安心して使うことはできません.よくチェックしたほうがいいです.
以下のプロファイルおよびツールクラスは、参照用のみです.
1.application.yml
spring:
  # REDIS(RedisProperties)
  # (    ,        )                    。
  redis:
    database: 0
    host: 127.0.0.1
    port: 6379
    timeout: 60000
    password:
    ssl: false
    pool:

      max-active: 8
      max-idle: 1
      max-wait: -1
      min-idle: 0
      # Redis     。
      #spring.redis.port=6379
      # (    ,        )Redis      。
      # spring.redis.sentinel.master=
      # (    ,        )  :          。
      # spring.redis.sentinel.nodes=
      #            。
2.RedisConfig.java


import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * @ClassName RedisConfig
 * @Description 

TODO

* @Author Jakemanse * @Date 2018/11/7 16:50 * @Version 1.0 **/ @Configuration @EnableCaching public class RedisConfig { /** * application.yml redis host . */ @Value("${spring.redis.host}") private String redisHost; /** * application.yml redis . */ @Value("${spring.redis.port}") private Integer redisPort; /** * Jedis . * * @return Jedis */ @Bean public JedisConnectionFactory jedisConnectionFactory() { RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(redisHost, redisPort); return new JedisConnectionFactory(configuration); } @Bean(name = "redisTemplate") public RedisTemplate redisTemplate(RedisConnectionFactory factory) { /* * Redis . * * RedisTemplate JdkSerializationRedisSerializer, JdkSerializationRedisSerializer , * Serializable 。 , , , 。 * * Jackson2JsonRedisSerializer GenericJackson2JsonRedisSerializer, json, * json @class , , 。 List * TypeReference java.util.LinkedHashMap cannot be cast to */ RedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer(); RedisSerializer stringRedisSerializer = new StringRedisSerializer(); // RedisTemplate, RedisTemplate redisTemplate = new RedisTemplate<>(); // key StringRedisSerializer redisTemplate.setKeySerializer(stringRedisSerializer); redisTemplate.setHashKeySerializer(stringRedisSerializer); // value GenericJackson2JsonRedisSerializer redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer); redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer); // redisTemplate.setConnectionFactory(factory); return redisTemplate; } @Bean public CacheManager initRedisCacheManager(RedisConnectionFactory factory) { RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager .RedisCacheManagerBuilder.fromConnectionFactory(factory); return builder.build(); } }
 
2.RedisUtils.java



import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName RedisUtils
 * @Description 

TODO

* @Author Jakemanse * @Date 2018/11/7 13:55 * @Version 1.0 **/ @Component public class RedisUtils { private static final Logger logger = Logger.getLogger(RedisUtils.class); /** */ @Autowired private StringRedisTemplate stringRedisTemplate; /** , */ @Autowired private RedisTemplate redisTemplate; public void reset(String key, Long seconds){ stringRedisTemplate.expire(key, seconds, TimeUnit.SECONDS); } /** * key * @param pattern * @return Set */ public Set keys(String pattern){ return stringRedisTemplate.keys(pattern); } /** * keys * @param pattern */ public void delKeys(String pattern){ redisTemplate.delete(stringRedisTemplate.keys(pattern)); } /** * Set * @param key * @param set */ public void addSet(String key ,Set> set){ try{ redisTemplate.opsForSet().add(key, set); }catch(Exception ex){ ex.printStackTrace(); } } /** * Set * @param key * @return */ public Set> getSet(String key){ try{ return redisTemplate.opsForSet().members(key); }catch(Exception ex){ ex.printStackTrace(); } return null ; } public void addString(String key , String value,Long seconds){ try { // redis ValueOperations valOps = stringRedisTemplate.opsForValue(); if(seconds!=null){ valOps.set(key, value,seconds,TimeUnit.SECONDS); }else{ valOps.set(key, value); } } catch (Exception e) { logger.warn(spellString("addString {0}={1},{2}", key,value,seconds),e); } } public String getString(String key) { String result = ""; try { result = stringRedisTemplate.opsForValue().get(key); } catch (Exception e) { logger.warn(spellString("getString {0}", key), e); } return result; } public void delString(String key) { try { stringRedisTemplate.delete(key); } catch (Exception e) { logger.warn(spellString("delString {0}", key),e); } } public void delAllString(String key) { if(key==null || "".equals(key)){ return; } try { if (!key.endsWith("*")) { key += "*"; } Set keys = stringRedisTemplate.keys(key); Iterator it = keys.iterator(); while (it.hasNext()) { String singleKey = it.next(); delString(singleKey); } } catch (Exception e) { logger.warn(spellString("delString {0}", key), e); } } /** * @see add * @param key * @param value * @param time */ public void addObj(String key ,Object obj, Long seconds){ try { // redis ValueOperations objOps = redisTemplate.opsForValue(); if(seconds!=null){ objOps.set(key, obj, seconds, TimeUnit.SECONDS); }else{ objOps.set(key, obj); } } catch (Exception e) { logger.warn(spellString("addObj {0}={1},{2}", key,obj,seconds),e); } } /** * @see get * @param key * @return Object */ public Object getObject(String key) { Object object = null; try { object = redisTemplate.opsForValue().get(key); } catch (Exception e) { logger.warn(spellString("getObj {0}", key), e); } return object; } /** * @see get * @param key * @return Object */ @SuppressWarnings({ "unchecked"}) public T getObj(String key, T t) { Object o = null; try { o = redisTemplate.opsForValue().get(key); } catch (Exception e) { logger.warn(spellString("getObj {0}->{1}", key, t), e); } return o == null ? null : (T) o; } public void expire(String key,long second){ try { stringRedisTemplate.expire(key, second, TimeUnit.SECONDS); } catch (Exception e) { logger.warn(spellString("expire {0}={1}", key, second),e); } } /** * @see del * @param key */ public void delObj(String key) { try { redisTemplate.delete(key); } catch (Exception e) { logger.warn(spellString("delObj {0}", key),e); } } /** * * * @param key * @param value * @return */ public Long push(String key, String value) { Long result = 0l; try { result = stringRedisTemplate.opsForList().leftPush(key, value); } catch (Exception e) { logger.warn(spellString("push {0}={1}", key,value),e); } return result; } /** * * * @param key * @return */ public String pop(String key) { String popResult = ""; try { popResult = stringRedisTemplate.opsForList().leftPop(key); } catch (Exception e) { logger.warn(spellString("pop {0}", key), e); } return popResult; } /** * * * @param key * @param value * @return */ public Long in(String key, String value) { Long inResult = 0l; try { inResult = stringRedisTemplate.opsForList().rightPush(key, value); } catch (Exception e) { logger.warn(spellString("in {0}={1}", key, value), e); } return inResult; } /** * * * @param key * @return */ public String out(String key) { String outResult = ""; try { outResult = stringRedisTemplate.opsForList().leftPop(key); } catch (Exception e) { logger.warn(spellString("out {0}", key),e); } return outResult; } /** * / * * @param key * @return */ public Long length(String key) { Long lengthResult = 0l; try { lengthResult = stringRedisTemplate.opsForList().size(key); } catch (Exception e) { logger.warn(spellString("length {0}", key), e); } return lengthResult; } /** * * * @param key * @param start * @param end * @return */ public List range(String key, int start, int end) { List rangeResult = null; try { rangeResult = stringRedisTemplate.opsForList().range(key, start, end); } catch (Exception e) { logger.warn(spellString("range {0},{1}-{2}", key, start, end), e); } return rangeResult; } /** * * * @param key * @param i * @param value */ public void remove(String key, long i, String value) { try { stringRedisTemplate.opsForList().remove(key, i, value); } catch (Exception e) { logger.warn(spellString("remove {0}={1},{2}", key,value,i),e); } } /** * * * @param key * @param index * @return */ public String index(String key, long index) { String indexResult = ""; try { indexResult = stringRedisTemplate.opsForList().index(key, index); } catch (Exception e) { logger.warn(spellString("index {0}", key), e); } return indexResult; } /** * * * @param key * @param index * @param value */ public void setObject(String key, Object value,long index) { try { redisTemplate.opsForValue().set(key,value,index); } catch (Exception e) { logger.warn(spellString("set {0}={1},{2}", key,value,index),e); } } public boolean setString(String key,String value ){ try { stringRedisTemplate.opsForValue().set(key,value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * * * @param key * @param start * @param end */ public void trim(String key, long start, int end) { try { stringRedisTemplate.opsForList().trim(key, start, end); } catch (Exception e) { logger.warn(spellString("trim {0},{1}-{2}", key,start,end),e); } } /** * : * @param key key * @param value * @time: 2017 3 9 4:28:21 * @return: Long */ public Long incr(String key, long value) { Long incrResult = 0l; try { incrResult = stringRedisTemplate.opsForValue().increment(key, value); } catch (Exception e) { logger.warn(spellString("incr {0}={1}", key, value), e); } return incrResult; } /** * * @param errStr * @param arguments * @return */ private String spellString(String errStr,Object ... arguments){ return MessageFormat.format(errStr,arguments); } }
 
ツールクラスを使用する場合は、StringRedisTemplateとRedisTemplateの違いに特に注意してください.