Spring Boot 1.5.x ã® Web ã¢ããªã 2.0.x ã¸ãã¼ã¸ã§ã³ã¢ãããã ( ãã®ï¼ï¼ )( Redis ã®ã¯ã©ã¤ã¢ã³ãã©ã¤ãã©ãªã Jedis â Lettuce ã«å¤æ´ãã )
æ¦è¦
è¨äºä¸è¦§ã¯ãã¡ãã§ãã
Spring Boot 1.5.x ã® Web ã¢ããªã 2.0.x ã¸ãã¼ã¸ã§ã³ã¢ãããã ( ãã®ï¼ï¼ )( build.gradle ã® dependencies ããä¸è¦ãªè¨è¿°ãåé¤ãã ) ã®ç¶ãã§ãã
- ä»åã®æé ã§ç¢ºèªã§ããã®ã¯ä»¥ä¸ã®å
容ã§ãã
- Spring Boot 2.0 Migration Guide - Redis ã«
Lettuce is now used instead of Jedis as the Redis driver when you use spring-boot-starter-data-redis.
ã¨ããè¨è¿°ããããspring-boot-starter-data-redis ã®ä¾åé¢ä¿ã«å ¥ã£ã¦ãã Redis ã®ã¯ã©ã¤ã¢ã³ãã©ã¤ãã©ãªã Jedis ãã Lettuce ã«ãªã£ã¦ãããã¨ã«æ°ã¥ãã¾ããã - 以å Redis Cluster ã¸ã®æ¥ç¶å¦çã Jedis ã§å®è£ ããã®ã§ãããLettuce ã«å¤æ´ãã¾ãã
- Spring Boot 2.0 Migration Guide - Redis ã«
åç §ãããµã¤ãã»æ¸ç±
-
Spring Data Redis
https://docs.spring.io/spring-data/data-redis/docs/current/reference/html/ Redis Spring data with Lettuce: com.lambdaworks.redis.RedisCommandExecutionException: MOVED error
https://stackoverflow.com/questions/53402326/redis-spring-data-with-lettuce-com-lambdaworks-redis-rediscommandexecutionexcepRedisCommandExecutionException: MOVED error when used cluster configuration endpoint
https://jira.spring.io/browse/DATAREDIS-898LINE LIVE ã®ãã£ããã?30,000+/min ã®ã³ã¡ã³ãæ稿ãæãããã«ãªãã¾ã§
https://www.slideshare.net/linecorp/line-live-30000min-98811987Lettuce Reference Guide
https://lettuce.io/core/release/reference/index.html- 7.2.1. Cluster-specific options ãåèã«ãã¾ããã
ç®æ¬¡
- spring-boot-starter-data-redis ã®ä¾åé¢ä¿ã« Lettuce ãå ¥ã£ã¦ãããã¨ã確èªãã
- build.gradle ãå¤æ´ãã
- åç´ã« JedisConnectionFactory â LettuceConnectionFactory ã«å¤æ´ãã¦ã¿ã
- Lettuce 㧠failover çºçæã«ãµã¼ãã®åæ¿ãèªèãããããã«å®è£ ãã
- build.gradle ã« spring-boot-configuration-processor ã追å ãã
æé
spring-boot-starter-data-redis ã®ä¾åé¢ä¿ã« Lettuce ãå ¥ã£ã¦ãããã¨ã確èªãã
gradlew dependencies
ã³ãã³ããå®è¡ãã㨠spring-boot-starter-data-redis ã®ä¾åé¢ä¿ã« io.lettuce:lettuce-core ãå
¥ã£ã¦ãããã¨ã確èªã§ãã¾ãã
+--- org.springframework.boot:spring-boot-starter-data-redis -> 2.0.6.RELEASE | +--- org.springframework.boot:spring-boot-starter:2.0.6.RELEASE (*) | +--- org.springframework.data:spring-data-redis:2.0.11.RELEASE | | +--- org.springframework.data:spring-data-keyvalue:2.0.11.RELEASE | | | +--- org.springframework.data:spring-data-commons:2.0.11.RELEASE (*) | | | +--- org.springframework:spring-context:5.0.10.RELEASE (*) | | | +--- org.springframework:spring-tx:5.0.10.RELEASE (*) | | | \--- org.slf4j:slf4j-api:1.7.25 | | +--- org.springframework:spring-tx:5.0.10.RELEASE (*) | | +--- org.springframework:spring-oxm:5.0.10.RELEASE | | | +--- org.springframework:spring-beans:5.0.10.RELEASE (*) | | | \--- org.springframework:spring-core:5.0.10.RELEASE (*) | | +--- org.springframework:spring-aop:5.0.10.RELEASE (*) | | +--- org.springframework:spring-context-support:5.0.10.RELEASE (*) | | \--- org.slf4j:slf4j-api:1.7.25 | \--- io.lettuce:lettuce-core:5.0.5.RELEASE | +--- io.projectreactor:reactor-core:3.1.6.RELEASE -> 3.1.10.RELEASE | | \--- org.reactivestreams:reactive-streams:1.0.2 | +--- io.netty:netty-common:4.1.24.Final -> 4.1.29.Final | +--- io.netty:netty-transport:4.1.24.Final -> 4.1.29.Final | | +--- io.netty:netty-buffer:4.1.29.Final | | | \--- io.netty:netty-common:4.1.29.Final | | \--- io.netty:netty-resolver:4.1.29.Final | | \--- io.netty:netty-common:4.1.29.Final | \--- io.netty:netty-handler:4.1.24.Final -> 4.1.29.Final | +--- io.netty:netty-buffer:4.1.29.Final (*) | +--- io.netty:netty-transport:4.1.29.Final (*) | \--- io.netty:netty-codec:4.1.29.Final | \--- io.netty:netty-transport:4.1.29.Final (*)
build.gradle ãå¤æ´ãã
build.gradle ã® dependencies block ãã implementation("redis.clients:jedis")
ãåé¤ãã¾ããå¤æ´å¾ãGradle Tool Window ã®å·¦ä¸ã«ãããRefresh all Gradle projectsããã¿ã³ãã¯ãªãã¯ãã¦æ´æ°ãã¾ãã
åç´ã« JedisConnectionFactory â LettuceConnectionFactory ã«å¤æ´ãã¦ã¿ã
src/main/java/ksbysample/webapp/lending/config/RedisClusterConfig.java ã以ä¸ã®ããã«å¤æ´ãã¾ãã
package ksbysample.webapp.lending.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisClusterConfiguration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import java.util.List; /** * Redis Cluster ç¨ Configuration ã¯ã©ã¹ */ @Data @Configuration @ConfigurationProperties(prefix = "spring.redis.cluster") public class RedisClusterConfig { List<String> nodes; /** * Redis Cluster ã«æ¥ç¶ããããã® {@link LettuceConnectionFactory} ãªãã¸ã§ã¯ããçæãã * * @return {@link LettuceConnectionFactory} ãªãã¸ã§ã¯ã */ @Bean public RedisConnectionFactory connectionFactory() { return new LettuceConnectionFactory(new RedisClusterConfiguration(nodes)); } }
- connectionFactory ã¡ã½ããå
ã§ã
JedisConnectionFactory
âLettuceConnectionFactory
ã«å¤æ´ãã¾ãã
åä½ç¢ºèªãã¦ã¿ã¾ããdocker-compose up -d
ã³ãã³ããå®è¡ããå¾ãTomcat ãèµ·åãã¾ãã
Spring Actuator ã® health check 㧠Redis ã«æ¥ç¶ã§ãã¦ãããã¨ã確èªãã¾ãã
docker exec -it redis-cluster-6382 redis-cli
ã³ãã³ã㧠Redis ã«æ¥ç¶ããå¾ãcluster nodes
ã³ãã³ããå®è¡ãã¦ã¯ã©ã¹ã¿æ§æã確èªãã¾ãã
ä»ã¯ä»¥ä¸ã®æ§æã«ãªã£ã¦ãã¾ãã
- redis-cluster-6379(master) - redis-cluster-6382(slave)
- redis-cluster-6380(master) - redis-cluster-6383(slave)
- redis-cluster-6381(master) - redis-cluster-6384(slave)
ã¾ã http://localhost:8080/ ã«ã¢ã¯ã»ã¹ãã¦ãã°ã¤ã³ç»é¢ã表示ããå¾ã[email protected] / taro ã§ãã°ã¤ã³ãã¾ãã
IntelliJ IDEA ã® Docker Plugin ãã Redis ã® master ï¼å°ï¼redis-cluster-6379, redis-cluster-6380, redis-cluster-6381ï¼ãåæ¢ãã¾ãã
redis-cli ãã cluster nodes
ã³ãã³ããå®è¡ãã¦ä»¥åã® master ã®ã¹ãã¼ã¿ã¹ã fail ã«ãªã£ã¦ãããã¨ãslave â master ã«ææ ¼ãã¦ãããã¨ã確èªãã¾ãã
ãã©ã¦ã¶ã®å³ä¸ã®ããã°ã¢ã¦ãããªã³ã¯ãã¯ãªãã¯ãã¦ãã°ã¢ã¦ããã¦ã¿ã¾ããJedisConnectionFactory ã®æã¯ãã°ã¢ã¦ãã§ããã®ã§ãããJedisConnectionFactory
â LettuceConnectionFactory
ã«å¤æ´ããã ãã®ç¶æ
ã ã¨ã¨ã©ã¼ã«ãªããã°ã¢ã¦ãã§ãã¾ããï¼Ctrl+F5 ãæ¼ãã¦ä½åº¦ããªãã¼ããã¦ã¿ã¾ããããã£ã¨ã¨ã©ã¼ã®ã¾ã¾ã§ããï¼ã
ã³ã³ã½ã¼ã«ã«ã¯
org.springframework.data.redis.RedisSystemException: Redis exception; nested exception is io.lettuce.core.RedisException: io.lettuce.core.RedisConnectionException: Unable to connect to 172.23.136.33:6381
ã¨ããã¨ã©ã¼ãåºã¦ãã¦ãã©ããã©ã¤ãã©ãªã®æ¹ã§ master ãå¤ãã£ããã¨ãèªèã§ãã¦ããªãããã§ãã
Tomcat ãåæ¢ããdocker-compose down
ã³ãã³ããå®è¡ãã¦ã³ã³ãããåæ¢ãã¾ãã
Lettuce 㧠failover çºçæã«ãµã¼ãã®åæ¿ãèªèãããããã«å®è£ ãã
Spring Data Redis ã®è¨è¿°ã ã¨åãããªãã£ãã®ã§ããã以ä¸ã®ããã¥ã¡ã³ããè¦ãã¨ãªãã·ã§ã³ã®è¨å®ãå¿ è¦ã ã£ãããã§ãã
- LINE LIVE ã®ãã£ããã?30,000+/min ã®ã³ã¡ã³ãæ稿ãæãããã«ãªãã¾ã§
- Lettuce Reference Guide - 7.2.1. Cluster-specific options
src/main/java/ksbysample/webapp/lending/config/RedisClusterConfig.java ã以ä¸ã®ããã«å¤æ´ãã¾ãã
package ksbysample.webapp.lending.config; import io.lettuce.core.cluster.ClusterClientOptions; import io.lettuce.core.cluster.ClusterTopologyRefreshOptions; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisClusterConfiguration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import java.time.Duration; import java.util.List; /** * Redis Cluster ç¨ Configuration ã¯ã©ã¹ */ @Data @Configuration @ConfigurationProperties(prefix = "spring.redis.cluster") public class RedisClusterConfig { List<String> nodes; /** * Redis Cluster ã«æ¥ç¶ããããã® {@link LettuceConnectionFactory} ãªãã¸ã§ã¯ããçæãã * * @return {@link LettuceConnectionFactory} ãªãã¸ã§ã¯ã */ @Bean public RedisConnectionFactory connectionFactory() { ClusterTopologyRefreshOptions clusterTopologyRefreshOptions = ClusterTopologyRefreshOptions.builder() .enablePeriodicRefresh(Duration.ofSeconds(30)) .enableAllAdaptiveRefreshTriggers() .build(); ClusterClientOptions clusterClientOptions = ClusterClientOptions.builder() .validateClusterNodeMembership(false) .topologyRefreshOptions(clusterTopologyRefreshOptions) .build(); LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder() .commandTimeout(Duration.ofSeconds(15)) .shutdownTimeout(Duration.ZERO) .clientOptions(clusterClientOptions) .build(); RedisClusterConfiguration serverConfig = new RedisClusterConfiguration(nodes); return new LettuceConnectionFactory(serverConfig, clientConfig); } }
åä½ç¢ºèªãã¦ã¿ã¾ããå
ç¨ã¨åãæé ã§ãdocker-compose up -d
ã³ãã³ãå®è¡ â Tomcat èµ·å â ãã°ã¤ã³ç»é¢ãã [email protected] / taro ã§ãã°ã¤ã³ãããã¾ã§å®è¡ãã¾ãã
cluster nodes
ã³ãã³ãã®å®è¡çµæã¯ä»¥ä¸ã®ããã«ãªã£ã¦ãããæ§æã¯å
ç¨ã¨åãã§ãã
IntelliJ IDEA ã® Docker Plugin ãã Redis ã® master ï¼å°ï¼redis-cluster-6379, redis-cluster-6380, redis-cluster-6381ï¼ãåæ¢ãã¾ãã
redis-cli ãã cluster nodes
ã³ãã³ããå®è¡ãã¦ä»¥åã® master ã®ã¹ãã¼ã¿ã¹ã fail ã«ãªã£ã¦ãããã¨ãslave â master ã«ææ ¼ãã¦ãããã¨ã確èªãã¾ãã
ãã©ã¦ã¶ã®å³ä¸ã®ããã°ã¢ã¦ãããªã³ã¯ãã¯ãªãã¯ããã¨ãä»åº¦ã¯ãã°ã¢ã¦ããããã¨ãã§ãã¾ããã
ãã®å¾ãã°ã¤ã³ï¼ãã°ã¢ã¦ããç¹°ãè¿ããããRedis ã® failover ãä½åº¦ãè¡ã£ã¦ã¿ã¾ããããã¨ã©ã¼ã¯åºã¾ããã§ããã
build.gradle ã« spring-boot-configuration-processor ã追å ãã
@ConfigurationProperties ãä»ä¸ãã㨠IntelliJ IDEA ã§ã¯ä»¥ä¸ã®ãããªç»é¢ï¼ã¨ãã£ã¿ã®ä¸é¨ã« Spring Boot Configuration Annotation Processor not found in classpath
ã®ã¡ãã»ã¼ã¸ã表示ããã@ConfigurationProperties ã«èµ¤æ³¢ä¸ç·ãä»ã ï¼ã«ãªãã¾ãã
build.gradle ã® dependencies block ã« compileOnly("org.springframework.boot:spring-boot-configuration-processor")
ã追è¨ãã¦åºãªãããã«ãã¾ãã
dependencies { .......... runtimeOnly("org.springframework.boot:spring-boot-devtools") compileOnly("org.springframework.boot:spring-boot-configuration-processor") implementation("org.springframework.session:spring-session-data-redis") ..........
Recommend the use of the compileOnly or annotationProcessor configurations for spring-boot-configuration-processor ã® Issue ãè¦ã㨠compileOnly ã§ã¯ãªã annotationProcessor ã§ãè¯ããããªæ°ããã¾ãããannotationProcessor ã ã¨ã¨ãã£ã¿ä¸ã®ã¡ãã»ã¼ã¸ãæ¶ãããbuild å®è¡æã« compileTestJava ã¿ã¹ã¯ã§ è¦å:次ã®ãªãã·ã§ã³ã¯ã©ã®ããã»ããµã§ãèªèããã¾ããã§ãã: '[org.springframework.boot.configurationprocessor.additionalMetadataLocations]'
ã¨ããè¦åãåºãã®ã§ compileOnly ã«ãã¾ããã
å±¥æ´
2019/01/06
åççºè¡ã