【问题标题】:Simple approach for storing time series data存储时间序列数据的简单方法
【发布时间】:2017-11-20 17:11:03
【问题描述】:

我每天有大约 10 亿个事件。我需要将过去 30 天的这些事件存储在数据库中,因此大约有 300 亿行。

假设它是运动员数据库,每行只有 4 列(运动员姓名、运动员学科、运动员等级、日期)。我只需要按运动员姓名和日期检索数据。例如,为特定运动员构建过去 30 天的图表。

  1. 最初我使用的是 Google Big Query,这是一个很棒的工具,非常便宜,具有开箱即用的日常分片和线性可扩展性,但几乎没有缺点。查询 30 亿张表大约需要 5 秒,对我来说太多了。插入数据时,它会出现在“流式缓冲区”中,并且有一段时间(大约 5-10 分钟)无法查询

  2. 另一种方法使用 Postgres 并将所有数据存储在具有适当索引的一个表中。我也可以使用每日分片(在一天开始时自动创建新表)但我担心 Postgres 是否可以处理十亿行。另外,如果我想获取最近 30 天的历史数据,我必须在以这种方式分片数据时进行 30 次 SELECT 查询。

我不想打扰像 Cassandra 这样过于复杂的解决方案(虽然从未尝试过)。另外我认为我不会从使用面向列的数据库中获得任何好处,因为我只有 4 列。

寻找类似于 Big Query 但没有提到的缺点的东西。我认为数据可以存储在一个节点中。

【问题讨论】:

  • 过去 30 天的查询不需要 30 次选择。如果查询始终是 30 天,那么您无论如何都不需要分区。在这种情况下,唯一的优势是使用简单的drop table 丢弃前一天。我不确定你是否理解 Postgresql 的分区。
  • 最佳解决方案取决于完整的情况和确切的要求。每日分区可能有用。
  • @ClodoaldoNeto 我的意思是当我在没有分区的情况下手动创建表时有 30 个选择查询。我需要查询的范围是 1 到 30 天。
  • 我意识到这是一个简化的例子,但列的基数是多少?总共有多少运动员,收集频率是多少(每天/小时/秒的“排名”测量次数)?对于每个“运动员”来说,“排名”指标的值是相对静态的还是随着每次观察而变化?
  • 在这里查看我的答案 - stackoverflow.com/questions/44614956/… - PostgreSQL 能够处理这样的数据,但您将需要非常强大的硬件或主/从架构 - 所以没有什么便宜的......要快速获得结果,您将必须预先汇总现有报告的数据。没有神奇的方法......

标签: database postgresql time-series google-bigquery nosql


【解决方案1】:

数据只能使用一个节点存储。实际上,每天 10 亿行并不多。它只有大约 32K 写入/秒。相比之下,Akumuli 在使用 SSD 的 m4.xlarge AWS 实例上每秒可以处理大约 150 万次插入(几乎是使用默认设置的 EBS 卷的一半,但您可以预置更多 IOPS)。要存储 30B 数据点,您需要少于 200GB 的磁盘空间(这取决于您的数据,但可以安全地假设数据点在磁盘上占用的空间少于 5 个字节)。

在您的情况下,数据模型很简单。系列名称如下所示:

athlet_rank name=<Name> discipline=<Discipline>

您将能够按名称查询数据:

{
  "select": "athlete_rank",
  "range": { "from": "20170501T000000",
             "to": "20170530T000000" },
  "where": { "name": <Name> }
}

如果您的基数很大(许多独特的系列),则不应选择 Akumuli。每个系列消耗大约 12KB 的 RAM,例如要处理具有 100 万个系列的数据库,您需要一台至少具有 16GB RAM 的服务器(实际数量取决于系列大小)。这最终会得到改进,但目前这就是我们所拥有的。

免责声明:我是 Akumuli 的作者,所以我有点偏见。但我很乐意收到任何反馈,无论好坏。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-17
    • 1970-01-01
    • 2014-08-03
    • 1970-01-01
    • 2016-08-27
    • 1970-01-01
    • 2012-05-30
    相关资源
    最近更新 更多