Comment utiliser Redis pour les applications de mesure en temps réel

Roshan Kumar est chef de produit senior chez Redis Labs .

Le comptage n'est pas qu'un simple problème de comptage. Le comptage est souvent confondu avec la mesure, mais c'est généralement plus que cela. Le comptage implique la mesure, mais en tant que processus continu, généralement dans le but de réguler l'utilisation ou le flux d'une ressource au fil du temps. Les applications modernes intègrent le comptage de différentes manières, allant du comptage de personnes, d'objets ou d'événements à la régulation de l'utilisation, au contrôle de l'accès et à l'allocation de capacité.

Les solutions de comptage doivent généralement traiter de gros volumes de données tout en répondant à des exigences de performances strictes. En fonction de l'échelle de la solution, le comptage et la mesure peuvent impliquer des milliers, voire des millions de mises à jour d'une base de données chaque seconde. Les principales exigences d'une base de données pour prendre en charge une telle solution sont un débit élevé pour les opérations d'écriture et une latence faible (inférieure à la milliseconde) pour les réponses.

Redis, la plate-forme de base de données en mémoire open source, offre ces deux avantages tout en étant rentable en termes d'utilisation de ressources matérielles minimales. Dans cet article, nous examinerons certaines fonctionnalités de Redis qui en font un bon choix pour les solutions de comptage, et comment nous pouvons utiliser Redis à cette fin. Mais tout d'abord, examinons quelques-unes des utilisations les plus courantes du comptage.

Applications de comptage courantes

Le comptage est requis dans toute application qui doit mesurer l'utilisation d'une ressource au fil du temps. Voici quatre scénarios courants:

  1. Modèles de tarification basés sur la consommation . Contrairement aux modèles de paiement uniques ou par abonnement, les modèles de tarification basés sur la consommation permettent aux consommateurs de ne payer que pour l'utilisation réelle. Les consommateurs bénéficient d'une plus grande flexibilité, d'une plus grande liberté et d'économies de coûts tandis que les fournisseurs obtiennent une plus grande rétention des consommateurs.

    La mise en œuvre de tels modèles peut être délicate. Parfois, le système de comptage doit suivre de nombreux éléments d'utilisation et de nombreuses mesures dans un seul plan. Par exemple, un fournisseur de cloud peut définir différents niveaux de tarification pour les cycles de processeur, le stockage, le débit, le nombre de nœuds ou la durée d'utilisation d'un service. Une entreprise de télécommunications peut définir différents niveaux de consommation autorisée pour les minutes, les données ou le texte. La solution de comptage doit appliquer le plafonnement, la facturation ou l'extension des services en fonction du type de tarification en fonction de la consommation.

  2. Restreindre l'utilisation des ressources . Chaque service sur Internet peut être abusé par une utilisation excessive à moins que ce service ne soit limité par un tarif. Des services populaires tels que l'API Google AdWords et l'API Twitter Stream intègrent des limites de taux pour cette raison. Certains cas extrêmes d'abus conduisent à un déni de service (DoS). Pour éviter les abus, les services et solutions accessibles sur Internet doivent être conçus avec des règles de limitation de débit appropriées. Même de simples pages d'authentification et de connexion doivent limiter le nombre de tentatives pour un intervalle de temps donné.

    Un autre exemple où la restriction de l'utilisation des ressources devient nécessaire est lorsque l'évolution des exigences métier impose une charge plus importante sur les systèmes hérités qu'ils ne peuvent le supporter. La limitation du débit des appels aux systèmes hérités permet aux entreprises de s'adapter à la demande croissante sans avoir à remplacer leurs systèmes hérités.

    En plus de prévenir les abus et de réduire la charge, une bonne limitation de débit permet également de gérer les scénarios de trafic en rafale. Par exemple, une API appliquant une méthode de limitation du taux de force brute peut autoriser 1000 appels toutes les heures. Sans une politique de configuration du trafic en place, un client peut appeler l'API 1000 fois dans les premières secondes de chaque heure, dépassant peut-être ce que l'infrastructure peut prendre en charge. Les algorithmes de limitation de débit populaires tels que Token Bucket et Leaky Bucket empêchent les rafales non seulement en limitant les appels, mais également en les répartissant dans le temps.

  3. Répartition des ressources . La congestion et les retards sont des scénarios courants dans les applications qui traitent du routage des paquets, de la gestion des tâches, de la congestion du trafic, du contrôle des foules, de la messagerie sur les réseaux sociaux, de la collecte de données, etc. Les modèles de file d'attente offrent plusieurs options pour gérer la taille de la file d'attente en fonction du taux d'arrivée et de départ, mais la mise en œuvre de ces modèles à grande échelle n'est pas facile.

    Le backlog et la congestion sont des soucis constants lorsqu'il s'agit de flux de données rapides. Les concepteurs intelligents doivent définir des limites de longueur de file d'attente acceptables, tout en intégrant à la fois la surveillance des performances de mise en file d'attente et le routage dynamique en fonction de la taille des files d'attente.

  4. Compter à grande échelle pour la prise de décision en temps réel . Les sites de commerce électronique, les applications de jeu, les réseaux sociaux et les applications mobiles attirent des millions d'utilisateurs quotidiens. Parce que plus de globes oculaires génèrent des revenus plus importants, il est essentiel pour l'entreprise de compter les visiteurs et leurs actions avec précision. Le comptage est également utile pour les cas d'utilisation tels que les tentatives d'erreurs, l'escalade des problèmes, la prévention des attaques DDoS, le profilage du trafic, l'allocation de ressources à la demande et l'atténuation de la fraude.

