Heim  >  Artikel  >  Datenbank  >  Detaillierte Erläuterung der Datenstruktur in Redis

Detaillierte Erläuterung der Datenstruktur in Redis

青灯夜游
青灯夜游nach vorne
2021-03-31 10:26:155445Durchsuche

Detaillierte Erläuterung der Datenstruktur in Redis

In der tatsächlichen Entwicklung wird Redis häufig verwendet. Wie sollten wir also den Datentyp während der Verwendung richtig auswählen? Welche Datentypen eignen sich in welchen Szenarien? Und in Interviews werden Interviewern oft Fragen zur Redis-Datenstruktur gestellt: Redis使用会频繁,那么在使用过程中我们该如何正确抉择数据类型呢?哪些场景下适用哪些数据类型。而且在面试中也很常会被面试官问到Redis数据结构方面的问题:

  • Redis为什么快呢?
  • 为什么查询操作会变慢了?
  • Redis Hash rehash过程
  • 为什么使用哈希表作为Redis的索引

当我们分析理解了Redis数据结构,可以为了我们在使用Redis的时候,正确抉择数据类型使用,提升系统性能。【相关推荐:Redis视频教程

Redis底层数据结构

Redis 是一个内存键值key-value 数据库,且键值对数据保存在内存中,因此Redis基于内存的数据操作,其效率高,速度快;

其中,KeyString类型,Redis 支持的 value 类型包括了 StringListHashSetSorted SetBitMap等。Redis 能够之所以能够广泛地适用众多的业务场景,基于其多样化类型的value

RedisValue的数据类型是基于为Redis自定义的对象系统redisObject实现的,

typedef struct redisObject{
    //类型
    unsigned type:4;
    //编码
    unsigned encoding:4;
    //指向底层实现数据结构的指针
    void *ptr;
    ….. 
}

redisObject除了记录实际数据,还需要额外的内存空间记录数据长度、空间使用等元数据信息,其中包含了 8 字节的元数据和一个 8 字节指针,指针指向具体数据类型的实际数据所在位置:

Detaillierte Erläuterung der Datenstruktur in Redis

其中,指针指向的就是基于Redis的底层数据结构存储数据的位置,Redis的底层数据结构:SDS,双向链表、跳表,哈希表,压缩列表、整数集合实现的。

那么Redis底层数据结构是怎么实现的呢?

Redis底层数据结构实现

我们先来看看Redis比较简单的SDS,双向链表,整数集合

SDS、双向链表和整数集合

SDS,使用len字段记录已使用的字节数,将获取字符串长度复杂度降低为O(1),而且SDS惰性释放空间的,你free了空间,系统把数据记录下来下次想用时候可直接使用。不用新申请空间。
Detaillierte Erläuterung der Datenstruktur in Redis
整数集合,在内存中分配一块地址连续的空间,数据元素会挨着存放,不需要额外指针带来空间开销,其特点为内存紧凑节省内存空间,查询复杂度为O(1)效率高,其他操作复杂度为O(N);

双向链表, 在内存上可以为非连续、非顺序空间,通过额外的指针开销前驱/后驱指针串联元素之间的顺序。

其特点为节插入/更新数据复杂度为O(1)效率高,查询复杂度为O(N);

Hash哈希表

哈希表,其实类似是一个数组,数组的每个元素称为一个哈希桶,每个哈希桶中保存了键值对数据,且哈希桶中的元素使用dictEntry结构,
Detaillierte Erläuterung der Datenstruktur in Redis

因此,哈希桶元素保存的并不是键值对值本身,而是指向具体值的指针,所以在保存每个键值对的时候会额外空间开销,至少有增加24个字节,特别是ValueString

  • Warum ist Redis schnell?
  • Warum verlangsamt sich der Abfragevorgang?
  • Redis-Hash-Rehash-Prozess
  • Warum Hash-Tabelle als Redis-Index verwenden
  • Wenn wir die Datenstruktur von Redis analysieren und verstehen, können wir den zu verwendenden Datentyp richtig auswählen und die Systemleistung verbessern, wenn wir Redis verwenden. [Verwandte Empfehlungen: 🎜Redis-Video-Tutorial] 🎜

    Rediszugrunde liegende Datenstruktur

    🎜Redis ist ein Speicher Schlüssel-Wert-Schlüssel-Wert-Datenbank und Schlüssel-Wert-Paardaten werden im Speicher gespeichert, also Redis basiert auf Speicher. Datenoperationen sind hocheffizient und schnell. 🎜🎜Unter diesen ist Key vom Typ String und Redis unterstützt Zu den Wert-Typen gehören String, List, Hash, Set, Sorted Set code> , <code>BitMap usw. Redis kann aufgrund seiner verschiedenen Arten von Werten umfassend auf viele Geschäftsszenarien angewendet werden. 🎜🎜Der Datentyp von Rediss Value basiert auf dem Objektsystem redisObject, das für Redis angepasst wurde. code> >Neben der Aufzeichnung tatsächlicher Daten benötigt 🎜rrreee🎜<code>redisObject auch zusätzlichen Speicherplatz zum Aufzeichnen von Metadateninformationen wie Datenlänge und Speicherplatznutzung, der 8 Byte Metadaten und einen 8-Wort-Abschnitt enthält Zeiger, der Zeiger zeigt auf den tatsächlichen Datenspeicherort des spezifischen Datentyps: 🎜🎜Detaillierte Erläuterung der Datenstruktur in Redis🎜🎜Unter diesen zeigt der Zeiger basierend auf Redis Die zugrunde liegende Datenstruktur von Code> speichert den Speicherort der Daten. Die zugrunde liegende Datenstruktur von <code>Redis: SDS, doppelt verknüpfte Liste, Sprungliste, Hash-Tabelle , komprimierte Liste und Integer-Set-Implementierung. 🎜🎜Wie wird also die zugrunde liegende Datenstruktur von Redis implementiert? 🎜

    Implementierung der zugrunde liegenden Datenstruktur von Redis

    🎜Werfen wir zunächst einen Blick auf das einfachere SDS von Redis, bidirektional verknüpfte Liste, Satz von ganzen Zahlen. 🎜

    SDS, doppelt verknüpfte Liste und Ganzzahlsatz

    🎜SDS, aufgezeichnet mit dem len Feld Die Anzahl der verwendeten Bytes reduziert die Komplexität der Ermittlung der Zeichenfolgenlänge auf O(1) und SDS ist Lazy-Freigabe von Speicherplatz, Sie frei Code> Code> Leerzeichen, das System zeichnet die Daten auf und kann sie direkt verwenden, wenn Sie sie das nächste Mal verwenden möchten. Es ist nicht erforderlich, sich für neue Räumlichkeiten zu bewerben. <br><span class="img-wrap"><img class="lazy" src="https://img.php.cn/upload/article/000/000/024/a6bb77c337b840fb785407be5753fa62-2.png" alt="Detaillierte Erläuterung der Datenstruktur in Redis" title="Detaillierte Erläuterung der Datenstruktur in Redis"></span><br><strong>Ganzzahlsammlung</strong>, weisen Sie einen Speicherplatz mit aufeinanderfolgenden Adressen im Speicher zu, und die Datenelemente werden gespeichert Nebeneinander gespeichert, sind keine zusätzlichen Zeiger erforderlich, um Platzaufwand zu verursachen. Seine Merkmale sind: kompakter Speicher, Einsparung von Speicherplatz, Abfragekomplexität von O(1) und hohe Effizienz sowie andere Operationskomplexität von O(N);🎜🎜Doppelt verknüpfte Liste kann ein nicht kontinuierlicher und nicht sequentieller Raum im Speicher sein, und die Reihenfolge zwischen den Elementen wird durch den zusätzlichen Zeiger-Overhead des Front-Drives in Reihe geschaltet /back-drive Zeiger. 🎜🎜Es zeichnet sich durch eine hohe Effizienz der Abschnittseinfügung/Aktualisierung der Datenkomplexität von O(1) und der Abfragekomplexität von O(N) aus; 🎜<h4> <strong><code>HashHash-Tabelle 🎜Eine Hash-Tabelle ähnelt tatsächlich einem Array. Jedes Element des Arrays wird als Hash-Bucket bezeichnet. Jeder Hash-Bucket speichert Schlüssel-Wert-Paardaten und die Elemente im Hash-Bucket verwenden dictEntryCode> Struktur,
    Detaillierte Erläuterung der Datenstruktur in Redis🎜🎜Daher speichert das Hash-Bucket-Element nicht das Schlüssel-Wert-Paar selbst, sondern den Zeiger auf einen Zeiger auf a spezifischer Wert, daher entsteht beim Speichern jedes Schlüssel-Wert-Paares zusätzlicher Speicherplatzaufwand, mindestens 24 zusätzliche Bytes, insbesondere wenn Wert String ist Bei den Schlüssel-Wert-Paaren benötigt jedes Schlüssel-Wert-Paar zusätzlich 24 Byte Speicherplatz. Wenn die gespeicherten Daten klein sind und der zusätzliche Overhead größer ist als die Daten, sollten Sie aus Platzgründen eine Änderung der Datenstruktur in Betracht ziehen. 🎜

    Sehen wir uns das vollständige Bild der globalen Hash-Tabelle an:
    Detaillierte Erläuterung der Datenstruktur in Redis
    Obwohl die Hash-Tabellenoperation schnell ist, tritt ein potenzielles Risiko auf, wenn die Redis-Daten größer werden: Redis数据变大后,就会出现一个潜在的风险:哈希表的冲突问题和 rehash开销问题这可以解释为什么哈希表操作变慢了?

    当往哈希表中写入更多数据时,哈希冲突是不可避免的问题 , Redis 解决哈希冲突的方式,就是链式哈希,同一个哈希桶中的多个元素用一个链表来保存,它们之间依次用指针连接,如图所示:
    Detaillierte Erläuterung der Datenstruktur in Redis

    当哈希冲突也会越来越多,这就会导致某些哈希冲突链过长,进而导致这个链上的元素查找耗时长,效率降低。

    为了解决哈希冲突带了的链过长的问题,进行rehash操作,增加现有的哈希桶数量,分散单桶元素数量。那么rehash过程怎么样执行的呢?

    Rehash

    为了使rehash 操作更高效,使用两个全局哈希表:哈希表 1 和哈希表 2,具体如下:

    • 将哈希表 2 分配更大的空间,
    • 把哈希表 1 中的数据重新映射并拷贝到哈希表 2 中;
    • 释放哈希表 1 的空间

    但由于表1和表2在重新映射复制时数据大,如果一次性把哈希表 1 中的数据都迁移完,会造成 Redis 线程阻塞,无法服务其他请求。

    为了避免这个问题,保证Redis能正常处理客户端请求,Redis 采用了渐进式 rehash

    每处理一个请求时,从哈希表 1 中依次将索引位置上的所有 entries 拷贝到哈希表 2 中,把一次性大量拷贝的开销,分摊到了多次处理请求的过程中,避免了耗时操作,保证了数据的快速访问。

    Detaillierte Erläuterung der Datenstruktur in Redis

    在理解完HashHash Tabellenkonfliktprobleme und rehash-Overhead-Probleme

    ,

    Kann dies erklären, warum Hash-Tabellenoperationen langsamer sind?

    Beim Schreiben weiterer Daten in die Hash-Tabelle sind Hash-Konflikte ein unvermeidliches Problem. Die Art und Weise, wie Redis Hash-Konflikte löst, ist

    Ketten-Hashing, also mehrere Hashes im selben Hash-Bucket. Die Elemente werden in einer verknüpften Liste gespeichert, und das sind sie auch wiederum mit Zeigern verbunden, wie in der Abbildung gezeigt:
    Detaillierte Erläuterung der Datenstruktur in RedisDetaillierte Erläuterung der Datenstruktur in Redis

    Wenn es immer mehr Hash-Konflikte gibt, führt dies dazu, dass einige Hash-Konflikte die Kette Long durchlaufen, was wiederum die Suche nach Elementen verursacht in dieser Kette viel Zeit in Anspruch nehmen und die Effizienz verringern.

    Um das Problem zu langer Ketten, die durch Hash-Konflikte verursacht werden, zu lösen, wird die rehash-Operation

    durchgeführt, um die Anzahl der vorhandenen Hash-Buckets zu erhöhen und die Anzahl der Elemente in einem einzelnen Bucket zu verteilen . Wie wird also der rehash-Prozess durchgeführt?

    Rehash

    Um den rehash-Vorgang effizienter zu gestalten, werden zwei globale Hash-Tabellen verwendet: Hash-Tabelle 1 und Hash-Tabelle 2 , die Details sind wie folgt:

    • Reservieren Sie größeren Speicherplatz für Hash-Tabelle 2,
    • Ordnen Sie die Daten in Hash-Tabelle 1 neu zu und kopieren Sie sie in Hash-Tabelle 2
    • li>
    • Geben Sie den Speicherplatz von Hash-Tabelle 1 frei

    Da jedoch die Daten von Tabelle 1 und Tabelle 2 beim Neuzuordnen und Kopieren groß sind, werden alle Daten in Hash-Tabelle 1 migriert Einmal führt dies dazu, dass der Redis-Thread blockiert wird und keine anderen Anfragen mehr bedienen kann. Detaillierte Erläuterung der Datenstruktur in Redis

    Um dieses Problem zu vermeiden und sicherzustellen, dass Redis Clientanfragen normal bearbeiten können, übernimmt Redis den

    progressiven Rehash

    .

    Jedes Mal, wenn eine Anfrage verarbeitet wird, werden alle Einträge an der Indexposition nacheinander von Hash-Tabelle 1 in Hash-Tabelle 2 kopiert, und der Overhead einer großen Anzahl von Kopien gleichzeitig wird dem Prozess der Verarbeitung mehrerer Anfragen zugewiesen Dadurch werden zeitaufwändige Vorgänge vermieden und ein schneller Zugriff auf Daten gewährleistet. Detaillierte Erläuterung der Datenstruktur in RedisKomprimierte Liste und SprunglisteKomprimierte ListeKompakter Speicher spart Speicherplatz im Speicher. Datenelemente werden nebeneinander gespeichert, ohne dass zusätzliche Zeiger für die Suche und Lokalisierung erforderlich sind Das erste Element und das letzte Element können direkt über die Länge der drei Header-Felder lokalisiert werden. Die Komplexität beträgt O (1). Sprungliste Funktionen: Wenn die Datenmenge groß ist, beträgt die Suchkomplexität der Sprungtabelle O (logN). Zusammenfassend können wir die zeitliche Komplexität der zugrunde liegenden Datenstruktur kennen: Zeitliche Komplexität
    at Nachdem wir die relevanten Wissenspunkte von Hash-Hashtabellen verstanden haben, werfen wir einen Blick auf die ungewöhnlichen Komprimierungslisten und Skip-Tabellen.
    Basierend auf dem Array verfügt die komprimierte Liste über drei Felder im Header: zlbytes, zltail und zllen, die jeweils die Länge der Liste und ihren Offset darstellen Ende der Liste und die Länge der Liste. Die Anzahl der Einträge der komprimierten Liste weist außerdem einen Zlend am Ende der Tabelle auf, der das Ende der Liste angibt.
    Vorteile:
    : Basierend auf der verknüpften Liste wird ein mehrstufiger Index hinzugefügt, um eine schnelle Positionierung der Daten durch mehrere Sprünge in der Indexposition zu erreichen, wie in der folgenden Abbildung dargestellt: Zum Beispiel Abfrage 33
    Datenstrukturtyp
    🎜🎜🎜🎜Hash-Tabelle🎜🎜O(1)🎜🎜🎜🎜 Ganzzahliges Array 🎜 🎜o (n) 🎜🎜🎜🎜ouble verknüpfte Liste (n) 🎜🎜🎜🎜kompressive Liste (n) 🎜🎜🎜🎜skip list🎜🎜o (logn) 🎜🎜🎜 🎜 🎜

    Der benutzerdefinierte Objektsystemtyp von Redis ist der Datentyp von Rediss Value und der Datentyp von Redis Code> ist Es wird basierend auf der zugrunde liegenden Datenstruktur implementiert. Welche Datentypen gibt es? <code>Redis自定义的对象系统类型即为RedisValue的数据类型,Redis的数据类型是基于底层数据结构实现的,那数据类型有哪些呢?

    Redis数据类型

    StringListHashSorted SetSet

    Redis-Datentyp

    String, Liste, Hash, Sortiert Set, Set sind relativ häufige Typen und ihre entsprechende Beziehung zur zugrunde liegenden Datenstruktur ist wie folgt: DatentypDatenstrukturString SDS (Einfache dynamische Zeichenfolge)ListeKomprimierte ListeHashKomprimierte Liste
    Hash-TabelleSortierter SatzKomprimierte Liste
    SetHash-Tabelle
    Integer-Array

    Doppelt verknüpfte Liste
    🎜

    Die entsprechenden Eigenschaften des Datentyps ähneln der zugrunde liegenden Datenstruktur seiner Implementierung und die Eigenschaften sind gleich.

    String, basierend auf der SDS-Implementierung, eignet sich für einfachen Schlüsselwertspeicherung, setnx-Schlüsselwert implementiert verteilte Sperren, Zähler (Atomizität) und verteilte globale eindeutige IDs. String,基于SDS实现,适用于简单key-value存储、setnx key value实现分布式锁、计数器(原子性)、分布式全局唯一ID。

    List, 按照元素进入List 的顺序进行排序的,遵循FIFO(先进先出)规则,一般使用在 排序统计以及简单的消息队列。

    Hash, 是字符串key和字符串value之间的映射,十分适合用来表示一个对象信息 ,特点添加和删除操作复杂度都是O(1)。

    Set,是String 类型元素的无序集合,集合成员是唯一的,这就意味着集合中不能出现重复的数据。 基于哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。

    Sorted Set,  是Set的类型的升级, 不同的是每个元素都会关联一个 double 类型的分数,通过分数排序,可以范围查询。

    那我们再来看看这些数据类型,Redis GeoHyperLogLogBitMap

    Redis Geo, 将地球看作为近似为球体,基于GeoHash 将二维的经纬度转换成字符串,来实现位置的划分跟指定距离的查询。特点一般使用在跟位置有关的应用。

    HyperLogLog, 是一种概率数据结构,它使用概率算法来统计集合的近似基数 , 错误率大概在0.81%。 当集合元素数量非常多时,它计算基数所需的空间总是固定的,而且还很小,适合使用做 UV 统计。

    BitMap ,用一个比特位来映射某个元素的状态, 只有 0 和 1 两种状态,非常典型的二值状态,且其本身是用 String 类型作为底层数据结构实现的一种统计二值状态的数据类型  ,优势大量节省内存空间,可是使用在二值统计场景。

    在理解上述知识后,我们接下来讨论一下根据哪些策略选择相对应的应用场景下的Redis数据类型?

    选择合适的Redis数据类型策略

    在实际开发应用中,Redis可以适用于众多的业务场景,但我们需要怎么选择数据类型存储呢?

    主要依据就是时间/空间复杂度,在实际的开发中可以考虑以下几个点:

    • 数据量,数据本身大小
    • 集合类型统计模式
    • 支持单点查询/范围查询
    • 特殊使用场景

    数据量,数据本身大小

    当数据量比较大,数据本身比较小,使用String就会使用额外的空间大大增加,因为使用哈希表保存键值对,使用dictEntry结构保存,会导致保存每个键值对时额外保存dictEntry的三个指针的开销,这样就会导致数据本身小于额外空间开销,最终会导致存储空间数据大小远大于原本数据存储大小。

    可以使用基于整数数组压缩列表实现了 ListHashSorted Set ,因为整数数组压缩列表在内存中都是分配一块地址连续的空间,然后把集合中的元素一个接一个地放在这块空间内,非常紧凑,不用再通过额外的指针把元素串接起来,这就避免了额外指针带来的空间开销。而且采用集合类型时,一个 key 就对应一个集合的数据,能保存的数据多了很多,但也只用了一个 dictEntry,这样就节省了内存。

    集合类型统计模式

    Redis

    List, das nach der Reihenfolge sortiert wird, in der Elemente in List eintreten, folgt der FIFO-Regel (First In, First Out) und wird im Allgemeinen zum Sortieren von Statistiken verwendet und einfache Nachrichtenwarteschlangen. 🎜🎜Hash ist die Zuordnung zwischen der Zeichenfolge key und der Zeichenfolge value. Sie eignet sich sehr gut zur Darstellung von Objektinformationen Die Komplexität von Löschvorgängen beträgt O(1). 🎜🎜Set ist eine ungeordnete Sammlung von Elementen vom Typ String. Die Set-Mitglieder sind eindeutig, was bedeutet, dass keine doppelten Daten im Set erscheinen können. Die Implementierung basiert auf einer Hash-Tabelle, sodass die Komplexität des Hinzufügens, Löschens und Suchens O(1) beträgt. 🎜🎜Sorted Set ist ein Upgrade des Typs Set. Der Unterschied besteht darin, dass jedes Element einem doppelten Typwert zugeordnet ist. Durch Sortieren des Werts ist eine Bereichsabfrage möglich. 🎜🎜Dann werfen wir einen Blick auf diese Datentypen: Redis Geo, HyperLogLog, BitMap? 🎜🎜Redis Geo, behandelt die Erde als ungefähre Kugel und wandelt zweidimensionale Längen- und Breitengrade basierend auf GeoHash in Zeichenfolgen um, um die Standortteilung und die Abfrage bestimmter Entfernungen zu implementieren. Funktionen werden im Allgemeinen in standortbezogenen Anwendungen verwendet. 🎜🎜HyperLogLog ist eine probabilistische Datenstruktur, die probabilistische Algorithmen verwendet, um die ungefähre Kardinalität einer Menge zu zählen, mit einer Fehlerrate von etwa 0,81 %. Wenn die Anzahl der Mengenelemente sehr groß ist, ist der für die Berechnung der Kardinalität erforderliche Platz immer fest und sehr klein, sodass sie für die UV-Statistik geeignet ist. 🎜🎜BitMap verwendet ein Bit, um den Zustand eines Elements abzubilden. Es gibt nur zwei Zustände: 0 und 1, die sehr typische Binärzustände sind, und es wird unter Verwendung des String-Typs als zugrunde liegende Daten implementiert Es handelt sich um einen Datentyp für die Statistik binärer Zustände. Er hat den Vorteil, dass er viel Speicherplatz spart und in binären Statistikszenarien verwendet werden kann. 🎜🎜Nachdem wir das obige Wissen verstanden haben, besprechen wir, welche Strategien zur Auswahl des Datentyps Redis im entsprechenden Anwendungsszenario verwendet werden sollten. 🎜

    Wählen Sie die geeignete Redis-Datentypstrategie

    🎜In tatsächlichen Entwicklungsanwendungen kann Redis auf viele Geschäftsszenarien angewendet werden, aber wie wählen wir aus? Was ist mit der Speicherung von Datentypen? 🎜🎜Die Hauptgrundlage ist die zeitliche/räumliche Komplexität. Bei der tatsächlichen Entwicklung können die folgenden Punkte berücksichtigt werden: 🎜
    • Datenvolumen, die Größe der Daten selbst
    • Statistischen Modus festlegen
    • Einzelpunktabfrage/Bereichsabfrage unterstützen
    • Besondere Nutzungsszenarien

    Datenmenge, die Größe der Daten selbst

    🎜 Wenn die Datenmenge relativ groß und die Daten selbst relativ klein sind, erhöht die Verwendung von String die Nutzung von zusätzlichem Speicherplatz aufgrund eines Hashs erheblich Die Tabelle wird zum Speichern von Schlüssel-Wert-Paaren verwendet, und die Verwendung der Struktur Saving the dictEntry führt dazu, dass beim Speichern jedes Schlüssel-Wert-Paares drei zusätzliche Zeiger von dictEntry gespeichert werden. Dies führt dazu, dass die Daten selbst kleiner sind als der zusätzliche Speicherplatzaufwand, und letztendlich wird der Speicherplatz reduziert. Die Datengröße ist viel größer als die ursprüngliche Datenspeichergröße. 🎜🎜Sie können List, Hash und Sorted SetInteger Array und <strong>Compressed List</strong> verwenden /code>, da <strong>integer array</strong> und <strong>compressed list</strong> beide einen Platz mit fortlaufenden Adressen im Speicher belegen und dann die Elemente in der Sammlung nacheinander in diesen Platz legen. Der Raum ist sehr kompakt und es besteht keine Notwendigkeit, zusätzliche Zeiger zu verwenden, um Elemente miteinander zu verbinden, wodurch der durch zusätzliche Zeiger verursachte Platzbedarf vermieden wird. Darüber hinaus entspricht bei Verwendung eines Sammlungstyps ein Schlüssel den Daten einer Sammlung, und es können viel mehr Daten gespeichert werden, es wird jedoch nur ein <code>dictEntry verwendet, wodurch Speicherplatz gespart wird. 🎜

    Statistischer Modus vom Sammlungstyp

    🎜RedisDie gängigen statistischen Modi vom Satztyp sind: 🎜
    • Aggregationsstatistiken (Schnitt-, Differenz- und Vereinigungsstatistiken): Wenn Sie Aggregationsberechnungen für mehrere Sätze durchführen, können Sie Set
    • wählen; Set
    • 排序统计(要求集合类型能对元素保序): RedisListSorted Set是有序集合,List是按照元素进入 List 的顺序进行排序的,Sorted Set 可以根据元素的权重来排序;
    • 二值状态统计( 集合元素的取值就只有 0 和 1 两种 ):Bitmap 本身是用 String 类型作为底层数据结构实现的一种统计二值状态的数据类型 , Bitmap通过 BITOP 按位 与、或、异或的操作后使用 BITCOUNT 统计 1 的个数。
    • 基数统计( 统计一个集合中不重复的元素的个数 ):HyperLogLog 是一种用于统计基数的数据集合类型 ,统计结果是有一定误差的,标准误算率是 0.81% 。需要精确统计结果的话,用 Set 或 Hash 类型。

    Detaillierte Erläuterung der Datenstruktur in Redis

    Set类型,适用统计用户/好友/关注/粉丝/感兴趣的人集合聚合操作,比如

    • 统计手机APP每天的新增用户数
    • 两个用户的共同好友

    RedisListSorted Set是有序集合,使用应对集合元素排序需求 ,比如

    • 最新评论列表
    • 排行榜

    Bitmap二值状态统计,适用数据量大,且可以使用二值状态表示的统计,比如:

    • 签到打卡,当天用户签到数
    • 用户周活跃
    • 用户在线状态

    HyperLogLog 是一种用于统计基数的数据集合类型, 统计一个集合中不重复的元素个数 ,比如

    • 统计网页的 UV , 一个用户一天内的多次访问只能算作一次

    支持单点查询/范围查询

    RedisListSorted Set是有序集合支持范围查询,但是Hash是不支持范围查询的

    特殊使用场景

    消息队列,使用Redis作为消息队列的实现,要消息的基本要求消息保序处理重复的消息保证消息可靠性,方案有如下:

    • 基于 List 的消息队列解决方案
    • 基于 Streams 的消息队列解决方案

    基于List 基于Strems
    消息保序 使用LPUSH/RPOP 使用XADD/XREAD
    阻塞读取 使用BRPOP 使用XREAD block
    重复消息处理 生产者自行实现全局唯一ID Streams自动生成全局唯一ID
    消息可靠性 使用BRPOPLPUSH 使用PENDING List自动留存消息
    适用场景 消息总量小 消息总量大,需要消费组形式读取数据

    基于位置 LBS 服务,使用Redis的特定GEO数据类型实现,GEO 可以记录经纬度形式的地理位置信息,被广泛地应用在 LBS 服务中。  比如:打车软件是怎么基于位置提供服务的。

    总结

    Redis之所以那么快,是因为其基于内存的数据操作和使用HashSortierungsstatistiken (erfordert den Satztyp, um die Elemente beizubehalten). Reihenfolge): List und Sorted Set in Redis sind geordnete Sammlungen, und List gibt nach Elementen ein . Liste ist der Reihe nach sortiert, Sorted Set kann nach dem Gewicht der Elemente sortiert werden;

    Binärzustandsstatistik (die Werte der Mengenelemente sind nur 0 und 1) ): Bitmap selbst ist ein statistischer binärer Zustandsdatentyp, der mithilfe des Typs String implementiert wird, da die zugrunde liegende Datenstruktur bitweises AND, OR und XOR über BITOP verwendet Verwenden Sie nach der Operation BITCOUNT, um die Anzahl der Einsen zu zählen.

    Kardinalitätsstatistik (Zählung der Anzahl eindeutiger Elemente in einem Satz): HyperLogLog ist ein Datenerfassungstyp, der zum Zählen der Kardinalität verwendet wird. Die statistischen Ergebnisse weisen einen bestimmten Fehler auf 0,81 %. Wenn Sie genaue statistische Ergebnisse benötigen, verwenden Sie den Typ „Set“ oder „Hash“.

