Heim  >  Artikel  >  Datenbank  >  20 Fragen, die in Redis gemeistert werden müssen, kommen Sie und sammeln Sie sie! !

20 Fragen, die in Redis gemeistert werden müssen, kommen Sie und sammeln Sie sie! !

青灯夜游
青灯夜游nach vorne
2021-10-19 10:31:241599Durchsuche

Dieser Artikel wird Ihnen 20 Redis-Probleme vorstellen, die Sie kennen und meistern müssen. Ich hoffe, er wird Ihnen helfen.

20 Fragen, die in Redis gemeistert werden müssen, kommen Sie und sammeln Sie sie! !

Was ist Redis?

Redis (Remote Dictionary Server) ist eine leistungsstarke, nicht relationale Schlüsselwertdatenbank, die in der Sprache C geschrieben ist. Im Gegensatz zu herkömmlichen Datenbanken werden Redis-Daten im Speicher gespeichert, sodass die Lese- und Schreibgeschwindigkeit sehr hoch ist und sie häufig beim Caching verwendet werden. Redis kann Daten auf die Festplatte schreiben und so Datensicherheit und -verlust gewährleisten, und Redis-Vorgänge sind atomar. [Verwandte Empfehlungen: Redis-Video-Tutorial]

Was sind die Vorteile von Redis?

  • Basierend auf dem Speicherbetrieb ist die Lese- und Schreibgeschwindigkeit des Speichers hoch.

  • Redis ist Single-Threaded, wodurch Thread-Switching-Overhead und Multi-Thread-Konkurrenzprobleme vermieden werden. Ein einzelner Thread bedeutet, dass Netzwerkanforderungen von einem Thread verarbeitet werden, d. h., dass ein Thread alle Netzwerkanforderungen verarbeitet, wenn Redis beispielsweise einen anderen Thread startet.

  • Unterstützt mehrere Datentypen, einschließlich String, Hash, List, Set, ZSet usw.

  • Unterstützen Sie die Ausdauer. Redis unterstützt zwei Persistenzmechanismen: RDB und AOF. Die Persistenzfunktion kann Datenverlustprobleme effektiv vermeiden.

  • Supportangelegenheiten. Alle Operationen von Redis sind atomar und Redis unterstützt auch die atomare Ausführung nach dem Zusammenführen mehrerer Operationen.

  • Unterstützt Master-Slave-Replikation. Der Master-Knoten synchronisiert die Daten automatisch mit dem Slave-Knoten und ermöglicht so eine Lese- und Schreibtrennung.

Warum ist Redis so schnell?

  • Basierend auf dem Arbeitsspeicher: Redis nutzt Arbeitsspeicher und hat keinen Festplatten-IO-Overhead. Die Daten werden im Speicher abgelegt und die Lese- und Schreibgeschwindigkeit ist hoch.
  • Single-Threaded-Implementierung (vor Redis 6.0): Redis verwendet einen einzelnen Thread zur Verarbeitung von Anforderungen und vermeidet so den Overhead durch Thread-Wechsel und Sperrressourcenkonflikte zwischen mehreren Threads.
  • IO-Multiplexing-Modell: Redis verwendet IO-Multiplexing-Technologie. Redis verwendet einen einzelnen Thread zum Abfragen von Deskriptoren und wandelt Datenbankoperationen in Ereignisse um, ohne zu viel Zeit mit Netzwerk-E/A zu verschwenden.
  • Effiziente Datenstruktur: Redis hat die unterste Ebene jedes Datentyps optimiert, um eine schnellere Geschwindigkeit zu erreichen.

Warum wählt Redis Single Thread?

  • Vermeiden Sie übermäßigen Kontextwechsel-Overhead. Das Programm wird dabei immer in einem einzelnen Thread ausgeführt, und es gibt kein Szenario für einen Multi-Thread-Wechsel.
  • Vermeiden Sie den Overhead des Synchronisationsmechanismus: Wenn Redis ein Multithread-Modell wählt und das Problem der Datensynchronisation berücksichtigen muss, werden zwangsläufig einige Synchronisationsmechanismen eingeführt, was zu mehr Overhead im Datenverarbeitungsprozess führt und zunimmt Die Komplexität des Programms verringert sich ebenfalls.
  • Einfache Implementierung und einfache Wartung: Wenn Redis den Multithreading-Modus verwendet, müssen beim Entwurf aller zugrunde liegenden Datenstrukturen Thread-Sicherheitsprobleme berücksichtigt werden, und die Implementierung von Redis wird komplizierter.

Was sind die Anwendungsszenarien von Redis?

  • Hotspot-Daten zwischenspeichern, um die Datenbank zu entlasten.

  • Mit der atomaren automatischen Inkrementierungsoperation von Redis können Sie die Funktionen von Zähler realisieren, z. B. das Zählen der Anzahl der Benutzer-Likes, Benutzerbesuche usw.

  • Einfache Nachrichtenwarteschlange Sie können den Redis-eigenen Publish/Subscribe-Modus oder die Liste verwenden, um eine einfache Nachrichtenwarteschlange zu implementieren und asynchrone Vorgänge zu implementieren.

  • Geschwindigkeitsbegrenzer kann verwendet werden, um die Häufigkeit des Zugriffs eines Benutzers auf eine bestimmte Oberfläche zu begrenzen. Beispielsweise wird das Flash-Sale-Szenario verwendet, um Benutzer vor unnötigem Druck durch schnelle Klicks zu schützen.

  • Freundschaftsbeziehung, wobei einige Sammlungsbefehle wie Schnittmenge, Vereinigung, Differenzmenge usw. verwendet werden, um Funktionen wie gemeinsame Freunde und gemeinsame Hobbys zu realisieren.

