una rendimiento entre comparación mongodb redis bigdata nosql

mongodb - rendimiento - ¿La mejor solución para encontrar una intersección de conjuntos de 1 x 1 millón? Redis, Mongo, otros



mongodb vs oracle (3)

Este es un problema interesante, y creo que Redis puede ayudar aquí.

Redis puede almacenar conjuntos de enteros utilizando un formato optimizado "intset". Consulte http://redis.io/topics/memory-optimization para obtener más información.

Creo que la estructura de datos correcta aquí es una colección de conjuntos de etiquetas específicas, más un índice inverso para asignar etiquetas a sus conjuntos de etiquetas específicas.

Para almacenar dos conjuntos de etiquetas dirigidas:

0 -> [ 1 2 3 4 5 6 7 8 ] 1 -> [ 6 7 8 9 10 ]

Yo usaría:

# Targeted tag sets sadd tgt:0 1 2 3 4 5 6 7 8 sadd tgt:1 2 6 7 8 9 10 # Reverse index sadd tag:0 0 sadd tag:1 0 sadd tag:2 0 1 sadd tag:3 0 sadd tag:4 0 sadd tag:5 0 sadd tag:6 0 1 sadd tag:7 0 1 sadd tag:8 0 1 sadd tag:9 1 sadd tag:10 1

Este índice inverso es bastante fácil de mantener cuando se agregan / eliminan conjuntos de etiquetas específicas del sistema.

El consumo global de memoria depende del número de etiquetas que son comunes a múltiples conjuntos de etiquetas dirigidas. Es bastante fácil almacenar pseudodatos en Redis y simular el consumo de memoria. Lo he hecho usando un simple script node.js.

Para 1 millón de conjuntos de etiquetas específicas (las etiquetas son números de 8 dígitos, 40 etiquetas por conjunto), el consumo de memoria es cercano a 4 GB cuando hay muy pocas etiquetas compartidas por los conjuntos de etiquetas específicas (más de 32 millones de entradas en el índice inverso), y alrededor de 500 MB cuando las etiquetas se comparten mucho (solo 100K entradas en el índice inverso).

Con esta estructura de datos, encontrar los conjuntos de etiquetas dirigidos que contienen todas las etiquetas de un cliente determinado es extremadamente eficiente.

1- Get customer tag set (suppose it is 1 2 3 4) 2- SINTER tag:1 tag:2 tag:3 tag:4 => result is a list of targeted tag sets having all the tags of the customer

La operación de intersección es eficiente porque Redis es lo suficientemente inteligente como para ordenar los conjuntos por cardinalidad y comienza con el conjunto que tiene la cardinalidad más baja.

Ahora entiendo que necesita implementar la operación inversa (es decir, encontrar los conjuntos de etiquetas específicos que tienen todas sus etiquetas en el conjunto de etiquetas del cliente). El índice inverso todavía puede ayudar.

Aquí en un ejemplo en feo pseudocódigo:

1- Get customer tag set (suppose it is 1 2 3 4) 2- SUNIONSTORE tmp tag:1 tag:2 tag:3 tag:4 => result is a list of targeted tag sets having at least one tag in common with the customer 3- For t in tmp (iterating on the selected targeted tag sets) n = SCARD tgt:t (cardinality of the targeted tag sets) intersect = SINTER customer tgt:t if n == len(intersect), this targeted tag set matches

Por lo tanto, nunca tiene que probar el conjunto de etiquetas del cliente con los conjuntos de etiquetas específicas de 1M. Puede confiar en el índice inverso para restringir el alcance de la búsqueda a un nivel aceptable.

Hola a todos y gracias de antemano. Soy nuevo en el juego NoSQL, pero mi lugar de trabajo actual me ha asignado la comparación de algunos datos importantes.

Nuestro sistema tiene un conjunto de etiquetas de cliente y conjuntos de etiquetas específicas. Una etiqueta es un número de 8 dígitos.
Un conjunto de etiquetas de cliente puede tener hasta 300 etiquetas pero promedia 100 etiquetas
Un conjunto de etiquetas específicas puede tener hasta 300 etiquetas pero promedia 40 etiquetas.

El cálculo previo no es una opción, ya que estamos buscando una base de clientes potencial de mil millones de usuarios.

(Estas etiquetas son jerárquicas, por lo que tener una etiqueta implica que usted también tiene sus etiquetas padre y ancestro. De momento, aparte esa información).

Cuando un cliente llega a nuestro sitio, debemos cruzar su conjunto de etiquetas con un millón de conjuntos de etiquetas específicas lo más rápido posible. El conjunto de clientes debe contener todos los elementos del conjunto objetivo para que coincida.

He estado explorando mis opciones y el conjunto de intersecciones en Redis parece que sería ideal. Sin embargo, mi rastreo a través de Internet no ha revelado la cantidad de RAM necesaria para mantener un millón de conjuntos de etiquetas. Me doy cuenta de que la intersección sería muy rápida, pero es una solución viable con Redis.

Me doy cuenta de que esto es fuerza bruta e ineficiente. También quería utilizar esta pregunta como medio para obtener sugerencias sobre las formas en que este tipo de problema se ha manejado en el pasado. Como se dijo antes, las etiquetas se almacenan en un árbol. También comencé a considerar a Mongodb como una posible solución.

Gracias de nuevo


Las respuestas proporcionadas me ayudaron inicialmente. Sin embargo, a medida que crecía nuestra base de clientes, me topé con una excelente técnica que involucraba el uso de bits de redis y operadores de bits para realizar análisis en cientos de millones de usuarios muy rápidamente.

Revisa este artículo. Antirez, creador de redis, también hace referencia a esto mucho.

http://blog.getspool.com/2011/11/29/fast-easy-realtime-metrics-using-redis-bitmaps/