Cómo manejar consultas de más de 500 millones de artículos

8

La estructura de mis datos es la siguiente:

date: <timestamp>
filter_a: <integer> -> range [0, 1000]
filter_b: <integer> -> range [0, 1000]
filter_c: <integer> -> range [0, 86400]
filter_d: <integer> -> range [0, 6]
group: <string>
second_group: <integer>
variable_a: <float>
variable_b: <float>
variable_c: <float>
a couple more no very important

Necesito realizar las siguientes consultas:

Primero:

  • Filtrar los datos por date, filter_a, filter_b, filter_cy otros

En segundo lugar, con los datos filtrados:

  • contar todos los registros
  • obtener un promedio de variable_a, variable_byvariable_c
  • obtener la desviación estándar de variable_a, variable_byvariable_c
  • obtener cuartiles de variable_a, variable_byvariable_c
  • agrupar datos por groupo second_groupy agregado (Count, Avg, Std, ..)

El número de usuarios del sistema es de aproximadamente 10 o 15, pero el número de artículos es enorme, en este momento es de 70 millones, pero será de 500 millones en un par de semanas y será de 1000 millones en aproximadamente un año.

El número de consultas es pequeño, no más de 10 usuarios al mismo tiempo, mi problema es cómo manejar esas consultas con esta gran cantidad de datos.

¿Qué he probado hasta ahora?

  • Comencé con mongodb, al principio fue rápido pero se hizo lento al calcular cuartiles con 10M +. Mejoró cuando agregué índices, pero no ayudó mucho cuando tuve que consultar todos los datos. Empecé a usar mongodb porque los datos eran muy dinámicos, pero afortunadamente el formato de datos "ya no va a cambiar".

  • Como filter_ay filter_bpodría verse como nodos, lo intenté neo4j. Me gustó mucho neo4j, pero mi gráfico tenía MUCHOS bordes, por lo que las consultas no fueron muy rápidas.

  • Finalmente, dado que el formato de datos no va a cambiar y es solo una colección / tabla, por lo que no necesita combinaciones en SQL, verifiqué postgresql. Mis pruebas han sido más rápidas con postgresql, pero tengo miedo de que no pueda escalar correctamente en el futuro.

¿Qué necesito?

  • ¿Postgresql es una buena opción para este caso?
  • ¿Hay otro tipo de base de datos que pueda usar? ¿Cuál es el mejor para este caso?
  • ¿Qué más podría hacer para mejorarlo?

Editar

  • Alrededor de 1 millón de elementos se insertan todos los días y "no deberían cambiar" a lo largo del tiempo.
  • La velocidad de escritura no es importante.
  • El requisito difícil es leer / agregar rápidamente

¡Gracias!

Andres
fuente
1
¿Qué hay de las vistas indizadas en SQL Server / vistas metastatizadas en Oracle? Esos son un agregado continuo de la tabla base, por lo que a medida que la tabla base se modifica, el índice también se modifica sobre la marcha. Entonces siempre puede consultar agregados que ya están calculados para usted.
Ali Razeghi
Las vistas indexadas de @AliRazeghi son una buena idea. De todos modos, primero quiero elegir la mejor base de datos / diseño antes de optimizar las consultas en sí mismo
Andres
1
Para optimizar puramente en Postgres, quiero decir que los índices BRIN podrían ayudar aquí, pero no he hecho nada aparte de leer sobre ellos. postgresql.org/docs/9.5/static/brin-intro.html
Erik Darling
1
Personalmente, heredé una base de datos de informes de miles de millones de filas en un servidor OLTP sin mucha cantidad de memoria. Afortunadamente, las partes más consultadas fueron las 'últimas 3 semanas', pero los escaneos de mesa no eran desconocidos. Honestamente, al usar muy buena compresión, particionamiento, eliminación de particiones, esquema de particionamiento, optimizaciones de caché SAN y eliminación de índices no utilizados, obtuvimos un rendimiento muy bueno en MS SQL 2008 Ent. Mil millones no serán demasiado difíciles para PGSQL. ¿Qué tan ancho es cada fila o aproximadamente cuánto espacio crees que ocupará cada fila y cuántos índices habrá por tabla o proceso de entrada?
Ali Razeghi
2
@Andres bueno, eso depende de en qué motor db esté y cuál sea el tamaño máximo de cada fila para que podamos calcular. Por ejemplo, PostgreSQL tiene varchar y solo char, char es fácil de calcular, varchar tendríamos que adivinar la longitud promedio. Si pudiéramos saber qué tipo de campo es (a menos que sea Mongo o algo que lo almacene en un documento con su propio formato), aproximadamente cuántos caracteres esperamos en cada uno y # de índices con las columnas. 8 GB de RAM suena como si fuera demasiado bajo para extraerlo eficientemente de la memoria, aunque especialmente si esa RAM se comparte con otras tablas y recursos en el servidor.
Ali Razeghi

