Tous les produits
Search
Centre de documentation

Tair (Redis® OSS-Compatible):Implémenter des compteurs bornés à l'aide de TairString

Dernière mise à jour :Aug 08, 2026

La commande EXINCRBY de TairString applique des limites supérieures et inférieures strictes de manière atomique, sans nécessiter de scripts Lua pour les cas simples. Cette fonctionnalité est idéale pour le suivi des stocks lors de ventes flash et la limitation du débit, où le dépassement d'un seuil a des conséquences réelles.

Fonctionnement

Les commandes EXINCRBY et EXINCRBYFLOAT étendent les commandes natives Redis INCRBY et INCRBYFLOAT en ajoutant des options supplémentaires, notamment MIN et MAX :

Option description
MIN Rejette l'opération si le résultat est inférieur à cette valeur
MAX Rejette l'opération si le résultat dépasse cette valeur
EX Définit l'expiration en secondes
NX Définit la valeur uniquement si la clé n'existe pas
VER Vérification de version pour le verrouillage optimiste
KEEPTTL Conserve le TTL existant

Lorsque la limite est violée, EXINCRBY renvoie "increment or decrement would overflow" au lieu de mettre à jour la clé. Traitez cette réponse comme un signal indiquant qu'il faut cesser d'accepter la requête ; aucune vérification secondaire n'est nécessaire.

Chaque appel à EXINCRBY est atomique. Il n'y a aucune fenêtre temporelle entre la lecture et l'écriture durant laquelle deux requêtes concurrentes pourraient voir la même valeur restante.

TairString prend en charge toutes les fonctionnalités natives des chaînes Redis, à l'exception des opérations sur les bits.

Pour la référence complète des commandes, consultez Commandes TairString.

Quand utiliser des compteurs bornés

Utilisez EXINCRBY avec MIN/MAX lorsque vous avez besoin d'un seuil strict qui ne doit jamais être franchi :

Scénario Approche Pourquoi les compteurs bornés sont adaptés
Stock pour vente flash Décrémenter avec MIN 0 Le stock ne peut jamais descendre en dessous de zéro ; aucune survente possible
Plafond de requêtes concurrentes Incrémenter avec MAX N Les requêtes actives ne peuvent jamais dépasser N
Limitation des tentatives de connexion Incrémenter avec MAX N + EX La limite se réinitialise après l'expiration de la fenêtre
Limitation du taux de changement de mot de passe Incrémenter avec MAX N + EX Empêche le bourrage d'identifiants au niveau du compteur

Comparaison avec INCRBY natif de Redis utilisant Lua : Les chaînes natives nécessitent un script Lua pour lire, comparer et mettre à jour conditionnellement en une seule étape atomique. EXINCRBY gère cette opération via une seule commande, ce qui réduit la complexité du code et les allers-retours réseau. Utilisez les chaînes natives avec Lua si vous avez besoin d'une logique conditionnelle plus complexe qui va au-delà d'un seuil min/max fixe.

Contrôle des stocks pour les ventes flash

Pour éviter les surventes, définissez le stock initial comme valeur TairString et décrémentez-le avec MIN 0. Une fois le stock arrivé à zéro, EXINCRBY rejette automatiquement les décrémentations suivantes.

if(EXINCRBY(key_iphone, -1, MIN:0) == "would overflow")
    run_out();

Limitation du débit et throttling

Utilisez MAX pour plafonner le compteur à une limite supérieure. L'exemple suivant limite les requêtes concurrentes à 1 000 :

if(EXINCRBY(rate_limitor, 1, MAX:1000) == "would overflow")
    traffic_control();

Ce modèle s'applique à tout scénario comportant un seuil numérique : requêtes par seconde (QPS), connexions simultanées, tentatives de connexion ou fréquence de changement de mot de passe.

Exemple Java : limiteur de requêtes concurrentes

La méthode tryAcquire suivante est thread-safe. Elle incrémente le compteur dans une fenêtre d'expiration et renvoie false une fois la limite supérieure atteinte.

/**
 * Attempts to acquire a slot within the rate limit window.
 *
 * @param key        The rate limit key
 * @param upperBound The maximum allowed count
 * @param interval   The time window in seconds
 * @return true if the slot was acquired; false if the limit is reached
 */
public static boolean tryAcquire(String key, int upperBound, int interval) {
    try (Jedis jedis = jedisPool.getResource()) {
        jedis.eval("if redis.call('exists', KEYS[1]) == 1 "
                + "then return redis.call('EXINCRBY', KEYS[1], '1', 'MAX', ARGV[1], 'KEEPTTL') "
                + "else return redis.call('EXSET', KEYS[1], 0, 'EX', ARGV[2]) end",
            Arrays.asList(key), Arrays.asList(String.valueOf(upperBound), String.valueOf(interval)));
        return true;
    } catch (Exception e) {
        if (e.getMessage().contains("increment or decrement would overflow")) {
            return false;
        }
        e.printStackTrace();
    }
    return false;
}

Le script Lua combine deux opérations de manière atomique :

  • Si la clé existe : incrémenter avec EXINCRBY, en appliquant MAX et en conservant le TTL existant avec KEEPTTL.

  • Si la clé n'existe pas : l'initialiser à 0 avec EXSET et définir la fenêtre d'expiration avec EX.

Gestion des échecs en production : La méthode tryAcquire traite le dépassement de capacité comme un signal de contrôle de flux attendu. Pour les autres exceptions, telles qu'une échec de connexion Redis, la méthode consigne actuellement l'erreur et renvoie false, ce qui bloque les requêtes (fail closed). Décidez si votre application doit autoriser les requêtes (fail open) ou les bloquer (fail closed) lorsque TairString est indisponible, et mettez à jour le gestionnaire d'exceptions en conséquence.

Étapes suivantes

  • Commandes TairString — Référence complète pour EXINCRBY, EXINCRBYFLOAT, EXSET et toutes les options prises en charge