簡體   English   中英

Spring Data Redis, Expiring and Redis Cluster

[英]Spring Data Redis, Expiring and Redis Cluster

我有一個應用程序使用

  • Spring Boot 2.2.6.RELEASE (spring-boot-starter-data-redis)
  • 絕地武士 3.1.0。

我有一個由 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 有着非常清晰的願景。 任何偏離這條道路都會導致奇怪的問題。 另一方面,堅持“正確的道路”意味着您將毫不費力地獲得所有 Redis 的好處。

我做了什么:

  • 將Redis庫更改為Jedis,基於它實現了我自己的非常簡單的客戶端
  • 將保存的數據限制在最低限度
  • 手動控制所有保存數據的 TTL
  • 使用{PART_OF_KEY}手動控制實體插槽(例如, exists於多個鍵上,要求它們都在一個插槽上)

我得到的結果:

  • 將單個數據大小從 ~60KB 減少到 ~60B,消除了所有索引、重復等,這反過來又讓我暫時比以前節省了幾個數量級的數據
  • 利用Redis優化的數據過期,沒有TTL就不會保存數據,因此瞬時內存使用總是准確的
  • 由於僅在需要時進行選擇性插槽,我仍然可以利用集群中的所有節點,但同時我可以利用所有以性能為中心的 Redis 調用 - 我從不通過多個鍵循環 redis 調用,因為所有的它們可以在具有多個參數的單個調用中完成

免責聲明:當我開始研究這個時,我只知道關於 Redis 的流行語,我沒有意識到它的真正潛力,也沒有意識到它是開發人員設想的用法。 一開始這一切似乎都在逆潮流而行,但是我越是根據 Redis 提供的功能調整我的代碼,就越覺得用它來工作。 我認為 Spring Data Redis 是用於快速原型設計的一個很棒的工具,但我覺得它的 ORM 類方法就像與 Redis 提供的一切背道而馳。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM