Panduan Lengkap Spring Boot 4 · Pelajaran

Cache Teragih dengan Redis dan TTL

Kongsi keadaan cache merentas tika menggunakan Redis sebagai bahagian belakang cache berpusat dengan kawalan pensirian.

Pelajaran 3 daripada 413 langkah

Cache Teragih dengan Redis dan TTL ialah pelajaran Panduan Lengkap Spring Boot 4 percuma di CoddyKit. Ini ialah pelajaran 3 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Panduan Lengkap Spring Boot 4, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Panduan Lengkap Spring Boot 4 merangkumi sejumlah 4 pelajaran.

Mengapa Pencachean Teragih?

Caffeine ialah cache dalam proses yang sangat baik: amat pantas, tetapi setiap tika aplikasi menyimpan salinan peribadinya sendiri. Sebaik sahaja anda membuat penskalaan mendatar kepada beberapa pod, salinan tersebut mula berbeza.

  • Tika A mengusir pengguna; tika B masih menyediakan entri yang lapuk.
  • Pemanasan cache pada satu nod tidak membantu nod lain.
  • Kos memori keseluruhan meningkat secara linear mengikut bilangan replika.

Cache teragih menyelesaikan masalah ini dengan meletakkan keadaan cache dalam bahagian belakang yang dikongsi dan dibaca serta ditulis oleh setiap tika. Dalam Spring Boot, Redis ialah pilihan yang paling lazim untuk peranan ini.

Menambah Pemula Cache Redis

Abstraksi pencachean Spring Boot tidak bergantung pada bahagian belakang tertentu. Untuk menukar Caffeine kepada Redis, anda kebanyakannya hanya menukar kebergantungan dan satu sifat — anotasi @Cacheable anda kekal sama.

Tambahkan pemula Redis dan abstraksi cache:

  • spring-boot-starter-data-redis menyediakan sambungan dan RedisCacheManager.
  • spring-boot-starter-cache mengaktifkan anotasi @Cacheable/@CacheEvict.

Kemudian isytiharkan Redis sebagai jenis cache supaya Boot mengkonfigurasi automatik RedisCacheManager, bukannya peta ringkas.

<!-- pom.xml -->
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
</dependencies>

Mengkonfigurasi Sambungan dan Jenis Cache

Arahkan Boot kepada pelayan Redis anda dan beritahu abstraksi cache supaya menggunakan Redis. Dengan spring.cache.type=redis, Boot menyambungkan RedisCacheManager secara automatik.

  • spring.data.redis.host / port mengkonfigurasi klien Lettuce (pemacu lalai).
  • spring.cache.redis.time-to-live menetapkan TTL lalai untuk setiap entri.
  • spring.cache.cache-names boleh mengisytiharkan cache terlebih dahulu semasa permulaan.
# application.yml
spring:
  data:
    redis:
      host: localhost
      port: 6379
  cache:
    type: redis
    cache-names: products, users
    redis:
      time-to-live: 10m
      cache-null-values: false
      use-key-prefix: true

@Cacheable yang Sama, Bahagian Belakang yang Dikongsi

Inilah manfaat abstraksi Spring: kod perkhidmatan adalah sama seperti versi Caffeine. Hanya CacheManager di belakangnya yang berubah.

Kini apabila tika A mengisi products::42, tika B membaca kunci yang sama daripada Redis pada panggilan seterusnya — tiada pengiraan pendua dan tiada perbezaan keadaan.

@Service
public class ProductService {

    private final ProductRepository repository;

    public ProductService(ProductRepository repository) {
        this.repository = repository;
    }

    @Cacheable(cacheNames = "products", key = "#id")
    public Product findById(Long id) {
        // Runs only on a cache miss across the whole cluster
        return repository.findById(id)
                .orElseThrow(() -> new ProductNotFoundException(id));
    }

    @CacheEvict(cacheNames = "products", key = "#product.id")
    public Product update(Product product) {
        return repository.save(product);
    }
}

TTL: Mengehadkan Kesepuhan

TTL (masa hayat) ialah umur maksimum entri cache sebelum Redis mengusirnya secara automatik. TTL ialah perlindungan utama daripada menyediakan data lapuk dalam cache teragih.

  • TTL pendek (saat) → data lebih segar, beban bahagian belakang lebih tinggi.
  • TTL panjang (jam) → lebih menjimatkan, tetapi risiko data lapuk meningkat.
  • TTL dikuatkuasakan pada bahagian pelayan oleh Redis, jadi ia digunakan secara seragam pada setiap tika.

Berbeza daripada expireAfterWrite Caffeine, TTL Redis kekal selepas satu tika dimulakan semula kerana data disimpan di luar JVM.

TTL Mengikut Cache dengan RedisCacheManager Tersuai

Satu TTL global jarang sesuai untuk setiap cache. Gantikan konfigurasi automatik untuk memberikan setiap cache tamat tempohnya sendiri dengan membekalkan RedisCacheManagerBuilderCustomizer (atau bean RedisCacheManager penuh).

Di sini products boleh menerima data lapuk selama 30 minit, manakala prices yang mudah berubah tamat tempoh selepas 1 minit.

@Configuration
public class CacheConfig {

    @Bean
    public RedisCacheManagerBuilderCustomizer cacheCustomizer() {
        return builder -> builder
            .withCacheConfiguration("products",
                RedisCacheConfiguration.defaultCacheConfig()
                    .entryTtl(Duration.ofMinutes(30)))
            .withCacheConfiguration("prices",
                RedisCacheConfiguration.defaultCacheConfig()
                    .entryTtl(Duration.ofMinutes(1)));
    }
}

Penyirilan: Cara Nilai Sampai ke Redis

Redis menyimpan bait, bukannya objek Java. Setiap nilai cache mesti disirikan semasa ditulis dan dinyahsirikan semasa dibaca. RedisCacheManager lalai menggunakan penyirilan natif Java (JdkSerializationRedisSerializer), yang mempunyai beberapa kelemahan nyata:

  • Nilai ialah gumpalan binari legap — tidak boleh dibaca dengan redis-cli.
  • Kelas yang dicache mesti melaksanakan Serializable.
  • Gandingan rapat dengan dalaman kelas menyebabkan masalah merentas versi.

Untuk entri yang boleh saling kendali dan mudah dibaca manusia, tukar penyirih nilai kepada JSON.

Mengawal Penyirilan dengan JSON

Gunakan GenericJackson2JsonRedisSerializer untuk nilai dan StringRedisSerializer biasa untuk kunci. JSON memastikan entri boleh diperiksa dan tidak bergantung pada dalaman kelas Java.

Penyirih tersebut membenamkan metadata jenis (@class) supaya nilai polimorfik dinyahsirikan kembali kepada jenis konkrit yang betul.

@Bean
public RedisCacheConfiguration cacheConfiguration() {
    return RedisCacheConfiguration.defaultCacheConfig()
        .entryTtl(Duration.ofMinutes(10))
        .disableCachingNullValues()
        .serializeKeysWith(
            RedisSerializationContext.SerializationPair.fromSerializer(
                new StringRedisSerializer()))
        .serializeValuesWith(
            RedisSerializationContext.SerializationPair.fromSerializer(
                new GenericJackson2JsonRedisSerializer()));
}

Awalan Kunci Mengelakkan Pertembungan

Apabila beberapa cache berkongsi satu pangkalan data Redis, kuncinya tidak boleh bertembung. Secara lalai, Spring menambah awalan nama cache pada setiap entri, jadi products::42 dan users::42 kekal berasingan.

  • use-key-prefix: true (lalai) memastikan cache terasing.
  • Anda boleh membekalkan awalan tersuai, contohnya nama aplikasi atau penyewa, untuk berkongsi tika Redis dengan selamat merentas perkhidmatan.

Hal ini paling penting dalam persediaan berbilang penyewa atau infrastruktur dikongsi, apabila satu Redis melayan banyak aplikasi.

@Bean
public RedisCacheConfiguration cacheConfiguration() {
    return RedisCacheConfiguration.defaultCacheConfig()
        .entryTtl(Duration.ofMinutes(10))
        .computePrefixWith(cacheName -> "shop:" + cacheName + "::");
    // key becomes shop:products::42
}

Mengelakkan Serbuan Serentak

Cache teragih menumpukan risiko: apabila TTL bagi kunci yang kerap digunakan tamat tempoh, setiap tika gagal mendapatkan nilai pada masa yang sama lalu menyerbu pangkalan data — masalah serbuan serentak.

