Redis-Cluster Java App on Kubernetes ①


  Overview  

Java (Spring) App for Redis-Cluster

We write and test a Java (Spring) App for the Redis-Cluster built as Kubernetes Pods.

  • Java 21
  • Spring Boot 3.4.3
  • Redis 8.8.2   🔗 Use the Redis-Cluster built here.
  • Develop the Java (Spring) app in IntelliJ on a PC (laptop)
  • Server: Linux (Rocky 9.6), Redis-Cluster already running

Java Spring Project

Create a Java Spring Project

Create a Java Spring Project and write the application.
URL to create a Java Spring Project with Spring Initializr: start.spring.io

Create a Java Spring Project
  • Project: Gradle-Groovy
  • Language: Java
  • Spring Boot: 4.1.1     ➡📍Change it to 3.4.3 in IntelliJ build.gradle.
  • Project Metadata
    • Group: com.redisgate
    • Artifact: KubeRedisClusterApp -> project name; the zip file is named this way.
    • Package name: com.redisgate.KubeRedisClusterApp -> Package Name
    • Packaging: Jar
    • Configuration: Properties
    • Java: 21 -> choose the Java version
  • In Dependencies, click [ADD … CTRL + B] and add the three items below.
    • Spring Web
    • Lombok
    • Spring Data Redis(Access+Driver)
  • Finally click [GENERATE CTRL + ⏎ ] and download the zip file.

🖥️ File/Class layout

💾 build.gradle file

  • Path: workspace\KubeRedisClusterAsync\build.gradle
  • 'org.springframework.boot' version '4.1.0' -> change to '3.4.3'
  • Change 'webmvc' -> 'web' in two places. Lowering to '3.4.3' makes 'webmvc' error, so it must be 'web'
  • Add the two libraries below
    implementation 'org.springframework.retry:spring-retry' // Add the Spring Retry library
    implementation 'org.springframework:spring-aspects' // AOP support
  • In IntelliJ, click the elephant (Gradle) icon at the top right -> click the refresh icon 'Reload All Gradle Projects'
  • Wait until the build finishes in the status bar
📄 build.gradle

💾 Dockerfile file

• Path: workspace\KubeRedisClusterAsync\Dockerfile

📄 Dockerfile

💾 application.properties file

• Path: workspace\KubeRedisClusterAsync\src\main\resources\application.properties
• In 'spring.data.redis.cluster.nodes', list redis-cluster-0 through 5 as shown below.

📄 application.properties

💾 KubeRedisClusterAppApplication.java file

📄 KubeRedisClusterAppApplication.java

💾 RedisClusterConfig.java file

Key settings are marked 📍 (see comments)

📄 RedisClusterConfig.java

✅ How do commandTimeout() and timeoutOptions() differ?

  • 1. Spring setting: commandTimeout(Duration.ofSeconds(1))
    • Where it applies: `LettuceClientConfigurationBuilder` (upper Spring Data Redis setting)
    • Role: the default synchronous command-execution timeout used when Spring Data Redis sends commands through the Lettuce client.
    • Behavior: with `RedisTemplate` or `StringRedisTemplate`, if Redis does not respond within 1 second, it throws `QueryTimeoutException` or `RedisCommandTimeoutException`.
    • Notes: the standard default. If no special TimeoutOptions are defined, Lettuce uses this value internally as the default timeout and cancels the command.
  • 2. Lettuce setting: timeoutOptions(TimeoutOptions.enabled(Duration.ofSeconds(1)))
    • Where it applies: `ClientOptions` (native Lettuce driver option)
    • Role: fine-grained control of each command's lifecycle and timeout strategy at the Lettuce engine level.
    • Behavior: inside Lettuce's async/reactive pipeline, if a command is sent and there is no result for 1 second or the network delays the response, a custom timeout scheduler cancels the command.
    • Notes:
      - Tighter failure control: combined with `disconnectedBehavior(REJECT_COMMANDS)`, commands waiting in the queue while disconnected or reconnecting are not stuck forever; they are cancelled after 1 second.
      - Dynamic timeout: `TimeoutOptions` supports not only a single `Duration` but also a `TimeoutSource` that can vary timeout by command type (READ/WRITE) or situation. (e.g. `GET` 500ms, `FLUSHALL` 5s)

💾 RedisOperationService.java file

📄 RedisOperationService.java

💾 RedisFailoverTestService.java file

📄 RedisFailoverTestService.java

App Docker image build, YAML files

Build the App Docker image

  • 1) Compile (make)
    IntelliJ [KubeRedisClusterApp]> ./gradlew clean bootJar
  • 2) Copy the two files 'KubeRedisClusterApp-0.0.1-SNAPSHOT.jar' and 'Dockerfile' to the server (~/kube/app/cluster/).
    Example dirs on the local PC (laptop)
    ① app\IntelliJ\workspace\KubeRedisClusterApp\build\libs\KubeRedisClusterApp-0.0.1-SNAPSHOT.jar
    ② app\IntelliJ\workspace\KubeRedisClusterApp\Dockerfile
  • 3) Build the Docker image (on the server)
    [~/kube/app/cluster/] $ docker build -t spring-redis-cluster-app:1.0 .
  • 4) Import the built Docker image into k3s (containerd) directly
    [~/kube/app/cluster/] $ docker save spring-redis-cluster-app:1.0 | sudo k3s ctr images import -

💾 app-deployment.yaml file

Write it in the server "~/kube/app/cluster/" dir

📄 app-deployment.yaml

➡ The Java App Pod is ready. Let’s run the failover test.


<< K8s Redis-Cluster Test ③ K8s Redis-Cluster App ② >>

Email 답글이 올라오면 이메일로 알려드리겠습니다.