Todos os produtos
Search
Central de documentação

Tair (Redis® OSS-Compatible):Implemente contadores limitados com TairString

Última atualização: Jun 26, 2026

O comando EXINCRBY do TairString impõe limites superiores e inferiores rígidos de forma atômica, sem necessidade de scripts Lua em casos simples. Esse recurso é ideal para rastrear estoque em vendas relâmpago e limitar taxas, cenários em que ultrapassar um limiar gera consequências reais.

Como funciona

Os comandos EXINCRBY e EXINCRBYFLOAT estendem os comandos nativos INCRBY e INCRBYFLOAT do Redis com opções adicionais, incluindo MIN e MAX:

Opção

Descrição

MIN

Rejeita a operação se o resultado ficar abaixo deste valor

MAX

Rejeita a operação se o resultado exceder este valor

EX

Defina a expiração em segundos

NX

Defina o valor apenas se a chave não existir

VER

Verifica a versão para bloqueio otimista

KEEPTTL

Preserva o TTL existente

Ao violar um limite, o EXINCRBY retorna "increment or decrement would overflow" em vez de atualizar a chave. Trate essa resposta como sinal para interromper a aceitação da requisição, sem necessidade de verificação secundária.

Cada chamada ao EXINCRBY é atômica. Não há intervalo entre leitura e escrita em que duas requisições simultâneas possam visualizar o mesmo valor restante.

O TairString oferece suporte a todos os recursos nativos de String do Redis, exceto operações de bits.

Para obter a referência completa dos comandos, consulte Comandos do TairString.

Quando usar contadores limitados

Use EXINCRBY com MIN/MAX quando for necessário um limiar rígido intransponível:

Cenário

Abordagem

Adequação dos contadores limitados

Estoque de venda relâmpago

Decrementar com MIN 0

O estoque nunca fica negativo; evita vendas excessivas

Limite de requisições simultâneas

Incrementar com MAX N

As requisições ativas nunca excedem N

Limitação de tentativas de login

Incrementar com MAX N + EX

O limite é redefinido após a expiração da janela

Limitação de taxa de alteração de senha

Incrementar com MAX N + EX

Impede credential stuffing no nível do contador

Comparação com INCRBY nativo do Redis e Lua: Strings nativas exigem um script Lua para ler, comparar e atualizar condicionalmente em uma única etapa atômica. O EXINCRBY executa isso em um único comando, reduzindo a complexidade do código e as idas e vindas à rede. Use strings nativas com Lua caso precise de lógica condicional mais complexa além de um limiar fixo de mínimo/máximo.

Controle de estoque em vendas relâmpago

Para evitar vendas excessivas, defina a contagem inicial de estoque como valor do TairString e decremente com MIN 0. Assim que o estoque chegar a zero, o EXINCRBY rejeitará automaticamente novos decrementos.

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

Limitação de taxa e throttling

Use MAX para limitar o contador a um teto superior. O exemplo a seguir restringe as requisições simultâneas a 1.000:

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

Esse padrão aplica-se a qualquer cenário com limiar numérico: consultas por segundo (QPS), conexões simultâneas, tentativas de login ou frequência de alteração de senha.

Exemplo em Java: limitador de requisições simultâneas

O método tryAcquire a seguir é thread-safe. Ele incrementa o contador dentro de uma janela de expiração e retorna false ao atingir o limite superior.

/**
 * 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;
}

O script Lua combina duas operações atomicamente:

  • Se a chave existir: incrementa com EXINCRBY, aplica MAX e preserva o TTL existente com KEEPTTL.

  • Se a chave não existir: inicializa-a com 0 via EXSET e defina a janela de expiração com EX.

Tratamento de falhas em produção: O método tryAcquire captura o overflow como sinal esperado de fluxo de controle. Para outras exceções — como falha de conexão com o Redis — o método registra o erro e retorna false, adotando a estratégia fail closed (bloqueia requisições). Decida se sua aplicação deve adotar fail open (permitir requisições) ou fail closed (bloquear requisições) quando o TairString estiver indisponível e atualize o manipulador de exceções adequadamente.

Próximos passos

  • Comandos do TairString — referência completa para EXINCRBY, EXINCRBYFLOAT, EXSET e todas as opções suportadas