Heim  >  Artikel  >  Java  >  So implementieren Sie den mehrstufigen Redis-Cache basierend auf Java

So implementieren Sie den mehrstufigen Redis-Cache basierend auf Java

WBOY
WBOYnach vorne
2023-05-13 19:52:17967Durchsuche

1. Mehrstufiges Caching

Nachdem die Anfrage Tomcat erreicht hat, geht sie zuerst an Redis, um den Cache abzurufen. Wenn dies fehlschlägt, geht sie an MySQL, um ihn abzurufen. Mehrstufiges Caching-Schema

So implementieren Sie den mehrstufigen Redis-Cache basierend auf Java Die Anzahl gleichzeitiger Anforderungen ist viel geringer als bei Redis, sodass Tomcat zu einem Engpass wird

    Verwenden Sie jeden Link der Anforderungsverarbeitung, um Cache hinzuzufügen bzw. den Druck auf Tomcat zu verringern Verbessern Sie die Serviceleistung
  • tomcat

  • 2. Lokaler JVM-Cache

  • Der Cache wird im Speicher gespeichert und die Datenlesegeschwindigkeit ist hoch, was den Zugriff auf die Datenbank erheblich reduzieren und den Druck auf die Datenbank verringern kann

So implementieren Sie den mehrstufigen Redis-Cache basierend auf JavaVerteilter Cache wie Redis

– Vorteile: Große Speicherkapazität, gute Zuverlässigkeit, kann im Cluster gemeinsam genutzt werden

– Nachteile: Es entsteht Netzwerk-Overhead für den Zugriff auf den Cache

– Szenario: Große Menge an zwischengespeicherten Daten, hoch Zuverlässigkeit, Daten, die im Cluster gemeinsam genutzt werden müssen

Lokalen Cache verarbeiten, z. B. HashMap, GuavaCache
- Vorteile: Lesen des lokalen Speichers, kein Netzwerk-Overhead, schneller
- Nachteile: begrenzte Speicherkapazität, geringe Zuverlässigkeit (z. B verloren nach dem Neustart), kann nicht im Cluster geteilt werden
- Szenario: hohe Leistungsanforderungen, kleine Menge zwischengespeicherter Daten

1 Praktischer Fall




Caffeine ist eine leistungsstarke lokale Cache-Bibliothek, die auf Basis von Java8 entwickelt wurde Nahezu optimale Trefferquote

Dies wird derzeit für den internen Cache von Spring verwendet
  • <dependency>
         <groupId>com.github.ben-manes.caffeine</groupId>
         <artifactId>caffeine</artifactId>
         <version>3.0.5</version>
     </dependency>
    package com.erick.cache;
    
    import com.github.benmanes.caffeine.cache.Cache;
    import com.github.benmanes.caffeine.cache.Caffeine;
    
    import java.time.Duration;
    
    public final class CacheUtil {
        private static int expireSeconds = 2;
        public static Cache<String, String> cacheWithExpireSeconds;
    
        private static int maxPairs = 1;
        public static Cache<String, String> cacheWithMaxPairs;
    
        static {
            /*过期策略,写完60s后过期*/
            cacheWithExpireSeconds = Caffeine.newBuilder()
                    .expireAfterWrite(Duration.ofSeconds(expireSeconds))
                    .build();
    
            /*过期策略,达到最大值后删除
             * 1. 并不会立即删除,等一会儿才会删除
             * 2. 会将之前存储的数据删除掉*/
            cacheWithMaxPairs = Caffeine.newBuilder()
                    .maximumSize(maxPairs)
                    .build();
        }
    
        /*从缓存中获取数据
         * 1. 如果缓存中有,则直接从缓存中返回
         * 2. 如果缓存中没有,则去数据查询并返回结果*/
        public static String getKeyWithExpire(String key) {
            return cacheWithExpireSeconds.get(key, value -> {
                return getResultFromDB();
            });
        }
    
        public static String getKeyWithMaxPair(String key) {
            return cacheWithMaxPairs.get(key, value -> {
                return getResultFromDB();
            });
        }
    
        private static String getResultFromDB() {
            System.out.println("数据库查询");
            return "db result";
        }
    }
    package com.erick.cache;
    
    import java.util.concurrent.TimeUnit;
    
    public class Test {
    
        @org.junit.Test
        public void test01() throws InterruptedException {
            CacheUtil.cacheWithExpireSeconds.put("name", "erick");
            System.out.println(CacheUtil.getKeyWithExpire("name"));
            TimeUnit.SECONDS.sleep(3);
            System.out.println(CacheUtil.getKeyWithExpire("name"));
        }
    
        @org.junit.Test
        public void test02() throws InterruptedException {
            CacheUtil.cacheWithMaxPairs.put("name", "erick");
            CacheUtil.cacheWithMaxPairs.put("age", "12");
    
            System.out.println(CacheUtil.getKeyWithMaxPair("name"));
            System.out.println(CacheUtil.getKeyWithMaxPair("age"));
    
            TimeUnit.SECONDS.sleep(2);
    
            System.out.println(CacheUtil.getKeyWithMaxPair("name")); // 查询不到了
            System.out.println(CacheUtil.getKeyWithMaxPair("age"));
        }
    }

    3. Cache-Konsistenzeigenschaften
  • 1. Gängige Lösungen

    1.1 Gültigkeitszeitraum festlegen

Gültigkeitszeitraum festlegen den Cache und löscht ihn nach Ablauf automatisch. Es kann bei einer erneuten Abfrage aktualisiert werden.

Vorteile: Einfach und bequem 1.2 Synchrones doppeltes Schreiben Cache-Daten mit hohen Anforderungen an Konsistenz und Ungültigkeit
  • 1.3 Asynchrone Benachrichtigung
  • Senden Sie Ereignisbenachrichtigungen, wenn die Datenbank geändert wird, und relevante Dienste ändern die zwischengespeicherten Daten nach dem Abhören
  • Vorteile: geringe Kopplung, kann sein Gleichzeitig benachrichtigt Mehrere Cache-Dienste
  • Nachteile: Aktualität, es können Probleme mit der Cache-Inkonsistenz auftreten
Szenario: Aktualität ist durchschnittlich, es gibt mehrere Dienste, die synchronisiert werden müssen
  • 2. Basierend auf Canal Die asynchrone Benachrichtigung

  • ist ein Open-Source-Projekt unter Alibaba, das auf Java basiert.

Basiert auf einer inkrementellen Datenbankprotokollanalyse und bietet inkrementelles Datenabonnement und -verbrauch der Master-Slave-Sicherung von MySQL
  • 2.1 MySQL-Master-Slave-Replikation

  • 2.2-Kanal-Funktionsprinzip

  • Kanal simuliert das Interaktionsprotokoll des MySQL-Slaves, tarnt sich als MySQL-Slave und sendet ein Dump-Protokoll an MySQL-Master

  • MySQL-Master erhält Dump-Anfrage, beginnt mit der Übertragung des Binärprotokolls an den Slave (d. h. Kanal)

Kanal analysiert das Binärprotokollobjekt (ursprünglich ein Byte-Stream)So implementieren Sie den mehrstufigen Redis-Cache basierend auf Java

Das obige ist der detaillierte Inhalt vonSo implementieren Sie den mehrstufigen Redis-Cache basierend auf Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen