redis
2025/10/23大约 2 分钟约 469 字
redis
简介
spring redis集群踩坑
1. 多值操作
- redis集群下如果进行多key操作则有可能报,原因是redis 对key hash存放在不同slot
org.springframework.data.redis.RedisSystemException: Error in execution; nested exception is io.lettuce.core.RedisCommandExecutionException: ERR 'EVALSHA' command keys must in same slot 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- 解决方案 key 可以设置多值操作的时候使用一个slot 如下
xxx:{userId}:1
xxx:{userId}:22.springboot 集群宕机后
https://help.aliyun.com/zh/redis/product-overview/notice-on-lettuce-update
近期,Lettuce社区修复了在Redis异常宕机导致没有回复RST(Reset)情况下,客户端恢复时间可能长达15分钟的BUG,详情请参见redis/lettuce#2082。建议您将Lettuce客户端升级到6.3.0.RELEASE及以上版本,以规避该问题。该问题由阿里云Tair(Redis)团队于redis/lettuce#2499修复。- xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>6.3.0.RELEASE</version>
</dependency>- java
import io.lettuce.core.ClientOptions;
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.SocketOptions;
import io.lettuce.core.SocketOptions.KeepAliveOptions;
import io.lettuce.core.SocketOptions.TcpUserTimeoutOptions;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.sync.RedisCommands;
import java.time.Duration;
public class LettuceExample {
/**
* Enable TCP keepalive and configure the following three parameters:
* TCP_KEEPIDLE = 30
* TCP_KEEPINTVL = 10
* TCP_KEEPCNT = 3
*/
private static final int TCP_KEEPALIVE_IDLE = 30;
/**
* The TCP_USER_TIMEOUT parameter can avoid situations where Lettuce remains stuck in a continuous timeout loop during a failure or crash event.
* refer: https://github.com/lettuce-io/lettuce-core/issues/2082
*/
private static final int TCP_USER_TIMEOUT = 30;
private static RedisClient client = null;
private static StatefulRedisConnection<String, String> connection = null;
public static void main(String[] args) {
// Replace the values of host, user, password, and port with the actual instance information.
String host = "r-bp1s1bt2tlq3p1****.redis.rds.aliyuncs.com";
String user = "r-bp1s1bt2tlq3p1****";
String password = "Da****3";
int port = 6379;
// Config RedisURL
RedisURI uri = RedisURI.Builder
.redis(host, port)
.withAuthentication(user, password)
.build();
// Config TCP KeepAlive
SocketOptions socketOptions = SocketOptions.builder()
.keepAlive(KeepAliveOptions.builder()
.enable()
.idle(Duration.ofSeconds(TCP_KEEPALIVE_IDLE))
.interval(Duration.ofSeconds(TCP_KEEPALIVE_IDLE/3))
.count(3)
.build())
.tcpUserTimeout(TcpUserTimeoutOptions.builder()
.enable()
.tcpUserTimeout(Duration.ofSeconds(TCP_USER_TIMEOUT))
.build())
.build();
client = RedisClient.create(uri);
client.setOptions(ClientOptions.builder()
.socketOptions(socketOptions)
.build());
connection = client.connect();
RedisCommands<String, String> commands = connection.sync();
System.out.println(commands.set("foo", "bar"));
System.out.println(commands.get("foo"));
// If your application exits and you want to destroy the resources, call this method. Then, the connection is closed, and the resources are released.
connection.close();
client.shutdown();
}
}