Heim  >  Artikel  >  Datenbank  >  Analysieren Sie Hotkey-Speicherprobleme in Redis und sprechen Sie über Lösungen für Cache-Ausnahmen

Analysieren Sie Hotkey-Speicherprobleme in Redis und sprechen Sie über Lösungen für Cache-Ausnahmen

青灯夜游
青灯夜游nach vorne
2022-05-19 10:15:553106Durchsuche

In diesem Artikel geht es um drei häufige Cache-Anomalien in Redis: Cache-Penetration, Cache-Aufschlüsselung und Cache-Lawine. Ich hoffe, dass es für alle hilfreich ist.

Analysieren Sie Hotkey-Speicherprobleme in Redis und sprechen Sie über Lösungen für Cache-Ausnahmen

Verwandte Empfehlungen: „Lassen Sie uns gemeinsam die Redis-Cache-Konsistenz, Cache-Penetration, Cache-Aufschlüsselung und Cache-Lawine-Probleme analysieren

Cache-Penetration, Cache-Aufschlüsselung und Cache-Lawine sind Redis-Interviews und tatsächlich Während der Entwicklung ist dies der Fall ist eine Frage, die oft berücksichtigt werden muss. Viele Menschen sind sich immer noch nicht im Klaren über den Ursprung, die Ursache und die Lösung dieses Problems. Tatsächlich können wir für diese drei Situationen eine gute Lösung finden, indem wir das generierte Prinzip sorgfältig analysieren. [Verwandte Empfehlungen: Redis-Video-Tutorial]

Dieser Artikel hilft Ihnen, diese drei Probleme anhand von Definitionen, Fällen, Gefahren und Lösungen schnell zu verstehen.

Ich glaube, Sie haben im Internet viele Lösungen für diese drei Probleme gesehen. Sind einige davon richtige Lösungen? In diesem Artikel werden auch die Vor- und Nachteile solcher Lösungen einzeln analysiert. 正确的方案呢?本文也将一一分析此类方案的优缺点。

下图为本文的内容大纲,文章也是围绕这几点进行分析与总结。

Analysieren Sie Hotkey-Speicherprobleme in Redis und sprechen Sie über Lösungen für Cache-Ausnahmen

三者比较

  • 缓存穿透、缓存击穿和缓存雪崩都是因为缓存中数据不存在,导致走数据库去查询数据。

  • 由于缓存数据不存在,所有的请求都会走到数据库,因此会导致数据库的压力过大甚至出现服务崩溃,导致整个系统无法使用。

缓存穿透

定义:缓存穿透是由于客户端求的数据在缓存中不存在,然后去查询数据库,然而数据库没有客户端要查询的数据,导致每一次请求都会走数据库查询操作。真正的问题在于该数据本身就是不存在的

举例:客户端请求商品详情信息时,携带一个商品ID,此时该商品ID是不存在的(不管是缓存中还是数据库中)。导致每一次请求该ID商品的数据信息都会走数据库。

危害:由于请求的参数对应的数据根本不存在,会导致每一次都会请求数据库,增加数据库的压力或者服务崩溃,更有甚至影响到其他的业务模块。经常发生在用户恶意请求的情况下会发生。

解决方案:

1、根据请求的参数缓存一个null值。并且为该值设置一个过期时间,可以将时间设置短暂一点。

2、使用布隆过滤器,首先通过布隆过滤器进行筛选,如果在过滤器中存在则去查询数据库,然后添加到缓存中。如果不存在则直接返回客户端数据不存在。

3、由于缓存穿透可能是用户发起恶意请求,可以将用户ip给记录下来,针对恶意的ip请求进行封禁。