3. jpgSet-Typ, geeignet zum Zählen von Benutzern/Freunden/Followern/Fans/Interessenten-Sammlungsaggregationsvorgängen, wie z. B. 🎜🎜🎜Zählen der Anzahl neuer Benutzer der mobilen APP jeden Tag🎜Gemeinsame Freunde zweier Benutzer🎜List und Sorted Set in Redis sind geordnete Mengen, verwenden Um die Sortieranforderungen von Sammlungselementen zu bewältigen, z. B. 🎜🎜🎜Liste der neuesten Kommentare🎜Rangliste🎜Bitmap binäre Statusstatistiken, geeignet für große Mengen B.: 🎜🎜🎜Anmelden und Einchecken, Anzahl der Benutzer-Check-ins am Tag🎜Wöchentlich aktiver Benutzer🎜Online-Status des Benutzers 🎜HyperLogLog code> ist ein Datenerfassungstyp, der zum Zählen der Kardinalität verwendet wird. Er zählt beispielsweise die Anzahl der eindeutigen Elemente in einer Sammlung Eine Webseite. Mehrere Besuche eines Benutzers an einem Tag können nur einmal gezählt werden<h4><strong>Einzelpunktabfrage/Bereichsabfrage unterstützen</strong></h4>🎜<code> List und Sorted Set in <code>Redis ist eine geordnete Sammlung, die Bereichsabfragen unterstützt, aber Hash unterstützt keine Bereichsabfragen🎜

