【问题标题】:A huge data storage problem巨大的数据存储问题
【发布时间】:2011-03-26 11:19:45
【问题描述】:

我开始设计一个可供大约 50000 台设备使用的新应用程序。每台设备每天生成大约 1440 个注册表,这意味着每天将存储超过 7200 万个注册表。这些注册表每分钟都在不断出现,我必须能够通过 Java 应用程序 (J2EE) 查询这些数据。所以它需要快速写入、快速读取和索引以允许生成报告。 设备只插入数据,J2EE 应用程序需要偶尔读取。 现在我正在寻找支持这种操作的软件替代品。

  • 将这些数据放在一个表上会导致灾难性的情况,因为我无法使用这些数据,因为它存储了一年多的数据量。

  • 我正在使用 Postgres,数据库分区似乎不是一个解决方案,因为我需要按月对表进行分区,或者可能是更细粒度的方法,例如天。

    李>

我正在考虑使用 SQLite 的解决方案。每台设备都有自己的 SQLite 数据库,信息的粒度足够细,便于维护和快速插入和查询。

你怎么看?

【问题讨论】:

  • 这个问题太笼统了。完全取决于数据/查询的类型等。
  • 因此,更具体地说,数据是插入数据库的 GPS 坐标。查询将是如下报告:“告诉我设备 1234 在 2010 年 7 月的位置”。
  • 您是否已经在数据库中安装了 PostGIS?
  • 我安装了 PostGIS,为什么:

标签: database database-design sqlite postgresql data-structures


【解决方案1】:

你问的这个问题有点含糊。而且我认为您面临的不是数据库软件的选择,而是架构问题。

一些注意事项:

  • 这些设备的可靠性如何,以及如何 它们是否与 查询软件?
  • 故障保护如何做 你需要存储吗?
  • 这些设备有多少额外的处理能力 必须处理您的查询?

基本上,您对空间分区的想法是个好主意。如有必要,这并不排除时间分区。您是在 postgres 还是 sqlite 中执行此操作取决于其他因素,例如处理能力和可用库。

另一个考虑因素是您的设备是否可靠且功能强大,足以处理您的查询。否则,您可能希望使用集中式数据库集群,您仍然可以并行查询。

【讨论】:

  • 设备和 J2EE 是分离的实体。设备只写入,J2EE 应用程序偶尔读取。 - 设备将通过数据库连接到查询软件。 - 数据必须是故障安全的,所以丢失数据是不好的。 - 设备不会查询数据,它们只会生成数据。
【解决方案2】:

时间间隔分区是一个非常好的解决方案,即使您必须自己动手。维护与 50,000 个 SQLite 数据库的单独连接远不如单个 Postgres 数据库实用,即使每天进行数百万次插入也是如此。

根据您需要针对数据集运行的查询类型,您可能会考虑将远程设备划分为多个服务器,然后查询这些服务器以将聚合数据写入后端服务器。

大容量表的关键是:尽量减少写入的数据量和必须更新的索引数量;不要执行 UPDATE 或 DELETE,只执行 INSERTS(并对将来要删除的数据使用分区 - DROP TABLE 比 DELETE FROM TABLE 快得多!)。

当您开始挑战数据库引擎时,表设计和查询优化变得非常特定于数据库。考虑聘请 Postgres 专家至少为您的设计提供咨询。

【讨论】:

    【解决方案3】:

    也许是时候建立一个可以在多台机器上分片的数据库了?卡桑德拉?雷迪斯?不要将自己限制在 sql db 中。

    【讨论】:

      【解决方案4】:
      1. 仅记录设备位置的变化 - 大多数情况下,任何设备都不会移动 - 汽车将停放,一个人会坐着或睡觉,手机会在静止的人身上或充电等 - 这将让您存储的数据减少一个数量级。

      2. 您每年最多会生成大约 1TB(即使没有实施第 1 点),这并不是一个非常大的数据量。这意味着大约 30MB/s 的数据,单个 SATA 驱动器可以处理。

      3. 即使是在不太大的硬件上的简单未分区 Postgres 数据库也应该能够处理这个问题。唯一的问题可能是当您需要查询或备份时——这可以通过使用Streaming ReplicationHot Standby 镜像来解决——这是即将发布的PostgreSQL 9.0 中的一项新功能。只需查询/备份一个镜像 - 如果它很忙,它将暂时自动排队更改,并稍后赶上。

      4. 当您确实需要分区时,例如在 device_id 模 256 上而不是时间上进行分区。这样,您就可以在每个分区上展开写入。如果您按时分区,那么任何时候只有一个分区会非常繁忙,而其他分区将处于空闲状态。 Postgres supports partitioning 这种方式非常好。然后,您还可以使用 tablespaces 将负载分散到多个存储设备,Postgres 也很好地支持这些设备。

      【讨论】:

      【解决方案5】:

      数据库分区管理可以自动化;基于时间的数据分区是处理这类问题的标准方法,and I'm not sure that I can see any reason 为什么 PostgreSQL 不能这样做。

      您每天大约有 72m 行 - 假设一个设备 ID、日期戳和两个用于坐标的浮点数,您将拥有(例如)每行 16-20 个字节加上一些 minor page metadata overhead. 支持数据包容量计划建议每天大约 1-1.5GB 的数据,或每年 400-500GB,必要时加上索引。

      如果您可以接受定期刷新的数据(即不完全是最新的),您可以构建一个单独的报告表并使用 ETL 流程定期更新它。如果此表存储在单独的物理磁盘卷上,则可以对其进行查询,而不会显着影响事务数据的性能。

      用于历史数据的单独报告数据库还允许您通过删除旧分区来修剪您的操作表,这可能有助于提高应用程序性能。您还可以为报告表编制索引并创建汇总表以优化报告性能。

      如果您需要低延迟数据(即报告最新数据),也可以构建一个视图,其中领先分区从操作系统报告,历史数据从数据集市报告.这将允许在为此优化的报告表上进行批量查询,同时可以直接从操作系统读取相对少量的当前数据。

      大多数低延迟报告系统都使用这种方法的一些变体 - 前导分区可以通过实时进程(可能是触发器)进行更新,并且包含相对较少的数据,因此可以快速查询,但不包含减慢更新速度。其余的历史数据可以被大量索引以进行报告。按日期分区意味着系统将自动开始填充下一个分区,并且定期进程可以移动、重新索引或执行任何需要对历史数据执行的操作以优化它以进行报告。

      注意:如果您的预算用于 PostgreSQL 而不是 Oracle,您可能会发现直连存储比 SAN 快得多,除非您想在 SAN 硬件上花很多钱。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-30
        相关资源
        最近更新 更多