[英]Spring Data Redis, Expiring and Redis Cluster
我有一個應用程序使用
我有一個由 6 個節點組成的 Redis 5.0.7 集群:3 個主節點和 3 個從節點,復制 127.0.0.1:7000-7005(只是示例值)。
我已經這樣配置了我的應用程序:
@Configuration
@EnableRedisRepositories(basePackages = "my.package.of.dtos", enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP)
public class RedisConfiguration {
@Bean
JedisConnectionFactory jedisConnectionFactory() {
return new JedisConnectionFactory(
new RedisClusterConfiguration(List.of(
"127.0.0.1:7000",
"127.0.0.1:7001",
"127.0.0.1:7002",
"127.0.0.1:7003",
"127.0.0.1:7004",
"127.0.0.1:7005")));
}
@Bean
public RedisTemplate<String, Object> redisTemplate(JedisConnectionFactory jedisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(jedisConnectionFactory);
return template;
}
}
我有幾個 DTO,例如:
@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
@RedisHash(value = "Foo", timeToLive = 300)
public class Foo {
private String id;
@Indexed
private String fooIndexedField;
private String fooField1;
private String fooField2;
}
和存儲庫:
@Repository
public interface FooRepository extends CrudRepository<Foo, String> {
List<Foo> findByFooIndexedField(String fooIndexedField);
}
我的用例:我有一個大流量處理應用程序,我將數據寫入 Redis 並希望通過索引字段讀取實體列表。 數據僅在一段時間內相關,因此我正在利用 Redis 的過期功能。
一切似乎都在工作,直到我注意到 Redis 中的數據沒有按預期過期。 當我連接到 Redis 集群(使用RedisClusterConfiguration
)時,一旦散列過期,與它相關聯並由 Spring Data Redis 寫入的其余數據仍然存在,幻像會在 5 分鍾后自行過期,但額外的集合 ex Foo
(與所有IDs)、 Foo:testId1:idx
(值Foo:fooIndexedField:testIndex1
)和Foo:fooIndexedField:testIndex1
(值 testId1)仍然存在。
我已將 redis 配置交換為RedisStandaloneConfiguration
(單節點,用於測試目的),並且當哈希過期時所有數據都消失了。
到目前為止,我在 Spring 文檔中唯一找到的是: Define and pin keyspaces by using @RedisHash("{yourkeyspace}") to specific slots when you use Redis cluster.
這不是我能做的。 一些散列需要分布在所有節點上,因為我不能假設它們適合一個節點。
唯一使我的集群不會因孤立索引而耗盡內存的是設置maxmemory_policy:allkeys-lru
覆蓋它們。 這是令人不安的,因為我看到我的所有節點一直都在使用最大內存。
我在應用程序、Spring Data Redis 或 Redis 集群設置中是否遺漏了什么?
編輯:使用 Redisson redisson-spring-data-22 版本 3.13.5 的配置:
@Configuration
@EnableRedisRepositories(basePackages = "my.package.of.dtos", enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP)
public class RedisConfiguration {
@Bean
public RedissonConnectionFactory redissonConnectionFactory() {
Config config = new Config();
config.useClusterServers().addNodeAddress("redis://127.0.0.1:7000", "redis://127.0.0.1:7001", "redis://127.0.0.1:7002", "redis://127.0.0.1:7003", "redis://127.0.0.1:7004", "redis://127.0.0.1:7005");
return new RedissonConnectionFactory(config);
}
@Bean
public RedisTemplate<String, Object> redisTemplate(RedissonConnectionFactory redissonConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redissonConnectionFactory);
return template;
}
}
不幸的是,給出了相同的結果。
嘗試使用Redisson庫更多功能和緩存管理、調度....
我特別在分布式任務事務中使用它。
這里列出了所有功能: https : //redisson.org/feature-comparison-redisson-vs-jedis.html
結果證明 Spring Data Redis 不適合我。 我對 Spring Data Redis 的體驗:
在徹底閱讀 Redis 文檔后,我解決了所有這些問題。 事實證明,Redis 開發人員對於他們希望如何使用 Redis 有着非常清晰的願景。 任何偏離這條道路都會導致奇怪的問題。 另一方面,堅持“正確的道路”意味着您將毫不費力地獲得所有 Redis 的好處。
我做了什么:
{PART_OF_KEY}
手動控制實體插槽(例如, exists
於多個鍵上,要求它們都在一個插槽上)我得到的結果:
免責聲明:當我開始研究這個時,我只知道關於 Redis 的流行語,我沒有意識到它的真正潛力,也沒有意識到它是開發人員設想的用法。 一開始這一切似乎都在逆潮流而行,但是我越是根據 Redis 提供的功能調整我的代碼,就越覺得用它來工作。 我認為 Spring Data Redis 是用於快速原型設計的一個很棒的工具,但我覺得它的 ORM 類方法就像與 Redis 提供的一切背道而馳。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.