Défis de conception de comptage

Les architectes de solutions doivent prendre en compte de nombreux paramètres lors de la création d'une application de comptage, en commençant par ces quatre:

  1. Complexité de conception. Le comptage, le suivi et la régulation des volumes de données, en particulier lorsqu'ils arrivent à grande vitesse, est une tâche ardue. Les architectes de solution peuvent gérer le comptage au niveau de la couche application en utilisant des structures de langage de programmation. Cependant, une telle conception n'est pas résistante aux pannes ou à la perte de données. Les bases de données traditionnelles sur disque sont robustes et promettent un degré élevé de durabilité des données en cas de panne. Mais non seulement ils ne parviennent pas à fournir les performances requises, mais ils augmentent également la complexité sans les structures de données et les outils appropriés pour mettre en œuvre le comptage.
  2. Latence. Le comptage implique généralement de nombreuses mises à jour constantes des comptages. La latence de lecture / écriture du réseau et du disque s'additionne lors du traitement de grands nombres. Cela pourrait entraîner la constitution d'un énorme arriéré de données, entraînant davantage de retards. L'autre source de latence est une conception de programme qui charge les données de mesure d'une base de données dans la mémoire principale du programme et réécrit dans la base de données une fois la mise à jour du compteur terminée.
  3. Concurrence et cohérence. La conception d'une solution pour compter des millions et des milliards d'éléments peut devenir complexe lorsque des événements sont capturés dans différentes régions, et qu'ils doivent tous converger en un seul endroit. La cohérence des données devient un problème si de nombreux processus ou threads mettent à jour le même nombre simultanément. Les techniques de verrouillage évitent les problèmes de cohérence et offrent une cohérence au niveau transactionnel, mais ralentissent la solution.
  4. Durabilité. Le comptage affecte les chiffres des revenus, ce qui implique que les bases de données éphémères ne sont pas idéales en termes de durabilité. Une banque de données en mémoire avec des options de durabilité est un choix parfait.

Utilisation de Redis pour les applications de mesure

Dans les sections suivantes, nous examinerons comment utiliser Redis pour les solutions de comptage et de mesure. Redis a des structures de données intégrées, des commandes atomiques et des capacités de durée de vie (TTL) qui peuvent être utilisées pour alimenter des cas d'utilisation de mesure. Redis fonctionne sur un seul thread. Par conséquent, toutes les mises à jour de la base de données sont sérialisées, ce qui permet à Redis de fonctionner comme un magasin de données sans verrouillage. Cela simplifie la conception de l'application car les développeurs n'ont pas besoin de consacrer aucun effort à la synchronisation des threads ou à l'implémentation de mécanismes de verrouillage pour la cohérence des données.  

