¿Cómo debo almacenar series temporales en mongodb?

11

Necesito crear una base de datos de series de tiempo y realizar las siguientes tareas:

  • crear nuevas series de tiempo
  • actualizar series de tiempo existentes
  • consultar una o varias series de tiempo a la vez (por ejemplo, todas las series de tiempo para la misma fecha, etc.)

¿Está Mongo adaptado a eso y, en caso afirmativo, cómo debo estructurar la base de datos? (¿una serie de tiempo = un documento? ¿O un documento = una entrada de la serie de tiempo, y todos estos documentos forman la colección que es la serie de tiempo completa?)

Estoy un poco perdido aquí y me resulta difícil encontrar información, ya que generalmente Mongo se presenta como muy flexible, por lo que el usuario tiene la opción en la infraestructura.

Cualquier enlace al tutorial que explique específicamente cómo administrar series temporales en Mongo es muy bienvenido.

¡Gracias!

RockScience
fuente
Lea el diseño de esquema para datos de series temporales en MongoDB hoy. Muy bien escribir sobre esto.
akauppi
Hay un documento técnico actualizado que analiza las series temporales en MongoDB. mongodb.com/collateral/time-series-best-practices
Robert Walters

Respuestas:

6

Sugiero una sola entrada de series de tiempo por documento. Hay algunos problemas con el almacenamiento de múltiples entradas por documento:

  • un solo documento está limitado a un cierto tamaño (actualmente 16 MB); esto limita cuántas entradas se pueden almacenar en un solo documento
  • A medida que se agreguen más entradas a un documento, todo el documento (y la serie temporal) se eliminarán innecesariamente y se reasignarán a una memoria más grande
  • las consultas en subdocumentos son limitadas en comparación con las consultas en documentos regulares
  • los documentos con estructuras muy planas (como un subdocumento por cada segundo) no tienen rendimiento
  • el mapa-reducción incorporado no funciona tan bien en subdocumentos

También tenga en cuenta que una marca de tiempo está integrada en el Id . De objeto MongoDB predeterminado . Puede usar esto si la precisión de la serie temporal es inferior a un segundo.

Aquí hay un documento BSON de ejemplo de una biblioteca de registro de eventos que usa MongoDB :

Example format of generated bson document:
{
    'thread': -1216977216,
    'level': 'ERROR',
    'timestamp': Timestamp(1290895671, 63),
    'message': 'test message',
    'fileName': '/var/projects/python/log4mongo-python/tests/test_mongo_handler.py',
    'lineNumber': 38,
    'method': 'test_emit_exception',
    'loggerName':  'testLogger',
    'exception': {
        'stackTrace': 'Traceback (most recent call last):
                       File "/var/projects/python/log4mongo-python/tests/test_mongo_handler.py", line 36, in test_emit_exception
                       raise Exception(\'exc1\')
                       Exception: exc1',
        'message': 'exc1',
        'code': 0
    }
}

Dado que un registro de eventos es similar a una serie de tiempo, puede valer la pena estudiar el resto del código . Hay versiones en Java, C #, PHP y Python.

Aquí hay otro proyecto similar de código abierto: Zarkov


[actualización] En respuesta al comentario de @ RockScience, agregué algunas referencias más:

Leftium
fuente
¡va a haber MUCHOS documentos si mi serie de tiempo tiene datos intradía durante varios años! ¿No es un problema tener tantos documentos? Viniendo de un fondo sql, me parece que no es muy efectivo en memoria. (Como habrá mucha repetición para todos los puntos de datos de la misma serie de tiempo)
RockScience
@RockScience: MongoDB, como muchas otras bases de datos NoSQL, evita la normalización y la eficiencia de la memoria en favor de otras cosas como la flexibilidad, la velocidad y el uso reducido de la CPU. Si necesita eficiencia de memoria, MongoDB podría no ser la solución adecuada para usted. MongoDB copia el nombre de texto completo de cada campo en cada documento, ¡por amor de Dios! De todos modos, he actualizado mi respuesta con algunos recursos más, incluido un estudio de caso de cómo MongoDB se usó para almacenar una serie de tiempo muy grande.
Leftium
2

Sí, definitivamente, la base de datos NoSQL se adapta mejor al almacenamiento de datos de series de tiempo que el RDBMS tradicional.

Sí, MongoDB está excepcionalmente adaptado a este caso de uso.

-¿Cómo debe estructurar la base de datos? Un documento = una entrada de series de tiempo VS múltiples series de tiempo.

La respuesta es almacenar en un documento múltiples series de tiempo. Tener menos documentos ayudará al rendimiento con menos lecturas. Un truco es preparar su documento con los valores predefinidos. Esto optimizará la actualización del documento evitando Record Padding .

Aquí hay un ejemplo de esquema sobre cómo almacenar de manera óptima una hora de series de tiempo con un intervalo de minutos:

{
  timestamp_hour: ISODate("2015-07-02T23:00:00.000Z"),
  type: memory_used”,
  values: {
    0: 999999,
    1: 1000000, 
    …,
    58: 0,
    59: 0
  }
}

Lo inicia con valores 0 y luego las actualizaciones se optimizarán. Las lecturas están optimizadas porque se lee un documento en lugar de 60. Si necesita almacenar un día de datos, o un mes para continuar con la misma técnica, se le ocurre la idea.

Aquí está el enlace a un tutorial que explica específicamente cómo administrar series temporales en MongoDb desde el blog oficial de MongoDb: http://blog.mongodb.org/post/65517193370/schema-design-for-time-series-data-in- mongodb

Naim Zard
fuente
1
El almacenamiento de datos dentro de un documento será mejor a partir del rendimiento y el uso de recursos. Hay tres escenarios de esquema discutidos en la serie de tiempo actualizada para el documento técnico de mejores prácticas de MongoDB. mongodb.com/collateral/time-series-best-practices
Robert Walters