我应该如何在mongodb中存储时间序列


11

我需要创建一个时间序列数据库,并执行以下任务:

  • 创建新的时间序列
  • 更新现有时间序列
  • 一次查询一个或多个时间序列(例如同一日期的所有时间序列等)

Mongo是否适应这种情况?如果是,我应该如何构建数据库?(一个时间序列=一个文档?或一个文档=时间序列的一项,所有这些文档构成了整个时间序列的集合?)

我在这里有点迷茫,我发现很难找到任何信息,因为通常Mongo呈现的非常灵活,因此用户可以在基础架构中进行选择。

非常欢迎任何指向教程的链接,这些链接专门解释了如何在Mongo中管理时间序列。

谢谢!


立即阅读MongoDB中的时间序列数据的架构设计。对此写得很好。
akauppi 2014年

有更新的白皮书讨论了MongoDB中的时间序列。 mongodb.com/collat​​eral/time-series-best-practices
罗伯特·沃尔特斯

Answers:


6

我建议每个文档有一个时间序列条目。每个文档存储多个条目存在一些问题:

  • 单个文档被限制为一定大小(当前为16 MB);这限制了一个文档中可以存储多少个条目
  • 随着更多条目添加到文档中,整个文档(和时间序列)将被不必要地删除并重新分配到更大的内存中
  • 与对常规文档的查询相比,对子文档的查询受到限制
  • 结构非常平坦的文档(例如每秒一个子文档)不起作用
  • 内置的map-reduce在子文档上效果不佳

还要注意,时间戳是默认MongoDB ObjectId内置的。如果时间序列精度小于一秒,则可以使用此方法

这是使用MongoDB的事件记录库中示例BSON文档

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
    }
}

由于事件日志类似于时间序列,因此值得研究其余代码。有Java,C#,PHP和Python版本。

这是另一个类似的开源项目:Zarkov


[更新]为了回应@RockScience的评论,我添加了更多参考:


如果我的时间序列中有几年的日内数据,那将是很多文档!!!有那么多文件不是​​问题吗?来自sql背景,我只是发现它不是非常有效的内存。(因为同一时间序列的所有数据点都会重复很多)
RockScience

@RockScience:MongoDB与许多其他NoSQL数据库一样,避开规范化和内存效率,而转向灵活性,速度和降低CPU使用率等其他方面。如果您需要提高内存效率,MongoDB可能不是您合适的解决方案。MongoDB将每个字段的全文名称复制到每个文档中,大声喊叫!无论如何,我已经用更多的资源更新了我的答案,包括关于如何使用MongoDB存储很大的时间序列的案例研究。
Leftium 2013年


2

可以肯定的是,NoSQL数据库比传统的RDBMS更适合存储时间序列数据。

是的,MongoDB特别适合此用例。

-您应该如何构建数据库?一个文档=一个时间序列输入与多个时间序列。

答案是在一个文档中存储多个时间序列。减少文档数量将有助于减少阅读次数。一种技巧是使用预定义的值准备文档。这样可以避免Record Padding来优化文档的更新。

这是一个有关如何以分钟为间隔来最佳存储一个小时的时间序列的模式示例:

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

您使用0值启动它,然后更新将被优化。由于只读取一个文档而不是60个文档,因此读取得到了优化。如果您需要存储一天的数据,或者一个月要使用相同的技术,那么您就可以了。

这是指向教程的链接,该教程从官方的MongoDb博客特别说明了如何在MongoDb中管理时间序列:http ://blog.mongodb.org/post/65517193370/schema-design-for-time-series-data-in- mongodb


1
通过性能和资源使用,在文档内存储数据将更好。关于MongoDB最佳实践白皮书的更新时间序列,讨论了三种模式方案。 mongodb.com/collat​​eral/time-series-best-practices
罗伯特·沃尔特斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.