Was ist der Unterschied zwischen Memcached und Redis?

  • Redis verwendet nur Einzelkern, während Memcached mehrere Kerne verwenden kann.

  • MemCached hat eine einzige Datenstruktur und wird nur zum Zwischenspeichern von Daten verwendet, während Redis mehrere Datentypen unterstützt.

  • MemCached unterstützt keine Datenpersistenz und die Daten verschwinden nach dem Neustart. Redis unterstützt Datenpersistenz.

  • Redis bietet Master-Slave-Synchronisationsmechanismen und Cluster-Bereitstellungsfunktionen, die hochverfügbare Dienste bereitstellen können. Memcached bietet keinen nativen Cluster-Modus und muss sich darauf verlassen, dass der Client Daten in Shards im Cluster schreibt.

  • Redis ist viel schneller als Memcached.

  • Redis verwendet ein Single-Threaded-Multi-Channel-IO-Wiederverwendungsmodell und Memcached verwendet ein Multithread-Non-Blocking-IO-Modell.

Was sind die Datentypen von Redis?

Grundlegende Datentypen:

1, String: Die am häufigsten verwendeten Datentypwerte können Zeichenfolgen, Zahlen oder Binärwerte sein, der Maximalwert darf jedoch 512 MB nicht überschreiten.

2, Hash: Hash ist eine Sammlung von Schlüssel-Wert-Paaren.

3. Set: Ein ungeordnetes und dedupliziertes Set. Set bietet Methoden wie Schnittmenge und Vereinigung, was besonders praktisch ist, um Funktionen wie gemeinsame Freunde und gemeinsame Aufmerksamkeit zu realisieren.

4, Liste: Eine geordnete und wiederholbare Sammlung. Die unterste Ebene wird mithilfe einer doppelt verknüpften Liste implementiert.

5, SortedSet(ZSet): Geordneter Satz. Für die Implementierung wird intern ein score-Parameter gepflegt. Geeignet für Szenarien wie Rankings und gewichtete Nachrichtenwarteschlangen. score的参数来实现。适用于排行榜和带权重的消息队列等场景。

特殊的数据类型

1、Bitmap:位图,可以认为是一个以位为单位数组,数组中的每个单元只能存0或者1,数组的下标在 Bitmap 中叫做偏移量。Bitmap的长度与集合中元素个数无关,而是与基数的上限有关。

2、Hyperloglog。HyperLogLog 是用来做基数统计的算法,其优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。典型的使用场景是统计独立访客。

3、Geospatial :主要用于存储地理位置信息,并对存储的信息进行操作,适用场景如定位、附近的人等。

Redis事务

事务的原理是将一个事务范围内的若干命令发送给 Redis,然后再让 Redis 依次执行这些命令。

事务的生命周期:

  • 使用MULTI开启一个事务;

  • 在开启事务的时候,每次操作的命令将会被插入到一个队列中,同时这个命令并不会被真正执行;

  • EXEC命令进行提交事务。

20 Fragen, die in Redis gemeistert werden müssen, kommen Sie und sammeln Sie sie! !

一个事务范围内某个命令出错不会影响其他命令的执行,不保证原子性:

first:0>MULTI
"OK"
first:0>set a 1
"QUEUED"
first:0>set b 2 3 4
"QUEUED"
first:0>set c 6
"QUEUED"
first:0>EXEC
1) "OK"
2) "OK"
3) "OK"
4) "ERR syntax error"
5) "OK"
6) "OK"
7) "OK"

WATCH命令

WATCH命令可以监控一个或多个键,一旦其中有一个键被修改,之后的事务就不会执行(类似于乐观锁)。执行EXEC命令之后,就会自动取消监控。

first:0>watch name
"OK"
first:0>set name 1
"OK"
first:0>MULTI
"OK"
first:0>set name 2
"QUEUED"
first:0>set gender 1
"QUEUED"
first:0>EXEC
(nil)
first:0>get gender
(nil)

比如上面的代码中:

  1. watch name开启了对name这个key的监控
  2. 修改name的值
  3. 开启事务a
  4. 在事务a中设置了namegender的值
  5. 使用EXEC命令进提交事务
  6. 使用命令get gender发现不存在,即事务a没有执行

使用UNWATCH可以取消WATCH命令对key的监控,所有监控锁将会被取消。

持久化机制

持久化就是把内存的数据写到磁盘中,防止服务宕机导致内存数据丢失。

Redis支持两种方式的持久化,一种是RDB的方式,一种是AOF的方式。前者会根据指定的规则定时将内存中的数据存储在硬盘上,而后者在每次执行完命令后将命令记录下来。一般将两者结合使用。

RDB方式

RDB是 Redis 默认的持久化方案。RDB持久化时会将内存中的数据写入到磁盘中,在指定目录下生成一个dump.rdb文件。Redis 重启会加载dump.rdb文件恢复数据。

bgsave是主流的触发 RDB 持久化的方式,执行过程如下:

20 Fragen, die in Redis gemeistert werden müssen, kommen Sie und sammeln Sie sie! !

  • 执行BGSAVE命令
  • Redis 父进程判断当前是否存在正在执行的子进程,如果存在,BGSAVE命令直接返回。
  • 父进程执行fork操作创建子进程,fork操作过程中父进程会阻塞。
  • 父进程forkSpezielle Datentypen:
  • 1,
  • Bitmap: Bitmap, die als Array von Bits betrachtet werden kann. Jede Einheit im Array kann nur 0 oder 1 speichern. Der Index des Arrays befindet sich in Bitmap wird Offset genannt. Die Länge von Bitmap hat nichts mit der Anzahl der Elemente in der Sammlung zu tun, sondern hängt mit der Obergrenze der Kardinalität zusammen.
  • 2,
Hyperloglog

. HyperLogLog ist ein Algorithmus für Kardinalitätsstatistiken. Sein Vorteil besteht darin, dass der für die Berechnung der Kardinalität erforderliche Platz immer fest und sehr klein ist, wenn die Anzahl oder das Volumen der Eingabeelemente sehr groß ist. Ein typisches Nutzungsszenario ist das Zählen einzelner Besucher.

3,

Geospatial🎜: Wird hauptsächlich zum Speichern geografischer Standortinformationen und zum Bearbeiten der gespeicherten Informationen wie Standortbestimmung, Personen in der Nähe usw. verwendet. 🎜

Redis-Transaktion🎜🎜Das Prinzip der Transaktion besteht darin, mehrere Befehle innerhalb eines Transaktionsbereichs an Redis zu senden und Redis diese Befehle dann nacheinander ausführen zu lassen. 🎜🎜Transaktionslebenszyklus: 🎜
    🎜🎜Verwenden Sie MULTI, um eine Transaktion zu eröffnen; 🎜🎜🎜🎜Beim Öffnen einer Transaktion wird jedes Mal Der Operationsbefehl wird in eine Warteschlange eingefügt und dieser Befehl wird nicht tatsächlich ausgeführt. Der Befehl 🎜🎜🎜🎜EXEC schreibt die Transaktion fest. 🎜🎜🎜🎜20 Fragen, die in Redis gemeistert werden müssen, kommen Sie und sammeln Sie sie! !🎜🎜Ein Fehler in einem Befehl innerhalb eines Transaktionsbereichs hat keinen Einfluss auf die Ausführung anderer Befehle und die Atomizität ist nicht garantiert: 🎜
    appendfsync always //每次写入aof文件都会执行同步,最安全最慢,不建议配置
    appendfsync everysec  //既保证性能也保证安全,建议配置
    appendfsync no //由操作系统决定何时进行同步操作
    🎜🎜WATCH-Befehl🎜🎜🎜WATCH kann einen oder mehrere Schlüssel überwachen. Sobald einer der Schlüssel geändert wird, werden nachfolgende Transaktionen nicht ausgeführt (ähnlich wie beim optimistischen Sperren). Nach Ausführung des Befehls <code>EXEC wird die Überwachung automatisch abgebrochen. 🎜
    //启动Redis实例作为主数据库
    redis-server  
    //启动另一个实例作为从数据库
    redis-server --port 6380 --slaveof  127.0.0.1 6379   
    slaveof 127.0.0.1 6379
    //停止接收其他数据库的同步并转化为主数据库
    SLAVEOF NO ONE
    🎜Zum Beispiel im obigen Code: 🎜
      🎜Name der Uhr aktiviert die Überwachung von name dieser Taste 🎜🎜Ändern Der Wert von name🎜🎜Öffnen Sie Transaktion a🎜🎜Die Werte von name und gender werden in Transaktion a festgelegt🎜🎜Verwenden Sie EXECBefehl zum Senden der Transaktion🎜🎜Verwenden Sie den Befehl get gender, um festzustellen, dass es nicht existiert, d. h. Transaktion a wurde nicht ausgeführt🎜
    🎜Verwenden Sie UNWATCH zum Abbrechen von WATCH Der Code>-Befehl überwacht den <code>Schlüssel und alle Überwachungssperren werden aufgehoben. 🎜

    Persistenzmechanismus🎜🎜Persistenz besteht darin, 🎜Speicherdaten auf die Festplatte zu schreiben🎜, um Speicherdatenverluste durch Dienstausfallzeiten zu verhindern. 🎜🎜Redis unterstützt zwei Persistenzmethoden, eine ist die RDB-Methode und die andere ist die AOF-Methode. 🎜Ersterer speichert die Daten regelmäßig gemäß den festgelegten Regeln im Speicher auf der Festplatte🎜, während 🎜Letzterer den Befehl nach jeder Befehlsausführung aufzeichnet🎜. Im Allgemeinen wird eine Kombination aus beiden verwendet. 🎜

    RDB-Methode

    🎜RDB ist die Standardpersistenzlösung von Redis. Wenn RDB beibehalten wird, werden die Daten im Speicher auf die Festplatte geschrieben und eine dump.rdb-Datei im angegebenen Verzeichnis generiert. Durch einen Neustart von Redis wird die Datei dump.rdb geladen, um die Daten wiederherzustellen. 🎜🎜bgsave ist die gängige Methode zum Auslösen der RDB-Persistenz. Der Ausführungsprozess ist wie folgt: 🎜🎜20 Fragen, die in Redis gemeistert werden müssen, kommen Sie und sammeln Sie sie! !🎜
      🎜Führen Sie den BGSAVE-Befehl aus🎜🎜Der übergeordnete Redis-Prozess bestimmt, ob derzeit welche vorhanden sind Ausführen des untergeordneten Prozesses 🎜, falls vorhanden, gibt der Befehl BGSAVE direkt zurück. 🎜🎜Der übergeordnete Prozess führt die fork-Operation aus, um einen untergeordneten Prozess zu erstellen. Der übergeordnete Prozess wird während der fork-Operation blockiert. 🎜🎜Nachdem der übergeordnete Prozess fork abgeschlossen ist, 🎜der übergeordnete Prozess empfängt und verarbeitet weiterhin die Anfrage des Clients🎜 und 🎜der untergeordnete Prozess beginnt, die Daten im Speicher in die temporäre Datei auf dem zu schreiben Festplatte🎜; 🎜🎜Wenn der untergeordnete Prozess alle Daten geschrieben hat, wird die alte RDB-Datei durch diese temporäre Datei ersetzt. 🎜🎜🎜Wenn Redis startet, liest es die RDB-Snapshot-Datei und lädt die Daten von der Festplatte in den Speicher. Durch die RDB-Persistenz gehen die seit der letzten Persistenz geänderten Daten verloren, sobald Redis abnormal beendet wird. 🎜🎜So lösen Sie die RDB-Persistenz aus:🎜
    1. 手动触发:用户执行SAVEBGSAVE命令。SAVE命令执行快照的过程会阻塞所有客户端的请求,应避免在生产环境使用此命令。BGSAVE命令可以在后台异步进行快照操作,快照的同时服务器还可以继续响应客户端的请求,因此需要手动执行快照时推荐使用BGSAVE命令。

    2. 被动触发

      • 根据配置规则进行自动快照,如SAVE 100 10,100秒内至少有10个键被修改则进行快照。
      • 如果从节点执行全量复制操作,主节点会自动执行BGSAVE生成 RDB 文件并发送给从节点。
      • 默认情况下执行shutdown命令时,如果没有开启 AOF 持久化功能则自动执行·BGSAVE·。