Commandes Atomic Redis pour le comptage

Redis fournit des commandes pour incrémenter les valeurs sans avoir à les lire dans la mémoire principale de l'application.

Commander La description
INCR clé Incrémenter la valeur entière d'une clé de un
INCRBY incrément de clé Incrémente la valeur entière d'une clé du nombre donné
INCRBYFLOAT incrément de clé Incrémenter la valeur flottante d'une clé du montant donné
DECR clé Décrémenter la valeur entière d'une clé de un
DECRBY décrémentation clé Décrémente la valeur entière d'une clé du nombre donné
HINCRBY incrément de champ clé Incrémente la valeur entière d'un champ de hachage du nombre donné
HINCRBYFLOAT incrément de champ clé Incrémenter la valeur flottante d'un champ de hachage du montant donné

Redis stocke les entiers sous la forme d'un entier signé de base 10 64 bits. Par conséquent, la limite maximale pour un entier est un très grand nombre: 263 - 1 = 9 223 372 036 854 775 807.

Durée de vie intégrée (TTL) sur les touches Redis

L'un des cas d'utilisation courants du comptage consiste à suivre l'utilisation en fonction du temps et à limiter les ressources une fois le temps écoulé. Dans Redis, on peut définir une valeur de durée de vie pour les clés. Redis désactivera automatiquement les touches après un délai défini. Le tableau suivant répertorie plusieurs méthodes d'expiration des clés.

Commander La description
EXPIRE secondes clés Définissez le temps de vie d'une clé en quelques secondes
EXPIREAT horodatage clé Définir l'expiration d'une clé comme horodatage Unix
PEXPIRE clé millisecondes Définir le temps de vie d'une clé en millisecondes
PEXPIREAT horodatage clé Définir l'expiration d'une clé comme horodatage UNIX en millisecondes
SET valeur de clé [EX secondes] [PX millisecondes] Définissez la valeur de la chaîne sur une clé avec la durée de vie facultative

Les messages ci-dessous vous donnent la durée de vie des touches en termes de secondes et de millisecondes.

Commander La description
TTL clé Obtenez le temps de vivre pour une clé
PTTL clé Obtenez le temps de vivre pour une clé en millisecondes

Structures de données et commandes Redis pour un comptage efficace

Redis est apprécié pour ses structures de données telles que les listes, les ensembles, les ensembles triés, les hachages et les hyperloglogs. Beaucoup d'autres peuvent être ajoutés via l'API des modules Redis.

Redis Labs

Les structures de données Redis sont livrées avec des commandes intégrées qui sont optimisées pour s'exécuter avec une efficacité maximale en mémoire (là où les données sont stockées). Certaines structures de données vous aident à accomplir bien plus que le comptage d'objets. Par exemple, la structure de données Set garantit l'unicité de tous les éléments.

Sorted Set va encore plus loin en s'assurant que seuls des éléments uniques sont ajoutés à l'ensemble et en vous permettant de classer les éléments en fonction d'un score. Par exemple, classer vos éléments par heure dans une structure de données Sorted Set vous offrira une base de données chronologique. Avec l'aide des commandes Redis, vous pouvez obtenir vos éléments dans un certain ordre ou supprimer des éléments dont vous n'avez plus besoin.

Hyperloglog est une autre structure de données spéciale qui estime le nombre de millions d'éléments uniques sans avoir besoin de stocker les objets eux-mêmes ou d'avoir un impact sur la mémoire.

Structure de données Commander La description
liste LLEN clé Obtenir la longueur d'une liste
Ensemble SCARD clé Obtenir le nombre de membres dans un ensemble (cardinalité)
Ensemble trié ZCARD clé Obtenir le nombre de membres dans un ensemble trié
Ensemble trié ZLEXCOUNT clé min max Compter le nombre de membres dans un ensemble trié entre une plage lexicographique donnée
Hacher HLEN clé Obtenir le nombre de champs dans un hachage
Hyperloglog PFCOUNT clé Obtenir la cardinalité approximative de l'ensemble observée par la structure de données Hyperloglog
Bitmap BITCOUNT touche [début fin] Compte les bits définis dans une chaîne