Spezielle Verwendungsszenarien

🎜Message Queue, bei der Verwendung von Redis als Implementierung der Nachrichtenwarteschlange sind die Grundanforderungen der Nachricht Bewahrung der Nachrichtenreihenfolge, Verarbeitung doppelter Nachrichten und Um die Nachrichtenzuverlässigkeit sicherzustellen, lauten die Lösungen wie folgt: 🎜🎜🎜Listenbasierte Nachrichtenwarteschlangenlösung🎜Streams-basierte Nachrichtenwarteschlangenlösung tr> tr>Nachrichtenzuverlässigkeit🎜Standortbasierter LBS-Dienst, implementiert mit Mit dem spezifischen Datentyp GEO von Redis kann GEO Längen- und Breitengrade aufzeichnen. Geografische Standortinformationen in Form von LBS werden häufig in LBS-Diensten verwendet. Zum Beispiel: Wie Taxi-Hailing-Software Dienste basierend auf dem Standort bereitstellt. 🎜

Zusammenfassung

🎜Redis ist aufgrund seiner speicherbasierten Datenoperationen und der Verwendung von Hash-Hashing As so schnell Als Index ist eine Tabelle äußerst effizient und schnell und kann dank der Diversifizierung der zugrunde liegenden Daten auf viele Szenarien angewendet werden. Durch die Auswahl des geeigneten Datentyps in verschiedenen Szenarien kann die Abfrageleistung verbessert werden. 🎜🎜Weitere Kenntnisse zum Thema Programmierung finden Sie unter: 🎜Programmiervideos🎜! ! 🎜

Basierend auf Liste Basierend auf Strems
Beibehaltung der Nachrichtenreihenfolge Verwenden Sie LPUSH/RPOP Verwenden Sie XADD/XREAD
Verwenden Sie BRPOP Verwenden Sie XREAD-Block
Verarbeitung doppelter Nachrichten Produzenten implementieren selbst globale eindeutige IDs Streams generiert automatisch global eindeutige IDs
Verwenden Sie BRPOPLPUSH Verwenden Sie PENDING Liste zur automatischen Aufbewahrung von Nachrichten
Anwendbare Szenarien Die Gesamtzahl der Nachrichten ist gering Die Die Gesamtmenge der Nachrichten ist groß und die Daten müssen in Form von Verbrauchergruppen gelesen werden

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Datenstruktur in Redis. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

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