方案分析:

  • 第一种方案,针对不存在的key,会缓存一个空的值。假设这样的请求特别多,是否都会一一去设置一个空值的缓存,此时Redis中就存在大量无效的缓存空值。假设这样的key是商品或者文章类的ID,我们在设置空值之后,如果后台添加数据应该去更新ID对应的缓存值,并设置一个合理的过期时间。

  • 第二种方案,也是业界使用最多的一种方案。布隆过滤器的优点在于基于Redis实现,内存操作并且底层的实现也是非常节约内存。 当后台添加数据成功时,将该数据的ID添加到布隆过滤器中,前端在请求时先走布隆过滤器进行验证是否存在。但布隆过滤器也存在一个弊端,就是hash冲突问题。这里的hash冲突是什么意思呢?就是说多个ID在进行hash计算时,得到的hash位都是同一个值,这就导致在验证是否存在时误判。本身是有的,得到的结果是没有。布隆过滤器的一个弊端就是,它说有并不一定有,它说没有就一点是没有的。

    Das Bild unten zeigt die Gliederung dieses Artikels. Der Artikel analysiert und fasst auch diese Punkte zusammen.
  • Analysieren Sie Hotkey-Speicherprobleme in Redis und sprechen Sie über Lösungen für Cache-Ausnahmen

  • Vergleich der drei

    Cache-Penetration, Cache-Zusammenbruch und Cache-Lawine werden alle dadurch verursacht, dass die Daten im Cache nicht vorhanden sind, was dazu führt, dass die Datenbank zum Abfragen der Daten verwendet wird.

    Da die zwischengespeicherten Daten nicht vorhanden sind, werden alle Anfragen an die Datenbank gesendet, was zu einer übermäßigen Belastung der Datenbank oder sogar zu einem Dienstabsturz führt, wodurch das gesamte System unbrauchbar wird. 🎜🎜🎜

    🎜Cache-Penetration🎜

    🎜Definition: Cache-Penetration liegt daran, dass sich die vom Client angeforderten Daten nicht im Cache befinden existiert und fragt dann die Datenbank ab. Die Datenbank verfügt jedoch nicht über die Daten, die der Client abfragen möchte, was dazu führt, dass jede Anfrage einen Datenbankabfragevorgang durchläuft. Das eigentliche Problem ist, dass die Daten selbst nicht existieren. 🎜🎜Beispiel: Wenn der Kunde Produktdetails anfordert, trägt er eine Produkt-ID. Zu diesem Zeitpunkt ist die Produkt-ID nicht vorhanden (weder im Cache noch in der Datenbank). Daher werden die Daten des Produkts mit dieser ID jedes Mal, wenn sie angefordert werden, in die Datenbank übernommen. 🎜🎜Gefahren: Da die den angeforderten Parametern entsprechenden Daten überhaupt nicht vorhanden sind, wird die Datenbank jedes Mal angefordert, was den Druck auf die Datenbank erhöht oder den Dienst abstürzt und sogar andere Geschäftsmodule beeinträchtigt. Dies geschieht häufig, wenn Benutzer böswillige Anfragen stellen. 🎜🎜🎜Lösung: 🎜🎜🎜1. Cachen Sie einen Nullwert basierend auf den angeforderten Parametern. Und legen Sie eine Ablaufzeit für diesen Wert fest. Sie können die Zeit auch kürzer einstellen. 🎜🎜2. Verwenden Sie den Bloom-Filter. Wenn er im Filter vorhanden ist, fragen Sie ihn ab und fügen Sie ihn dann dem Cache hinzu. Wenn sie nicht vorhanden sind, wird direkt zurückgegeben, dass die Clientdaten nicht vorhanden sind. 🎜🎜3. Da das Eindringen in den Cache durch Benutzer verursacht werden kann, die böswillige Anfragen initiieren, kann die Benutzer-IP aufgezeichnet und böswillige IP-Anfragen blockiert werden. 🎜🎜🎜 Lösungsanalyse: 🎜🎜
      🎜🎜Die erste Lösung speichert einen leeren Wert für einen nicht vorhandenen Schlüssel zwischen. Angenommen, es gibt zu viele solcher Anfragen. Werden sie alle nacheinander einen Cache mit Nullwerten festlegen? Zu diesem Zeitpunkt gibt es in Redis eine große Anzahl ungültiger Cache-Nullwerte. Unter der Annahme, dass ein solcher Schlüssel die ID eines Produkts oder Artikels ist, sollten wir nach dem Festlegen des Nullwerts, wenn Daten im Hintergrund hinzugefügt werden, den der ID entsprechenden Cache-Wert aktualisieren und eine angemessene Ablaufzeit festlegen. 🎜🎜🎜🎜Die zweite Lösung ist auch die am häufigsten verwendete Lösung in der Branche. Der Vorteil des Bloom-Filters besteht darin, dass er auf der Redis-Implementierung und dem Speicherbetrieb basiert und die zugrunde liegende Implementierung auch sehr speichersparend ist. Wenn Daten im Hintergrund erfolgreich hinzugefügt werden, wird die ID der Daten zum Bloom-Filter hinzugefügt, und das Frontend durchläuft bei der Anforderung zunächst den Bloom-Filter, um zu überprüfen, ob er vorhanden ist. Aber Bloom-Filter haben auch einen Nachteil, nämlich das Problem des Hash-Konflikts. Was bedeutet hier der Hash-Konflikt? Das heißt, wenn mehrere IDs gehasht werden, haben die erhaltenen Hash-Bits denselben Wert, was zu Fehleinschätzungen bei der Überprüfung ihrer Existenz führt. Es ist etwas an sich, aber das Ergebnis enthält nichts. Einer der Nachteile des Bloom-Filters besteht darin, dass er nicht unbedingt existiert, wenn er sagt, dass er existiert, und dass er bedeutet, dass er nicht existiert, wenn er nicht existiert. 🎜🎜🎜🎜Die dritte Möglichkeit besteht darin, innerhalb eines bestimmten Zeitraums eine große Anzahl von Anfragen für denselben Benutzer zu initiieren und so den Cache-Penetrationsmechanismus auszulösen. Zu diesem Zeitpunkt können wir den Zugriff des Clients anzeigen. Wenn der Angreifer jedoch einen DDOS-Angriff startet, kann er solche Angriffe nicht vollständig vermeiden, sodass diese Lösung keine gute Lösung ist. 🎜🎜🎜🎜🎜 Zusammenfassung des Plans: 🎜🎜
      • Wir fügen zunächst die dritte Lösung auf Anforderungsebene hinzu und erstellen einen aktuellen Begrenzungsmechanismus und einen IP-Blacklist-Mechanismus, um einige böswillige Anforderungen zu kontrollieren. Bei Fehleinschätzungen können wir Vorgänge wie die IP-Entsperrung implementieren. Die Cache-Schicht wird mit der ersten Lösung implementiert. Legen Sie eine angemessene Cache-Zeit fest.

      • Für Geschäftsszenarien, die Fehleinschätzungen tolerieren können, können Sie direkt die zweite Lösung verwenden. Vollständig auf Redis basierend, wodurch die Systemkomplexität reduziert wird.

      Cache-Ausfall

      Definition: Ein Cache-Ausfall liegt daran, dass kein Hotspot-Schlüssel vorhanden ist, was zu einer Datenbankabfrage führt. Erhöhter Druck auf die Datenbank. Dieser Druck kann vorübergehend oder länger anhaltend sein. 真正的问题在于该key是存在,只是缓存中不存在,导致走数据库操作.

      Zum Beispiel: Es gibt ein beliebtes Produkt. Wenn Benutzer Produktdetails anzeigen, tragen sie die Produkt-ID, um Produktdetails zu erhalten. Zu diesem Zeitpunkt sind die Daten im Cache abgelaufen, sodass alle eingehenden Anforderungen zur Abfrage an die Datenbank gesendet werden müssen.

      Gefahren: Im Vergleich zur Cache-Penetration sind die Daten in der Datenbank vorhanden, aber da der Cache abgelaufen ist, müssen sie einmal in die Datenbank gehen und dann dem Cache hinzugefügt werden, und die nächste Anfrage kann in den Cache gehen normalerweise. Der sogenannte Schaden richtet sich auch auf die Datenbankebene.

      Lösung:

      1. Fügen Sie eine Mutex-Sperre hinzu. Bei der ersten Anfrage wurde festgestellt, dass sich keine Daten im Cache befanden. Zu diesem Zeitpunkt wurde die Abfragedatenbank zum Cache hinzugefügt. Auf diese Weise müssen nachfolgende Anfragen keine Datenbankabfragen durchlaufen.

      2. Erhöhen Sie die Ablaufzeit der Geschäftslogik. Beim Einrichten des Caches können wir eine Cache-Ablaufzeit hinzufügen. Treffen Sie bei jedem Lesen eine Beurteilung. Wenn die Ablaufzeit kürzer als die aktuelle Zeit ist, lösen Sie einen Hintergrundthread aus, rufen Sie die Daten ab und aktualisieren Sie dann die zwischengespeicherten Daten und die zwischengespeicherte Ablaufzeit. Tatsächlich besteht das Prinzip darin, die Cache-Dauer für den Cache auf Codeebene zu verlängern.

      3. Datenaufwärmen. Implementieren Sie das Hinzufügen von Daten zum Cache über den Hintergrund. Bevor beispielsweise die Flash-Sale-Szene beginnt, wird der Bestand des Produkts dem Cache hinzugefügt, sodass er bei einer Benutzeranfrage direkt in den Cache verschoben wird.

      4. Läuft nie ab. Wenn Sie eine Ablaufzeit für den Cache festlegen, achten Sie darauf, dass dieser niemals abläuft. Im Hintergrund wird ein separater Thread geöffnet, um die Ablaufzeit und Datenaktualisierungen dieser Caches aufrechtzuerhalten.

      Projektanalyse:

      • Die Mutex-Sperre stellt sicher, dass nur eine Anfrage an die Datenbank geht, was ein Vorteil ist. Bei verteilten Systemen werden jedoch verteilte Sperren verwendet, um verteilte Sperren zu implementieren. Die Implementierung verteilter Sperren selbst weist gewisse Schwierigkeiten auf, was die Komplexität des Systems erhöht.

      • Die zweite Lösung wird durch die Verwendung von Redis implementiert, um Ablauf und Geschäftsablauf zu verhindern. Dadurch wird sichergestellt, dass bei jeder Anfrage Daten abgerufen werden können und auch ein Hintergrundthread zur Aktualisierung der Daten genutzt werden kann. Der Nachteil besteht darin, dass der Hintergrundthread die Aktualisierung der Daten zu diesem Zeitpunkt noch nicht abgeschlossen hat. Bei den angeforderten Daten handelt es sich um alte Daten, was in Geschäftsszenarien mit hohen Echtzeitanforderungen Nachteile haben kann.

      • Die dritte Lösung besteht darin, bei jedem Laden die Cache-Vorwärmung und den Cache zu verwenden, was der zweiten Lösung ähnelt. Allerdings besteht auch das Problem der Hot-Data-Aktualisierung, sodass diese Lösung für Daten geeignet ist, die keine hohen Echtzeitdaten erfordern.

      • Die vierte Lösung ähnelt der zweiten und dritten Lösung. Auf dieser Grundlage wurden bestimmte Optimierungen vorgenommen, indem asynchrone Hintergrundthreads verwendet werden, um zwischengespeicherte Daten aktiv zu aktualisieren. Die Schwierigkeit besteht darin, die Häufigkeit der Aktualisierungen zu kontrollieren.

      Zusammenfassung der Lösung:

      • Für Daten mit hohen Echtzeitanforderungen wird empfohlen, die erste Lösung zu verwenden. Obwohl sie technisch schwierig ist, kann damit eine Echtzeitverarbeitung der Daten erreicht werden. Wenn einige Anfragen lange warten, kann eine Ausnahme zurückgegeben werden und der Client kann die Anfrage erneut senden.

      • Für Daten, die keine hohe Echtzeitleistung erfordern, können Sie die vierte Option verwenden.

      Cache-Lawine

      Definition: Wie bereits erwähnt, liegt ein Cache-Ausfall daran, dass ein bestimmter Hotkey im Cache fehlschlägt, was dazu führt, dass eine große Anzahl von Anfragen an die Datenbank gesendet wird. Die Cache-Lawine ist jedoch tatsächlich dieselbe, aber diese ist schwerwiegender. Die meisten zwischengespeicherten Schlüssel sind ungültig und nicht ein oder zwei Schlüssel.

      Beispiel: In einem E-Commerce-System sind die Produktdaten einer bestimmten Kategorie im Cache ungültig. Allerdings beziehen sich viele Anfragen des aktuellen Systems auf Produktdaten in dieser Kategorie. Dies führt dazu, dass alle Anfragen Datenbankabfragen durchlaufen.

      Gefahren: Aufgrund des gleichzeitigen Zustroms einer großen Anzahl von Anfragen muss jede Anfrage in der Datenbank abgefragt werden. Der unmittelbare Zufluss von Datenverkehr in die Datenbank erhöht die Belastung der Datenbank erheblich und kann leicht zu einer direkten Datenbanklähmung führen.

      Lösung:

      1. Die Cache-Zeit ist zufällig. Da eine große Anzahl von Caches zu einem bestimmten Zeitpunkt abläuft, bedeutet dies, dass die Cache-Ablaufzeit relativ konzentriert ist. Wir stellen die Ablaufzeit direkt auf unkonzentriert und zufällig ein. Auf diese Weise wird die Cache-Ablaufzeit nicht sehr konzentriert und es wird nicht gleichzeitig eine große Anzahl von Abfragevorgängen an die Datenbank gesendet.

      2. Mehrstufiger Cache. Anstatt sich beim Caching einfach auf Redis zu verlassen, können wir auch memcached zum Caching verwenden (hier nur ein Beispiel, es können auch andere Caching-Dienste verwendet werden). Erstellen Sie beim Zwischenspeichern von Daten einen Cache für Redis und einen Cache für Memcached. Wenn Redis fehlschlägt, können wir Memcached verwenden.

      3. Mutex-Sperre. Bei der Cache-Aufschlüsselung haben wir die Verwendung von Mutex-Sperren erwähnt, und wir können sie auch im Falle einer Lawine verwenden.

      4. Ablaufflag setzen. Tatsächlich können Sie auch die in der Cache-Aufschlüsselung erwähnte permanente Nicht-Ablaufzeit verwenden. Bei der Anforderung wird die Ablaufzeit ermittelt. Wenn die Ablaufzeit naht, wird ein Ablaufflag gesetzt und ein unabhängiger Thread zur Aktualisierung des Caches ausgelöst.

      Projektanalyse:

      • Die erste Lösung verwendet Zufallszahlen-Cache-Zeit, um sicherzustellen, dass die Schlüsselablaufzeit verteilt wird. Die Schwierigkeit besteht darin, die Cache-Zeit festzulegen. Für einige Daten, die eine kurze Cache-Zeit und eine sehr große Datenmenge erfordern, erfordert diese Lösung eine angemessene Kontrolle der Zeit.

      • Die zweite Lösung verwendet einen mehrstufigen Cache, der sicherstellen kann, dass alle Anfragen zwischengespeichert werden. Dies erhöht jedoch die architektonische Schwierigkeit des Systems und verschiedene andere Probleme, wie z. B. das Zwischenspeichern mehrstufiger Aktualisierungen.

      • Die dritte Lösung verwendet Mutex-Sperren. Wir haben Mutex-Sperren in der Cache-Aufschlüsselung erwähnt. Obwohl wir sie in Lawinenszenarien verwenden können, wird dies eine große Anzahl verteilter Sperren erzeugen.

      • Die vierte Lösung verwendet logische Cache-Zeit, die den Cache-Druck des Systems gut garantiert.

      Zusammenfassung des Plans:

      In tatsächlichen Projekten wird empfohlen, den 1., 2. und 4. Plan zum Ausprobieren zu verwenden, was besser ist.

      Zusammenfassung

      • Die Cache-Penetration ist darauf zurückzuführen, dass die Datenbank selbst nicht über die Daten verfügt.

      • Cache-Aufschlüsselung und Cache-Lawine bedeuten, dass die Daten in der Datenbank vorhanden sind, die Daten im Cache jedoch ungültig sind, was dazu führt, dass die Datenbank erneut abgefragt und dann dem Cache hinzugefügt wird.

      • Cache-Ausfall tritt bei einigen Hotkeys auf, während Cache-Avalanche ein großflächiger Cache-Fehler ist. Die beiden Prinzipien sind eigentlich gleich, außer dass die Aufteilung der Cache-Schlüssel unterschiedlich ist.

      Weitere Kenntnisse zum Thema Programmierung finden Sie unter: Einführung in die Programmierung! !

    Das obige ist der detaillierte Inhalt vonAnalysieren Sie Hotkey-Speicherprobleme in Redis und sprechen Sie über Lösungen für Cache-Ausnahmen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

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