Estoy escribiendo una aplicación que necesita almacenar y analizar grandes cantidades de datos eléctricos y de temperatura.
Básicamente, necesito almacenar grandes cantidades de mediciones de consumo de electricidad por hora durante los últimos años y durante muchos años para decenas de miles de ubicaciones y luego analizar los datos de una manera no muy compleja.
La información que necesito almacenar (por ahora) es Identificación de ubicación, Marca de tiempo (Fecha y hora), Temperatura y uso de electricidad.
Acerca de la cantidad de datos que deben almacenarse, esto es una aproximación, pero algo así: más de
20 000 ubicaciones, 720 registros por mes (mediciones por hora, aproximadamente 720 horas por mes), 120 meses (durante 10 años) ) y muchos años en el futuro. Los cálculos simples arrojan los siguientes resultados:
20 000 ubicaciones x 720 registros x 120 meses (10 años atrás) = 1 728 000 000 registros .
Estos son los registros anteriores, los nuevos registros se importarán mensual, por lo que es de aproximadamente 20 000 x 720 = 14 400 000 nuevos registros al mes .
Las ubicaciones totales también crecerán constantemente.
En todos esos datos, se deberán ejecutar las siguientes operaciones:
- Recupere los datos para una fecha y un período de tiempo determinados: todos los registros para una identificación de ubicación determinada entre las fechas 01.01.2013 y 01.01.2017 y entre 07:00 y 13:00.
- Operaciones matemáticas simples para un determinado rango de fecha Y hora, por ejemplo, temperatura MIN, MAX y AVG y uso de electricidad para una determinada ID de ubicación durante 5 años entre las 07:00 y las 13:00.
Los datos se escribirán mensualmente, pero serán leídos por cientos de usuarios (al menos) constantemente, por lo que la velocidad de lectura es significativamente más importante.
No tengo experiencia con las bases de datos NoSQL, pero por lo que he reunido, son la mejor solución para usar aquí. Leí en las bases de datos NoSQL más populares, pero como son bastante diferentes y también permiten una arquitectura de tabla muy diferente, no he podido decidir cuál es la mejor base de datos para usar.
Mis opciones principales fueron Cassandra y MongoDB, pero desde que tengo un conocimiento muy limitado y no tengo experiencia real cuando se trata de datos grandes y NoSQL, no estoy muy seguro. También leí que PostreSQL también maneja bien tales cantidades de datos.
Mis preguntas son las siguientes:
- ¿Debo usar una base de datos NoSQL para cantidades tan grandes de datos? Si no, ¿puedo seguir con MySQL?
- ¿Qué base de datos debo usar?
- ¿Debo mantener la fecha y la hora en columnas separadas e indexadas (si es posible) para recuperar y procesar los datos rápidamente durante ciertos períodos de tiempo y fecha, o puede hacerlo manteniendo la marca de tiempo en una sola columna?
- ¿Es apropiado un enfoque de modelado de datos de series de tiempo aquí, y si no, podría darme consejos para un buen diseño de tabla?
Gracias.
Respuestas:
Esto es exactamente lo que hago todos los días, excepto que en lugar de usar los datos por hora, uso los datos de 5 minutos. Descargo unos 200 millones de registros todos los días, por lo que la cantidad de la que habla aquí no es un problema. Los datos de 5 minutos tienen un tamaño de aproximadamente 2 TB y tengo datos meteorológicos que retroceden 50 años a un nivel por hora por ubicación. Déjame responderte preguntas basadas en mi experiencia:
Consejo general: almaceno la mayor parte de los datos entre dos bases de datos, la primera es una serie de datos directos y está normalizada. Mi segunda base de datos está muy desnormalizada y contiene datos agregados previamente. Tan rápido como es mi sistema, no estoy ciego al hecho de que los usuarios ni siquiera quieren esperar 30 segundos para que se cargue un informe, incluso si personalmente creo que 30 segundos para procesar 2 TB de datos es extremadamente rápido.
Para explicar por qué recomiendo almacenar la hora por separado de la fecha, aquí hay algunas razones por las que lo hago de esa manera:
DATETIME
columna.Como dije anteriormente, todo esto se basa en mi experiencia personal, y déjenme decirles que han sido unos años difíciles y muchos rediseños para llegar a donde estoy ahora. No haga lo que hice, aprenda de mis errores y asegúrese de involucrar a los usuarios finales de su sistema (o desarrolladores, autores de informes, etc.) al tomar decisiones sobre su base de datos.
fuente
Índices PostgreSQL y BRIN
Pruébalo por ti mismo. Esto no es un problema en una computadora portátil de 5 años con un ssd.
Por lo tanto, tardó 22 minutos en crear la tabla. En gran parte, porque la mesa es un modesto 97GB. Luego creamos los índices,
Tomó bastante tiempo crear los índices también. Aunque debido a que son BRIN, solo tienen 2-3 MB y se almacenan fácilmente en ram. Leer 96 GB no es instantáneo, pero no es un problema real para mi computadora portátil en su carga de trabajo.
Ahora lo consultamos.
Actualizar con marcas de tiempo
Aquí generamos una tabla con diferentes marcas de tiempo para satisfacer la solicitud de indexar y buscar en una columna de marca de tiempo, la creación tarda un poco más porque
to_timestamp(int)
es sustancialmente más lenta quenow()
(que se almacena en caché para la transacción)Ahora podemos ejecutar una consulta en un valor de marca de tiempo en su lugar ,,
Resultado:
Entonces, en 83.321 ms podemos agregar 86.401 registros en una tabla con 1.7 mil millones de filas. Eso debería ser razonable.
Hora final
Calcular el final de la hora también es bastante fácil, truncar las marcas de tiempo y luego simplemente agregar una hora.
Es importante tener en cuenta que no está utilizando un índice en la agregación, aunque podría hacerlo. Si esa es su consulta típica, probablemente desee un BRIN
date_trunc('hour', tsin)
allí, ya quedate_trunc
existe un pequeño problema que no es inmutable, por lo que primero debe envolverlo para que sea así.Fraccionamiento
Otro punto importante de información sobre PostgreSQL es que PG 10 trae particiones DDL . Entonces, por ejemplo, puede crear particiones fácilmente para cada año. Desglosando su modesta base de datos en pequeñas que son pequeñas. Al hacerlo, debería poder usar y mantener índices btree en lugar de BRIN, lo que sería aún más rápido.
O lo que sea.
fuente
Me sorprende que nadie aquí haya mencionado el benchmarking , ¡hasta que @EvanCarroll llegó con su excelente contribución!
Si yo fuera usted, pasaría algún tiempo (y sí, ¡sé que es un bien precioso!) Configurando sistemas, ejecutando lo que cree que será (¡obtenga la entrada del usuario final aquí!), Digamos, sus 10 consultas más comunes.
Mis propios pensamientos:
Las soluciones NoSQL pueden funcionar muy bien para casos de uso particulares, pero con frecuencia son inflexibles para consultas ad-hoc. Para una versión divertida de NoSQL por Brian Aker, ex arquitecto jefe de MySQL, ¡mira aquí !
¡Estoy de acuerdo con @ Mr.Brownstone en que sus datos son muy adecuados para una solución relacional (y esta opinión ha sido confirmada por Evan Carroll )!
Si tuviera que comprometerme con algún gasto, ¡sería con la tecnología de mi disco! ¡Gastaría todo el dinero que tuviera a mi disposición en NAS o SAN o tal vez en algunos discos SSD para almacenar mis datos agregados raramente escritos!
Primero miraría lo que tengo disponible ahora . Ejecute algunas pruebas y muestre los resultados a los tomadores de decisiones. ¡Ya tienes un proxy en forma de trabajo de EC ! Pero, una prueba rápida o dos realizadas en su propio hardware sería más convincente.
¡Entonces piensa en gastar dinero! Si va a gastar dinero, primero mire el hardware en lugar del software. AFAIK, puede contratar tecnología de disco por un período de prueba, o mejor aún, hacer un par de pruebas de concepto en la nube.
Mi primer puerto de escala personal para un proyecto como este sería PostgreSQL. ¡Eso no quiere decir que descartaría una solución patentada, pero las leyes de la física y los discos son las mismas para todos! "Ya no puedes remover las leyes de la física Jim" :-)
fuente
Si aún no lo ha hecho, eche un vistazo a un DBMS de serie temporal, ya que está optimizado para almacenar y consultar datos donde el foco principal es el tipo de fecha / hora. Por lo general, las bases de datos de series temporales se utilizan para registrar datos en los intervalos de minuto / segundo / sub-segundo, por lo que no estoy seguro de si aún es apropiado para incrementos por hora. Dicho esto, parece que vale la pena analizar este tipo de DBMS. Actualmente, InfluxDB parece ser la base de datos de series de tiempo más establecida y ampliamente utilizada.
fuente
Claramente, este no es un problema de NoSQL, pero sugeriría que si bien una solución RDBMS funcionaría, creo que un enfoque OLAP se ajustará mucho mejor y dados los muy limitados rangos de datos involucrados, sugeriría encarecidamente investigar el uso de un DB basado en columnas en lugar de uno basado en filas. Piénselo de esta manera, puede tener 1.700 millones de datos, pero aún necesita 5 bits para indexar cada valor posible de hora o día del mes.
Tengo experiencia con un dominio de problemas similar en el que Sybase IQ (ahora SAP IQ) se utiliza para almacenar hasta 300 millones de contadores por hora de datos de gestión de rendimiento de equipos de telecomunicaciones, pero dudo si tiene el presupuesto para ese tipo de solución. En el campo del código abierto, MariaDB ColumnStore es un candidato muy prometedor, pero recomendaría también investigar MonetDB.
Dado que el rendimiento de las consultas es un motor importante para usted, considere cómo se formularán las consultas. Aquí es donde OLAP y RDBMS muestran sus mayores diferencias: - con OLAP usted normaliza el rendimiento de la consulta, no para reducir la repetición, reducir el almacenamiento o incluso para garantizar la coherencia. Entonces, además de la marca de tiempo original (¿recordó capturar su zona horaria, espero?) Tenga un campo separado para la marca de tiempo UTC, otras para la fecha y hora, y aún más para el año, mes, día, hora, minuto y desplazamiento UTC. Si tiene información adicional sobre ubicaciones, siéntase libre de guardarla en una tabla de ubicación separada que se pueda buscar a pedido y siéntase libre de mantener la clave de esa tabla en su registro principal, pero mantenga el nombre completo de la ubicación en su tabla principal como bueno, después de todo
Como sugerencia final, use tablas separadas para datos agregados populares y use trabajos por lotes para rellenarlos, de esa manera no tendrá que repetir el ejercicio para todos y cada uno de los informes que usan un valor agregado y hacen consultas que comparan actual con histórico o histórico a histórico mucho más fácil y mucho, mucho más rápido.
fuente