Spring Data Redis Documentation

repository·main·Indexed 23 days ago

https://github.com/spring-projects/spring-data-redis

An integration layer between Spring applications and Redis (or Valkey) stores. It provides high-level abstractions like RedisTemplate, Repository support, and specialized operations interfaces (List, Value, Set, ZSet, and Hash). Key features include connection abstraction for Lettuce and Jedis, exception translation, Pub/Sub support via MessageListenerContainer, Redis Sentinel and Cluster topology support, and a reactive API.

Tokens
48.3K
Snippets
100
Records
243
Agent score
83%

What's inside Spring Data Redis

  1. Overview of Spring Data Redis features

    main

    Spring Data Redis provides both low-level and high-level abstractions for interacting with Redis, handling infrastructural concerns like serialization and exception translation.

    Key features include:

    • RedisTemplate and ReactiveRedisTemplate: Helper classes for common Redis operations with integrated serialization.
    • Exception Translation: Converts Redis-specific errors into Spring's portable Data Access Exception hierarchy.
    • Repository Support: Automatic implementation of Repository interfaces with custom query method support.
    • Object Mapping: Feature-rich mapping integrated with Spring's Conversion Service and extensible annotation-based metadata.
    • Advanced Operations: Support for Transactions, Pipelining, and Redis Pub/Sub or Redis Stream Listeners.
    • Caching: Integration with Spring's Cache abstraction.
    • Collection Implementations: Java-friendly implementations like RedisList or RedisSet.
  2. Overview of Redis Pub/Sub messaging in Spring Data Redis

    main

    Spring Data Redis provides messaging integration for Redis, following the Publish/Subscribe (Pub/Sub) pattern. Messaging functionality is split into two primary areas:

    1. Publication (Sending messages): You can send messages using several different abstraction levels:

      • The low-level RedisConnection contract.
      • RedisOperations (typically implemented by RedisTemplate).
      • The message-oriented RedisMessageSendingTemplate.
    2. Subscription (Receiving messages):

      • Asynchronous reception: Uses a dedicated message listener container to create Message-Driven POJOs (MDPs), similar to Java EE's message-driven beans.
      • Synchronous reception: Uses the RedisConnection contract.

    Core functionality is organized into the following packages:

    • org.springframework.data.redis.connection and org.springframework.data.redis.listener: Core messaging functionality.
    • org.springframework.data.redis.annotation: Infrastructure for annotation-driven listener endpoints using @RedisListener.
    • org.springframework.data.redis.config: Support for the redis namespace parser and Java configuration for listener endpoints.
  3. Use Redis-backed collections and atomic counters

    main

    The org.springframework.data.redis.support package provides reusable components that use Redis as a backing store while exposing standard JDK interfaces. This allows you to manage Redis keys with minimal API leakage and makes your code decoupled from the underlying storage.

    Key features include:

    • Atomic Counters: Wrappers for Redis key incrementation.
    • Redis Collections: Implementations of standard JDK Collection interfaces.
      • RedisSet: Provides access to Redis set operations like intersection and union.
      • RedisZSet: Provides access to Redis sorted set operations.
      • RedisList: Implements List, Queue, and Deque contracts (including blocking variants). It can be configured as a FIFO, LIFO, or capped collection. Note that RedisList is forward-compatible with Java 21 SequencedCollection.
  4. Core features of Spring Data Redis

    main

    Spring Data Redis provides several key capabilities for interacting with Redis and Valkey:

    • Connection Abstraction: Low-level abstraction across multiple drivers like Lettuce and Jedis.
    • Exception Translation: Converts driver-specific exceptions into Spring's portable Data Access exception hierarchy.
    • High-level Abstractions: RedisTemplate for operations, serialization support, and specialized Operations interfaces.
    • Pub/Sub Support: Includes MessageListenerContainer for message-driven POJOs.
    • Topology Support: Support for Redis Sentinel and Redis Cluster.
    • Reactive Programming: Reactive API available via the Lettuce driver.
    • Serialization: Support for JDK, String, JSON, and Spring Object/XML mapping.
    • Data Structures: JDK Collection implementations on top of Redis, atomic counters, and sorting/pipelining functionality.
    • Repository Support: Automatic implementation of Repository interfaces via @EnableRedisRepositories and CDI support.
  5. Handle Redis key expiration events

    main

    Spring Data Redis can publish RedisKeyExpiredEvent whenever a key expires. To enable this, the repository implementation subscribes to Redis keyspace notifications.

    How it works

    When a positive expiration is set, Spring Data Redis performs two actions:

    1. Persists the original object.
    2. Persists a "phantom copy" set to expire five minutes after the original. This phantom copy allows the repository to hold the expired value and publish a RedisKeyExpiredEvent via Spring's ApplicationEventPublisher even after the original data is gone.

    Configuring Event Startup

    By default, the key expiry listener is disabled. You can adjust the startup behavior using @EnableRedisRepositories or RedisKeyValueAdapter via the EnableKeyspaceEvents setting:

    • Start with the application: The listener starts immediately upon startup.
    • Start on first insert: The listener starts only when an entity with a TTL is first inserted.

    Disabling Phantom Copies

    You can disable the storage of phantom copies using @EnableKeyspaceEvents(shadowCopy = OFF). This reduces Redis data size, but RedisKeyExpiredEvent will only contain the id of the expired key instead of the full domain object.

  6. How repository insertion works

    main

    When calling repository.save() for a new entity, the repository performs several steps to ensure the entity is searchable via its indexed fields:

    1. Save the Hash: The entity is saved as a flattened HMSET hash.
    2. Keyspace Index: The entity's key is added to a helper set for the entire keyspace (e.g., SADD "people" <id>).
    3. Secondary Index: The entity's key is added to a specific index set based on the indexed property value (e.g., SADD "people:firstname:rand" <id>).
    4. Index Tracking: The index key is added to a helper structure attached to the entity to track which indexes must be cleaned up if the entity is later deleted or updated (e.g., SADD "people:<id>:idx" "people:firstname:rand").
    repository.save(new Person("rand", "al'thor"));
  7. How Geo Data is saved in Redis Repositories

    main

    Entities using @GeoIndexed properties utilize Redis Geo commands. Saving a geo-indexed entity involves:

    1. GEOADD: Adding the entity's key to a specialized geo index structure (e.g., GEOADD "people:hometown:location" <long> <lat> <id>).
    2. Index Tracking: Adding the geo index key to the entity's index tracker set (SADD "people:<id>:idx" "people:hometown:location") to allow for proper cleanup.
  8. How Spring Data Redis relates to Spring and NoSQL

    main

    Spring Integration

    Spring Data Redis applies core Spring concepts to key-value data stores. It provides a template as a high-level abstraction for sending and receiving messages, similar to how JdbcTemplate works in Spring JDBC.

    To use advanced features like Repository support, you must configure the library to work with the Spring IoC container. However, the core Redis functionality can be used directly without invoking Spring IoC services.

    NoSQL Concepts

    Spring Data Redis is designed for NoSQL key-value stores. Users are encouraged to familiarize themselves with Redis-specific patterns and documentation, as the principles differ from traditional RDBMS.

  9. Use RedisTemplate and ReactiveRedisTemplate

    main

    Spring Data Redis provides two primary ways to interact with Redis depending on your programming model:

    Imperative Programming

    Use org.springframework.data.redis.core.RedisTemplate to perform standard synchronous operations. You create an instance of this template using a org.springframework.data.redis.connection.RedisConnectionFactory.

    Reactive Programming

    Use org.springframework.data.redis.core.ReactiveRedisTemplate for non-blocking, reactive usage. Like the imperative version, it requires a org.springframework.data.redis.connection.RedisConnectionFactory.

    RedisConnectionFactory acts as an abstraction layer over the underlying drivers (Lettuce or Jedis).

  10. Usage constraints when using Redis transactions

    main

    When RedisTemplate is participating in a managed transaction (via setEnableTransactionSupport(true)), observe the following behaviors:

    1. Writes: Must be performed on the thread-bound connection.
    2. Reads: Commands like keys("*") are executed on a separate, non-transaction-aware connection.
    3. Visibility: Values set within a transaction are not visible to standard get operations until the transaction is committed.
    // must be performed on thread-bound connection
    template.opsForValue().set("thing1", "thing2");
    
    // read operation must be run on a free (not transaction-aware) connection
    template.keys("*");
    
    // returns null as values set within a transaction are not visible
    template.opsForValue().get("thing1");
  11. Customize RedisKeyValueAdapter and RedisKeyValueTemplate in CDI

    main

    Redis Repositories require instances of RedisKeyValueAdapter and RedisKeyValueTemplate.

    By default, the Spring Data Redis CDI extension will automatically create and manage these beans if they are not found in the CDI container. However, if you need to configure specific properties for these components, you can supply your own custom beans for RedisKeyValueAdapter and RedisKeyValueTemplate in your CDI configuration.

  12. Understand Redis Cluster behavior and limitations

    main

    Redis Cluster uses automatic sharding to map keys to one of 16384 slots distributed across nodes. This affects how commands are executed:

    • Single Node Scope: A single cluster node only serves a specific set of keys. Commands like KEYS issued to a single node only return keys for that node.
    • Cross-Slot Errors: Commands involving multiple keys must ensure all keys map to the same slot to avoid errors. If they don't, the driver must split the command into multiple single-slot requests, which is less performant.
    • Keyspace Events: Do not rely on keyspace events in a cluster, as they are not replicated across shards. Pub/Sub subscriptions may only receive events from a single shard.
    • Slot Pinning: To ensure multiple keys map to the same slot, use curly bracket syntax (hash tags), e.g., \{my-prefix}.thing1 and \{my-prefix}.thing2.