Heim > Datenbank > Redis > Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

青灯夜游
Freigeben: 2021-09-17 11:22:04
nach vorne
8457 Leute haben es durchsucht

Golden Nine und Silver Ten erscheinen bald. Dieser Artikel wird Ihnen 20 Redisklassische Interviewfragen vorstellen.

Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

1. Was ist Redis? Wofür wird es hauptsächlich verwendet?

Redis, der vollständige englische Name lautet Remote Dictionary Server (Remote Dictionary Service), ist eine Open-Source-Protokolltyp-Schlüsselwertdatenbank, die in ANSI C-Sprache geschrieben ist, das Netzwerk unterstützt, speicherbasiert sein kann und kann kann beibehalten werden und bietet eine API in mehreren Sprachen. [Verwandte Empfehlungen: Redis-Video-Tutorial]

Anders als bei der MySQL-Datenbank werden Redis-Daten im Speicher gespeichert. Seine Lese- und Schreibgeschwindigkeiten sind sehr hoch und können mehr als 100.000 Lese- und Schreibvorgänge pro Sekunde bewältigen. Daher wird Redis häufig beim Caching verwendet. Darüber hinaus wird Redis auch häufig für verteilte Sperren verwendet. Darüber hinaus unterstützt Redis Transaktionen, Persistenz, LUA-Skripte, LRU-gesteuerte Ereignisse und verschiedene Clusterlösungen.

2. Lassen Sie uns über die grundlegenden Datenstrukturtypen von Redis sprechen. Die meisten Freunde wissen, dass Redis die folgenden fünf Grundtypen hat:

String (String)

Hash (Hash)

    List (Liste)
  • Set (Satz)
  • zset (geordneter Satz)
  • Es gibt außerdem drei spezielle Datenstrukturtypen:
  • Geospatial

Hyperloglog

    Bitmap
  • 2.1 Fünf grundlegende Datentypen von Redis

String ( string)

Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)Einführung: String ist der grundlegendste Datenstrukturtyp von Redis. Er ist binärsicher und kann Bilder oder serialisierte Objekte speichern. Der maximale gespeicherte Wert beträgt 512 MB. Einfaches Anwendungsbeispiel: Schlüsselwert festlegencode>, <code>get key usw.

Anwendungsszenarien: gemeinsame Sitzung, verteilte Sperre, Zähler, aktuelles Limit.

    Es gibt 3 Arten der internen Codierung: int (8-Byte lange Ganzzahl)/embstr (kleiner oder gleich 39-Byte-String)/raw (größer als 39-Byte-String)
  • C Die Sprachzeichenfolge wird durch char[] implementiert und Redis verwendet die Kapselung set key valueget key
  • 应用场景:共享session、分布式锁,计数器、限流。
  • 内部编码有3种,int(8字节长整型)/embstr(小于等于39字节字符串)/raw(大于39个字节字符串)

C语言的字符串是char[]实现的,而Redis使用SDS(simple dynamic string) 封装,sds源码如下:

struct sdshdr{
  unsigned int len; // 标记buf的长度
  unsigned int free; //标记buf中未使用的元素个数
  char buf[]; // 存放元素的坑
}
Nach dem Login kopieren

SDS 结构图如下:

Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

Redis为什么选择SDS结构,而C语言原生的 char[]不香吗?

举例其中一点,SDS中,O(1)时间复杂度,就可以获取字符串长度;而C 字符串,需要遍历整个字符串,时间复杂度为O(n)

Hash(哈希)

  • 简介:在Redis中,哈希类型是指v(值)本身又是一个键值对(k-v)结构
  • 简单使用举例:hset key field valuehget key field
  • 内部编码:ziplist(压缩列表)hashtable(哈希表)
  • 应用场景:缓存用户信息等。
  • 注意点:如果开发使用hgetall,哈希元素比较多的话,可能导致Redis阻塞,可以使用hscan。而如果只是获取部分field,建议使用hmget。

字符串和哈希类型对比如下图:

Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

List(列表)

  • 简介:列表(list)类型是用来存储多个有序的字符串,一个列表最多可以存储2^32-1个元素。
  • 简单实用举例: lpush key value [value ...]lrange key start endSDS (einfache dynamische Zeichenfolge)
  • Der SDS-Quellcode lautet wie folgt:
  • zadd user:ranking:2021-03-03 Jay 3
    Nach dem Login kopieren
    Nach dem Login kopieren
  • SDS-Strukturdiagramm lautet wie folgt:
  • Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

Warum Hat Redis die

SDS

-Struktur gewählt? Und ist das native char[] der C-Sprache nicht gut? Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

Zum Beispiel kann in SDS die Länge des Strings mit der Zeitkomplexität O(1) ermittelt werden, während für C-Strings der gesamte String durchlaufen werden muss und die Zeitkomplexität O(n) beträgt

< h4 data- id="heading-5">Hash (Hash)
  • Einführung: In Redis bezieht sich der Hash-Typ auf v (Wert) selbst, der auch eine Schlüssel-Wert-Paar-Struktur (k-v) ist
  • Einfaches Anwendungsbeispiel : hset key field value, hget key field
  • Interne Codierung: ziplist (komprimierte Liste), hashtable (Hash-Tabelle)< /code ><li></li>Anwendungsszenarien: Zwischenspeichern von Benutzerinformationen usw. </ul></blockquote><h4 data-id="heading-7">Hinweis</h4>: Wenn hgetall in der Entwicklung verwendet wird und viele Hash-Elemente vorhanden sind, kann dies dazu führen, dass Redis blockiert. Sie können hscan verwenden. Wenn Sie nur einige Felder abrufen möchten, empfiehlt sich die Verwendung von hmget. <p><img src="https://img.php.cn/upload/image/656/664/457/1631501863989751.png" title="1631501863989751.png" alt="Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)"/></p>Der Vergleich zwischen String- und Hash-Typen ist wie folgt: 🎜🎜<img src="https://img.php.cn/upload/image/984/524/946/16315018485778Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)" title="1631501848577830 .png " alt="Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)"/>🎜<h4 data-id="heading-6">Liste (Liste)🎜🎜🎜Einführung: Der Listentyp (Liste) wird zum Speichern mehrerer geordneter Zeichenfolgen verwendet, einer Liste kann bis zu 2^32-1 Elemente speichern. 🎜🎜Einfache und praktische Beispiele: <code> lpush key value [value ...], lrange key start end🎜🎜Interne Codierung: ziplist (komprimierte Liste), linkedlist (verknüpfte Liste). )🎜 🎜Anwendungsszenarien: Nachrichtenwarteschlange, Artikelliste, 🎜🎜🎜Ein Bild zum Verständnis des Einfügens und Popups des Listentyps: 🎜🎜🎜🎜🎜Listenanwendungsszenarien beziehen sich auf Folgendes: 🎜🎜🎜🎜lpush+lpop= Stack (Stack)🎜🎜lpush +rpop=Queue (Warteschlange)🎜🎜lpsh+ltrim=Capped Collection (begrenzte Sammlung)🎜🎜lpush+brpop=Message Queue (Nachrichtenwarteschlange)🎜🎜🎜🎜Set (Set)🎜🎜🎜🎜
    • Einführung: Der Set-Typ wird auch zum Speichern mehrerer Zeichenfolgenelemente verwendet, doppelte Elemente sind jedoch nicht zulässig.
    • Einfaches Anwendungsbeispiel: sadd key element [element ...], smembers key sadd key element [element ...]smembers key
    • 内部编码:intset(整数集合)hashtable(哈希表)
    • 注意点:smembers和lrange、hgetall都属于比较重的命令,如果元素过多存在阻塞Redis的可能性,可以使用sscan来完成。
    • 应用场景: 用户标签,生成随机数抽奖、社交需求。

    有序集合(zset)

    • 简介:已排序的字符串集合,同时元素不能重复
    • 简单格式举例:zadd key score member [score member ...]zrank key member
    • 底层内部编码:ziplist(压缩列表)skiplist(跳跃表)
    • Interne Kodierung: intset (ganzzahlige Menge), hashtable (Hash-Tabelle)
    • Hinweise: smembers, lrange und Bei hgetall handelt es sich um relativ umfangreiche Befehle. Wenn zu viele Elemente vorhanden sind und die Möglichkeit besteht, dass Redis blockiert wird, können Sie dies mit sscan vervollständigen.

    Anwendungsszenarien: Benutzer-Tags, Generierung von Zufallszahlenlotterien, soziale Bedürfnisse.

      Ordered set (zset)
    • Einführung: eine sortierte String-Sammlung, und die Elemente können nicht wiederholt werden
    • Einfaches Formatbeispiel: zadd key score member [ Score Mitglied ...], zrank-Schlüsselmitglied
    Zugrunde liegende interne Codierung: ziplist (komprimierte Liste), skiplist (Überspringliste)</code > Code><h2 data-id="heading-10"></h2>Anwendungsszenarien: Rankings, soziale Bedürfnisse (z. B. Benutzer-Likes). <p><img src="https://img.php.cn/upload/image/701/100/216/1631501869718890.png" title="1631501869718890.png" alt="Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)"/></p>2.2 Drei spezielle Datentypen von Redis<h3 data-id="heading-11"></h3><p>Geo: Die von Redis3.2 eingeführte geografische Standortpositionierung wird zum Speichern geografischer Standortinformationen und zum Bearbeiten der gespeicherten Informationen verwendet. </p><h3 data-id="heading-12">HyperLogLog: Eine Datenstruktur, die für statistische Kardinalitätsalgorithmen verwendet wird, wie z. B. UV für statistische Websites. </h3><p>Bitmaps: Verwenden Sie ein Bit, um den Status eines Elements abzubilden. In Redis basiert die unterste Ebene auf dem String-Typ. Sie können Bitmaps in ein Array mit Bits als Einheit umwandeln. </p><p><img src="https://img.php.cn/upload/image/959/396/733/1631501874129651.png" title="1631501874129651.png" alt="Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)"/>3 Warum so schnell? </p><h4 data-id="heading-13"></h4><p><img src="https://img.php.cn/upload/image/879/413/599/16315018818874Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)" title="16315018818874Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)" alt="Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)"/>3.1 Implementierung basierend auf Speicherspeicherung</p><blockquote>Wir alle wissen, dass das Lesen und Schreiben im Speicher viel schneller ist als bei einer auf Speicherspeicherung basierenden Redis-Datenbank. Im Vergleich zur MySQL-Datenbank, bei der Daten auf der Festplatte gespeichert werden, werden Festplatten-I/O eingespart. O Verbrauch. <ul><li>3.2 Effiziente Datenstruktur</li><li>Wir wissen, dass der MySQL-Index zur Verbesserung der Effizienz die B+-Baumdatenstruktur wählt. Tatsächlich kann eine vernünftige Datenstruktur Ihre Anwendung/Ihr Programm schneller machen. Werfen wir zunächst einen Blick auf die Datenstruktur und das interne Codierungsdiagramm von Redis: </li><li></li><li></li>SDS einfache dynamische Zeichenfolge </ul></blockquote><h4 data-id="heading-14"></h4><p></p><h4 data-id="heading-15">Verarbeitung der Zeichenfolgenlänge: Redis erhält die Zeichenfolgenlänge, die zeitliche Komplexität beträgt O(1) , und In der C-Sprache muss es von Anfang an durchlaufen werden, und die Komplexität beträgt O(n); verbrauchen Leistung, und SDS-Änderungen und Speicherplatzerweiterungen erfordern zusätzliche Zuweisung von ungenutztem Speicherplatz, um Leistungsverluste zu reduzieren. </h4><p>Lazy Space Release: Wenn SDS gekürzt wird, wird der überschüssige Speicherplatz durch Free aufgezeichnet, und bei späteren Änderungen wird der in Free aufgezeichnete Speicherplatz direkt zur Reduzierung der Zuweisung verwendet. <img src="https://img.php.cn/upload/image/349/649/661/163150189098463Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)" title="163150189098463Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)" alt="Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)"/></p>Binäre Sicherheit: Redis kann einige Binärdaten und in der C-Sprache vorkommende Zeichenfolgen speichern.<blockquote><ul><li>String: Wenn Zahlen gespeichert werden, wird die Codierung vom Typ int verwendet. Wenn keine Zahlen gespeichert werden, wird eine Zeichenfolge kleiner oder gleich 39 Bytes verwendet. Wenn sie größer als 39 Bytes ist, wird die Rohcodierung verwendet. </li><li>Liste: Wenn die Anzahl der Elemente in der Liste weniger als 512 beträgt und der Wert jedes Elements in der Liste weniger als 64 Byte (Standard) beträgt, verwenden Sie die Ziplist-Kodierung, andernfalls verwenden Sie die Linkedlist-Kodierung. </li><li>Hash: Die Anzahl der Hash-Typ-Elemente sind kleiner als 512. Wenn alle Werte weniger als 64 Bytes sind, verwenden Sie die Ziplist-Codierung, andernfalls verwenden Sie die Hashtable-Codierung. </li><li>Set: Wenn die Elemente im Set alle ganze Zahlen sind und die Anzahl der Elemente weniger als 512 beträgt, verwenden Sie die Intset-Codierung, andernfalls verwenden Sie die Hashtable-Codierung. </li><li>Zset: Wenn die Anzahl der Elemente in der geordneten Menge weniger als 128 beträgt und der Wert jedes Elements weniger als 64 Byte beträgt, verwenden Sie die Ziplist-Codierung, andernfalls verwenden Sie die Skiplist-Codierung (Skiplist) </li></ul></blockquote><h3 data-id="heading-17">3.4 Angemessenes Threading-Modell </h3> <p> <strong>I/O-Multiplexing</strong></p><p><img src="https://img.php.cn/upload/image/222/494/553/1631501897175981.png" title="1631501897175981.png" alt="Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)"/></p><blockquote><p>Die Multiple-I/O-Multiplexing-Technologie ermöglicht es einem einzelnen Thread, mehrere Verbindungsanfragen effizient zu verarbeiten, und Redis verwendet Epoll als I/O-Multiplexing-Technologie. Darüber hinaus wandelt das eigene Ereignisverarbeitungsmodell von Redis Verbindungen, Lesevorgänge, Schreibvorgänge und Abschaltungen in Epoll in Ereignisse um, ohne zu viel Zeit mit Netzwerk-E/A zu verschwenden. </p></blockquote><p>Was ist I/O-Multiplexing? </p><blockquote><ul><li>I/O: Netzwerk-I/O</li><li>Multiple: mehrere Netzwerkverbindungen</li><li>Multiplexing: Wiederverwendung desselben Threads. </li><li>IO-Multiplexing ist eigentlich ein synchrones E/A-Modell, das einen Thread implementiert, der mehrere Dateihandles überwachen kann. Sobald ein Dateihandle bereit ist, kann es die Anwendung benachrichtigen, entsprechende Lese- und Schreibvorgänge ohne Dateihandle durchzuführen Die Anwendung wird gesperrt und die CPU wird übergeben. </li></ul></blockquote><p><strong>Single-Threaded-Modell</strong></p><ul><li>Redis ist ein Single-Threaded-Modell und Single-Threading vermeidet unnötigen CPU-Kontextwechsel und den Verbrauch von Konkurrenzsperren. Gerade weil es sich um einen einzelnen Thread handelt, führt die Ausführung eines bestimmten Befehls (z. B. des Befehls hgetall) zu einer Blockierung. Redis ist eine Datenbank für schnelle Ausführungsszenarien. Daher sollten Befehle wie smembers, lrange, hgetall usw. mit Vorsicht verwendet werden. </li><li>Redis 6.0 führt Multithreading ein, um die Geschwindigkeit zu erhöhen, und die Ausführung von Befehlen und Speicheroperationen erfolgt immer noch in einem einzelnen Thread. </li></ul><h3 data-id="heading-18">3.5 Virtueller Speichermechanismus</h3><p>Redis baut den VM-Mechanismus direkt selbst auf. Es ruft keine Systemfunktionen wie normale Systeme auf, wodurch eine gewisse Zeit beim Verschieben und Anfordern verschwendet wird. </p><p><strong>Was ist der virtuelle Speichermechanismus von Redis? </strong></p><blockquote><p>Der virtuelle Speichermechanismus verlagert Daten, auf die selten zugegriffen wird (kalte Daten), vorübergehend vom Speicher auf die Festplatte und gibt so wertvollen Speicherplatz für andere Daten frei, auf die zugegriffen werden muss (heiße Daten). Die VM-Funktion kann die Trennung von heißen und kalten Daten realisieren, sodass sich die heißen Daten noch im Speicher befinden und die kalten Daten auf der Festplatte gespeichert werden. Dadurch kann das Problem einer langsamen Zugriffsgeschwindigkeit vermieden werden, die durch unzureichenden Speicher verursacht wird. </p></blockquote><h2 data-id="heading-19">4. Was ist Cache-Aufschlüsselung, Cache-Penetration, Cache-Lawine? </h2><h3 data-id="heading-20">4.1 Cache-Penetrationsproblem</h3><p>Sehen wir uns zunächst eine gängige Methode zur Verwendung des Caches an: Wenn eine Leseanforderung eingeht, überprüfen Sie zuerst den Cache. Wenn es einen Treffer im Cache gibt, wird dieser direkt zurückgegeben Überprüfen Sie die Datenbank und stellen Sie sie dann ein. Der Wert wird im Cache aktualisiert und dann zurückgegeben. </p><p><img src="https://img.php.cn/upload/image/546/664/907/1631501902654880.png" title="1631501902654880.png" alt="1Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)"/></p><p><strong>Cache-Penetration</strong>: bezieht sich auf das Abfragen von Daten, die definitiv nicht vorhanden sind. Da der Cache nicht vorhanden ist, muss er aus der Datenbank abgefragt werden Der Cache führt dazu, dass die nicht vorhandenen Daten bei jeder Anforderung in der Datenbank abgefragt werden, was Druck auf die Datenbank ausübt. </p><blockquote><p>Um es einfach auszudrücken: Wenn auf eine Leseanforderung zugegriffen wird, haben weder der Cache noch die Datenbank einen bestimmten Wert, was dazu führt, dass jede Abfrageanforderung für diesen Wert in die Datenbank eindringt. Dies ist eine Cache-Penetration. </p></blockquote><p>Cache-Penetration wird im Allgemeinen durch die folgenden Situationen verursacht: </p><ul><li><strong>Unangemessenes Geschäftsdesign</strong> Beispielsweise haben die meisten Benutzer keinen Schutz aktiviert, aber jede von Ihnen gestellte Anfrage geht in den Cache und fragt eine bestimmte Benutzer-ID ab Sehen Sie nach, ob es einen Schutz gibt. </li><li><strong>Geschäfts-/Betriebs- und Wartungs-/Entwicklungsfehler</strong>, wie z. B. versehentliches Löschen von Cache- und Datenbankdaten. </li><li><strong>Illegaler Anforderungsangriff durch Hacker</strong> Beispielsweise fabrizieren Hacker absichtlich eine große Anzahl illegaler Anforderungen, um nicht vorhandene Geschäftsdaten zu lesen. </li></ul><p><strong>Wie vermeide ich das Eindringen in den Cache? </strong> Generell gibt es drei Methoden. </p><ul><li>1. Wenn es sich um eine illegale Anfrage handelt, überprüfen wir die Parameter am API-Eingang und filtern illegale Werte heraus. </li><li>2. Wenn die Abfragedatenbank leer ist, können wir einen Nullwert oder einen Standardwert für den Cache festlegen. Wenn jedoch eine Schreibanforderung eingeht, muss der Cache aktualisiert werden, um die Cache-Konsistenz sicherzustellen. Gleichzeitig wird schließlich die entsprechende Ablaufzeit für den Cache festgelegt. (In der Wirtschaft häufig verwendet, einfach und effektiv) </li><li>3. Verwenden Sie den Bloom-Filter, um schnell festzustellen, ob Daten vorhanden sind. Das heißt, wenn eine Abfrageanforderung eingeht, beurteilt sie zunächst mithilfe des Bloom-Filters, ob der Wert vorhanden ist, und prüft dann weiter, ob er vorhanden ist. </li></ul><blockquote><p>Bloom-Filterprinzip: Es besteht aus einem Bitmap-Array mit einem Anfangswert von 0 und N Hash-Funktionen. Führen Sie N Hash-Algorithmen für einen Schlüssel aus, um N Werte im Bitarray zu erhalten, und setzen Sie sie auf 1. Wenn dann überprüft wird, ob diese spezifischen Positionen alle 1 sind, stellt der Bloom-Filter fest, dass der Schlüssel vorhanden ist . </p></blockquote><h3 data-id="heading-21">4.2 Cache-Snowrun-Problem</h3><p><strong>Cache-Snowrun: </strong> bezieht sich auf die Ablaufzeit einer großen Datenmenge im Cache, die Abfragedaten sind riesig und die Anforderungen greifen direkt auf die Datenbank zu, was zu übermäßigem Druck auf die Datenbank führt und sogar Ausfallzeiten. </p><ul><li>Cache-Schneefall wird im Allgemeinen dadurch verursacht, dass eine große Datenmenge gleichzeitig abläuft. Aus diesem Grund kann das Problem gelöst werden, indem die Ablaufzeit gleichmäßig eingestellt wird, dh die Ablaufzeit relativ diskret gestaltet wird. Wenn Sie einen größeren Festwert + einen kleineren Zufallswert verwenden, 5 Stunden + 0 bis 1800 Sekunden. </li><li>Redis-Fehler können auch zu Cache-Schneefall führen. Dies erfordert den Aufbau eines Redis-Hochverfügbarkeitsclusters. </li></ul><h3 data-id="heading-22">4.3 Cache-Aufschlüsselungsproblem</h3><p><strong>Cache-Aufschlüsselung: </strong> bezieht sich darauf, dass der Hotspot-Schlüssel zu einem bestimmten Zeitpunkt abläuft und es zu diesem Zeitpunkt zufällig eine große Anzahl gleichzeitiger Anforderungen für diesen Schlüssel gibt, also a Eine große Anzahl von Anfragen wird auf die Datenbank übertragen. </p><p>Der Cache-Ausfall sieht ein wenig ähnlich aus. Tatsächlich besteht der Unterschied darin, dass der Cache-Absturz bedeutet, dass die Datenbank übermäßig belastet ist oder sogar ausfällt. Es kann davon ausgegangen werden, dass die Aufschlüsselung eine Teilmenge des Cache-Snowruns ist. Einige Artikel glauben, dass der Unterschied zwischen den beiden darin besteht, dass die Aufschlüsselung auf einen bestimmten Hotkey-Cache abzielt, während Xuebeng auf viele Schlüssel abzielt. </p><p>Es gibt zwei Lösungen: </p><ul><li><strong>1. Verwenden Sie das Mutex-Sperrschema</strong>. Wenn der Cache fehlschlägt, laden Sie die Datenbankdaten nicht sofort, sondern verwenden bei erfolgreicher Rückkehr zunächst einige atomare Operationsbefehle, z. B. (Setnx von Redis), um den Vorgang durchzuführen. Laden Sie bei Erfolg die Datenbankdatenbankdaten und richten Sie den Cache ein. Versuchen Sie andernfalls erneut, den Cache abzurufen. </li><li><strong>2. „Lässt nie ab“</strong> bedeutet, dass keine Ablaufzeit festgelegt ist, aber wenn die Hotspot-Daten bald ablaufen, aktualisiert der asynchrone Thread die Ablaufzeit und legt sie fest. </li></ul><h2 data-id="heading-23">5. Was ist das Hotkey-Problem und wie löst man das Hotkey-Problem</h2><p><strong>Was ist der Hotkey</strong>? In Redis bezeichnen wir Schlüssel mit hoher Zugriffshäufigkeit als Hotspot-Schlüssel. </p><p>Wenn aufgrund eines besonders großen Anforderungsvolumens eine Anfrage nach einem bestimmten Hotspot-Schlüssel an den Server-Host gesendet wird, kann dies zu unzureichenden Host-Ressourcen oder sogar Ausfallzeiten führen und somit die normalen Dienste beeinträchtigen. </p><p><img src="https://img.php.cn/upload/image/681/859/235/163150190722212Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)" title="163150190722212Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)" alt="1Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)"/></p><p>Und wie wird der Hotspot-Schlüssel generiert? Dafür gibt es zwei Hauptgründe: </p><blockquote><ul><li>Die von den Benutzern verbrauchten Daten sind viel größer als die produzierten Daten, wie z. B. Flash-Sales, aktuelle Nachrichten und andere Szenarien, in denen mehr gelesen und weniger geschrieben wird. </li><li>Das Anforderungs-Sharding ist konzentriert, was die Leistung eines einzelnen Redi-Servers übersteigt. Wenn beispielsweise der Schlüssel mit dem festen Namen und der Hash auf denselben Server fallen, ist der Umfang des sofortigen Zugriffs enorm, übersteigt den Maschinenengpass und verursacht Hot Schlüsselprobleme. </li></ul></blockquote><p>Wie erkennt man also Hotkeys in der täglichen Entwicklung? </p><blockquote><ul><li>Bestimmen Sie, welche Hotkeys auf Erfahrung basieren. </li><li>Client-Statistikberichte; </li><li>Reporting an die Service-Agent-Ebene. </li></ul></blockquote><p>Redis-Cluster-Erweiterung: Shard-Kopien hinzufügen, um den Leseverkehr auszugleichen; </p><blockquote>Hotkeys auf verschiedene Server verteilen; <ul><li>Zwischenspeicher der zweiten Ebene, d. h. lokalen JVM-Cache, verwenden, um Redis-Leseanforderungen zu reduzieren. </li><li></li><li>6. Redis-Ablaufstrategie und Speicherbeseitigungsstrategie</li></ul></blockquote><h2 data-id="heading-24"></h2>6.1 Redis-Ablaufstrategie<p><img src="https://img.php.cn/upload/image/196/230/831/163150191159182Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)" title="163150191159182Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)" alt="1Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)"/>Wir sind hier</p>. Geben Sie an, dass dieser Schlüssel nach 60 Sekunden abläuft. Wie wird Redis nach 60 Sekunden damit umgehen? Lassen Sie uns zunächst mehrere Ablaufstrategien vorstellen: <h3 data-id="heading-25"></h3>Zeitgesteuerter Ablauf<p><code>set key的时候,可以给它设置一个过期时间,比如expire key 60

    Jeder Schlüssel mit einer Ablaufzeit muss einen Timer erstellen, und der Schlüssel wird sofort gelöscht, wenn die Ablaufzeit erreicht ist. Diese Strategie kann abgelaufene Daten sofort löschen und ist sehr speicherschonend; sie beansprucht jedoch eine große Menge an CPU-Ressourcen für die Verarbeitung abgelaufener Daten, was sich auf die Cache-Reaktionszeit und den Durchsatz auswirkt.

Verzögerter Ablauf

Nur wenn auf einen Schlüssel zugegriffen wird, wird beurteilt, ob der Schlüssel abgelaufen ist, und er wird gelöscht, wenn er abläuft. Diese Strategie kann CPU-Ressourcen maximal einsparen, ist jedoch sehr speicherunfreundlich. In extremen Fällen kann es vorkommen, dass auf eine große Anzahl abgelaufener Schlüssel nicht erneut zugegriffen werden kann, sodass sie nicht gelöscht werden und viel Speicher belegen.

Periodischer Ablauf

Zu jedem bestimmten Zeitpunkt wird eine bestimmte Anzahl von Schlüsseln im Ablaufwörterbuch einer bestimmten Anzahl von Datenbanken gescannt und die abgelaufenen Schlüssel werden gelöscht. Diese Strategie ist ein Kompromiss zwischen den ersten beiden. Durch Anpassen des Zeitintervalls geplanter Scans und des begrenzten Zeitverbrauchs jedes Scans kann unter verschiedenen Umständen ein optimales Gleichgewicht zwischen CPU- und Speicherressourcen erreicht werden.

Das Expires-Wörterbuch speichert die Ablaufzeitdaten aller Schlüssel mit festgelegter Ablaufzeit, wobei „key“ ein Zeiger auf einen Schlüssel im Schlüsselraum und „value“ die Ablaufzeit ist, die durch den UNIX-Zeitstempel des Schlüssels mit Millisekundengenauigkeit dargestellt wird. Der Schlüsselraum bezieht sich auf alle im Redis-Cluster gespeicherten Schlüssel.

Redis verwendet sowohl Lazy Expiration als auch Periodic Expirationzwei Ablaufstrategien.

  • Angenommen, Redis speichert derzeit 300.000 Schlüssel und für alle sind Ablaufzeiten festgelegt. Wenn Sie alle 100 ms alle Schlüssel überprüfen, ist die CPU-Auslastung extrem hoch und es kann passieren, dass sie hängen bleibt.
  • Daher verwendet Redis den regulären Ablauf und wählt alle 100 ms zufällig eine bestimmte Anzahl von Schlüsseln aus, um sie zu überprüfen und zu löschen.
  • Allerdings kann es viele abgelaufene Schlüssel geben, die am Ende nicht gelöscht wurden. Derzeit verwendet Redis das verzögerte Löschen. Wenn Sie einen Schlüssel erhalten, überprüft Redis ihn. Wenn für den Schlüssel eine Ablaufzeit festgelegt ist und er abgelaufen ist, wird er zu diesem Zeitpunkt gelöscht.

Aber wenn beim regulären Löschen viele abgelaufene Schlüssel übersehen werden, wird das verzögerte Löschen nicht verwendet. Im Speicher werden viele abgelaufene Schlüssel angesammelt, was direkt dazu führt, dass der Speicher explodiert. Oder manchmal, wenn das Geschäftsvolumen zunimmt, werden die Redis-Schlüssel stark beansprucht, der Speicher reicht einfach nicht aus und der Betriebs- und Wartungsmitarbeiter vergisst, den Speicher zu erhöhen. Könnte Redis einfach so auflegen? NEIN! Redis schützt sich mit 8 Speichereliminierungsstrategien~

