Heim > Datenbank > Redis > Hauptteil

Was sind die seltsamen Datentypen und Clusterkenntnisse von Redis?

王林
Freigeben: 2023-06-02 22:01:56
nach vorne
641 Leute haben es durchsucht

    Verschiedene Datentypen

    String-Typ ist einfach und bequem und unterstützt Leerzeichenvorgabe -Zuweisung. Das heißt, es wird jedes Mal mehr Speicherplatz zugewiesen, sodass kein Bedarf besteht, zusätzlichen Speicherplatz zu beantragen, wenn der verbleibende Speicherplatz ausreicht.

    Der Listentyp kann eine einfache Nachrichtenwarteschlange implementieren. Beachten Sie jedoch, dass es zu Nachrichtenverlusten kommen kann. Der ACK-Modus wird nicht unterstützt.

    Die Hash-Tabelle ähnelt ein wenig einer relationalen Datenbank. Wenn die Hash-Tabelle jedoch immer größer wird, vermeiden Sie bitte die Verwendung von Anweisungen wie hgetall, da das Anfordern einer großen Datenmenge zu Redis führt zu blockieren, was später geschehen wird. Brüder müssen warten.

    set Der Sammlungstyp kann Ihnen bei der Erstellung einiger Statistiken helfen. Wenn Sie beispielsweise die aktiven Benutzer an einem bestimmten Tag zählen möchten, können Sie die Benutzer-ID direkt in die Sammlung einfügen Coole Operationen wie sdiff, mit denen die Differenzmenge zwischen Mengen ermittelt werden kann, haben viele Funktionen, aber Sie müssen vorsichtig sein, da die großartigen Funktionen ihren Preis haben Vorgänge erfordern einige CPU- und E/A-Ressourcen, daher ist Vorsicht geboten, wenn Vorgänge zwischen Sätzen ausgeführt werden.

    zset ist der hellste Stern Es kann sortiert werden, es gibt viele Anwendungsszenarien, z. B. die Top-xx-Benutzer, denen es gefallen hat, die Verzögerungszeitwarteschlange und so weiter.

    Bitmap Der Vorteil von Bitmap besteht darin, Platz zu sparen, insbesondere bei der Erstellung einiger Statistiken, z. B. beim Zählen, wie viele Benutzer sich an einem bestimmten Tag angemeldet haben und ob sich ein bestimmter Benutzer angemeldet hat, wenn Bitmap dies nicht ist used , denken Sie vielleicht an die Verwendung von set.

    SADD day 1234//签到就添加到集合
    SISMEMBER day 1234//判断1234是否签到
    SCARD day   //有多少个签到的
    Nach dem Login kopieren

    set ist funktional zufriedenstellend, aber im Vergleich zu Bitmaps verbraucht Set mehr Speicherplatz. Die unterste Ebene von Set besteht hauptsächlich aus einer Ganzzahlsammlung oder einer Ganzzahlsammlung, die nur verwendet werden kann, wenn die Datenmenge groß ist Es wird nur unter bestimmten Umständen verwendet, normalerweise weniger als 512 Elemente, und die Elemente müssen alle Ganzzahlen sein. Die Daten von Ganzzahlsammlungen sind kompakter und können nur im Speicher gespeichert werden sei eine binäre Suche und die Zeit Die Komplexität beträgt O (logN), aber die Hashtabelle ist hier dieselbe wie die Hashtabelle in den fünf Hauptdatentypen von Redis, es gibt jedoch keinen Wert , und es gibt keinen Konflikt, da es sich hier um eine Sammlung handelt, aber Probleme im Zusammenhang mit der Wiederaufbereitung müssen berücksichtigt werden. Ok, es ist ein bisschen weit. Wenn wir über das Problem der Benutzeranmeldung sprechen, wird bei vielen Benutzern definitiv eine Hashtabelle verwendet. Im Fall einer Hashtabelle ist tatsächlich jedes Element eine dictEntry-Struktur

    typedef struct dictEntry {
        // 键
        void *key;
        // 值
        union {
            void *val;
            uint64_t u64;
            int64_t s64;
        } v;
        // 指向下个哈希表节点,形成链表
        struct dictEntry *next;
    } dictEntry;
    Nach dem Login kopieren
    #🎜🎜 #Was können wir aus dieser Struktur erkennen? Obwohl die Werte Union (kein Wert) und Next (kein Konflikt) leer sind, benötigt die Struktur selbst Platz und einen Schlüssel. Dieser belegte Platz ist real, und wenn Sie eine Bitmap verwenden, reicht ein Bit. Es stellt eine Zahl dar und spart Platz. Schauen wir uns an, wie man Bitmaps einrichtet und zählt.

    SETBIT day 1234 1//签到
    GETBIT day 1234//判断1234是否签到
    BITCOUNT day//有多少个签到的
    Nach dem Login kopieren

    bf Dies ist der Bloom-Filter, den RedisBloom nach Redis4.0 unterstützt, aber das entsprechende Modul muss separat geladen werden. Natürlich können wir auch unseren eigenen Bloom-Filter basierend auf der obigen Bitmap implementieren Da Redis nun unterstützt wird, können wir unsere Entwicklungszeit durch RedisBloom verkürzen. Was macht der Bloom-Filter? Ich werde hier nicht näher auf die Verwendung von RedisBloom eingehen.

    # 可以通过docker的方式快速拉取镜像来玩耍
    docker run -p 6379:6379 --name redis-redisbloom redislabs/rebloom:latest
    docker exec -it redis-redisbloom bash
    redis-cli
    # 相关操作
    bf.reserve sign 0.001 10000
    bf.add sign 99 //99这个用户加入
    bf.add exists 99//判断99这个用户是否存在
    Nach dem Login kopieren

    Da der Bloom-Filter eine Fehleinschätzung aufweist, unterstützen alle BF eine benutzerdefinierte Fehleinschätzungsrate. 0,001 stellt die Fehleinschätzungsrate dar, 10000 stellt die Anzahl der Elemente dar, die der Bloom-Filter speichern kann, wenn die tatsächliche Anzahl der gespeicherten Elemente ist Wenn dieser Wert überschritten wird, erhöht sich die Falsch-Positiv-Rate.

    HyperLogLog kann für Statistiken verwendet werden. Sein Vorteil besteht darin, dass es nur 12 KB Speicher benötigt, um 2^64 Elemente zu zählen. Tatsächlich handelt es sich hauptsächlich um Kardinalitätsstatistiken wie UV. Funktionell kann UV mit Set oder Hash gespeichert werden. Der Nachteil besteht jedoch darin, dass es Speicherplatz verbraucht und leicht zu einem großen Schlüssel werden kann Kann auch verwendet werden, 12 KB Die räumliche Bitmap kann nur 12 * 1024 * 8 = 98304 Elemente zählen, während HyperLogLog 2 ^ 64 Elemente zählen kann. Allerdings weist HyperLogLog tatsächlich Fehler auf, die auf der Wahrscheinlichkeit und dem Standardfehler basieren Die Berechnungsrate beträgt 0,81 %. In Szenarien, in denen große Datenmengen gezählt werden und die Genauigkeitsanforderungen nicht so hoch sind, ist HyperLogLog immer noch sehr gut darin, Platz zu sparen.

    PFADD uv 1 2 3 //1 2 3是活跃用户
    PFCOUNT uv //统计
    Nach dem Login kopieren

    GEO 是可以应用在地理位置的业务上,比如微信附近的人或者附近的车辆等等,先来看一下如果没有GEO 这种数据结构,你如何知道你附近的人?首先得上报自己的地理位置信息吧,比如经度 116.397128,纬度 39.916527,此时可以用 string、hash 数据类型存储,但是如果要查找你附近的人,string 和 hash 这种就无能为例了,你不可能每次都要遍历全部的数据来判断,这样太耗时了,当然你也不可能通过 zset 这种数据结构来把经纬度信息当成权重,但是如果我们能把经纬度信息通过某种方式转换成一个数字,然后当成权重好像也可以,这时我们只需通过zrangebyscore key v1 v2也可以找到附近的人。真的需要这么麻烦吗?于是 GEO 出现了,GEO 转换经纬度为数字的方法是“二分区间,区间编码”,这是什么意思呢?以经度为例,它的范围是[-180,180],如果要采用3位编码值,那么就是需要二分3次,二分后落在左边的用0表示,右边的用1表示,以经度是121.48941 来说,第一次是在[0,180]这个区间,因此记1,第二次是在[90,180],因此再记1,第三次是在[90,135],因此记0。纬度也是同样的逻辑,假设此时对应的纬度编码后是010,最后把经纬度合并在一起,需要注意的是经度的每个值在偶数位,纬度的每个值在奇数位。

    1 1 0   //经度
     0 1 0  //纬度
    ------------
    101100 //经纬度对应的数值
    Nach dem Login kopieren

    原理是这样,我们再来看看 redis 如何使用 GEO:

    GEOADD location 112.123456 41.112345 99 //上报用户99的地理位置信息
    GEORADIUS location  112.123456 41.112345 1 km ASC COUNT 10 //获取附近1KM的人
    Nach dem Login kopieren

    搞懂集群

    生产环境用单实例 redis 的应该比较少,单实例的风险在于:

    1. 单点故障即服务故障,没有backup

    2. 单实例压力大,又要提供读,又要提供写

    于是我们首先想到的就是经典的主从模式,而且往往是一主多从,这是因为大部分应用都是读多写少的情况,我们的主负责更新,从负责提供读,就算我们的主宕机了,我们也可以选择一个从来充当主,这样整个应用依然可以提供服务。

    复制过程的细节

    当一个 redis 实例首次成为某个主的从的时候,这时主得把数据发给它,也就是 rdb 文件,这个过程 master 是要 fork 一个子进程来处理的,这个子进程会执行 bgsave 把当前的数据重新保存一下,然后准备发给新来的从,bgsave 的本质是读取当前内存中的数据然后保存到 rdb 文件中,这个过程涉及大量的 IO,如果直接在主进程中来处理的话,大概率会阻塞正常的请求,因此使用个子进程是个明智的选择。

    那 fork 的子进程在 bgsave 过程中如果有新的变更请求会怎么办?

    严格来说子进程出来的一瞬间,要保存的数据应该就是当时那个点的快照数据,所以是直接把当时的内存再复制一份吗?不复制的话,如果这期间又有变更改怎么办?其实这要说到写实复制(COW)机制,首先从表象上来看内存是一整块空间,其实这不太好维护,因此操作系统会把内存分成一小块一小块的,也就是内存分页管理,一页的大小一般是4K、8K或者16K等等,redis 的数据都是分布在这些页面上的,出于效率问题,fork 出来的子进程是和主进程是共享同一块的内存的,并不会复制内存,如果这期间主进程有数据变更,那么为了区分,这时最快捷的做法就是把对应的数据页重新复制一下,然后主的变更就在这个新的数据页上修改,并不会修改来的数据页,这样就保证了子进程处理的还是当时的快照。

    以上说的变更是从快照的角度来考虑的,如果从数据的一致性来说,当快照的 rdb 被从库应用之后,这期间的变更该如何同步给从库?答案是缓冲区,这个缓冲区叫做 replication buffer,主库在收到需要同步的命令之后,会把期间的变更都先保存在这个缓冲区中,这样在把 rdb 发给从库之后,紧接着会再把 replication buffer 的数据也发给从库,最终主从就保持了一致。

    replication buffer不是万能的补给剂

    我们来看看 replication buffer 持续写入的时间有多长。

    1. 我们知道主从同步的时候,主库会执行 fork 来让子进程完成相应地工作,因此子进程从开始执行 bgsave 到执行完毕这期间,变更是要写入 replication buffer 的。

    2. rdb 生成好之后,需要把它发送给从库,这个网络传输是不是也需要耗点时间,这期间也是要写入 replication buffer 的。

    3. 从库在收到 rdb 之后需要把 rdb 应用到内存里,这期间从库是阻塞的,无法提供服务,因此这期间也是要写入 replication buffer 的。

    Da es sich beim Replikationspuffer um einen Puffer handelt, ist seine Größe begrenzt. Wenn einer der oben genannten drei Schritte lange dauert, wächst der Replikationspuffer schnell an (vorausgesetzt, es werden normale Schreibvorgänge ausgeführt). Wenn die Verbindung zwischen der Master-Bibliothek und der Slave-Bibliothek den Grenzwert überschreitet, wird die Replikation neu gestartet und die gleichen langen Replikationsschritte wiederholt Die Puffergröße ist immer noch sehr kritisch und muss im Allgemeinen anhand von Faktoren wie Schreibgeschwindigkeit, Schreibmenge pro Sekunde und Netzwerkübertragungsgeschwindigkeit beurteilt werden.

    Was soll ich tun, wenn das Netzwerk der Slave-Datenbank nicht in Ordnung ist und die Verbindung zur Master-Datenbank getrennt ist?

    Normalerweise können nachfolgende Änderungen an der Master-Datenbank direkt an die Slave-Datenbank gesendet werden, um direkt von der Slave-Datenbank wiedergegeben zu werden, solange die Verbindung zwischen Master und Slave hergestellt ist. Wir können jedoch nicht garantieren, dass die Netzwerkumgebung vorhanden ist 100 % reibungslos, daher muss auch das Trennungsproblem zwischen der Slave-Datenbank und der Master-Datenbank berücksichtigt werden.

    Es sollte so sein, dass vor Redis2.8 die Hauptdatenbank direkt und gedankenlos eine vollständige Synchronisierung durchführte, solange die Slave-Datenbank auch nur für kurze Zeit getrennt war und die Slave-Datenbank später wieder verbunden wurde. In Version 2.8 und höher wird die inkrementelle Replikation unterstützt. Dieser Puffer wird hier als repl_backlog_buffer bezeichnet. Es wird von Anfang an überschrieben, daher gibt es auch eine Größenbeschränkung. Wenn die Slave-Bibliothek die Verbindung wiederherstellt, teilt die Slave-Bibliothek der Hauptbibliothek mit: „Ich habe an den Speicherort xx kopiert.“ Nachdem die Hauptbibliothek die Nachricht von der Slave-Bibliothek erhalten hat, beginnt sie zu prüfen, ob die Daten am Speicherort xx noch vorhanden sind Wenn ja, senden Sie die Daten einfach nach xx an die Slave-Bibliothek. Wenn sie nicht vorhanden sind, können Sie nichts tun und nur eine vollständige Synchronisierung durchführen.

    Erfordert einen Manager

    Wenn im Master-Slave-Modus die Master-Datenbank ausfällt, können wir eine Slave-Datenbank auf die Master-Datenbank aktualisieren. Dieser Vorgang ist jedoch manuell und erfordert menschliche Arbeit, wodurch der Verlust eines Satzes nicht minimiert werden kann Es sind weiterhin automatische Verwaltungs- und Wahlmechanismen erforderlich. Sentinel selbst ist ebenfalls ein Dienst, der jedoch nicht für die regelmäßige Verwaltung aller Redis-Instanzen zuständig ist Bei der Redis-Kommunikation (Ping-Vorgang) kann jede Redis-Instanz ihre Position ausdrücken, solange sie innerhalb der angegebenen Zeit antwortet. Natürlich kann der Sentinel selbst ausgefallen sein oder das Netzwerk nicht verfügbar sein, daher wird der Sentinel im Allgemeinen auch einen Sentinel-Cluster erstellen. Es ist am besten, eine ungerade Anzahl von Clustern zu haben, z. B. 3 oder 5. Der Zweck der ungeraden Anzahl ist hauptsächlich für Wahlen (Die Minderheit gehorcht der Mehrheit).

    Wenn ein Sentinel nach dem Initiieren eines Pings nicht rechtzeitig Pong empfängt, wird die Redis-Instanz als offline markiert. Zu diesem Zeitpunkt ist sie noch nicht wirklich offline. Zu diesem Zeitpunkt ermitteln auch andere Sentinels, ob der aktuelle Sentinel offline ist . Echt offline: Wenn die meisten Wachposten feststellen, dass die Redis offline sind, ist es in Ordnung, sie direkt aus dem Cluster zu entfernen , dann ist es in Ordnung, dass die Datenbank eine Wahl auslöst. Es muss die am besten geeignete Datenbank ausgewählt werden. Die am besten geeignete Bibliothek als Hauptbibliothek wird im Allgemeinen anhand der folgenden Prioritäten bestimmt:

    1. Gewichtung: Jede Slave-Bibliothek kann tatsächlich eine Gewichtung festlegen. Die Slave-Bibliothek mit einer höheren Gewichtung wird priorisiert Der Fortschritt des Kopierens von jeder Slave-Datenbank kann unterschiedlich sein. Priorisieren Sie die ID des Dienstes mit dem geringsten Unterschied zwischen den aktuellen und den Hauptdatenbankdaten. Tatsächlich hat jede Redis-Instanz ihre eigene ID. Anschließend wird die Bibliothek mit der kleinsten ID als Hauptbibliothek ausgewählt , und der Sentinel-Modus Es kann den Cluster automatisch überwachen, eine automatische Masterauswahl realisieren und fehlerhafte Knoten automatisch beseitigen.

    2. Normalerweise können wir Slave-Bibliotheken hinzufügen, um ihn zu lindern, solange der Lesedruck zunimmt. Aber was ist, wenn der Druck auf die Hauptbibliothek sehr hoch ist? Dies bringt uns zu der Sharding-Technologie, über die wir als Nächstes sprechen werden. Wir müssen nur die Hauptbibliothek in mehrere Teile zerlegen und sie auf verschiedenen Maschinen bereitstellen. Dieses Sharding ist das Slot-Konzept in Redis. Beim Sharding wird Redis standardmäßig in 0 bis 16384 Slots aufgeteilt. Anschließend werden diese Slots gleichmäßig auf jeden Shard-Knoten verteilt. Welchem ​​Steckplatz soll jeder Schlüssel zugewiesen werden? Die Hauptsache ist, zuerst CRC16 zu verwenden, um eine 16-Bit-Zahl zu erhalten, und dann diese Zahl modulo 16384 zu verwenden:
    3. crc16(key)%16384
      Nach dem Login kopieren

      客户端将缓存插槽信息,以便在每个键到达时只需计算即可确定该将其发送到哪个实例进行处理。但是客户端缓存的槽信息并不是一成不变的,比如在增加实例的时候,这时候会导致重新分片,那么原来客户端缓存的信息就会不准确,一般这时候会发生两个常见的错误,严格来说也不是错误,更像一种信息,一个叫做MOVED,一个叫做ASK。moved的意思就说,原来是实例A负责的数据,现在被迁移到了实例B,MOVED 代表的是迁移完成的,但是 ASK 代表的是正在迁移过程中,比如原来是实例A负责的部分数据,现在被迁移到了实例B,剩下的还在等待迁移中,当数据迁移完毕之后 ASK 就会变成 MOVED,然后客户端收到 MOVED 信息之后就会再次更新下本地缓存,这样下次就不会出现这两个错误了。

      Das obige ist der detaillierte Inhalt vonWas sind die seltsamen Datentypen und Clusterkenntnisse von Redis?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Verwandte Etiketten:
    Quelle:yisu.com
    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
    Über uns Haftungsausschluss Sitemap
    Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!