优点

  • Redis 加载 RDB 恢复数据远远快于 AOF 的方式

  • 使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 Redis 的高性能

缺点

  • RDB方式数据无法做到实时持久化。因为BGSAVE每次运行都要执行fork操作创建子进程,属于重量级操作,频繁执行成本比较高。

  • RDB 文件使用特定二进制格式保存,Redis 版本升级过程中有多个格式的 RDB 版本,存在老版本 Redis 无法兼容新版 RDB 格式的问题

AOF方式

AOF(append only file)持久化:以独立日志的方式记录每次写命令,Redis重启时会重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性,AOF 是Redis持久化的主流方式。

默认情况下Redis没有开启AOF方式的持久化,可以通过appendonly参数启用:appendonly yes。开启AOF方式持久化后每执行一条写命令,Redis就会将该命令写进aof_buf缓冲区,AOF缓冲区根据对应的策略向硬盘做同步操作。

默认情况下系统每30秒会执行一次同步操作。为了防止缓冲区数据丢失,可以在Redis写入AOF文件后主动要求系统将缓冲区数据同步到硬盘上。可以通过appendfsync参数设置同步的时机。

appendfsync always //每次写入aof文件都会执行同步,最安全最慢,不建议配置
appendfsync everysec  //既保证性能也保证安全,建议配置
appendfsync no //由操作系统决定何时进行同步操作

接下来看一下 AOF 持久化执行流程:

20 Fragen, die in Redis gemeistert werden müssen, kommen Sie und sammeln Sie sie! !

  • 所有的写入命令会追加到 AOP 缓冲区中。

  • AOF 缓冲区根据对应的策略向硬盘同步。

  • 随着 AOF 文件越来越大,需要定期对 AOF 文件进行重写,达到压缩文件体积的目的。AOF文件重写是把Redis进程内的数据转化为写命令同步到新AOF文件的过程。

  • 当 Redis 服务器重启时,可以加载 AOF 文件进行数据恢复。

优点

  • AOF可以更好的保护数据不丢失,可以配置 AOF 每秒执行一次fsync操作,如果Redis进程挂掉,最多丢失1秒的数据。

  • AOF以append-only的模式写入,所以没有磁盘寻址的开销,写入性能非常高。

缺点

  • 对于同一份文件AOF文件比RDB数据快照要大。

  • 数据恢复比较慢。

主从复制

Redis的复制功能是支持多个数据库之间的数据同步。主数据库可以进行读写操作,当主数据库的数据发生变化时会自动将数据同步到从数据库。从数据库一般是只读的,它会接收主数据库同步过来的数据。一个主数据库可以有多个从数据库,而一个从数据库只能有一个主数据库。

//启动Redis实例作为主数据库
redis-server  
//启动另一个实例作为从数据库
redis-server --port 6380 --slaveof  127.0.0.1 6379   
slaveof 127.0.0.1 6379
//停止接收其他数据库的同步并转化为主数据库
SLAVEOF NO ONE

主从复制的原理?

  • 当启动一个从节点时,它会发送一个 PSYNC 命令给主节点;

  • 如果是从节点初次连接到主节点,那么会触发一次全量复制。此时主节点会启动一个后台线程,开始生成一份 RDB 快照文件;

  • 同时还会将从客户端 client 新收到的所有写命令缓存在内存中。RDB 文件生成完毕后, 主节点会将RDB文件发送给从节点,从节点会先将RDB文件写入本地磁盘,然后再从本地磁盘加载到内存中

  • Dann sendet der Master-Knoten den im Speicher zwischengespeicherten Schreibbefehl an den Slave-Knoten und der Slave-Knoten synchronisiert die Daten.

  • Wenn ein Netzwerkfehler zwischen dem Slave-Knoten und dem Master-Knoten auftritt Wenn die Verbindung getrennt wird, wird die Verbindung automatisch wiederhergestellt. Nach dem Herstellen der Verbindung synchronisiert der Master-Knoten nur einen Teil der fehlenden Daten mit dem Slave-Knoten.