6.2 Redis-Speichereliminierungsstrategie

  • volatile-lru: Wenn der Speicher nicht ausreicht, um neu geschriebene Daten aufzunehmen, verwenden Sie LRU (zuletzt verwendet) aus dem Schlüssel mit einer Ablaufzeit set)-Algorithmus zur Eliminierung;
  • allkeys-lru: Wenn der Speicher nicht ausreicht, um neu geschriebene Daten aufzunehmen, wird der LRU-Algorithmus (zuletzt verwendet) zur Eliminierung aus allen Schlüsseln verwendet.
  • volatile-lfu: Neu hinzugefügt in Version 4.0: Wenn der Speicher nicht ausreicht, um neu geschriebene Daten aufzunehmen, wird der LFU-Algorithmus verwendet, um Schlüssel unter abgelaufenen Schlüsseln zu löschen.
  • allkeys-lfu: Neu in Version 4.0: Wenn der Speicher nicht ausreicht, um die neu geschriebenen Daten aufzunehmen, wird der LFU-Algorithmus verwendet, um alle Schlüssel zu entfernen.
  • volatile-random: Wenn der Speicher nicht ausreicht, um die neu geschriebenen Daten aufzunehmen Neu geschriebene Daten, aus dem Schlüssel mit festgelegter Ablaufzeit, werden die Daten zufällig gelöscht;.
  • allkeys-random: Wenn der Speicher nicht ausreicht, um die neu geschriebenen Daten aufzunehmen, werden Daten zufällig aus allen Schlüsseln entfernt.
  • volatile-ttl: Wenn der Speicher nicht ausreicht, um die neu geschriebenen Daten aufzunehmen, wird der Schlüssel mit einer festgelegten Ablaufzeit entsprechend der Ablaufzeit gelöscht, und die zuvor abgelaufenen werden zuerst gelöscht;
  • noeviction: Der Standardstrategie: Wenn der Speicher nicht ausreicht, um neu geschriebene Daten aufzunehmen, meldet der neue Schreibvorgang einen Fehler.

7. Lassen Sie uns über die gängigen Anwendungsszenarien von Redis sprechen

  • Cache
  • Rangliste
  • Gegenanwendung
  • Geteilte Sitzung
  • Verteilte Sperre
  • Soziales Netzwerk
  • Nachrichtenwarteschlange
  • Bit-Operation

7.1 Caching

Wenn wir Redis erwähnen, denken wir natürlich daran, dass mittlere und große Websites im In- und Ausland untrennbar mit dem Cache verbunden sind. Eine angemessene Verwendung des Caches, z. B. das Zwischenspeichern von Hotspot-Daten, kann nicht nur die Zugriffsgeschwindigkeit der Website verbessern, sondern auch den Druck auf die Datenbank-DB verringern. Darüber hinaus bietet Redis im Vergleich zu Memcached auch umfangreiche Datenstrukturen und Persistenzmechanismen wie RDB und AOF, die zu den stärksten gehören.

7.2 Rankings

In heutigen Internetanwendungen gibt es verschiedene Rankings, wie zum Beispiel monatliche Verkaufsrankings von E-Commerce-Websites, Geschenkrankings von sozialen APPs, Abstimmungsrankings von Miniprogrammen usw. Der von Redis bereitgestellte zsetDatentyp kann diese komplexen Rankings implementieren.

Wenn Nutzer beispielsweise jeden Tag Videos hochladen, kann die Rangliste der Likes so gestaltet werden:

  • 1.用户Jay上传一个视频,获得6个赞,可以酱紫:
zadd user:ranking:2021-03-03 Jay 3
Nach dem Login kopieren
Nach dem Login kopieren
    1. 过了一段时间,再获得一个赞,可以这样:
zincrby user:ranking:2021-03-03 Jay 1
Nach dem Login kopieren
    1. 如果某个用户John作弊,需要删除该用户:
zrem user:ranking:2021-03-03 John
Nach dem Login kopieren
    1. 展示获取赞数最多的3个用户
zrevrangebyrank user:ranking:2021-03-03 0 2
Nach dem Login kopieren

7.3 计数器应用

各大网站、APP应用经常需要计数器的功能,如短视频的播放数、电商网站的浏览数。这些播放数、浏览数一般要求实时的,每一次播放和浏览都要做加1的操作,如果并发量很大对于传统关系型数据的性能是一种挑战。Redis天然支持计数功能而且计数的性能也非常好,可以说是计数器系统的重要选择。

7.4 共享Session

如果一个分布式Web服务将用户的Session信息保存在各自服务器,用户刷新一次可能就需要重新登录了,这样显然有问题。实际上,可以使用Redis将用户的Session进行集中管理,每次用户更新或者查询登录信息都直接从Redis中集中获取。

7.5 分布式锁

几乎每个互联网公司中都使用了分布式部署,分布式服务下,就会遇到对同一个资源的并发访问的技术难题,如秒杀、下单减库存等场景。

  • 用synchronize或者reentrantlock本地锁肯定是不行的。
  • 如果是并发量不大话,使用数据库的悲观锁、乐观锁来实现没啥问题。
  • 但是在并发量高的场合中,利用数据库锁来控制资源的并发访问,会影响数据库的性能。
  • 实际上,可以用Redis的setnx来实现分布式的锁。

7.6 社交网络

赞/踩、粉丝、共同好友/喜好、推送、下拉刷新等是社交网站的必备功能,由于社交网站访问量通常比较大,而且传统的关系型数据不太适保存 这种类型的数据,Redis提供的数据结构可以相对比较容易地实现这些功能。

7.7 消息队列

消息队列是大型网站必用中间件,如ActiveMQ、RabbitMQ、Kafka等流行的消息队列中间件,主要用于业务解耦、流量削峰及异步处理实时性低的业务。Redis提供了发布/订阅及阻塞队列功能,能实现一个简单的消息队列系统。另外,这个不能和专业的消息中间件相比。

7.8 位操作

用于数据量上亿的场景下,例如几亿用户系统的签到,去重登录次数统计,某用户是否在线状态等等。腾讯10亿用户,要几个毫秒内查询到某个用户是否在线,能怎么做?千万别说给每个用户建立一个key,然后挨个记(你可以算一下需要的内存会很恐怖,而且这种类似的需求很多。这里要用到位操作——使用setbit、getbit、bitcount命令。原理是:redis内构建一个足够长的数组,每个数组元素只能是0和1两个值,然后这个数组的下标index用来表示用户id(必须是数字哈),那么很显然,这个几亿长的大数组就能通过下标和元素值(0和1)来构建一个记忆系统。

8. Redis 的持久化机制有哪些?优缺点说说

Redis是基于内存的非关系型K-V数据库,既然它是基于内存的,如果Redis服务器挂了,数据就会丢失。为了避免数据丢失了,Redis提供了持久化,即把数据保存到磁盘。

Redis提供了RDB和AOF两种持久化机制,它持久化文件加载流程如下:

1Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

8.1 RDB

RDB,就是把内存数据以快照的形式保存到磁盘上。

什么是快照?可以这样理解,给当前时刻的数据,拍一张照片,然后保存下来。

RDB持久化,是指在指定的时间间隔内,执行指定次数的写操作,将内存中的数据集快照写入磁盘中,它是Redis默认的持久化方式。执行完操作后,在指定目录下会生成一个dump.rdb文件,Redis 重启的时候,通过加载dump.rdb文件来恢复数据。RDB触发机制主要有以下几种:

1Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

RDB 的优点

  • 适合大规模的数据恢复场景,如备份,全量复制等

RDB缺点

  • Es gibt keine Möglichkeit, Echtzeit-Persistenz/Persistenz der zweiten Ebene zu erreichen.
  • Bei der alten und der neuen Version gibt es Kompatibilitätsprobleme mit dem RDB-Format

AOF

AOF (nur Datei anhängen) Persistenz, Protokollform zum Aufzeichnen jedes Schreibvorgangs, Anhängen an die Datei und erneutes Ausführen der AOF-Datei bei Bedarf Neustartbefehl zum Wiederherstellen von Daten. Es löst hauptsächlich das Echtzeitproblem der Datenpersistenz. Die Standardeinstellung ist nicht aktiviert.

Der Workflow von AOF ist wie folgt:

1Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

Atvantations von AOF

  • High -Konsistenz und Integrität von Daten

DisadVantations von AOF

  • Die mehr Inhaltsdatensätze, desto besser die Datei besser Groß, die Datenwiederherstellung verlangsamt sich.

9. Wie erreicht man eine hohe Verfügbarkeit von Redis?

Wir verwenden Redis im Projekt und werden den Redis-Dienst definitiv nicht an einem einzigen Punkt bereitstellen. Denn sobald die Single-Point-Bereitstellung ausfällt, ist sie nicht mehr verfügbar. Um eine hohe Verfügbarkeit zu erreichen, besteht eine gängige Praxis darin, mehrere Kopien der Datenbank zu kopieren und auf verschiedenen Servern bereitzustellen. Wenn einer von ihnen ausfällt, kann er weiterhin Dienste bereitstellen. Es gibt drei Bereitstellungsmodi für Redis, um eine hohe Verfügbarkeit zu erreichen: Master-Slave-Modus, Sentinel-Modus und Cluster-Modus.

9.1 Master-Slave-Modus

Im Master-Slave-Modus stellt Redis mehrere Maschinen bereit, wobei ein Master-Knoten für Lese- und Schreibvorgänge verantwortlich ist und ein Slave-Knoten nur für Lesevorgänge verantwortlich ist. Die Daten des Slave-Knotens stammen vom Master-Knoten. Das Implementierungsprinzip ist der Master-Slave-Replikationsmechanismus. Die Master-Slave-Replikation umfasst die vollständige Replikation und die inkrementelle Replikation. Wenn der Slave zum ersten Mal eine Verbindung zum Master herstellt oder die Verbindung zum ersten Mal hergestellt wird, wird im Allgemeinen eine vollständige Kopie verwendet. Der vollständige Kopiervorgang ist wie folgt:

1 . Der Slave sendet einen Sync-Befehl an den Master.

1Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)2. Nach Erhalt des SYNC-Befehls führt der Master den bgsave-Befehl aus, um die vollständige RDB-Datei zu generieren.

    3. Der Master verwendet einen Puffer, um alle Schreibbefehle während der RDB-Snapshot-Generierung aufzuzeichnen.
  • 4. Nachdem der Master bgsave ausgeführt hat, sendet er RDB-Snapshot-Dateien an alle Slaves.
  • 5. Nach dem Empfang der RDB-Snapshot-Datei lädt und analysiert der Slave den empfangenen Snapshot.
  • 6. Der Master verwendet einen Puffer, um alle während der RDB-Synchronisierung generierten geschriebenen Befehle aufzuzeichnen.
  • 7. Nachdem der Master-Snapshot gesendet wurde, beginnt er, den Schreibbefehl im Puffer an den Slave zu senden.
  • 8.salve akzeptiert die Befehlsanforderung und führt den Schreibbefehl aus dem Master-Puffer aus Version wurde
  • psync als Ersatz für sync
  • verwendet, da der sync-Befehl Systemressourcen verbraucht und psync effizienter ist.
  • Nachdem der Slave vollständig mit dem Master synchronisiert ist und die Daten auf dem Master erneut aktualisiert werden, wird eine
  • inkrementelle Replikation
  • ausgelöst.