Respuestas:

5

En lugar de apoyarse en una base de datos relacional para realizar estos cálculos estadísticos en datos de series de tiempo, sugiero que traslade este trabajo matemático y de procesamiento posterior fuera de la base de datos a una aplicación cliente.

Usando un lenguaje de script como Python o Ruby, puede resolver el problema de forma incremental al consultar "fragmentos" de datos durante un período de tiempo de ancho fijo, calcular un resumen estadístico intermedio y luego combinar los resultados en varios fragmentos, a medida que realiza un bucle a lo largo de toda la historia. Algunas medidas estadísticas son difíciles de combinar entre fragmentos, pero algo como Avg () solo necesita sum () y count () por fragmento, O (1) frente a O (tamaño de fragmento), por lo que la fusión de fragmentos puede escalar bien.

Jpierc
fuente
Intenté algo así usando python / pandas . el cálculo fue más rápido (un par de segundos) pero recuperar todos los datos fue lento. Quizás un mejor chunksizepodría ayudar. +1
Andrés
1

Como sus datos no cambian y solo se adjuntan, los almacenaría donde lo desee; Amazon S3, por ejemplo, pero cualquier base de datos de lectura rápida estará bien. Sin índices La base de datos / FS que elija debe tener la opción de leer los datos en cubos: podría tener, por ejemplo, un archivo por día con sus registros de 1M.

Entonces usaría Spark para hacer el filtrado / análisis. Está basado en clúster, puede escalarlo según sus necesidades.

León
fuente
Estoy de acuerdo, ya tengo mi conjunto de datos separados por día. También estaba pensando en HDFS y HBase
Andres
0

La respuesta depende de la forma en que va a utilizar los datos después de esto. Si para procesar mejor use Cassandra, si para análisis mejor use Hive.

Artemy Prototyping
fuente
Comprendí que la colmena no podía ser la mejor opción para real time. ¿Me equivoco?
Andres
1
Sí, HBase es para lectura / escritura en tiempo real. Pero Cassandra también puede hacer lo mismo. Pero creo que HBase es mejor.
Artemy Prototyping
0

Este tipo de situación es ideal para el almacenamiento de datos, utilizando las técnicas perfeccionadas por Ralph Kimball y compañía, en plataformas como SQL Server (con la que estoy más familiarizado). Fueron diseñados específicamente con este tipo de escenario en mente: enormes cantidades de registros de datos que son relativamente estáticos, para los cuales necesita calcular agregados de este tipo. Nola técnica relacional será una combinación para el almacenamiento de datos implementado adecuadamente en aplicaciones de este tipo, aunque algunas serán mejores que otras si su organización simplemente no puede pagar las licencias de los paquetes de software (como SQL Server Analysis Services) que los implementan. También hay una curva de aprendizaje para implementar lenguajes como MDX que están hechos a medida para este tipo de acceso a datos. Sin embargo, si el almacenamiento de datos es una opción viable para su organización, no pierda el tiempo buscando una solución relacional; Este no es un problema de base de datos relacional. Puedo publicar algunas referencias básicas a Kimball, etc. y enlaces a SSAS y MDX (lo siento, no puedo ayudar con Oracle y otros competidores con los que no estoy familiarizado) si es necesario. Espero que eso ayude.

SQLServerSteve
fuente