我开始设计一个将被大约50000台设备使用的新应用程序。每个设备每天生成大约1440个注册表,这意味着每天将存储超过7200万个注册表。这些注册表每分钟都会出现,我必须能够通过Java应用程序(J2EE)查询这些数据。因此,需要快速编写,快速读取和索引以允许生成报告。 设备只插入数据,J2EE应用程序需要偶尔读取。 现在我正在寻找支持这种操作的软件替代方案。
将这些数据放在一张桌子上会导致灾难性的情况,因为由于存储了一年多的数据,我将无法使用这些数据。
我正在使用Postgres,数据库分区似乎不是一个答案,因为我需要按月对表进行分区,或者可能是更精细的方法,例如天。
我正在考虑使用SQLite的解决方案。每个设备都有自己的SQLite数据库,而信息的细节足以保证良好的维护和快速插入和查询。
您怎么看?
答案 0 :(得分:4)
仅记录设备位置的变化 - 大部分时间任何设备都不会移动 - 汽车将被停放,一个人将坐着或睡觉,一个手机将在不动的人或收费等等 - 这将使您存储的数据量减少一个数量级。
每年最多产生1TB(即使没有实现第1点),这不是一个非常大的数据量。这意味着大约30MB / s的数据,单个SATA驱动器可以处理。
即使是一个简单的未分区的Postgres数据库,也不应该设置太大的硬件。唯一的问题可能是当您需要查询或备份时 - 可以使用Hot Standby使用Streaming Replication镜像来解决这个问题 - 这是即将发布的PostgreSQL 9.0中的一项新功能。只需查询/备份镜像 - 如果它正忙,它将暂时自动排队更改,然后再赶上。
当你真的需要分区时,例如在device_id模256而不是时间上进行分区。这样你就可以在每个分区上展开写入。如果按时分区,任何时刻只有一个分区会非常繁忙,而其他分区将处于空闲状态。 Postgres supports partitioning这种方式非常好。然后,您还可以使用tablespaces将负载分散到多个存储设备,这在Postgres中也得到了很好的支持。
答案 1 :(得分:2)
时间间隔分区是一个非常好的解决方案,即使你必须自己动手。保持与50,000个SQLite数据库的单独连接比单个Postgres数据库更不实用,即使每天有数百万个插入。
根据您需要针对数据集运行的查询类型,您可以考虑跨多个服务器对远程设备进行分区,然后查询这些服务器以将聚合数据写入后端服务器。
高容量表的关键是:最小化您写入的数据量和必须更新的索引数量;不要执行UPDATE或DELETE,只执行INSERTS(并对将来删除的数据使用分区--DROP TABLE比DELETE FROM TABLE快得多!)。
当您开始挑战数据库引擎时,表设计和查询优化变得非常特定于数据库。考虑聘请Postgres专家至少咨询您的设计。
答案 2 :(得分:2)
也许现在是时候让你可以在多台机器上进行分片了?卡桑德拉? Redis的?不要局限于sql db。
答案 3 :(得分:1)
数据库分区管理可以自动化;基于时间的数据分区是解决这类问题的标准方法,and I'm not sure that I can see any reason为什么用PostgreSQL无法做到这一点。
你每天大约有72米的行 - 假设你有一个设备ID,日期戳和两个浮点数(比方说)每行16-20个字节加上一些minor page metadata overhead.后面的fag-packet容量计划建议每天大约1-1.5GB的数据,或每年400-500GB的数据,并在必要时加上索引。
如果您可以使用定期刷新的数据(即不完全是最新的),您可以构建一个单独的报告表,并使用ETL过程定期更新。如果此表存储在单独的物理磁盘卷上,则可以查询它,而不会显着影响事务数据的性能。
历史数据的单独报告数据库还允许您通过删除旧分区来修剪操作表,这可能有助于提高应用程序性能。您还可以索引报告表并创建汇总表以优化报告性能。
如果您需要低延迟数据(即报告最新数据),也可以构建一个视图,其中引导分区从操作系统报告,并且历史数据从数据集市报告。这将允许批量查询在针对此优化的报告表上进行,而可以从操作系统直接读取相对少量的当前数据。
大多数低延迟报告系统使用这种方法的一些变体 - 领先的分区可以通过实时进程(可能是触发器)更新并包含相对较少的数据,因此可以快速查询,但不包含任何行李减慢更新速度。其余的历史数据可以大量索引以进行报告。按日期分区意味着系统将自动开始填充下一个分区,并且定期流程可以移动,重新索引或执行历史数据需要执行的任何操作以优化报告。
注意:如果您的预算运行到PostgreSQL而不是Oracle,您可能会发现直接连接存储比SAN快得多,除非您想在SAN硬件上花费很多钱。
答案 4 :(得分:0)
这是你要问的一个模糊的问题。我认为你不是面临数据库软件的选择,而是一个架构问题。
一些注意事项:
基本上,您对空间分区的想法是个好主意。如果需要,这不排除时间分区。无论你是使用postgres还是sqlite,都取决于其他因素,例如处理能力和可用库。
另一个考虑因素是您的设备是否可靠且功能强大,足以处理您的查询。否则,您可能希望使用集中的数据库集群,您仍然可以并行查询。