Langkah pengurangan:

  • Jarakkan TTL dengan menambah sedikit gangguan rawak supaya kunci tidak tamat tempoh serentak.
  • Muat semula entri secara proaktif sebelum tamat tempoh, bukannya secara malas apabila bacaan gagal.
  • Gunakan kunci jangka pendek supaya hanya satu tika mengira semula kunci yang gagal diperoleh, sementara tika lain menunggu.

Pembantu Java tulen ini menunjukkan cara mengira TTL dengan gangguan yang akan anda masukkan ke dalam entryTtl(...).

import java.time.Duration;
import java.util.concurrent.ThreadLocalRandom;

public class TtlJitter {

    static Duration withJitter(Duration base, double jitterFraction) {
        long baseMs = base.toMillis();
        long spread = (long) (baseMs * jitterFraction);
        long offset = ThreadLocalRandom.current().nextLong(-spread, spread + 1);
        return Duration.ofMillis(baseMs + offset);
    }

    public static void main(String[] args) {
        Duration base = Duration.ofMinutes(10);
        for (int i = 0; i < 3; i++) {
            Duration ttl = withJitter(base, 0.1); // +/- 10%
            System.out.println("TTL seconds: " + ttl.getSeconds());
        }
    }
}

Pencachean Dua Tingkat: Caffeine + Redis

Anda tidak perlu memilih salah satu. Corak pengeluaran yang lazim ialah cache dua tingkat (berdekatan):

  • L1 — Caffeine dalam setiap tika, TTL sangat pendek, menyerap bacaan panas pada kelajuan nanosaat.
  • L2 — Redis, dikongsi merentas kelompok, menjadi sumber kebenaran untuk keadaan cache.

Permintaan menyemak Caffeine terlebih dahulu; jika gagal, ia beralih kepada Redis; jika Redis juga gagal, ia mengakses pangkalan data. Ini mengurangkan perjalanan pergi balik rangkaian sambil mengekalkan konsistensi kelompok. Spring boleh mengarangnya dengan CompositeCacheManager atau pustaka cache berdekatan khusus.

Semakan Pantas: Memilih Strategi TTL

Uji pemahaman anda tentang pertukaran dalam cache teragih.

Rangkuman: Pencachean Teragih dengan Redis

Anda telah beralih daripada cache peribadi dalam proses kepada cache teragih yang dikongsi:

  • Mengapa Redis: satu keadaan cache merentas semua tika menghapuskan perbezaan keadaan dan kerja pendua.
  • Penukaran terus: tetapkan spring.cache.type=redis dan kod @Cacheable anda tidak berubah.
  • TTL: Redis menguatkuasakan tamat tempoh pada bahagian pelayan secara seragam merentas kelompok, dan keadaan ini kekal selepas tika dimulakan semula; tala setiap cache dengan RedisCacheManagerBuilderCustomizer.
  • Penyirilan: utamakan GenericJackson2JsonRedisSerializer untuk nilai yang boleh dibaca dan tahan terhadap perubahan versi berbanding penyirilan JDK lalai.
  • Awalan kunci mengasingkan cache yang berkongsi satu Redis; gangguan TTL dan cache dua tingkat Caffeine+Redis membantu mengawal serbuan serentak.
Percuma untuk bermula

Pelajari Java dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
21
Pelajaran
84

Soalan Lazim

Adakah pelajaran “Cache Teragih dengan Redis dan TTL” percuma?

Ya — sebanyak 3 pelajaran dalam laluan pembelajaran Panduan Lengkap Spring Boot 4, termasuk “Cache Teragih dengan Redis dan TTL”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus Panduan Lengkap Spring Boot 4 merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Cache Teragih dengan Redis dan TTL”?

Kongsi keadaan cache merentas tika menggunakan Redis sebagai bahagian belakang cache berpusat dengan kawalan pensirian. Anda berlatih Panduan Lengkap Spring Boot 4 menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Panduan Lengkap Spring Boot 4?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Panduan Lengkap Spring Boot 4 di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 3 daripada 4.

Berapa lamakah pelajaran “Cache Teragih dengan Redis dan TTL” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Panduan Lengkap Spring Boot 4 ini?

Ya. Setiap pelajaran Panduan Lengkap Spring Boot 4 menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Asas Abstraksi Cache Spring
  2. Cache Dalam Memori dengan Penalaan Caffeine
  3. Cache Teragih dengan Redis dan TTL
  4. Limpahan Cache, Pembatalan dan Ketekalan
← Kembali ke Panduan Lengkap Spring Boot 4