Wenn die Datenmenge auf dem Master-Knoten zunimmt oder abnimmt, wird eine Synchronisierung mit dem Slave-Knoten ausgelöst. Vor der Ausführung dieser Funktion ermittelt der Masterknoten, ob der vom Benutzer ausgeführte Befehl über Datenaktualisierungen verfügt. Wenn eine Datenaktualisierung vorliegt und der Slaveknoten nicht leer ist, wird diese Funktion ausgeführt. Die Funktion dieser Funktion ist: Senden Sie den vom Benutzer ausgeführten Befehl an alle Slave-Knoten

und lassen Sie ihn vom Slave-Knoten ausführen. Der Prozess ist wie folgt:

9.2 Sentinel-Modus replicationFeedSalves()函数,接下来在 Master节点上调用的每一个命令会使用replicationFeedSlaves()Sobald der Master-Knoten im Master-Slave-Modus aufgrund eines Fehlers keine Dienste bereitstellen kann, muss der Slave-Knoten manuell zum Master-Knoten heraufgestuft werden Benachrichtigen Sie gleichzeitig die Anwendung, um die Master-Knotenadresse zu aktualisieren. Offensichtlich ist diese Methode der Fehlerbehandlung in den meisten Geschäftsszenarien inakzeptabel. Um dieses Problem zu lösen, stellt Redis ab Version 2.8 offiziell die Redis Sentinel-Architektur (Sentinel) bereit.

Sentinel-Modus1Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse), ein Sentinel-System, das aus einer oder mehreren Sentinel-Instanzen besteht, das alle Redis-Masterknoten und Slave-Knoten überwachen kann, und wenn der überwachte Masterknoten in den Offline-Zustand wechselt,

automatisch den Offline-Master-A-Slave-Knoten darunter entfernen Der Server wird auf einen neuen Masterknoten aktualisiert

. Wenn jedoch ein Sentinel-Prozess einen Redis-Knoten überwacht, können Probleme auftreten (

Einzelpunktproblem

). Daher können mehrere Sentinels zur Überwachung von Redis-Knoten verwendet werden, und jeder Sentinel überwacht sich auch gegenseitig.

Einfach ausgedrückt hat der Sentinel-Modus drei Funktionen: Senden Sie Befehle und warten Sie, bis der Redis-Server (einschließlich des Master-Servers und des Slave-Servers) zurückkehrt, um seinen Betriebsstatus zu überwachen;

Sentinel überwacht den Der Master-Knoten ist ausgefallen und schaltet den Slave-Knoten automatisch auf den Master-Knoten um, benachrichtigt dann andere Slave-Knoten über den Veröffentlichungs- und Abonnementmodus, ändert die Konfigurationsdatei und lässt sie den Host wechseln Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

