CodisLabs / codis

Proxy based Redis cluster solution supporting pipeline and scaling dynamically
MIT License
13.15k stars 2.69k forks source link

支持spring-boot-starter-redis? #678

Closed Dreampie closed 8 years ago

Apache9 commented 8 years ago

支持具体指什么?codis本身用的就是redis的协议,大部分redis的client都可以直接连

Dreampie commented 8 years ago
2016-01-26 17:09:41.475 ERROR 20845 --- [ XNIO-2 task-22] t.a.c.c.r.e.JsonExceptionResolver        : Unexpected end of stream.; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream.

org.springframework.data.redis.RedisConnectionFailureException: Unexpected end of stream.; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream.
    at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:47) ~[spring-data-redis-1.6.2.RELEASE.jar:1.6.2.RELEASE]
    at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:36) ~[spring-data-redis-1.6.2.RELEASE.jar:1.6.2.RELEASE]
    at org.springframework.data.redis.PassThroughExceptionTranslationStrategy.translate(PassThroughExceptionTranslationStrategy.java:37) ~[spring-data-redis-1.6.2.RELEASE.jar:1.6.2.RELEASE]
    at org.springframework.data.redis.FallbackExceptionTranslationStrategy.translate(FallbackExceptionTranslationStrategy.java:37) ~[spring-data-redis-1.6.2.RELEASE.jar:1.6.2.RELEASE]
    at org.springframework.data.redis.connection.jedis.JedisConnection.convertJedisAccessException(JedisConnection.java:210) ~[spring-data-redis-1.6.2.RELEASE.jar:1.6.2.RELEASE]
    at org.springframework.data.redis.connection.jedis.JedisConnection.exec(JedisConnection.java:762) ~[spring-data-redis-1.6.2.RELEASE.jar:1.6.2.RELEASE]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_60]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_60]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_60]
    at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_60]
    at org.springframework.data.redis.core.CloseSuppressingInvocationHandler.invoke(CloseSuppressingInvocationHandler.java:57) ~[spring-data-redis-1.6.2.RELEASE.jar:1.6.2.RELEASE]
    at com.sun.proxy.$Proxy158.exec(Unknown Source) ~[na:na]
    at org.springframework.data.redis.cache.RedisCache$RedisCachePutCallback.doInRedis(RedisCache.java:629) ~[spring-data-redis-1.6.2.RELEASE.jar:1.6.2.RELEASE]
    at org.springframework.data.redis.cache.RedisCache$RedisCachePutCallback.doInRedis(RedisCache.java:608) ~[spring-data-redis-1.6.2.RELEASE.jar:1.6.2.RELEASE]
    at org.springframework.data.redis.cache.RedisCache$AbstractRedisCacheCallback.doInRedis(RedisCache.java:424) ~[spring-data-redis-1.6.2.RELEASE.jar:1.6.2.RELEASE]
    at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:191) ~[spring-data-redis-1.6.2.RELEASE.jar:1.6.2.RELEASE]
    at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:153) ~[spring-data-redis-1.6.2.RELEASE.jar:1.6.2.RELEASE]
    at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:141) ~[spring-data-redis-1.6.2.RELEASE.jar:1.6.2.RELEASE]
    at org.springframework.data.redis.cache.RedisCache.put(RedisCache.java:140) ~[spring-data-redis-1.6.2.RELEASE.jar:1.6.2.RELEASE]
    at org.springframework.data.redis.cache.RedisCache.put(RedisCache.java:124) ~[spring-data-redis-1.6.2.RELEASE.jar:1.6.2.RELEASE]
    at org.springframework.cache.interceptor.AbstractCacheInvoker.doPut(AbstractCacheInvoker.java:82) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.cache.interceptor.CacheAspectSupport$CachePutRequest.apply(CacheAspectSupport.java:677) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:361) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:302) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655) ~[spring-aop-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at tv.acfun.cloud.api.log.controller.LogController$$EnhancerBySpringCGLIB$$2b7590be.findAll(<generated>) ~[main/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_60]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_60]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_60]
    at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_60]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:222) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) [spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) [spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:969) [spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:860) [spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) [javax.servlet-api-3.1.0.jar:3.1.0]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:845) [spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [javax.servlet-api-3.1.0.jar:3.1.0]
    at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration$ApplicationContextHeaderFilter.doFilterInternal(EndpointWebMvcAutoConfiguration.java:243) [spring-boot-actuator-1.3.1.RELEASE.jar:1.3.1.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterInternal(ShallowEtagHeaderFilter.java:87) [spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at tv.acfun.cloud.api.common.filter.CorsFilter.doFilterInternal(CorsFilter.java:23) [api-common-1.0-SNAPSHOT.jar:na]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:111) [spring-boot-actuator-1.3.1.RELEASE.jar:1.3.1.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) [spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:103) [spring-boot-actuator-1.3.1.RELEASE.jar:1.3.1.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) [undertow-core-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) [undertow-core-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) [undertow-core-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:284) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:263) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:174) [undertow-servlet-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202) [undertow-core-1.3.10.Final.jar:1.3.10.Final]
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:793) [undertow-core-1.3.10.Final.jar:1.3.10.Final]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_60]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_60]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_60]
Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream.
    at redis.clients.util.RedisInputStream.ensureFill(RedisInputStream.java:198) ~[jedis-2.7.3.jar:na]
    at redis.clients.util.RedisInputStream.readByte(RedisInputStream.java:40) ~[jedis-2.7.3.jar:na]
    at redis.clients.jedis.Protocol.process(Protocol.java:141) ~[jedis-2.7.3.jar:na]
    at redis.clients.jedis.Protocol.read(Protocol.java:205) ~[jedis-2.7.3.jar:na]
    at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:297) ~[jedis-2.7.3.jar:na]
    at redis.clients.jedis.Connection.getAll(Connection.java:267) ~[jedis-2.7.3.jar:na]
    at redis.clients.jedis.Transaction.exec(Transaction.java:43) ~[jedis-2.7.3.jar:na]
    at org.springframework.data.redis.connection.jedis.JedisConnection.exec(JedisConnection.java:758) ~[spring-data-redis-1.6.2.RELEASE.jar:1.6.2.RELEASE]
    ... 87 common frames omitted
spinlock commented 8 years ago

codis 不支持 transaction,不支持指令列表

如果是测试的话,麻烦贴一下详细的测试程序。谢谢

Dreampie commented 8 years ago

测试很简单 创建一个spring boot的项目 引入

compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-redis")

启动类

@SpringBootApplication
@EnableCaching
@ComponentScan(basePackages = {"demo"})
public class DemoApplication {

  public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
  }
}

写个controller,启动测试一下

@RestController
@CacheConfig(cacheNames = "demos")
public class DemoController {
  @Cacheable(key = "#id")
  @RequestMapping(value = "logs/{id}" method = RequestMethod.GET)
  public Demo findById(@PathVariable Long id) {
  ...
  }
}
spinlock commented 8 years ago

exception 里面出现了 transaction,应该是默认的 redis conn 用了 multi 指令,你看看有没有开关关掉。codis 不支持 transaction。

Dreampie commented 8 years ago

没发现有关闭事务的地方,还有没有其他解决方法?spring使用率还是挺高,不支持的功能能忽略就好了

yangzhe1991 commented 8 years ago

你用的Spring模块太重了,你搜下接口能不能配置,如果不能配置就没法用了,或者改业务代码去掉比较重的依赖,自己实现缓存逻辑之类的。。。

Dreampie commented 8 years ago

希望能提供spring boot相关的解决方案,要申请技术支持了

yangzhe1991 commented 8 years ago

我们只能解答codis的问题,上层业务我们不熟悉也没精力解答……你可以去spring相关的社区问下这个模块在用jedis的时候能否关掉transaction、multi什么的

Dreampie commented 8 years ago

嗯,问了,还没回复,自己实现太费时间了,spring boot目前还是很不错的

huguiqi commented 7 years ago

楼主解决了吗,我也遇到同类问题了

purplest commented 6 years ago

刚解决了该问题的来Mark一下思路: 其实默认spring-boot-data-redis是和RedisTemplate无关的,默认是不会启用transaction。 但是对应的RedisCache会在当前的连接不是cluster的时候给加上multi,code sample如下:

public Void doInRedis(BinaryRedisCacheElement element, RedisConnection connection) throws DataAccessException {

    if (!isClusterConnection(connection)) {
        connection.multi();
    }

    if (element.get().length == 0) {
        connection.del(element.getKeyBytes());
    } else {
        connection.set(element.getKeyBytes(), element.get());

        processKeyExpiration(element, connection);
        maintainKnownKeys(element, connection);
    }

    if (!isClusterConnection(connection)) {
        connection.exec();
    }
    return null;
}

对应的思路即去掉对应的connection.multi(),或者让isClusterConnection(connection)返回一直为true即可。

spinlock commented 6 years ago

其实 Codis 里面 MULTI + EXEC 很好实现,但是难得地方在 check hashtag 以及现在太忙了没有时间。[Concerned][Concerned][Concerned]

On 11 January 2018 at 3:18:03 PM, purplest (notifications@github.com) wrote:

刚解决了该问题的来Mark一下思路: 其实默认spring-boot-data-redis是和RedisTemplate无关的,默认是不会启用。 但是对应的RedisCache会在当前的连接不是cluster的时候给加上multi,code sample如下: `@override https://github.com/override public Void doInRedis(BinaryRedisCacheElement element, RedisConnection connection) throws DataAccessException {

if (!isClusterConnection(connection)) { connection.multi(); }

if (element.get().length == 0) { connection.del(element.getKeyBytes()); } else { connection.set(element.getKeyBytes(), element.get());

processKeyExpiration(element, connection);
maintainKnownKeys(element, connection);

}

if (!isClusterConnection(connection)) { connection.exec(); } return null;

}` 对应的思路即去掉对应的connection.multi(),或者让isClusterConnection(connection)返回一直为true即可。

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/CodisLabs/codis/issues/678#issuecomment-356847215, or mute the thread https://github.com/notifications/unsubscribe-auth/AAsHpdGJMHMe-_IAjM5JMOGbJV7AUb3Lks5tJbWqgaJpZM4HMN6q .

gongsiran commented 5 years ago

想知道 这个贴子 最终怎么解决的

bjxiaowen commented 5 years ago

能分享一下源码吗?谢谢

gongsiran commented 5 years ago

@bjxiaowen 按照原文改下 或者用 spring boot 2.x 版本 就解决了。