¿Almacenamiento de datos de series temporales, relacionales o no?

185

Estoy creando un sistema que sondea los dispositivos en busca de datos sobre diferentes métricas, como la utilización de la CPU, la utilización del disco, la temperatura, etc. a (probablemente) intervalos de 5 minutos utilizando SNMP. El objetivo final es proporcionar visualizaciones a un usuario del sistema en forma de gráficos de series temporales.

He analizado el uso de RRDTool en el pasado, pero lo rechacé porque almacenar los datos capturados indefinidamente es importante para mi proyecto, y quiero un nivel más alto y un acceso más flexible a los datos capturados. Entonces mi pregunta es realmente:

Lo que es mejor, una base de datos relacional (como MySQL o PostgreSQL) o una base de datos no relacional o NoSQL (como MongoDB o Redis) con respecto al rendimiento al consultar datos para la representación gráfica.

Relacional

Dada una base de datos relacional, usaría una data_instancestabla, en la que se almacenaría cada instancia de datos capturados para cada métrica que se mide para todos los dispositivos, con los siguientes campos:

Campos: id fk_to_device fk_to_metric metric_value timestamp

Cuando quiero dibujar un gráfico para una métrica particular en un dispositivo particular, debo consultar esta tabla singular que filtra los otros dispositivos y las otras métricas que se analizan para este dispositivo:

SELECT metric_value, timestamp FROM data_instances
    WHERE fk_to_device=1 AND fk_to_metric=2

El número de filas en esta tabla sería:

d * m_d * f * t

donde des el número de dispositivos , m_des el número acumulativo de métricas que se registran para todos los dispositivos, fes la frecuencia con la que se sondean los datos y tes la cantidad total de tiempo que el sistema ha estado recopilando datos.

Para un usuario que registra 10 métricas para 3 dispositivos cada 5 minutos durante un año, tendríamos menos de 5 millones de registros.

Índices

Sin índices activados fk_to_devicey fk_to_metricescaneando, esta tabla en continua expansión llevaría demasiado tiempo. Por lo tanto, timestampes obligatorio indexar los campos mencionados anteriormente y también (para crear gráficos con períodos localizados).

No relacional (NoSQL)

MongoDB tiene el concepto de una colección , a diferencia de las tablas, estas se pueden crear mediante programación sin configuración. Con estos podría particionar el almacenamiento de datos para cada dispositivo, o incluso cada métrica registrada para cada dispositivo.

No tengo experiencia con NoSQL y no sé si proporcionan alguna función de mejora del rendimiento de la consulta, como la indexación, sin embargo, el párrafo anterior propone hacer la mayor parte del trabajo de consulta relacional tradicional en la estructura mediante la cual los datos se almacenan en NoSQL.

Indeciso

¿Una solución relacional con una indexación correcta se reduciría a un rastreo dentro del año? ¿O la estructura basada en la recopilación de enfoques NoSQL (que coincide con mi modelo mental de los datos almacenados) proporciona un beneficio notable?

Marcus Whybrow
fuente
1
Pregunta muy válida, yo mismo he reflexionado sobre esto si la base de datos relacional es la forma correcta de almacenar una estructura de datos que en realidad es jerárquica (estructura SNMP). A veces, cuando escribo una consulta para obtener incluso datos triviales, la consulta es demasiado complicada, sentí que los datos tenían que ser modificados en un formulario que no es el suyo. Por ejemplo, hacer coincidir ifnames y sus índices es supuestamente una tarea trivial, siendo ambos hijos del mismo oid principal. Pero la forma en que se almacena en la base de datos relacional no se relaciona con su estructura original y creo que es más eficiente almacenarlo de forma jerárquica.
Benny
"Para un usuario que registra 10 métricas para 3 dispositivos cada 5 minutos durante un año, tendríamos poco menos de 5 millones de registros". ¿No es 10 * 3 * 365 * 24 * 12 aproximadamente igual a 3 millones que no es menos de 5 millones?
Mathieu Borderé

Respuestas:

152

Definitivamente relacional. Ilimitada flexibilidad y expansión.

Dos correcciones, tanto en concepto como en aplicación, seguidas de una elevación.

Corrección

  1. No es "filtrar los datos innecesarios"; está seleccionando solo los datos necesarios. Sí, por supuesto, si tiene un índice para admitir las columnas identificadas en la cláusula WHERE, es muy rápido y la consulta no depende del tamaño de la tabla (capturar 1,000 filas de una tabla de 16 billones de filas es instantáneo) .

  2. Tu mesa tiene un impedimento serio. Dada su descripción, la PK real es (Dispositivo, Métrica, Fecha y hora). (No lo llame TimeStamp, eso significa otra cosa, pero es un problema menor). La singularidad de la fila se identifica por:

       (Device, Metric, DateTime)
    
    • La Idcolumna no hace nada, es total y completamente redundante.

      • Una Idcolumna nunca es una clave (las filas duplicadas, que están prohibidas en una base de datos relacional, deben evitarse por otros medios).
      • La Idcolumna requiere un índice adicional, que obviamente impide la velocidad INSERT/DELETEy agrega espacio en el disco utilizado.

      • Puedes deshacerte de él. Por favor.

Elevación

  1. Ahora que ha eliminado el impedimento, es posible que no lo haya reconocido, pero su tabla está en Sexta forma normal. Muy alta velocidad, con solo un índice en el PK. Para comprender, lea esta respuesta de ¿Qué es la sexta forma normal? hacia adelante.

    • (Solo tengo un índice, no tres; en Non-SQLs puede que necesite tres índices).

    • Tengo exactamente la misma tabla (sin la Id"clave", por supuesto). Tengo una columna adicional Server. Apoyo a múltiples clientes de forma remota.

      (Server, Device, Metric, DateTime)

    La tabla se puede usar para Pivotar los datos (es decir, Devicesen la parte superior y Metricslateral, o pivotar) usando exactamente el mismo código SQL (sí, cambiar las celdas). Utilizo la tabla para erigir una variedad ilimitada de gráficos y cuadros para que los clientes puedan ver el rendimiento de su servidor.

    • Monitorear el modelo de datos estadísticos .
      (Demasiado grande para en línea; algunos navegadores no pueden cargar en línea; haga clic en el enlace. Además, esa es la versión de demostración obsoleta, por razones obvias, no puedo mostrarle el producto comercial DM).

    • Me permite producir gráficos como este , seis pulsaciones de teclas después de recibir un archivo de estadísticas de monitoreo sin procesar del cliente, usando un solo comando SELECCIONAR . Observe la combinación y combinación; SO y servidor en el mismo gráfico; Una variedad de pivotes. Por supuesto, no hay límite para el número de matrices estadísticas y, por lo tanto, para los gráficos. (Utilizado con el amable permiso del cliente).

    • Los lectores que no estén familiarizados con el Estándar para modelar bases de datos relacionales pueden encontrar útil la notación IDEF1X .

Una cosa más

Por último, pero no menos importante, SQL es un estándar IEC / ISO / ANSI. El freeware es en realidad no SQL; es fraudulento usar el término SQL si no proporcionan el Estándar. Pueden proporcionar "extras", pero están ausentes de lo básico.

PerformanceDBA
fuente
1
@PerformanceDBA ¿usaría el esquema sugerido para una configuración que tiene que manejar ~ 3 millones de medidas con una frecuencia de 1 minuto? ¿Cómo ordenarías el PK para una mesa así? ¿Device, Metric, DateTime no crearían fragmentación y obligarían al RDBMS a dividir muchas páginas? En cambio, poner DateTime primero reduciría la fragmentación (supongo que las inserciones ordenadas por tiempo) pero empeorarían las lecturas.
marcob
1
@Buchi. Yo uso Sybase ASE. Pero esto no es un problema de plataforma (claro, las plataformas altas proporcionan un rendimiento que es de órdenes de magnitud mejor que el extremo inferior; tres órdenes de magnitud mejores que Oracle, pero ese no es el punto), la erección del gráfico de la tabla " funciona "en cualquier plataforma. Use la herramienta adecuada para el trabajo. El RDBMS es una herramienta de base de datos, no una herramienta gráfica. gnuplot, los números de Apple (o si le gusta pagar diez veces más, por la mitad, MS Excel) son herramientas de gráficos, no herramientas de bases de datos. En estos días usamos capas de herramientas para producir un resultado, el monolito es un dinosaurio.
PerformanceDBA
1
@marcob. Su pregunta es buena, pero no se puede responder correctamente en los comentarios. Si abre una nueva pregunta y me envía un correo electrónico (vaya al perfil), la responderé. Para la respuesta rápida aquí. (1) ~ 3 millones de métricas. Genial, cuanto más, mejor, distribuye los puntos INSERT maravillosamente, los suyos garantizarían conflictos en la última página. El servidor es multiproceso, ¿sí? Particionar la mesa. Use FILLFACTOR y deje espacio para las inserciones, y así evitar divisiones de página. (2) ~ 3 Mill indica que las métricas no están normalizadas, si corrige eso, será aún más rápido.
PerformanceDBA
1
@marcob. (3) Utilizo el índice dado precisamente para distribuir los insertos bajo carga, lo que garantiza que no haya conflictos. (4) Por lo tanto, mi método obtiene ambas inserciones sin conflictos y de alto rendimiento en SELECT.
PerformanceDBA
2
@Loic. ¿Por qué alguien, que tiene una inversión (datos; código) en una plataforma SQL, que maneja datos de series de tiempo fácilmente y con un rendimiento muy alto (como se detalla en la respuesta), migraría a una TSDB sin SQL; velocidad desconocida para cualquier cosa, excepto datos de series temporales? ¿Por qué alguien que tiene un requisito que excede solo las series temporales de datos, no usaría una plataforma SQL? La mente se aturde. TSDB es más rápido que Relacional solo en el caso triste cuando los datos se almacenan en una base de datos pero no se normalizan Relacionalmente. P.ej. cuando Idse usan columnas, como "claves". Según lo aconsejado por los "teóricos".
PerformanceDBA
21

