【问题标题】:Django + Postgres + Large Time SeriesDjango + Postgres + 大时间序列
【发布时间】:2014-10-02 10:27:34
【问题描述】:

我正在研究一个包含大量、大部分不可压缩的时间序列数据的项目,并且想知道使用原始 SQL 的 Django + Postgres 是否是正确的选择。

我有大约 2K 个对象/小时的时间序列数据,每小时。这大约是我每年存储的 200 万行,我希望 1) 能够通过连接分割数据以进行分析,2) 能够在 Django 提供的网络上进行基本的概述工作。我认为最好的想法是对对象本身使用 Django,但使用原始 SQL 来处理相关的大型时间序列数据。我认为这是一种混合方法;这可能是一个危险信号,但对一长串数据样本使用完整的 ORM 感觉有点矫枉过正。有没有更好的办法?

【问题讨论】:

    标签: python django postgresql heroku bigdata


    【解决方案1】:

    如果我正确理解您的想法,您正在考虑将时间序列存储在 PostgreSQL 中,一个时间序列记录在一个数据库行中。不要那样做。

    一方面,这个问题是理论上的。关系数据库(我认为大多数数据库)是基于行独立的前提,而时间序列的记录是物理排序的。当然,数据库索引为数据库表提供了某种顺序,但这种顺序是为了加快搜索速度或按字母顺序或其他顺序显示结果;它并不暗示该顺序的任何自然意义。无论您如何订购它们,每个客户都独立于其他客户,并且每个客户的购买都独立于他的其他购买,即使您可以按时间顺序一起获得它们以形成客户的购买历史。时间序列记录的相互依赖性更强,这使得关系数据库不合适。

    实际上,这意味着表及其索引占用的磁盘空间会很大(可能比将时间序列存储在文件中大 20 倍),从数据库中读取时间序列会很慢,有些比存储在文件中慢一个数量级。它也不会给你任何重要的好处。您可能永远不会进行查询“给我所有值大于 X 的时间序列记录”。如果您需要这样的查询,您还需要进行关系数据库未设计用于执行的其他分析,因此无论如何您都会将整个时间序列读入某个对象。

    所以每个时间序列都应该存储为一个文件。它可能是文件系统上的一个文件,也可能是数据库中的一个 blob。尽管我有implemented the latter,但我相信前者更好;在 Django 中,我会这样写:

    class Timeseries(models.model):
        name = models.CharField(max_length=50)
        time_step = models.ForeignKey(...)
        other_metadata = models.Whatever(...)
        data = models.FileField(...)
    

    使用FileField 将使您的数据库更小,并且更容易对系统进行增量备份。通过在文件中查找也可以更容易地获得切片,这对于 blob 来说可能是不可能或困难的。

    现在,什么样的文件?我建议你看看熊猫。这是一个用于数学分析的python库,支持时间序列,它还应该有一种将时间序列存储在文件中的方法。

    我在上面链接到我不建议您使用的库;一方面它没有做你想做的事(它不能处理比​​一分钟更精细的粒度,而且它还有其他缺点),另一方面它已经过时了——我在 pandas 之前写过它,我打算转换它将来使用熊猫。 pandas 的作者有一本书,《Python for data analysis》,我觉得这本书很有价值。

    更新(2016 年): 还有 InfluxDB。从未使用过它,因此我没有意见,但如果您想知道如何存储时间序列,这绝对是您需要检查的东西。

    更新(2020-02-07):还有 TimescaleDB,一个 PostgreSQL 的扩展。

    更新(2020-08-07):我们(再次)更改了我们的软件,以便它使用 TimescaleDB 将数据存储在数据库中。我们已经精通 PostgreSQL,学习一些 TimescaleDB 很容易。最重要的具体优势是我们可以进行诸如“查找 2019 年 24 小时内降雨 >50 毫米的所有位置”之类的查询,这在将数据存储在平面文件中时会非常困难。另一个优点是完整性检查——多年来,由于到处都有小错误,我们有一些带有重复行的时间序列。缺点也很明显。它使用了 10 倍以上的磁盘空间。因此,我们可能需要更改我们的 PostgreSQL 备份策略。它更慢。检索具有 30 万条记录的时间序列可能需要一秒钟。这是之前的瞬间。我们需要实现缓存以检索时间序列,而这在以前是不需要的。

    【讨论】:

    • 我不确定文件是否能解决我的用例。我正在查看天气数据,因此我对 1) 几个地方的所有历史记录进行切片,2) 对较短历史切片 (!month) 的所有地方进行切片,以及 3) 一段时间内所有位置的最大值。 (因为天气在时间和地点上是相关的,所以不同的地方可以有意义地相互通知。)如果我使用一个文件实现,它要么是地方主要的(每个地方都有一个文件)要么是时间主要的(每天/每周/每月得到一个文件),如果我拉上面的各种切片,我将不得不触摸所有文件。数据库肯定行不通吗?
    • 我误会你了;我以为你有一个每小时 2k 行的时间序列;现在我知道你在 2k 个地点有每小时的时间序列。然而,我的看法并没有改变。不,关系数据库并非绝对不可行,而且我确信已经用它编写了成功的应用程序。但是我认为这是次优的。但是,它可能适合您。我看到 pandas 具有从数据库读取和写入数据的功能。
    • 您对开盘高低收盘数据的建议是否相同?我正在研究时间序列,但存储为 pandas 数据框会让我的一切变得更容易。
    • 我真的不知道。我有一些代码可以从数据库读取到熊猫,反之亦然,从文件读取到熊猫,反之亦然。
    • 看看VictoriaMetrics。它很有可能会以较低的资源使用量为您的工作负载显示更好的性能。
    【解决方案2】:

    时间序列数据库似乎是不断被重新发明的事物之一,如上所述,关系数据库并不适合。

    我所做的是将 Django 与为时间序列数据构建的 InfluxDB 结合使用。使用起来非常棒,python 客户端库可以与 pandas 数据框一起使用。这意味着您可以使用 InfluxDB 查询语言就地处理数据,或者提取所有数据(如果需要,聚合)以在 python 中进行分析。我的应用正在处理与您需要的数据量相似的数据流。

    我根据需要将 InfluxDB 系列名称与 django app/model/primary key 相关联。时间序列数据进入链接的 InfluxDB 系列,杂项变化缓慢或关系数据进入 django ORM 字段。

    【讨论】:

      【解决方案3】:

      听起来您想查看timescale。我自己还没有使用过它,但它显然是 PostgreSQL 的扩展,所以我假设完全支持 Django 并且它按照他们所说的那样处理

      每秒 10 万行和数百万个指标,即使在单个节点上达到 1000 亿行也是如此。

      【讨论】:

        【解决方案4】:

        您也可以考虑使用 PostGIS postgres 扩展,该扩展包括对栅格数据类型(基本上是大的数字网格)的支持,并且具有许多可以使用它们的功能。

        但是,在这种情况下不要使用 ORM,您将希望直接在服务器上执行 SQL。 ORM 将为大型数值数据集增加大量开销。它也不太适合在 python 本身中处理大型矩阵,因为你需要 numpy。

        【讨论】:

          猜你喜欢
          • 2016-07-17
          • 2013-10-26
          • 2012-11-02
          • 1970-01-01
          • 1970-01-01
          • 2023-03-21
          • 1970-01-01
          • 1970-01-01
          • 2011-01-16
          相关资源
          最近更新 更多