Sentinel

Bei der Master-Slave-Replikation besteht das Problem, dass kein automatisches Failover möglich ist und keine hohe Verfügbarkeit erreicht werden kann. Der Sentry-Modus löst diese Probleme. Der Sentinel-Mechanismus kann automatisch zwischen Master- und Slave-Knoten wechseln.

Wenn der Client eine Verbindung zu Redis herstellt, stellt er zunächst eine Verbindung zum Sentinel her. Der Sentinel teilt dem Client die Adresse des Redis-Masterknotens mit, und dann stellt der Client eine Verbindung zu Redis her und führt nachfolgende Vorgänge aus. Wenn der Master-Knoten ausfällt, erkennt Sentinel, dass der Master-Knoten ausgefallen ist, und wählt einen Slave-Knoten mit guter Leistung erneut zum neuen Master-Knoten und benachrichtigt dann andere Slave-Server über den Publish-Subscribe-Modus, damit sie wechseln können Gastgeber.

20 Fragen, die in Redis gemeistert werden müssen, kommen Sie und sammeln Sie sie! !

Wie es funktioniert

  • Jeder Sentinel sendet einmal pro Sekunde Nachrichten an den ihm bekannten Master und Slave und Andere Sentinel-Instanzen senden einen PING-Befehl. Sentinel以每秒钟一次的频率向它所知道的MasterSlave以及其他 Sentinel实例发送一个 PING命令。
  • 如果一个实例距离最后一次有效回复 PING 命令的时间超过指定值, 则这个实例会被 Sentine 标记为主观下线。
  • 如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel要以每秒一次的频率确认Master是否真正进入主观下线状态。
  • 当有足够数量的 Sentinel(大于等于配置文件指定值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线 。若没有足够数量的 Sentinel同意 Master 已经下线, Master 的客观下线状态就会被解除。若 Master重新向 SentinelPING 命令返回有效回复, Master 的主观下线状态就会被移除。
  • 哨兵节点会选举出哨兵 leader,负责故障转移的工作。
  • 哨兵 leader 会推选出某个表现良好的从节点成为新的主节点,然后通知其他从节点更新主节点信息。

Redis cluster

哨兵模式解决了主从复制不能自动故障转移、达不到高可用的问题,但还是存在主节点的写能力、容量受限于单机配置的问题。而cluster模式实现了Redis的分布式存储,每个节点存储不同的内容,解决主节点的写能力、容量受限于单机配置的问题。

Redis cluster集群节点最小配置6个节点以上(3主3从),其中主节点提供读写操作,从节点作为备用节点,不提供请求,只作为故障转移使用。

Redis cluster采用虚拟槽分区,所有的键根据哈希函数映射到0~16383个整数槽内,每个节点负责维护一部分槽以及槽所映射的键值数据。

20 Fragen, die in Redis gemeistert werden müssen, kommen Sie und sammeln Sie sie! !

哈希槽是如何映射到 Redis 实例上的?

  • 对键值对的key使用 crc16 算法计算一个结果

  • 将结果对 16384 取余,得到的值表示 key 对应的哈希槽

  • 根据该槽信息定位到对应的实例

优点:

  • 无中心架构,支持动态扩容;
  • 数据按照slot存储分布在多个节点,节点间数据共享,可动态调整数据分布
  • 高可用性。部分节点不可用时,集群仍可用。集群模式能够实现自动故障转移(failover),节点之间通过gossip协议交换状态信息,用投票机制完成SlaveMaster
  • Wenn die Zeit seit der letzten gültigen Antwort auf den PING-Befehl für eine Instanz den angegebenen Wert überschreitet, wird die Instanz von Sentine als subjektiv offline markiert.

Wenn ein Master als subjektiv offline markiert ist, müssen alle Sentinel, die diesen Master überwachen, einmal pro Sekunde bestätigen, ob der Code>Master ist /code> geht tatsächlich in den subjektiven Offline-Zustand über. Wenn eine ausreichende Anzahl von Sentinel (größer oder gleich dem in der Konfigurationsdatei angegebenen Wert) bestätigt, dass Master tatsächlich innerhalb der angegebenen Zeit in den subjektiven Offline-Status eingetreten ist Bereich, dann wird Master als objektiv offline markiert. Wenn nicht genügend Sentinel vorhanden sind, um zu bestätigen, dass Master offline ist, wird der objektive Offline-Status von Master aufgehoben. Wenn Master eine gültige Antwort auf den PING-Befehl von Sentinel zurückgibt, wird der subjektive Offline-Status von Master verschoben entfernen.

🎜Der Sentinel-Knoten wählt einen Sentinel-Leiter, der für das Failover verantwortlich ist. 🎜🎜Der Sentry-Anführer wählt einen Slave-Knoten mit guter Leistung zum neuen Master-Knoten und benachrichtigt dann andere Slave-Knoten, um die Master-Knoteninformationen zu aktualisieren. 🎜🎜

Redis-Cluster🎜🎜Der Sentinel-Modus löst das Problem, dass die Master-Slave-Replikation kein automatisches Failover durchführen und keine hohe Verfügbarkeit erreichen kann, verfügt aber dennoch über begrenzte Schreibfunktionen und Kapazität des Masterknotens Probleme mit der eigenständigen Konfiguration. Der Clustermodus implementiert die verteilte Speicherung von Redis, und jeder Knoten speichert unterschiedliche Inhalte, wodurch das Problem gelöst wird, dass die Schreibfähigkeit und Kapazität des Masterknotens durch die Einzelmaschinenkonfiguration begrenzt sind. 🎜🎜Die Mindestkonfiguration eines Redis-Cluster-Knotens beträgt mehr als 6 Knoten (3 Master und 3 Slaves). Der Master-Knoten stellt Lese- und Schreibvorgänge bereit, und der Slave-Knoten dient als Backup-Knoten, stellt keine Anforderungen bereit und dient nur dazu Wird für Failover verwendet. 🎜🎜Redis-Cluster verwendet 🎜virtuelle Slot-Partitionierung🎜 Alle Schlüssel werden gemäß der Hash-Funktion 0 bis 16383 Ganzzahl-Slots zugeordnet. Jeder Knoten ist für die Verwaltung eines Teils der Slots und der durch die Slots zugeordneten Schlüsselwertdaten verantwortlich. 🎜🎜20 Fragen, die in Redis gemeistert werden müssen, kommen Sie und sammeln Sie sie! !🎜🎜🎜 Wie werden Hash-Slots Redis-Instanzen zugeordnet? 🎜🎜
    🎜🎜Verwenden Sie den crc16-Algorithmus für den key des Schlüssel-Wert-Paares, um ein Ergebnis zu berechnen 🎜🎜🎜🎜 Das Ergebnis ist ein Modul von 16384, und der erhaltene Wert stellt den Hash-Slot dar, der key entspricht🎜🎜🎜🎜Die entsprechende Instanz wird basierend auf den Slot-Informationen lokalisiert🎜🎜🎜🎜🎜Vorteile: 🎜🎜🎜🎜Keine zentrale Architektur, 🎜Unterstützt dynamische Erweiterung; 🎜🎜Daten werden je nach Slot gespeichert und verteilt, und Daten werden zwischen Knoten geteilt. 🎜Die Datenverteilung kann dynamisch angepasst werden ; 🎜🎜🎜Hohe Verfügbarkeit🎜. Der Cluster ist weiterhin verfügbar, wenn einige Knoten nicht verfügbar sind. Der Cluster-Modus kann ein automatisches Failover realisieren. Die Knoten tauschen Statusinformationen über das gossip-Protokoll aus und nutzen den Abstimmungsmechanismus, um die Übertragung vom Slave zum Master abzuschließen. Code>. Rollentausch. 🎜🎜🎜🎜Nachteile: 🎜🎜<ul> <li> <strong>Batch-Operationen</strong> (Pipeline) werden nicht unterstützt. </li> <li>Daten werden asynchron kopiert, <strong>eine starke Konsistenz der Daten ist nicht garantiert</strong>. </li> <li> <strong>Die Unterstützung für Transaktionsvorgänge ist begrenzt. Es werden nur mehrere <code>Schlüssel-Transaktionsvorgänge auf demselben Knoten unterstützt. Wenn mehrere Schlüssel auf verschiedene Knoten verteilt sind, ist dies nicht möglich gebraucht. . key在同一节点上的事务操作,当多个key分布于不同的节点上时无法使用事务功能。
  • key作为数据分区的最小粒度,不能将一个很大的键值对象如hashlist等映射到不同的节点。
  • 不支持多数据库空间,单机下的Redis可以支持到16个数据库,集群模式下只能使用1个数据库空间。

过期键的删除策略?

1、被动删除(惰性)。在访问key时,如果发现key已经过期,那么会将key删除。

2、主动删除(定期)。定时清理key,每次清理会依次遍历所有DB,从db随机取出20个key,如果过期就删除,如果其中有5个key过期,那么就继续对这个db进行清理,否则开始清理下一个db。

3、内存不够时清理。Redis有最大内存的限制,通过maxmemory参数可以设置最大内存,当使用的内存超过了设置的最大内存,就要进行内存释放, 在进行内存释放的时候,会按照配置的淘汰策略清理内存。

内存淘汰策略有哪些?

当Redis的内存超过最大允许的内存之后,Redis 会触发内存淘汰策略,删除一些不常用的数据,以保证Redis服务器正常运行。

Redisv4.0前提供 6 种数据淘汰策略

  • volatile-lru:LRU(Least Recently Used),最近使用。利用LRU算法移除设置了过期时间的key
  • allkeys-lru:当内存不足以容纳新写入数据时,从数据集中移除最近最少使用的key
  • volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰
  • volatile-random:从已设置过期时间的数据集中任意选择数据淘汰
  • allkeys-random:从数据集中任意选择数据淘汰
  • no-eviction:禁止删除数据,当内存不足以容纳新写入数据时,新写入操作会报错

Redisv4.0后增加以下两种

  • volatile-lfu:LFU,Least Frequently Used,最少使用,从已设置过期时间的数据集中挑选最不经常使用的数据淘汰。
  • allkeys-lfu:当内存不足以容纳新写入数据时,从数据集中移除最不经常使用的key。

内存淘汰策略可以通过配置文件来修改,相应的配置项是maxmemory-policy,默认配置是noevictionkey ist die minimale Granularität der Datenpartitionierung. Ein großes Schlüsselwertobjekt wie hash, list usw. kann nicht zugeordnet werden verschiedene Knoten.

Unterstützt nicht mehrere Datenbankbereiche

Im Standalone-Modus kann Redis bis zu 16 Datenbanken unterstützen, und im Clustermodus kann nur 1 Datenbankbereich verwendet werden.

Löschstrategie für abgelaufene Schlüssel? 1.

Passives Löschen (faul)

. Wenn beim Zugriff auf den Schlüssel festgestellt wird, dass der Schlüssel abgelaufen ist, wird der Schlüssel gelöscht.

2.

Aktiv (regelmäßig) löschen. Bei jeder Bereinigung werden alle Datenbanken nach dem Zufallsprinzip durchlaufen, 20 Schlüssel werden aus der Datenbank entfernt und bei Ablauf gelöscht. Wenn 5 Schlüssel ablaufen, fahren Sie mit der Bereinigung dieser Datenbank fort, andernfalls beginnen Sie mit der Bereinigung der nächsten Datenbank.

3.

Räumen Sie auf, wenn der Speicher nicht ausreicht

. Redis verfügt über ein maximales Speicherlimit, das über den Parameter „maxmemory“ festgelegt werden kann. Wenn der verwendete Speicher den festgelegten maximalen Speicher überschreitet, muss der Speicher gemäß der konfigurierten Eliminierungsstrategie freigegeben werden.

Welche Strategien zur Gedächtnisbeseitigung gibt es?

Wenn der Speicher von Redis den maximal zulässigen Speicher überschreitet, löst Redis die Speicherbeseitigungsstrategie aus und löscht einige selten verwendete Daten, um den normalen Betrieb des Redis-Servers sicherzustellen.

Redisv4.0 bietet 6 Dateneliminierungsstrategien

:

volatile-lru: LRU (Least Latest Used), kürzlich verwendet. Verwenden Sie den LRU-Algorithmus, um Schlüssel mit festgelegter Ablaufzeit zu entfernen

allkeys-lru

: Wenn der Speicher nicht ausreicht, um neu geschriebene Daten aufzunehmen, entfernen Sie den am längsten verwendeten Schlüssel aus dem Datensatz Wählen Sie Daten aus dem Datensatz aus, die mit einer Ablaufzeit ablaufen, und löschen Sie sie Löschen Sie den Datensatz und löschen Sie ihn Redisv4.0, die folgenden zwei Typen

wurden hinzugefügt:

    volatile-lfu
  • : LFU, Least Frequently Used, am wenigsten verwendet, wählt die am wenigsten häufig verwendeten Daten aus dem Datensatz mit einer Ablaufzeit aus und eliminiert sie.

    allkeys-lfu

    : Wenn der Speicher nicht ausreicht, um neu geschriebene Daten aufzunehmen, entfernen Sie die am seltensten verwendeten Schlüssel aus dem Datensatz. 🎜
🎜🎜Die Speichereliminierungsrichtlinie kann über die Konfigurationsdatei geändert werden🎜 Das entsprechende Konfigurationselement ist maxmemory-policy und die Standardkonfiguration ist noeviction. 🎜🎜Wie kann die Datenkonsistenz beim doppelten Schreiben zwischen Cache und Datenbank sichergestellt werden? 🎜🎜🎜1. Löschen Sie zuerst den Cache und aktualisieren Sie dann die Datenbank. 🎜🎜🎜Wenn Sie einen Aktualisierungsvorgang durchführen, löschen Sie zuerst den Cache und aktualisieren Sie dann die Datenbank. Wenn nachfolgende Anforderungen erneut gelesen werden, werden die neuen Daten aus der Datenbank gelesen dann im Cache aktualisiert. 🎜🎜Bestehende Probleme: Wenn nach dem Löschen zwischengespeicherter Daten und vor dem Aktualisieren der Datenbank in diesem Zeitraum eine neue Leseanforderung vorliegt, werden die alten Daten aus der Datenbank gelesen und neu in den Cache geschrieben, was erneut zu Inkonsistenzen führt und nachfolgende Lesevorgänge auftreten scheitern. Es sind alles alte Daten. 🎜🎜🎜2. Aktualisieren Sie zuerst die Datenbank und löschen Sie dann den Cache. 🎜🎜🎜 Wenn Sie einen Aktualisierungsvorgang durchführen, aktualisieren Sie zuerst MySQL. Löschen Sie dann den Cache und schreiben Sie dann bei nachfolgenden Leseanforderungen die neuen Daten zurück. 🎜🎜Bestehendes Problem: Während der Zeit zwischen der Aktualisierung von MySQL und dem Löschen des Caches handelt es sich bei der Leseanforderung immer noch um die zwischengespeicherten alten Daten. Wenn die Datenbankaktualisierung jedoch abgeschlossen ist, sind sie konsistent und die Auswirkungen sind relativ gering. 🎜🎜🎜3. Asynchroner Update-Cache🎜🎜🎜Nach Abschluss des Datenbank-Update-Vorgangs wird der Cache nicht direkt ausgeführt. Stattdessen wird der Operationsbefehl in eine Nachricht gekapselt und in die Nachrichtenwarteschlange geworfen, und dann verbraucht Redis selbst die Aktualisierung Die Nachrichtenwarteschlange kann die Konsistenz der Datenoperationssequenz gewährleisten und sicherstellen, dass die Daten im Cache-System normal sind. 🎜🎜🎜Cache-Penetration, Cache-Lawine, Cache-Aufschlüsselung [Detaillierte Erklärung]🎜Redis-Cache-Penetration, Penetration, Lawinenkonzepte und -lösungen🎜🎜🎜🎜Cache-Penetration🎜🎜Cache-Penetration bezieht sich auf die Abfrage von 🎜nicht vorhandenen Daten 🎜, da der Cache Bei einem Fehler wird passiv geschrieben. Wenn die Daten nicht in der Datenbank gefunden werden können, werden sie nicht in den Cache geschrieben. Dies führt dazu, dass die nicht vorhandenen Daten bei jeder Anforderung in der Datenbank abgefragt werden und verloren gehen Bedeutung von Caching. Bei starkem Datenverkehr kann die DB hängen bleiben. 🎜🎜🎜🎜🎜Cache-Nullwert🎜 und überprüft die Datenbank nicht. 🎜
  • 采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,查询不存在的数据会被这个bitmap拦截掉,从而避免了对DB的查询压力。

  • 布隆过滤器的原理:当一个元素被加入集合时,通过K个散列函数将这个元素映射成一个位数组中的K个点,把它们置为1。查询时,将元素通过散列函数映射之后会得到k个点,如果这些点有任何一个0,则被检元素一定不在,直接返回;如果都是1,则查询元素很可能存在,就会去查询Redis和数据库。

    缓存雪崩

    缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重挂掉。

    解决方法:在原有的失效时间基础上增加一个随机值,使得过期时间分散一些。

    缓存击穿

    缓存击穿:大量的请求同时查询一个 key 时,此时这个 key 正好失效了,就会导致大量的请求都落到数据库。缓存击穿是查询缓存中失效的 key,而缓存穿透是查询不存在的 key。

    解决方法:加分布式锁,第一个请求的线程可以拿到锁,拿到锁的线程查询到了数据之后设置缓存,其他的线程获取锁失败会等待50ms然后重新到缓存取数据,这样便可以避免大量的请求落到数据库。

    public String get(String key) {
        String value = redis.get(key);
        if (value == null) { 
            //缓存值过期
            String unique_key = systemId + ":" + key;
            //设置30s的超时
            if (redis.set(unique_key, 1, &#39;NX&#39;, &#39;PX&#39;, 30000) == 1) {  //设置成功
                value = db.get(key);
                redis.set(key, value, expire_secs);
                redis.del(unique_key);
            } else {  
                //其他线程已经到数据库取值并回写到缓存了,可以重试获取缓存值
                sleep(50);
                get(key);  //重试
            }
        } else {
            return value;
        }
    }

    pipeline的作用?

    redis客户端执行一条命令分4个过程:发送命令、命令排队、命令执行、返回结果。使用pipeline可以批量请求,批量返回结果,执行速度比逐条执行要快。

    使用pipeline组装的命令个数不能太多,不然数据量过大,增加客户端的等待时间,还可能造成网络阻塞,可以将大量命令的拆分多个小的pipeline命令完成。

    原生批命令(mset和mget)与pipeline对比:

    • 原生批命令是原子性,pipeline非原子性。pipeline命令中途异常退出,之前执行成功的命令不会回滚

    • 原生批命令只有一个命令,但pipeline支持多命令

    LUA脚本

    Redis 通过 LUA 脚本创建具有原子性的命令:当lua脚本命令正在运行的时候,不会有其他脚本或 Redis 命令被执行,实现组合命令的原子操作。

    在Redis中执行Lua脚本有两种方法:evalevalshaeval命令使用内置的 Lua 解释器,对 Lua 脚本进行求值。

    //第一个参数是lua脚本,第二个参数是键名参数个数,剩下的是键名参数和附加参数
    > eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
    1) "key1"
    2) "key2"
    3) "first"
    4) "second"

    lua脚本作用

    1、Lua脚本在Redis中是原子执行的,执行过程中间不会插入其他命令。

    2、Lua脚本可以将多条命令一次性打包,有效地减少网络开销。

    应用场景

    举例:限制接口访问频率。

    在Redis维护一个接口访问次数的键值对,key是接口名称,value是访问次数。每次访问接口时,会执行以下操作:

    • 通过aop拦截接口的请求,对接口请求进行计数,每次进来一个请求,相应的接口访问次数count加1,存入redis。
    • 如果是第一次请求,则会设置count=1,并设置过期时间。因为这里set()expire()组合操作不是原子操作,所以引入lua脚本,实现原子操作,避免并发访问问题。
    • 如果给定时间范围内超过最大访问次数,则会抛出异常。
    private String buildLuaScript() {
        return "local c" +
            "\nc = redis.call(&#39;get&#39;,KEYS[1])" +
            "\nif c and tonumber(c) > tonumber(ARGV[1]) then" +
            "\nreturn c;" +
            "\nend" +
            "\nc = redis.call(&#39;incr&#39;,KEYS[1])" +
            "\nif tonumber(c) == 1 then" +
            "\nredis.call(&#39;expire&#39;,KEYS[1],ARGV[2])" +
            "\nend" +
            "\nreturn c;";
    }
    
    String luaScript = buildLuaScript();
    RedisScript<Number> redisScript = new DefaultRedisScript<>(luaScript, Number.class);
    Number count = redisTemplate.execute(redisScript, keys, limit.count(), limit.period());

    PS:这种接口限流的实现方式比较简单,问题也比较多,一般不会使用,接口限流用的比较多的是令牌桶算法和漏桶算法。

    更多编程相关知识,请访问:编程入门!!

    Das obige ist der detaillierte Inhalt von20 Fragen, die in Redis gemeistert werden müssen, kommen Sie und sammeln Sie sie! !. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

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