Encontró muy interesante las respuestas anteriores. Intentando agregar un par de consideraciones más aquí.

1) envejecimiento de datos

La gestión de series temporales generalmente necesita crear políticas antiguas. Un escenario típico (por ejemplo, la CPU del servidor de supervisión) requiere almacenar:

  • Muestras crudas de 1 segundo durante un período corto (por ejemplo, durante 24 horas)

  • Muestras agregadas detalladas de 5 minutos durante un período medio (por ejemplo, 1 semana)

  • Detalle de 1 hora sobre eso (por ejemplo, hasta 1 año)

Si bien los modelos relacionales lo hacen posible (mi empresa implementó bases de datos centralizadas masivas para algunos grandes clientes con decenas de miles de series de datos) para administrarlo adecuadamente, la nueva generación de almacenes de datos agrega funcionalidades interesantes para explorar como:

  • purga de datos automatizada (ver comando EXPIRE de Redis)

  • agregaciones multidimensionales (por ejemplo, trabajos de reducción de mapas a-la-Splunk)

2) colección en tiempo real

Aún más importante, algunos almacenes de datos no relacionales están distribuidos inherentemente y permiten una recopilación de datos mucho más eficiente en tiempo real (o casi en tiempo real) que podría ser un problema con RDBMS debido a la creación de puntos de acceso (gestión de indexación al insertar en Una sola mesa). Este problema en el espacio RDBMS generalmente se resuelve volviendo a los procedimientos de importación por lotes (lo gestionamos de esta manera en el pasado) mientras que las tecnologías sin sql han tenido éxito en la recopilación y agregación masiva en tiempo real (ver Splunk, por ejemplo, mencionado en respuestas anteriores) .

Paolo Bozzola
fuente
7

Su tabla tiene datos en una sola tabla. Entonces relacional vs no relacional no es la cuestión. Básicamente, necesitas leer muchos datos secuenciales. Ahora, si tiene suficiente RAM para almacenar datos que valen años, entonces nada como usar Redis / MongoDB, etc.

La mayoría de las bases de datos NoSQL almacenarán sus datos en la misma ubicación en el disco y en forma comprimida para evitar el acceso múltiple al disco.

NoSQL hace lo mismo que crear el índice en la identificación del dispositivo y la identificación métrica, pero a su manera. Con la base de datos, incluso si hace esto, el índice y los datos pueden estar en diferentes lugares y habría una gran cantidad de E / S de disco.

Herramientas como Splunk están utilizando backends NoSQL para almacenar datos de series de tiempo y luego usan map reduce para crear agregados (que podrían ser lo que quieras más adelante). Entonces, en mi opinión, usar NoSQL es una opción, ya que las personas ya lo han probado para casos de uso similares. Pero un millón de filas hará que la base de datos se rastree (tal vez no, con un hardware decente y configuraciones adecuadas).

Ravindra
fuente
1
¿Podría explicar cómo se "normaliza" la tabla? Marcus tiene un error en la tabla, pero no es un error de normalización.
PerformanceDBA
Me corregiré, las tablas están normalizadas en el sentido tradicional. Quise decir normalizado en el sentido de que el caso de uso tiene todos los datos en una tabla aquí.
Ravindra
4

Cree un archivo, asígnele el nombre 1_2.data. idea cansada? lo que obtienes:

  • Ahorra hasta un 50% de espacio porque no necesita repetir el valor fk_to_device y fk_to_metric para cada punto de datos.
  • Ahorras aún más espacio porque no necesitas ningún índice.
  • Guarde pares de (marca de tiempo, valor_métrico) en el archivo agregando los datos para obtener un pedido de marca de tiempo de forma gratuita. (suponiendo que sus fuentes no envíen datos fuera de servicio para un dispositivo)

=> Las consultas por marca de tiempo se ejecutan increíblemente rápido porque puede usar la búsqueda binaria para encontrar el lugar correcto en el archivo para leer.

