redis – Usando Hashes

Estoy implementando un flujo social y un sistema de notificación para mi aplicación web usando redis. Soy nuevo en redis y tengo algunas dudas sobre los hashes y su eficiencia.

He leído esta increíble publicación de Instagram y planeo implementar su solución similar para un almacenamiento mínimo.

Como se menciona en su blog, les gustó esto.

Para aprovechar el tipo de hash, agrupamos todas nuestras ID de medios en grupos de 1000 (solo tomamos la ID, dividimos por 1000 y descartamos el rest). Eso determina en qué llave caemos; a continuación, dentro del hash que vive en esa clave, el ID de medios es la clave de búsqueda dentro del hash, y el ID de usuario es el valor. Un ejemplo, dado un ID de medio de 1155315, lo que significa que cae en el contenedor 1155 (1155315/1000 = 1155):

HSET "mediabucket:1155" "1155315" "939" HGET "mediabucket:1155" "1155315" > "939" 

Así que en lugar de tener 1000 claves separadas , las almacenan en un hash con mil claves de búsqueda . Y mi duda es por qué no podemos boost los valores clave de búsqueda para que sean aún más grandes.

Por ejemplo, el Media ID of 1155315 will fall into mediabucket:115 by dividing it by 10000 o incluso más.

¿Por qué se están resolviendo con un cubo de hash con 1000 claves de búsqueda? ¿Por qué no pueden tener un cubo de hash con 100000 claves de búsqueda ? ¿Está eso relacionado con la eficiencia ?

Necesito su sugerencia para implementar el método eficiente en mi aplicación web.

PS Por favor! no digas que stackoverflow no es para pedir sugerencias y no sé dónde encontrar ayuda.

¡Gracias!

Sí, está relacionado con la eficiencia.

Le pedimos a Pieter Noordhuis, uno de los desarrolladores centrales de Redis, que nos ayudara siempre y nos pidiera su opinión, y nos sugirió que usáramos los hashes de Redis. Los hash en Redis son diccionarios que se pueden codificar en la memoria de manera muy eficiente; La configuración de Redis ‘hash-zipmap-max-entries’ configura el número máximo de entradas que un hash puede tener mientras se codifica de manera eficiente. Encontramos que este ajuste era mejor alrededor de 1000; cualquier comando superior y HSET causaría una actividad de la CPU notable. Para más detalles, puedes revisar el archivo fuente zipmap.

Los hashes pequeños se codifican de una manera especial (zipmaps), que es eficiente en memoria, pero realiza las operaciones O (N) en lugar de O (1). Entonces, con un zipmap con campos de 100k en lugar de 100 zipmaps con campos de 1k, no obtiene beneficios de memoria, pero todas sus operaciones se vuelven 100 veces más lentas.

Básicamente, quieren que el número de valores almacenados en un solo hash no exceda los 1000. Probablemente, configuran su configuración de instancia de Redis para que funcione bien con este número (tu conjunto hash-zipmap-max-entries ).

Cada vez que un hash exceda el número de elementos o el tamaño del elemento especificado, se convertirá en una tabla de hash real y se perderá el ahorro de memoria.

http://redis.io/topics/memory-optimization

Según tengo entendido, tu pregunta es “¿por qué exactamente 1000 y no más?” Bueno, es porque tuvieron que elegir entre eficiencia de espacio y velocidad. La representación de espacio eficiente tiene una complejidad de operación O(N) , no O(1) como hashes normales; es N veces más lenta , pero requiere menos memoria.

Probaron diferentes valores y encontraron que 1000 es una buena solución de compromiso: no ocupa mucho espacio, pero es lo suficientemente rápido.