Persistance Redis et réplication en mémoire

Les cas d'utilisation de compteurs tels que les paiements impliquent le stockage et la mise à jour d'informations essentielles pour les entreprises. La perte de données a un impact direct sur les revenus. Cela peut également détruire les enregistrements de facturation, qui sont souvent une exigence de conformité ou de gouvernance.

Vous pouvez régler la cohérence et la durabilité dans Redis en fonction de vos besoins en données. Si vous avez besoin d'une preuve d'enregistrement permanente pour vos données de mesure, vous pouvez atteindre la durabilité grâce aux capacités de persistance de Redis. Redis prend en charge AOF (fichier d'ajout uniquement), qui copie les commandes d'écriture sur le disque au fur et à mesure qu'elles se produisent, et la capture instantanée, qui prend les données telles qu'elles existent à un moment donné et les écrit sur le disque.

Architecture Redis intégrée sans verrouillage

Le traitement Redis est monothread; cela garantit l'intégrité des données, car toutes les commandes d'écriture sont automatiquement sérialisées. Cette architecture soulage les développeurs et les architectes du fardeau de la synchronisation des threads dans un environnement multithread.

Dans le cas d'une application mobile grand public populaire, des milliers et parfois des millions d'utilisateurs peuvent accéder simultanément à l'application. Disons que l'application mesure le temps utilisé et que deux ou plusieurs utilisateurs peuvent partager des minutes simultanément. Les threads parallèles peuvent mettre à jour le même objet sans imposer la charge supplémentaire d'assurer l'intégrité des données. Cela réduit la complexité de la conception de l'application tout en garantissant rapidité et efficacité.

Implémentations d'exemples de comptage Redis

Jetons un coup d'œil à un exemple de code. Plusieurs des scénarios ci-dessous nécessiteraient des implémentations très complexes si la base de données utilisée n'était pas Redis.

Bloquer plusieurs tentatives de connexion

Pour empêcher l'accès non autorisé aux comptes, les sites Web empêchent parfois les utilisateurs de faire plusieurs tentatives de connexion dans un délai spécifié. Dans cet exemple, nous empêchons les utilisateurs de faire plus de trois tentatives de connexion en une heure en utilisant une simple fonctionnalité clé de durée de vie.

La clé pour contenir le nombre de tentatives de connexion:

user_login_attempts:

Pas:

Obtenez le nombre actuel de tentatives:

GET user_login_attempts:

Si nul, définissez la clé avec le délai d'expiration en secondes (1 heure = 3600 secondes):

SET user_login_attempts: 1 3600

S'il n'est pas nul et si le nombre est supérieur à 3, lancez une erreur:

S'il n'est pas nul et si le nombre est inférieur ou égal à 3, incrémentez le nombre:

INCR user_login_attempts:

Lors d'une tentative de connexion réussie, la clé peut être supprimée comme suit:

DEL user_login_attempts:

Payez au fur et à mesure

La structure de données Redis Hash fournit des commandes simples pour suivre l'utilisation et la facturation. Dans cet exemple, supposons que chaque client a ses données de facturation stockées dans un hachage, comme indiqué ci-dessous:

customer_billing:

     usage

     Coût

     .

     .

Supposons que chaque unité coûte deux cents et que l'utilisateur ait consommé 20 unités. Les commandes pour mettre à jour l'utilisation et la facturation sont:

client hincrby: utilisation 20

client hincrbyfloat: coût 0,40

Comme vous l'avez peut-être remarqué, votre application peut mettre à jour les informations de la base de données sans lui demander de charger les données de la base de données dans sa propre mémoire. De plus, vous pouvez modifier un champ individuel d'un objet Hash sans lire l'objet entier.

Remarque: le but de cet exemple est de montrer comment utiliser les commandes hincrbyet hincrbyfloat. Dans une bonne conception, vous évitez de stocker des informations redondantes telles que l'utilisation et le coût.