El comando EXINCRBY de TairString aplica límites superiores e inferiores estrictos de forma atómica, sin necesidad de scripts Lua para casos sencillos. Esta función resulta ideal para el seguimiento de inventario en ventas flash y la limitación de tasas, escenarios donde superar un umbral tiene consecuencias reales.
Funcionamiento
Los comandos EXINCRBY y EXINCRBYFLOAT amplían los comandos nativos de Redis INCRBY y INCRBYFLOAT con opciones adicionales, entre ellas MIN y MAX:
|
Opción |
Descripción |
|
|
Rechaza la operación si el resultado quedara por debajo de este valor |
|
|
Rechaza la operación si el resultado superara este valor |
|
|
Establece la caducidad en segundos |
|
|
Establece el valor solo si la clave no existe |
|
|
Verificación de versión para bloqueo optimista |
|
|
Conserva el TTL existente |
Cuando se infringe el límite, EXINCRBY devuelve "increment or decrement would overflow" en lugar de actualizar la clave. Interprete esta respuesta como una señal para dejar de aceptar la solicitud; no se requiere ninguna comprobación adicional.
Cada llamada a EXINCRBY es atómica. No existe ningún intervalo entre la lectura y la escritura en el que dos solicitudes simultáneas puedan observar el mismo valor restante.
TairString admite todas las funciones nativas de Redis String, excepto las operaciones de bits.
Para consultar la referencia completa de comandos, consulte Comandos de TairString.
Cuándo utilizar contadores acotados
Utilice EXINCRBY con MIN/MAX cuando necesite un umbral estricto que nunca deba cruzarse:
|
Escenario |
Enfoque |
Por qué son adecuados los contadores acotados |
|
Inventario de venta flash |
Decremento con |
El stock nunca puede bajar de cero; se evita la sobreventa |
|
Límite de solicitudes simultáneas |
Incremento con |
Las solicitudes activas nunca pueden superar N |
|
Limitación de intentos de inicio de sesión |
Incremento con |
El límite se restablece al expirar la ventana de tiempo |
|
Limitación de frecuencia de cambio de contraseña |
Incremento con |
Previene ataques de relleno de credenciales en el nivel del contador |
Comparación con INCRBY nativo de Redis y Lua: Las cadenas nativas requieren un script Lua para leer, comparar y actualizar condicionalmente en un solo paso atómico. EXINCRBY resuelve esto en un único comando, lo que reduce la complejidad del código y los viajes de ida y vuelta a la red. Utilice cadenas nativas con Lua si necesita una lógica condicional más compleja que vaya más allá de un umbral mínimo/máximo fijo.
Control de inventario en ventas flash
Para evitar la sobreventa, establezca el recuento inicial de existencias como el valor de TairString y disminuya el valor con MIN 0. Una vez que el stock llega a cero, EXINCRBY rechaza automáticamente cualquier decremento adicional.
if(EXINCRBY(key_iphone, -1, MIN:0) == "would overflow")
run_out();
Limitación y control de tasas
Utilice MAX para limitar el contador a un tope superior. El siguiente ejemplo restringe las solicitudes simultáneas a 1,000:
if(EXINCRBY(rate_limitor, 1, MAX:1000) == "would overflow")
traffic_control();
Este patrón se aplica a cualquier escenario con un umbral numérico: consultas por segundo (QPS), conexiones simultáneas, intentos de inicio de sesión o frecuencia de cambio de contraseña.
Ejemplo en Java: limitador de solicitudes simultáneas
El siguiente método tryAcquire es seguro para hilos. Incrementa el contador dentro de una ventana de caducidad y devuelve false cuando se alcanza el límite 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;
}
El script Lua combina dos operaciones de forma atómica:
Si la clave existe: incrementa con
EXINCRBY, aplicaMAXy conserva el TTL existente medianteKEEPTTL.Si la clave no existe: la inicializa en
0conEXSETy establece la ventana de caducidad conEX.
Gestión de fallos en producción: El método tryAcquire captura el desbordamiento como una señal esperada del flujo de control. Para otras excepciones, como un fallo de conexión a Redis, el método registra actualmente el error y devuelve false, lo que provoca un cierre seguro (bloqueo de solicitudes). Determine si su aplicación debe operar con apertura ante fallos (permitir solicitudes) o con cierre seguro (bloquear solicitudes) cuando TairString no esté disponible, y actualice el controlador de excepciones en consecuencia.
Pasos siguientes
Comandos de TairString — referencia completa de
EXINCRBY,EXINCRBYFLOAT,EXSETy todas las opciones compatibles