Die Sentinels überwachen auch jeden andere, um eine hohe Verfügbarkeit zu erreichen.

  • Was ist der Failover-Prozess?

    Angenommen, der Hauptserver ist ausgefallen und Sentinel 1 erkennt dieses Ergebnis nicht sofort. Es ist nur so, dass Sentinel 1 subjektiv davon ausgeht, dass der Hauptserver nicht verfügbar ist. Wenn die nachfolgenden Sentinels ebenfalls feststellen, dass der Hauptserver nicht verfügbar ist und die Anzahl einen bestimmten Wert erreicht, findet eine Abstimmung zwischen den Sentinels statt. Das Ergebnis der Abstimmung wird von einem Sentinel veranlasst, einen Failover-Vorgang durchzuführen. Nachdem der Wechsel erfolgreich war, wechselt jeder Sentinel im Publish-Subscribe-Modus den von ihm überwachten Slave-Server zum Host. Dieser Vorgang wird als objektiv offline bezeichnet. Auf diese Weise ist für den Kunden alles transparent.

    Der Arbeitsmodus von Sentinel ist wie folgt:

    • Jeder Sentinel sendet einmal pro Sekunde einen PING-Befehl an den Master, den Slave und andere ihm bekannte Sentinel-Instanzen.

    • Wenn die Zeit seit der letzten gültigen Antwort auf den PING-Befehl den durch die Option down-after-milliseconds angegebenen Wert überschreitet, wird die Instanz von Sentinel als subjektiv offline markiert.

    • Wenn ein Master als subjektiv offline markiert ist, müssen alle Sentinels, die diesen Master überwachen, einmal pro Sekunde bestätigen, dass der Master tatsächlich in den subjektiven Offline-Status übergegangen ist.

    • Wenn eine ausreichende Anzahl von Sentinels (größer oder gleich dem in der Konfigurationsdatei angegebenen Wert) bestätigt, dass der Master innerhalb des angegebenen Zeitraums tatsächlich in einen subjektiven Offline-Zustand eingetreten ist, wird der Master als objektiv offline markiert.

    • Unter normalen Umständen sendet jeder Sentinel alle 10 Sekunden INFO-Befehle an alle ihm bekannten Master und Slaves.

    • Wenn der Master von Sentinel als objektiv offline markiert wird, wird die Häufigkeit, mit der Sentinel INFO-Befehle an alle Slaves des Offline-Masters sendet, von einmal alle 10 Sekunden auf einmal jede Sekunde geändert.

    • Wenn nicht genug davon vorhanden sind Sentinels stimmen zu: Wenn der Master offline ist, wird der objektive Offline-Status des Masters entfernt; wenn der Master erneut eine gültige Antwort auf den PING-Befehl des Sentinel zurückgibt, wird der subjektive Offline-Status des Masters entfernt.

    9.3 Cluster-Cluster-Modus

    Der Sentinel-Modus basiert auf dem Master-Slave-Modus und realisiert die Lese- und Schreibtrennung. Er kann auch automatisch umschalten und die Systemverfügbarkeit ist höher. Allerdings sind die in jedem Knoten gespeicherten Daten gleich, was Speicher verschwendet und online nicht einfach zu erweitern ist. Aus diesem Grund entstand der Cluster-Cluster, der in Redis 3.0 hinzugefügt wurde und den „verteilten Speicher“ von Redis implementierte. Segmentieren Sie die Daten, was bedeutet, dass Sie auf jedem Redis-Knoten unterschiedliche Inhalte speichern müssen, um das Problem der Online-Erweiterung zu lösen. Darüber hinaus bietet es Replikations- und Failover-Funktionen. Kommunikation von Cluster-Cluster-KnotenEin Redis-Cluster besteht aus mehreren Knoten

    Wie kommunizieren die einzelnen Knoten miteinander? Durch das

    Gossip-Protokoll

    !

    Der Redis-Cluster-Cluster kommuniziert über das Gossip-Protokoll. Zu den ausgetauschten Informationen gehören Knotenfehler, neue Knotenbeitritte, Master-Slave-Knotenwechselinformationen, Slot-Informationen usw. Häufig verwendete Klatschnachrichten werden in vier Typen unterteilt: Ping, Pong, Meet und Fail.

    Meet-Nachricht: Benachrichtigen Sie neue Knoten zum Beitritt. Der Absender der Nachricht benachrichtigt den Empfänger, dem aktuellen Cluster beizutreten. Nachdem die Meet-Nachrichtenkommunikation normal abgeschlossen wurde, tritt der empfangende Knoten dem Cluster bei und führt einen regelmäßigen Ping- und Pong-Nachrichtenaustausch durch. Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

    Ping-Nachricht: Die am häufigsten ausgetauschte Nachricht im Cluster. Jeder Knoten im Cluster sendet jede Sekunde Ping-Nachrichten an mehrere andere Knoten, die verwendet werden, um zu erkennen, ob die Knoten online sind, und um Statusinformationen untereinander auszutauschen.
      Pong-Nachricht: Beim Empfang einer Ping- oder Meet-Nachricht antwortet diese dem Absender als Antwortnachricht, um die normale Kommunikation der Nachricht zu bestätigen. Die Pong-Nachricht kapselt intern ihre eigenen Statusdaten. Ein Knoten kann auch seine eigene Pong-Nachricht an den Cluster senden, um den gesamten Cluster zu benachrichtigen, seinen Status zu aktualisieren.
    • Fehlermeldung: Wenn ein Knoten feststellt, dass ein anderer Knoten im Cluster offline ist, sendet er eine Fehlernachricht an den Cluster. Nach Erhalt der Fehlernachricht versetzen andere Knoten den entsprechenden Knoten in den Offline-Status.
    • Insbesondere kommuniziert jeder Knoten mit anderen Knoten über den
    • Cluster-Bus
    • . Verwenden Sie bei der Kommunikation eine spezielle Portnummer, d. h. die Portnummer des externen Dienstes plus 10000. Wenn die Portnummer eines Knotens beispielsweise 6379 ist, lautet die Portnummer, über die er mit anderen Knoten kommuniziert, 16379. Die Kommunikation zwischen Knoten verwendet ein spezielles Binärprotokoll.
    Hash-Slot-Algorithmus

    Da es sich um verteilten Speicher handelt, ist der vom Cluster-Cluster verwendete verteilte Algorithmus Konsistenter Hash

    ? Nein, es ist der

    Hash-Slot-Algorithmus

    .

    Slot-AlgorithmusDie gesamte Datenbank ist in 16384 Slots (Slots) unterteilt. Jedes in Redis eingegebene Schlüssel-Wert-Paar wird entsprechend dem Schlüssel gehasht und einem dieser 16384 Slots zugewiesen. Die verwendete Hash-Map ist ebenfalls relativ einfach. Sie verwendet den CRC16-Algorithmus zur Berechnung eines 16-Bit-Werts und dann Modulo 16384. Jeder Schlüssel in der Datenbank gehört zu einem dieser 16384 Slots, und jeder Knoten im Cluster kann diese 16384 Slots verarbeiten.

    Jeder Knoten im Cluster ist für einen Teil der Hash-Slots verantwortlich. Der aktuelle Cluster hat beispielsweise die Knoten A, B und C und die Anzahl der Hash-Slots auf jedem Knoten = 16384/3, dann gibt es:

    • Knoten A ist verantwortlich für die Hash-Slots 0~5460
    • Knoten B ist verantwortlich für die Hash-Slots 5461~10922
    • Knoten C ist verantwortlich für die Hash-Slots 10923~16383

    Redis-Cluster-Cluster

    Im Redis-Cluster-Cluster ist Sie müssen sicherstellen, dass 16384 Steckplätze übereinstimmen. Alle Knoten funktionieren normal. Wenn ein Knoten ausfällt, wird auch der Steckplatz, für den er verantwortlich ist, ungültig und der gesamte Cluster funktioniert nicht.

    Um eine hohe Verfügbarkeit sicherzustellen, führt der Cluster-Cluster eine Master-Slave-Replikation ein, und ein Masterknoten entspricht einem oder mehreren Slave-Knoten. Wenn andere Master-Knoten einen Master-Knoten A anpingen und mehr als die Hälfte der Master-Knoten mit A kommunizieren, tritt eine Zeitüberschreitung auf, dann gilt der Master-Knoten A als ausgefallen. Wenn der Master-Knoten ausfällt, wird der Slave-Knoten aktiviert.

    Auf jedem Knoten von Redis gibt es zwei Dinge, eines ist der Slot und sein Wertebereich ist 016383. Der andere ist Cluster, der als Cluster-Management-Plug-In verstanden werden kann. Wenn der Schlüssel, auf den wir zugreifen, eintrifft, erhält Redis einen 16-Bit-Wert basierend auf dem CRC16-Algorithmus und nimmt dann das Ergebnis modulo 16384. Jeder Schlüssel in Jiangzi entspricht einem Hash-Slot mit einer Nummer zwischen 0 und 16383. Verwenden Sie diesen Wert, um den Knoten zu finden, der dem entsprechenden Slot entspricht, und springen Sie dann automatisch zum entsprechenden Knoten, um Zugriffsvorgänge durchzuführen.

    Obwohl die Daten separat auf verschiedenen Knoten gespeichert werden, wird für den Client der gesamte Cluster als Ganzes betrachtet. Der Client stellt eine Verbindung zu einem beliebigen Knoten her und sieht genauso aus, als würde er eine einzelne Instanz von Redis betreiben. Wenn der vom Client betätigte Schlüssel nicht dem richtigen Knoten zugewiesen ist, gibt Redis die Umleitungsanweisung zurück und zeigt schließlich auf den richtigen Knoten. Dies ähnelt dem 302-Umleitungssprung der Browserseite.

    2Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

    Failover

    Der Redis-Cluster erreicht eine hohe Verfügbarkeit. Wenn ein Knoten im Cluster ausfällt, wird

    Failover verwendet, um sicherzustellen, dass der Cluster normale externe Dienste bereitstellen kann.

    Der Redis-Cluster realisiert die Fehlererkennung durch Ping/Pong-Nachrichten. Diese Umgebung umfasst

    subjektives Offline und objektives Offline.

    Subjektiv offline: Ein Knoten geht davon aus, dass ein anderer Knoten nicht verfügbar ist, d.

    2Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

    Ziel offline: Zeigt an, dass ein Knoten wirklich offline ist. Mehrere Knoten im Cluster gehen davon aus, dass der Knoten nicht verfügbar ist, und erzielen so einen Konsens. Wenn der Master-Knoten, der den Steckplatz hält, ausfällt, muss für den Knoten ein Failover durchgeführt werden.

      Angenommen, Knoten A markiert Knoten B als subjektiv offline. Nach einer gewissen Zeit sendet Knoten A den Status von Knoten B über Nachrichten an andere Knoten und analysiert den Nachrichtentext, wenn Knoten B gefunden wird Im pfail-Zustand wird der objektive Offline-Prozess ausgelöst.
    • Wenn der Master-Knoten offline ist, stimmt der Redis-Cluster-Cluster für den Master-Knoten ab, der den Statistik-Slot hält, um zu sehen, ob die Anzahl der Stimmen die Hälfte erreicht Die Berichtsstatistik beträgt mehr als die Hälfte und wird als „objektiver Offline-Status“ markiert.
    • Der Prozess ist wie folgt:

    2Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)Fehlerbehebung

    : Nachdem der Fehler entdeckt wurde und der Offline-Knoten der Master-Knoten ist, müssen Sie einen seiner Slave-Knoten auswählen, um ihn zu ersetzen, um den Hochwert sicherzustellen Verfügbarkeit des Clusters. Der Prozess ist wie folgt:

    2Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)Qualifikationsprüfung: Überprüfen Sie, ob der Slave-Knoten die Bedingungen zum Ersetzen des ausgefallenen Master-Knotens erfüllt.

      Wahlzeit vorbereiten: Nachdem die Qualifikationsprüfung bestanden wurde, aktualisieren Sie die Wahlzeit für Triggerfehler.
    • Eine Wahl einleiten: Wenn der Zeitpunkt der Fehlerwahl kommt, führen Sie eine Wahl durch.
    • Wahlabstimmung: Nur der
    • Master-Knoten
    • , der den Slot innehat, hat Stimmen (mehr als die Hälfte) von den Slave-Knoten, die
    • Ersetzung des Master-Knotenvorgangs ausgelöst wird10 Haben Sie jemals die verteilte Redis-Sperre verwendet? Auf welche Punkte ist zu achten?

    Distributed Lock

    ist eine Implementierung einer Sperre, die verschiedene Prozesse in einem verteilten System steuert, um gemeinsam auf gemeinsam genutzte Ressourcen zuzugreifen. Geschäftsszenarien wie das Aufgeben von Flash-Verkaufsaufträgen, das Ergreifen roter Umschläge usw. erfordern alle die Verwendung verteilter Sperren. Redis wird in unseren Projekten häufig als verteilte Sperre verwendet.

    选了Redis分布式锁的几种实现方法,大家来讨论下,看有没有啥问题哈。

    • 命令setnx + expire分开写
    • setnx + value值是过期时间
    • set的扩展命令(set ex px nx)
    • set ex px nx + 校验唯一随机值,再删除

    10.1 命令setnx + expire分开写

    if(jedis.setnx(key,lock_value) == 1){ //加锁
        expire(key,100); //设置过期时间
        try {
            do something  //业务请求
        }catch(){
      }
      finally {
           jedis.del(key); //释放锁
        }
    }
    Nach dem Login kopieren

    如果执行完setnx加锁,正要执行expire设置过期时间时,进程crash掉或者要重启维护了,那这个锁就“长生不老”了,别的线程永远获取不到锁啦,所以分布式锁不能这么实现。

    10.2 setnx + value值是过期时间

    long expires = System.currentTimeMillis() + expireTime; //系统时间+设置的过期时间
    String expiresStr = String.valueOf(expires);
    
    // 如果当前锁不存在,返回加锁成功
    if (jedis.setnx(key, expiresStr) == 1) {
            return true;
    } 
    // 如果锁已经存在,获取锁的过期时间
    String currentValueStr = jedis.get(key);
    
    // 如果获取到的过期时间,小于系统当前时间,表示已经过期
    if (currentValueStr != null && Long.parseLong(currentValueStr) < System.currentTimeMillis()) {
    
         // 锁已过期,获取上一个锁的过期时间,并设置现在锁的过期时间(不了解redis的getSet命令的小伙伴,可以去官网看下哈)
        String oldValueStr = jedis.getSet(key_resource_id, expiresStr);
        
        if (oldValueStr != null && oldValueStr.equals(currentValueStr)) {
             // 考虑多线程并发的情况,只有一个线程的设置值和当前值相同,它才可以加锁
             return true;
        }
    }
            
    //其他情况,均返回加锁失败
    return false;
    }
    Nach dem Login kopieren

    笔者看过有开发小伙伴是这么实现分布式锁的,但是这种方案也有这些缺点

    • 过期时间是客户端自己生成的,分布式环境下,每个客户端的时间必须同步。
    • 没有保存持有者的唯一标识,可能被别的客户端释放/解锁。
    • 锁过期的时候,并发多个客户端同时请求过来,都执行了jedis.getSet(),最终只能有一个客户端加锁成功,但是该客户端锁的过期时间,可能被别的客户端覆盖。

    10.3: set的扩展命令(set ex px nx)(注意可能存在的问题)

    if(jedis.set(key, lock_value, "NX", "EX", 100s) == 1){ //加锁
        try {
            do something  //业务处理
        }catch(){
      }
      finally {
           jedis.del(key); //释放锁
        }
    }
    Nach dem Login kopieren

    这个方案可能存在这样的问题:

    • 锁过期释放了,业务还没执行完。
    • 锁被别的线程误删。

    10.4 set ex px nx + 校验唯一随机值,再删除

    if(jedis.set(key, uni_request_id, "NX", "EX", 100s) == 1){ //加锁
        try {
            do something  //业务处理
        }catch(){
      }
      finally {
           //判断是不是当前线程加的锁,是才释放
           if (uni_request_id.equals(jedis.get(key))) {
            jedis.del(key); //释放锁
            }
        }
    }
    Nach dem Login kopieren

    在这里,判断当前线程加的锁和释放锁是不是一个原子操作。如果调用jedis.del()释放锁的时候,可能这把锁已经不属于当前客户端,会解除他人加的锁

    2Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

    一般也是用lua脚本代替。lua脚本如下:

    if redis.call(&#39;get&#39;,KEYS[1]) == ARGV[1] then 
       return redis.call(&#39;del&#39;,KEYS[1]) 
    else
       return 0
    end;
    Nach dem Login kopieren

    这种方式比较不错了,一般情况下,已经可以使用这种实现方式。但是存在锁过期释放了,业务还没执行完的问题(实际上,估算个业务处理的时间,一般没啥问题了)。

    11. 使用过Redisson嘛?说说它的原理

    分布式锁可能存在锁过期释放,业务没执行完的问题。有些小伙伴认为,稍微把锁过期时间设置长一些就可以啦。其实我们设想一下,是否可以给获得锁的线程,开启一个定时守护线程,每隔一段时间检查锁是否还存在,存在则对锁的过期时间延长,防止锁过期提前释放。

    当前开源框架Redisson就解决了这个分布式锁问题。我们一起来看下Redisson底层原理是怎样的吧:

    2Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

    只要线程一加锁成功,就会启动一个watch dog看门狗,它是一个后台线程,会每隔10秒检查一下,如果线程1还持有锁,那么就会不断的延长锁key的生存时间。因此,Redisson就是使用Redisson解决了锁过期释放,业务没执行完问题。

    12. 什么是Redlock算法

    Redis一般都是集群部署的,假设数据在主从同步过程,主节点挂了,Redis分布式锁可能会有哪些问题呢?一起来看些这个流程图:

    2Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

    如果线程一在Redis的master节点上拿到了锁,但是加锁的key还没同步到slave节点。恰好这时,master节点发生故障,一个slave节点就会升级为master节点。线程二就可以获取同个key的锁啦,但线程一也已经拿到锁了,锁的安全性就没了。

    为了解决这个问题,Redis作者 antirez提出一种高级的分布式锁算法:Redlock。Redlock核心思想是这样的:

    搞多个Redis master部署,以保证它们不会同时宕掉。并且这些master节点是完全相互独立的,相互之间不存在数据同步。同时,需要确保在这多个master实例上,是与在Redis单实例,使用相同方法来获取和释放锁。

    我们假设当前有5个Redis master节点,在5台服务器上面运行这些Redis实例。

    2Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

    RedLock的实现步骤:如下

    • 1. Ermitteln Sie die aktuelle Zeit in Millisekunden.
    • 2. Sperren nacheinander von 5 Masterknoten anfordern. Der Client legt das Zeitlimit für die Netzwerkverbindung und die Antwort fest. Das Zeitlimit sollte kürzer sein als die Ablaufzeit der Sperre. (Unter der Annahme, dass die Ablaufzeit der automatischen Sperre 10 Sekunden beträgt, liegt die Timeout-Zeit im Allgemeinen zwischen 5 und 50 Millisekunden. Nehmen wir an, dass die Timeout-Zeit 50 ms beträgt.) Wenn das Zeitlimit überschritten wird, überspringen Sie den Masterknoten und versuchen Sie es so schnell wie möglich mit dem nächsten Masterknoten.
    • 3. Der Client verwendet die aktuelle Zeit abzüglich der Startzeit des Erwerbs der Sperre (d. h. die in Schritt 1 aufgezeichnete Zeit), um die Zeit zu ermitteln, die zum Erwerb der Sperre verwendet wurde. Die Sperre wird nur dann erfolgreich erworben, wenn mehr als die Hälfte (N/2+1, hier 5/2+1=3 Knoten) der Redis-Masterknoten die Sperre erhalten haben und die Nutzungsdauer kürzer als die Ablaufzeit der Sperre ist . (Wie im Bild oben gezeigt, 10s>30ms+40ms+50ms+4m0s+50ms)
    • Wenn die Sperre erhalten wird, ändert sich die tatsächliche effektive Zeit des Schlüssels und die Zeit, die zum Erhalten der Sperre benötigt wird, muss abgezogen werden.
    • Wenn die Sperrenerfassung fehlschlägt (die Sperre wird nicht auf mindestens N/2+1 Master-Instanzen erworben oder die Sperrenerfassungszeit hat die effektive Zeit überschritten), muss der Client auf allen Master-Knoten entsperren (auch wenn einige Master-Knoten (Sie erhalten die Sperre überhaupt nicht.) Auch wenn die Sperre nicht erfolgreich ist, muss sie dennoch entriegelt werden, um zu verhindern, dass einige Fische durch das Netz rutschen.

    Die vereinfachten Schritte sind:

    • Fordern Sie Sperren von 5 Masterknoten der Reihe nach an.
    • Bestimmen Sie, ob der Masterknoten entsprechend der eingestellten Zeitüberschreitungsperiode übersprungen werden soll.
    • Wenn mehr als oder gleich drei Knoten erfolgreich gesperrt wurden und die Nutzungsdauer kürzer als die Gültigkeitsdauer der Sperre ist, kann davon ausgegangen werden, dass die Sperre erfolgreich war.
    • Wenn der Erwerb der Sperre fehlschlägt, entsperren Sie sie!

    13. Die Skip-Tabelle von Redis

    Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

    • Die Skip-Tabelle ist eine der zugrunde liegenden Implementierungen der geordneten Menge zset
    • Die Skip-Tabelle unterstützt Knoten mit durchschnittlichem O(logN) und Worst-Case-O(N). ) Komplexität Finden und Batch-Verarbeitung von Knoten durch sequentielle Operationen.
    • Die Skip-List-Implementierung besteht aus zwei Strukturen: zskiplist und zskiplistNode, wobei zskiplist zum Speichern von Skip-Tabelleninformationen (z. B. Header-Knoten, Endknoten, Länge) und zskiplistNode zur Darstellung von Skip-List-Knoten verwendet wird.
    • Die Sprungliste basiert auf der verknüpften Liste und fügt mehrstufige Indizes hinzu, um die Sucheffizienz zu verbessern.

    14. Wie stellen MySQL und Redis die Konsistenz beim doppelten Schreiben sicher?

      Was ist eine verzögerte doppelte Löschung? Das Flussdiagramm sieht wie folgt aus:
    Zuerst den Cache löschen

    und dann die Datenbank aktualisieren

    Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

      Eine Weile schlafen (z. B. 1 Sekunde) und den Cache erneut löschen.
    • Wie lange dauert es normalerweise, bis man eine Weile schläft? Sind sie alle 1 Sekunde lang?
    • Diese Ruhezeit = die Zeit, die zum Lesen von Geschäftslogikdaten benötigt wird + ein paar hundert Millisekunden. Um sicherzustellen, dass die Leseanforderung endet, kann die Schreibanforderung zwischengespeicherte fehlerhafte Daten löschen, die möglicherweise durch die Leseanforderung mitgebracht wurden.
    • Diese Lösung ist nicht schlecht. Nur während der Ruhephase (z. B. nur 1 Sekunde) können schmutzige Daten vorhanden sein, und allgemeine Unternehmen werden dies akzeptieren. Was aber, wenn das

      Löschen des Caches zum zweiten Mal fehlschlägt
    • ? Die Cache- und Datenbankdaten sind möglicherweise immer noch inkonsistent, oder? Wie wäre es, wenn Sie eine natürliche Ablaufzeit für den Schlüssel festlegen und ihn automatisch ablaufen lassen? Muss das Unternehmen Dateninkonsistenzen innerhalb der Ablauffrist akzeptieren? Oder gibt es eine andere bessere Lösung?

    14.2 Cache-Löschwiederholungsmechanismus

    Aufgrund des verzögerten doppelten Löschens schlägt der zweite Schritt des Cache-Löschens möglicherweise fehl, was zu Dateninkonsistenzen führt. Sie können diese Lösung zur Optimierung verwenden: Wenn das Löschen fehlschlägt, löschen Sie es noch einige Male, um sicherzustellen, dass das Löschen des Caches erfolgreich ist. Sie können also einen Wiederholungsmechanismus für den Löschcache einführen

    Schreibanforderung zum Aktualisieren der Datenbank

    Der Cache ist aus bestimmten Gründen fehlgeschlagen.

    3Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

      Legen Sie den Schlüssel, der nicht gelöscht werden konnte, in die Nachrichtenwarteschlange gelöscht werden
    • Wiederholen Sie den Lösch-Cache-Vorgang
    • 14.3 Biglog lesen Der asynchrone Cache-Löschmechanismus
    • Löschungs-Cache-Mechanismus erneut versuchen ist in Ordnung, führt aber zu vielen

      Geschäftscodeeinbrüchen
    • . Tatsächlich kann es auch so optimiert werden: Schlüssel asynchron über das Binlog der Datenbank entfernen.
    • Nehmen Sie MySQL als Beispiel

      • Sie können Alibabas Kanal verwenden, um Binlog-Protokolle zu sammeln und an die MQ-Warteschlange zu senden.
      • Bestätigen und verarbeiten Sie dann die Aktualisierungsnachricht über den ACK-Mechanismus, löschen Sie den Cache und stellen Sie die Daten-Cache-Konsistenz sicher.

      15 ​​Warum hat sich Redis geändert? auf Multithreading nach 6.0?

      • Vor Redis 6.0 wurden Clientanforderungen, einschließlich Lesen von Sockets, Parsen, Ausführen, Schreiben von Sockets usw., alle von einem sequentiellen und seriellen Hauptthread verarbeitet. Dies ist der sogenannte „einzelne Thread“.
      • Warum wurde Multithreading vor Redis6.0 nicht verwendet? Bei der Verwendung von Redis kommt es fast nie zu Situationen, in denen die CPU zum Engpass wird. Redis wird hauptsächlich durch Speicher und Netzwerk begrenzt. Auf einem normalen Linux-System kann Redis beispielsweise mithilfe von Pipelining 1 Million Anfragen pro Sekunde verarbeiten. Wenn die Anwendung also hauptsächlich O(N)- oder O(log(N))-Befehle verwendet, wird sie kaum viel CPU beanspruchen.

      Die Verwendung von Multi-Threading durch Redis bedeutet nicht, dass Redis weiterhin ein Single-Thread-Modell zur Verarbeitung von Client-Anfragen verwendet. Es verwendet nur Multi-Threading, um das Lesen und Schreiben von Daten sowie die Protokollanalyse zu verarbeiten es verwendet immer noch einen einzelnen Thread, um Befehle auszuführen.

      Der Zweck besteht darin, dass der Leistungsengpass von Redis im Netzwerk-IO und nicht in der CPU liegt. Durch die Verwendung von Multithreading kann die Effizienz des IO-Lesens und -Schreibens verbessert werden, wodurch die Gesamtleistung von Redis verbessert wird.

      16. Lassen Sie uns über den Redis-Transaktionsmechanismus sprechen

      Redis implementiert den Transaktionsmechanismus durch eine Reihe von Befehlen wie MULTI, EXEC, WATCH. Transaktionen unterstützen die gleichzeitige Ausführung mehrerer Befehle und alle Befehle in einer Transaktion werden serialisiert. Während des Transaktionsausführungsprozesses werden die Befehle in der Warteschlange serialisiert und der Reihe nach ausgeführt, und von anderen Clients übermittelte Befehlsanforderungen werden nicht in die Befehlssequenz für die Transaktionsausführung eingefügt.

      Kurz gesagt ist eine Redis-Transaktion sequentielle, einmalige und exklusive Ausführung einer Reihe von Befehlen in einer Warteschlange.

      Der Vorgang zum Ausführen von Transaktionen in Redis ist wie folgt:

        Transaktion starten (MULTI)
      • Befehl in die Warteschlange stellen
      • Transaktion ausführen (EXEC), Transaktion abbrechen (DISCARD)
      Befehl. Beschreibung EXECAlle Befehle innerhalb des Transaktionsblocks ausführenDISCARDDie Transaktion abbrechen und die Ausführung aller Befehle innerhalb des Transaktionsblocks abbrechen UNWATCHWATCH

      17. Umgang mit Hash-Konflikten in Redis

      Redis ist eine K-V-In-Memory-Datenbank, die einen globalen Hash verwendet, um alle Schlüssel-Wert-Paare zu speichern. Diese Hash-Tabelle besteht aus mehreren Hash-Buckets. Das Eintragselement im Hash-Bucket speichert die key- und value-Zeiger, wobei *key auf den tatsächlichen Schlüssel und *value auf den tatsächlichen Wert zeigt.

      3Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

      Die Geschwindigkeit der Hash-Tabellensuche ist sehr hoch, ähnlich wie bei HashMap in Java, wodurch wir schnell Schlüssel-Wert-Paare in O(1)-Zeitkomplexität finden können. Berechnen Sie zunächst den Hash-Wert über den Schlüssel, suchen Sie den entsprechenden Hash-Bucket-Speicherort, suchen Sie dann den Eintrag und suchen Sie die entsprechenden Daten im Eintrag.

      Was ist eine Hash-Kollision?

      Hash-Konflikt: Derselbe Hash-Wert wird über verschiedene Schlüssel berechnet, was zu demselben Hash-Bucket führt.

      Um Hash-Konflikte zu lösen, verwendet Redis Chain-Hashing. Verkettetes Hashing bedeutet, dass mehrere Elemente im selben Hash-Bucket in einer verknüpften Liste gespeichert und nacheinander mithilfe von Zeigern verbunden werden.

      3Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

      Einige Leser haben möglicherweise noch Fragen: Elemente in der Hash-Konfliktkette können nur einzeln über Zeiger durchsucht und dann bearbeitet werden. Wenn viele Daten in die Hash-Tabelle eingefügt werden, wird die Konfliktverknüpfungsliste umso länger, je mehr Konflikte auftreten, und die Abfrageeffizienz wird verringert.

      Um die Effizienz aufrechtzuerhalten, führt Redis eine Rehash-Operation für die Hash-Tabelle durch, was bedeutet, dass Hash-Buckets hinzugefügt und Konflikte reduziert werden. Um die Wiederaufbereitung effizienter zu gestalten, verwendet Redis außerdem standardmäßig zwei globale Hash-Tabellen, eine für die aktuelle Verwendung, die sogenannte Haupt-Hash-Tabelle, und eine für die Erweiterung, die sogenannte Backup-Hash-Tabelle. 18. Kann Redis während der RDB-Generierung gleichzeitig Schreibanfragen verarbeiten?

      Ja, Redis bietet zwei Anweisungen zum Generieren von RDB, nämlich

      save und bgsave

      .

      Wenn es sich um eine Speicheranweisung handelt, wird sie blockiert, da sie vom Hauptthread ausgeführt wird. Wenn es sich um eine bgsave-Anweisung handelt, gibt sie einen untergeordneten Prozess zum Schreiben der RDB-Datei weiter. Die Snapshot-Persistenz wird vollständig vom untergeordneten Prozess verwaltet und der übergeordnete Prozess kann weiterhin Clientanforderungen verarbeiten.

      • 19. Welches Protokoll wird unten in Redis verwendet?
      • RESP, der vollständige englische Name ist Redis Serialization Protocol, eine Reihe von Serialisierungsprotokollen, die speziell für Redis entwickelt wurden. Dieses Protokoll erschien tatsächlich in Version 1.2 von Redis. Aber erst mit Redis2.0 wurde es schließlich zum Standard für das Redis-Kommunikationsprotokoll.
      RESP bietet vor allem die Vorteile einer einfachen Implementierung, einer schnellen Analysegeschwindigkeit und einer guten Lesbarkeit

      .

      20. Bloom-Filter

      Um das Problem der Cache-Penetration zu lösen, können wir den

      Bloom-Filter

      verwenden. Was ist ein Bloomfilter?

      Ein Bloom-Filter ist eine Datenstruktur, die sehr wenig Platz einnimmt. Er besteht aus einem langen Binärvektor und einer Reihe von Hash-Mapping-Funktionen. Er wird verwendet, um abzurufen, ob sich ein Element in einer Menge befindet, um Platzeffizienz und Abfragezeit zu ermitteln. Sie sind viel besser als gewöhnliche Algorithmen. Die Nachteile sind eine gewisse Fehlerkennungsrate und Schwierigkeiten beim Löschen. Was ist das Prinzip des Bloom-Filters? Angenommen, wir haben eine Menge A und es gibt n Elemente in A. Mithilfe von

      k-Hashing-Funktionen wird jedes Element

      in A verschiedenen Positionen in einem Array B mit einer Länge von einem Bit zugeordnet

      und die Binärzahlen an diesen Positionen werden alle auf 1 gesetzt. Wenn das zu prüfende Element durch diese k Hash-Funktionen abgebildet wird und sich herausstellt, dass die Binärzahlen

      an seinen k Positionen alle 1 sind, gehört dieses Element wahrscheinlich zur Menge A. Im Gegenteil, darf nicht zur Menge A gehören . . Schauen wir uns ein einfaches Beispiel an. Angenommen, Menge A hat 3 Elemente, nämlich {d1, d2, d3}. Es gibt 1 Hash-Funktion, nämlich Hash1. Ordnen Sie nun jedes Element von A einem Array B mit einer Länge von 16 Bit zu.

      Unter der Annahme, dass Hash1(d1) = 2 ist, ändern wir das Raster mit Index 2 in Array B wie folgt auf 1:

      3Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)Wir bilden jetzt auch

      d2 ab, vorausgesetzt Hash1 (d2) = 5, wir ändern das Raster mit Index 5 in Array B wie folgt auf 1:

      3Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

      Dann ordnen wir auch

      d3 zu, vorausgesetzt, Hash1(d3) ist ebenfalls gleich 2, was auch das markiert Raster mit Index 2 als 1:

      3Zusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse)

      Daher müssen wir bestätigen, ob sich ein Element dn in der Menge A befindet. Wir müssen nur den durch Hash1 (dn) erhaltenen Indexindex berechnen. Solange er 0 ist, bedeutet dies, dass sich dieses Element nicht in der Menge A befindet . Was ist, wenn der Indexindex 1 ist? Dann kann das Element ein Element in A sein. Wie Sie sehen, können die von d1 und d3 erhaltenen Indexwerte beide 1 sein oder durch andere Zahlen abgebildet werden. Der Bloom-Filter hat diesen Nachteil: Es kommt zu Fehlalarmen, die durch eine Hash-Kollision verursacht werden ist ein Fehler im Urteil. Wie diesen Fehler reduzieren?

      Erstellen Sie mehr Hash-Funktionszuordnungen, um die Wahrscheinlichkeit einer Hash-Kollision zu verringern

      Gleichzeitig kann eine Erhöhung der Bitlänge des B-Arrays den Bereich der von der Hash-Funktion generierten Daten vergrößern und auch die Wahrscheinlichkeit einer Hash-Kollision verringern

        Wir fügen eine weitere Hash2-Hash-Map-Funktion hinzu. Angenommen, Hash2 (d1) = 6, Hash2 (d3) = 8. Sie werden wie folgt nicht in Konflikt geraten: Selbst wenn ein Fehler vorliegt, können wir ihn finden Der Bloom-Filter speichert nicht die vollständigen Daten, sondern verwendet lediglich eine Reihe von Hash-Map-Funktionen, um die Position zu berechnen, und füllt dann den Binärvektor. Wenn die
      • Anzahl groß ist
      • , kann der Bloom-Filter durch eine sehr geringe Fehlerquote viel Speicherplatz sparen, was recht kostengünstig ist.
      • Derzeit verfügen Bloom-Filter bereits über Open-Source-Bibliotheken, die sie entsprechend implementieren, wie z. B. die Guava-Klassenbibliothek von Google und die Algebird-Klassenbibliothek von Twitter, die jederzeit verfügbar sind. Sie können aber auch Ihr eigenes Design basierend auf den mit Redis gelieferten Bitmaps implementieren .

      Weitere Kenntnisse zum Thema Programmierung finden Sie unter: Programmiervideos! !

      Abbrechen Der WATCH-Befehl überwacht alle Tasten.
      Überwachen Sie den Schlüssel, bevor die Transaktion ausgeführt wird.

    Das obige ist der detaillierte Inhalt vonZusammenfassung und Teilen von 20 klassischen Interviewfragen zu Redis (mit Antwortanalyse). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:juejin.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage