sql >> Base de Datos >  >> NoSQL >> Redis

Cómo invalidar partes de una jerarquía (árbol) de datos en caché de Redis

Hay al menos 3 formas diferentes de hacerlo, cada una tiene sus pros y sus contras.

El primer enfoque es usar un escaneo ad-hoc no atómico del árbol para identificar e invalidar (eliminar) el segundo nivel del árbol (primer conjunto de personalizaciones). Para hacer eso, use un esquema de nomenclatura jerárquica para los campos de su Hash e itere a través de ellos usando HSCAN . Por ejemplo, suponiendo que el nombre de la clave de su Hash es el ID del producto (por ejemplo, ProductoA), usaría algo como '0001:0001' como nombre de campo para la primera versión de la primera personalización, '0001:0002' para su segunda versión y así sucesivamente. Del mismo modo, '0002:0001' sería la segunda personalización, la primera versión, etc... Luego, busque todas las versiones de la personalización 42, use HSCAN ProductA 0 MATCH 0042:* , HDEL los campos en la respuesta y repita hasta que el cursor quede en cero.

El enfoque opuesto es "indexar" de manera proactiva las versiones de cada personalización para que pueda obtenerlas de manera eficiente en lugar de realizar el análisis completo de Hash. La forma de hacerlo es usar los Conjuntos de Redis:mantiene un Conjunto con todos los nombres de campo para la versión de un producto determinado. Las versiones pueden ser secuenciales (como en mi ejemplo) o cualquier otra cosa, siempre que sean únicas. El costo es mantener estos índices:siempre que agregue o elimine la personalización y/o versión de un producto, deberá mantener la coherencia con estos Conjuntos. Por ejemplo, la creación de una versión sería algo como:

HSET ProductA 0001:0001 "<customization 1 version 1 JSON payload"
SADD ProductA:0001 0001

Tenga en cuenta que estas dos operaciones deben estar en una sola transacción (es decir, use un MULTI\EXEC bloquear o EVAL una escritura Lua). Cuando tiene esta configuración, invalidar una personalización es solo una cuestión de llamar a SMEMBERS en el Conjunto relevante y eliminando las versiones en él del Hash (y el Conjunto mismo también). Sin embargo, es importante tener en cuenta que leer todos los miembros de un conjunto grande puede llevar mucho tiempo:1000 miembros no es tan malo, pero para conjuntos más grandes hay SSCAN .

Por último, podría considerar usar un conjunto ordenado en lugar de un hash. Aunque quizás sea menos intuitivo en este caso de uso, el conjunto ordenado le permitirá realizar todas las operaciones que necesita. Sin embargo, el precio por usarlo es la mayor complejidad de O(logN) para agregar/quitar/leer en comparación con el O(1) de Hash, pero dados los números, la diferencia no es significativa.

Para liberar el poder del conjunto ordenado, utilizará el orden lexicográfico para que todos los miembros del conjunto ordenado tengan la misma puntuación (por ejemplo, use 0). Cada producto estará representado por un Conjunto Ordenado, al igual que con el Hachís. Los miembros del Conjunto son los equivalentes del campo Hash, es decir, las versiones de las personalizaciones. El "truco" es construir los miembros de una manera que le permita realizar búsquedas de rango (o invalidaciones de nivel 2, si lo desea). Aquí hay un ejemplo de cómo debería verse (tenga en cuenta que aquí la clave ProductA no es un hash sino un conjunto ordenado):

ZADD ProductA 0 0001:0001:<JSON>

Para leer una versión personalizada, use ZRANGEBYLEX ProductA [0001:0001: [0001:0001:\xff y divida el JSON de la respuesta y para eliminar una personalización completa, use ZREMRANGEBYLEX .