我正在尝试解决请求中的 CROSSSLOT 键在变量上使用 @RedisHash 时,请求中的键不会散列到同一个插槽,该实体类上有多个 @Indexed。
有什么方法可以将哈希值存储在同一个 Redis 插槽中吗?
这是我的实体类供参考。
@RedisHash(value = "corp:TransactionDetails", timeToLive = Constants.TIME_TO_LIVE_REDIS)
public class TransactionDetailsEntity {
private static final long serialVersionUID = 1L;
@Id
@Indexed
private UUID transactionId;
@Indexed
private String sessionId;
@Indexed
private String referenceNumber;
private String fromAccountNumber;
private String remainingBalance;
private String fromAccountType;
private String beneficiaryName;
private String toAccountNumber;
private String toAccountBalance;
}
@Repository
public interface TransactionDetailsRepository extends CrudRepository<TransactionDetailsEntity, UUID> {
Optional<TransactionDetailsEntity> findBySessionIdAndTransactionId(String sessionId, UUID uuid);
Optional<TransactionDetailsEntity> findByReferenceNumber(String referenceNumber);
}
我面临以下错误。
Caused by: io.lettuce.core.RedisCommandExecutionException: CROSSSLOT Keys in request don't hash to the same slot (context='', command='sinter', original-slot='11760', wrong-slot='9232', first-key='corp:TransactionDetails:sessionId:aeb30c5a-a8d4-433e-9bd6-a2078b7499f7', violating-key='corp:TransactionDetails:transactionId:299b21fc-1538-43a3-8a0f-b515dec4241d')
at io.lettuce.core.internal.ExceptionFactory.createExecutionException(ExceptionFactory.java:147)
也许可以使用哈希标签:
哈希标签 用于实现哈希标签的哈希槽的计算有一个例外。哈希标签是一种确保多个键分配在同一个哈希槽中的方法。这是为了在 Redis 集群中实现多键操作。
为了实现哈希标签,在某些条件下以稍微不同的方式计算键的哈希槽。如果键包含“{...}”模式,则仅对 { 和 } 之间的子字符串进行哈希处理以获得哈希槽。然而,由于 { 或 } 可能会多次出现,因此算法可以通过以下规则很好地指定:
另一方面,spring-data-redis 允许您使用 Keyspaces 或现有的 RedisHash 来包含哈希标签。
@RedisHash(value = "{corp:TransactionDetails}", timeToLive = Constants.TIME_TO_LIVE_REDIS)
public class TransactionDetailsEntity {
private static final long serialVersionUID = 1L;
@Id
@Indexed
private UUID transactionId;
@Indexed
private String sessionId;
@Indexed
private String referenceNumber;
private String fromAccountNumber;
private String remainingBalance;
private String fromAccountType;
private String beneficiaryName;
private String toAccountNumber;
private String toAccountBalance;
}