Redis
 sql >> Base de données >  >> NoSQL >> Redis

Quelles sont les structures de données sous-jacentes utilisées pour Redis ?

Je vais essayer de répondre à votre question, mais je vais commencer par quelque chose qui peut sembler étrange au premier abord :si vous n'êtes pas intéressé par les composants internes de Redis, vous ne devriez pas vous en soucier sur la façon dont les types de données sont implémentés en interne. C'est pour une raison simple :pour chaque opération Redis, vous trouverez la complexité temporelle dans la documentation et, si vous avez l'ensemble des opérations et la complexité temporelle, la seule autre chose dont vous avez besoin est un indice sur l'utilisation de la mémoire (et parce que nous effectuons de nombreuses optimisations qui peuvent varier en fonction des données, la meilleure façon d'obtenir ces derniers chiffres est de faire quelques tests triviaux dans le monde réel).

Mais puisque vous avez demandé, voici l'implémentation sous-jacente de chaque type de données Redis.

  • Chaînes sont implémentés à l'aide d'une bibliothèque de chaînes dynamiques C afin que nous ne payions pas (de manière asymptotique) pour les allocations dans les opérations d'ajout. De cette façon, nous avons des ajouts O(N), par exemple, au lieu d'avoir un comportement quadratique.
  • Listes sont mis en œuvre avec des listes liées.
  • Ensembles et Hachages sont implémentés avec des tables de hachage.
  • Ensembles triés sont implémentés avec des listes de sauts (un type particulier d'arbres équilibrés).

Mais lorsque les listes, les ensembles et les ensembles triés sont petits en nombre d'éléments et en taille des plus grandes valeurs, un codage différent, beaucoup plus compact, est utilisé. Ce codage diffère selon les types, mais a la particularité d'être un blob compact de données qui force souvent une analyse O(N) pour chaque opération. Comme nous n'utilisons ce format que pour les petits objets, ce n'est pas un problème ; scanner une petite goutte O(N) est cache inconscient donc en pratique c'est très rapide, et lorsqu'il y a trop d'éléments l'encodage passe automatiquement à l'encodage natif (liste chaînée, hachage, etc.).

Mais votre question ne concernait pas vraiment les composants internes, votre point était Quel type utiliser pour accomplir quoi ? .

Chaînes

C'est le type de base de tous les types. C'est l'un des quatre types, mais c'est aussi le type de base des types complexes, car une liste est une liste de chaînes, un ensemble est un ensemble de chaînes, etc.

Une chaîne Redis est une bonne idée dans tous les scénarios évidents où vous souhaitez stocker une page HTML, mais aussi lorsque vous souhaitez éviter de convertir vos données déjà encodées. Ainsi, par exemple, si vous avez JSON ou MessagePack, vous pouvez simplement stocker des objets sous forme de chaînes. Dans Redis 2.6, vous pouvez même manipuler ce type d'objet côté serveur à l'aide de scripts Lua.

Une autre utilisation intéressante des chaînes est celle des bitmaps et, en général, des tableaux d'octets à accès aléatoire, puisque Redis exporte des commandes pour accéder à des plages d'octets aléatoires, voire à des bits uniques. Par exemple, consultez ce bon article de blog :Mesures en temps réel rapides et faciles à l'aide de Redis.

Listes

Les listes sont bonnes lorsque vous êtes susceptible de ne toucher que les extrêmes de la liste :près de la queue ou près de la tête. Les listes ne sont pas très bonnes pour paginer des choses, car l'accès aléatoire est lent, O(N). Les bonnes utilisations des listes sont donc les files d'attente et les piles simples, ou le traitement des éléments en boucle à l'aide de RPOPLPUSH avec la même source et la même destination pour "faire pivoter" un anneau d'articles.

Les listes sont également utiles lorsque nous voulons simplement créer une collection limitée de N éléments où habituellement nous accédons uniquement aux éléments du haut ou du bas, ou lorsque N est petit.

Ensembles

Les ensembles sont une collection de données non ordonnée, ils sont donc bons chaque fois que vous avez une collection d'éléments et il est très important de vérifier l'existence ou la taille de la collection de manière très rapide. Une autre chose intéressante à propos des ensembles est la prise en charge de l'affichage ou de la suppression d'éléments aléatoires (commandes SRANDMEMBER et SPOP).

Les ensembles sont également bons pour représenter des relations, par exemple, "Quels sont les amis de l'utilisateur X ?" et ainsi de suite. Mais d'autres bonnes structures de données pour ce genre de choses sont des ensembles triés comme nous le verrons.

Les ensembles prennent en charge des opérations complexes telles que les intersections, les unions, etc. Il s'agit donc d'une bonne structure de données pour utiliser Redis de manière "informatique", lorsque vous avez des données et que vous souhaitez effectuer des transformations sur ces données pour obtenir une sortie.

Les petits ensembles sont encodés de manière très efficace.

Hachages

Les hachages sont la structure de données idéale pour représenter des objets, composés de champs et de valeurs. Les champs de hachages peuvent également être incrémentés de manière atomique à l'aide de HINCRBY. Lorsque vous avez des objets tels que des utilisateurs, des articles de blog ou tout autre type d'élément , les hachages sont probablement la solution si vous ne souhaitez pas utiliser votre propre encodage comme JSON ou similaire.

Cependant, gardez à l'esprit que les petits hachages sont encodés très efficacement par Redis, et vous pouvez demander à Redis de GET, SET ou incrémenter atomiquement des champs individuels très rapidement.

Les hachages peuvent également être utilisés pour représenter des structures de données liées, à l'aide de références. Par exemple, vérifiez la mise en œuvre des commentaires sur lamernews.com.

Ensembles triés

Les ensembles triés sont les seules autres structures de données, en plus des listes, pour maintenir les éléments ordonnés . Vous pouvez faire un certain nombre de trucs sympas avec des ensembles triés. Par exemple, vous pouvez avoir toutes sortes de Top Something listes dans votre application Web. Meilleurs utilisateurs par score, meilleurs messages par pages vues, etc., mais une seule instance Redis prendra en charge des tonnes d'opérations d'insertion et d'obtention d'éléments supérieurs par seconde.

Les ensembles triés, comme les ensembles réguliers, peuvent être utilisés pour décrire des relations, mais ils vous permettent également de paginer la liste des éléments et de mémoriser l'ordre. Par exemple, si je me souviens des amis de l'utilisateur X avec un ensemble trié, je peux facilement me souvenir d'eux par ordre d'amitié acceptée.

Les ensembles triés conviennent aux files d'attente prioritaires.

Les ensembles triés sont comme des listes plus puissantes où l'insertion, la suppression ou l'obtention de plages à partir du milieu de la liste est toujours rapide. Mais ils utilisent plus de mémoire et sont des structures de données O(log(N)).

Conclusion

J'espère avoir fourni des informations dans cet article, mais il est de loin préférable de télécharger le code source de lamernews à partir de http://github.com/antirez/lamernews et de comprendre comment cela fonctionne. De nombreuses structures de données de Redis sont utilisées dans Lamer News, et il existe de nombreux indices sur ce qu'il faut utiliser pour résoudre une tâche donnée.

Désolé pour les fautes de grammaire, il est minuit ici et trop fatigué pour revoir le message ;)