si te gusta aún más optimizado, comienza a pensar en dividir tus archivos así;

  • 1_2_january2014.data
  • 1_2_february2014.data
  • 1_2_march2014.data

o use kdb + de http://kx.com porque hacen todo esto por usted :) orientado a columnas es lo que puede ayudarlo.

Aparece una solución orientada a columnas basada en la nube, por lo que es posible que desee ver: http://timeseries.guru

hellomichibye
fuente
Escribí una publicación de blog sobre el tema. con el traductor de google puede resultarle útil: blog.michaelwittig.info/die-spaltenorientierte-datenbank-kdb
hellomichibye
3

Si está buscando paquetes GPL, RRDTool es bueno para mirar. Es una buena herramienta para almacenar, extraer y graficar datos de series de tiempo. Su caso de uso se ve exactamente como datos de series temporales.

sunil
fuente
2

Este es un problema que hemos tenido que resolver en ApiAxle. Escribimos una publicación de blog sobre cómo lo hicimos usando Redis. No ha estado ahí por mucho tiempo, pero está demostrando ser efectivo.

También he usado RRDTool para otro proyecto que fue excelente.

Phil Jackson
fuente
2

Creo que la respuesta a este tipo de preguntas debe girar principalmente sobre la forma en que su base de datos utiliza el almacenamiento. Algunos servidores de bases de datos usan RAM y disco, algunos solo usan RAM (opcionalmente Disco para persistencia), etc. La mayoría de las soluciones comunes de bases de datos SQL usan memoria + almacenamiento en disco y escribe los datos en un diseño basado en filas (cada raw insertado se escribe en el mismo localizacion fisica). Para las tiendas de series de tiempo, en la mayoría de los casos la carga de trabajo es algo así como: intervalo relativamente bajo de gran cantidad de inserciones, mientras que las lecturas se basan en columnas (en la mayoría de los casos, desea leer un rango de datos de una columna específica, que representa una métrica)

He encontrado que las bases de datos en columnas (busca en Google, encontrarás que MonetDB, InfoBright, parAccel, etc.) están haciendo un trabajo excelente para las series de tiempo.

En cuanto a su pregunta, que personalmente creo que es algo inválida (ya que todas las discusiones usan el término de falla NoSQL - IMO): puede usar un servidor de base de datos que puede hablar SQL por un lado, haciendo su vida muy fácil ya que todos conocen SQL para muchos años y este lenguaje se ha perfeccionado una y otra vez para consultas de datos; pero aún utiliza RAM, caché de CPU y disco de forma orientada en columnas, lo que hace que su solución se adapte mejor a la serie temporal

Shay
fuente
2

5 millones de filas no son nada para los datos torrenciales de hoy. Espere que los datos estén en TB o PB en solo unos meses. En este punto, RDBMS no escala a la tarea y necesitamos la escalabilidad lineal de las bases de datos NoSql. Se lograría el rendimiento para la partición columnar utilizada para almacenar los datos, agregando más columnas y menos filas de concepto para aumentar el rendimiento. Aproveche el trabajo Open TSDB realizado sobre HBASE o MapR_DB, etc.

Juan Asenjo
fuente
"RDBMS no se adapta a la tarea", ¿por qué no lo harían? code.facebook.com/posts/190251048047090/…
Zathrus Writer
1

Me enfrento a requisitos similares regularmente, y recientemente comencé a usar Zabbix para recopilar y almacenar este tipo de datos. Zabbix tiene su propia capacidad de gráficos, pero es bastante fácil extraer los datos de la base de datos de Zabbix y procesarlos como desee. Si aún no ha echado un vistazo a Zabbix, es posible que valga la pena hacerlo.

monch1962
fuente
Sí, Zabbix es agradable y ya se integra con el monitoreo SNMP. Zabbix puede usar MySQL o PostgreSQL y funciona más o menos fuera de la caja en Ubuntu.
Dirk Eddelbuettel
Gracias, tengo conocimiento de Zabbix y muchas otras herramientas SNMP. Sin embargo, estoy desarrollando este proyecto como un proceso educativo, en el tema discutido aquí y muchos otros aspectos. Un buen punto sin embargo!
Marcus Whybrow
0

Debe buscar en la base de datos de series temporales . Fue creado para este propósito.

Una base de datos de series de tiempo (TSDB) es un sistema de software que está optimizado para manejar datos de series de tiempo, matrices de números indexados por tiempo (un intervalo de fecha / hora).

Ejemplo popular de la base de datos de series temporales InfluxDB

Adán
fuente
agregue timescaledb a esta lista ahora
PirateApp