gpt4 book ai didi

java - 我有哪些选择来存储和查询大量重复的数据?

转载 作者:搜寻专家 更新时间:2023-11-01 01:39:29 24 4
gpt4 key购买 nike

我正在评估 Java 中高效数据存储的选项。数据集是带有命名主键的时间戳数据值。例如

Name: A|B|C:D
Value: 124
TimeStamp: 01/06/2009 08:24:39,223

可能是给定时间点的股票价格,所以我想这是一个经典的时间序列数据模式。但是,我确实需要一个通用的 RDBMS 解决方案,它可以与任何合理的 JDBC 兼容数据库一起使用,因为我想使用 Hibernate。因此,像 Oracle 这样的数据库的时间序列扩展并不是真正的选择,因为我希望实现者能够使用他们自己的支持 JDBC/Hibernate 的数据库。

这里的挑战只是可以在短时间内积累的海量数据。到目前为止,我的实现主要集中在定义定期汇总和清除计划,其中原始数据聚合到 DAY、WEEK、MONTH 等表中,但缺点是粒度的早期丢失以及存储在不同时间段之间的时间段不匹配带来的轻微不便聚合体。

挑战的选项有限,因为在保留数据原始粒度的同时可以物理压缩多少数据存在绝对限制,并且使用关系数据库和通用 JDBC 能力的指令加剧了这一限制一个。

借用经典数据压缩算法中的概念性概念,并利用相同命名键的许多连续值预期相同的事实,我想知道是否有办法通过合并来无缝减少存储记录的数量将值重复到一个逻辑行中,同时还存储一个计数器,该计数器有效地指示“接下来的 n 记录具有相同的值”。实现这一点似乎很简单,但代价是数据模型现在非常复杂,无法使用标准 SQL 进行查询,尤其是在使用任何类型的聚合 SQL 函数时。这显着降低了数据存储的实用性,因为只有复杂的自定义代码才能将数据恢复到“解压缩”状态,从而导致阻抗不匹配,数百种工具将无法正确呈现此数据。

我考虑过定义自定义 Hibernate 类型的可能性,这些类型基本上可以“理解”压缩数据集并将其备份并使用动态创建的合成行返回查询结果。 (除了严格控制的输入流之外,数据库将只对所有客户端读取)。除了原始 JDBC(例如 JasperReports)之外,我想到的一些工具将与 Hibernate/POJOS 集成,但这并没有真正解决聚合函数问题,可能还有很多其他问题。

因此,我正在部分地放弃自己可能不得不使用更专有的 [可能是非 SQL] 数据存储(任何建议表示赞赏),然后专注于编写一个伪 JDBC 驱动程序的可能不那么复杂的任务,至少轻松与外部工具集成。

我听说有一种叫做“位压缩文件”的东西作为实现这种数据压缩的机制,但我不知道有任何数据库提供这种机制,我最不想做的事情(或者可以做,真的......)是写我自己的数据库。

有什么建议或见解吗?

最佳答案

Hibernate(或任何 JPA 解决方案)不适合这项工作。

JPA/Hibernate 不是一个轻量级的解决方案。在大容量应用程序中,开销不仅很大而且令人望而却步。你真的需要调查grid and cluster solutions .我不会在这里重复各种技术的概述。

我在金融市场信息系统方面拥有丰富的经验。你说的一些话让我印象深刻:

  • 你有很多原始数据;
  • 您想对该数据应用各种聚合(例如开盘价/高价/低价/收盘价每日摘要);
  • 高可用性可能是一个问题(在这类系统中总是如此);和
  • 低延迟可能是一个问题(同上)。

现在对于网格/集群类型的解决方案,我将它们松散地分为两类:

  1. 基于 map 的解决方案,例如 Coherence 或 Terracotta;和
  2. 基于 Javaspaces 的解决方案,例如 GigaSpaces。

我经常使用 Coherence,Map 解决方案可能不错,但也可能存在问题。 Coherence maps 上可以有监听器,你可以使用这种东西来做这样的事情:

  • 市场价格提醒(用户可能希望在价格达到特定水平时收到通知);
  • 衍生品定价(例如,交易所交易的期权定价系统希望在标的证券的最后交易价格发生变化时重新定价);
  • 交易匹配/预订系统可能希望匹配收到的交易通知以进行对帐;
  • 等等

所有这些都可以通过监听器来完成,但是在 Coherence 中,例如监听器必须是便宜的,这导致像 Map 具有监听器而不是向另一个 Map 写入内容的事情,这可以持续一段时间。此外,修改缓存条目可能会有问题(尽管也有处理此类问题的机制;我说的是关闭市场价格警报这样它不会触发第二次的情况)。

我发现 GigaSpaces 类型的网格解决方案对于此类应用程序更具吸引力。读取(或破坏性读取)操作是一种非常优雅且可扩展的解决方案,您可以获得亚毫秒级性能的事务性网格更新。

考虑两种经典的队列架构:

  • 请求/响应:错误的消息可能会阻塞队列,虽然您可以有很多发送者和接收者(为了可扩展性),但增加管道数量并不总是那么简单;和
  • 发布/订阅:这分离了发送者和接收者,但缺乏可扩展性,因为如果您有多个订阅者,他们每个人都会收到消息(不一定是您想要的预订系统)。

在 GigaSpaces 中,破坏性读取就像一个可扩展的发布-订阅系统,而读取操作就像传统的发布-订阅模型。在网格之上构建了一个 Map 和 JMS 实现,它可以进行 FIFO 排序。

现在我听到你问关于持久性的问题是什么?坚持是决定所有其他事情的结果。对于这种应用程序,我喜欢 Persistence as a Service模型(具有讽刺意味的是关于 Hibernate 的文章,但它适用于任何事物)。

基本上这意味着您的日期存储命中是异步的,并且它可以很好地处理汇总数据。就像您可以让服务监听交易通知并只保留它感兴趣的通知(如果需要,在内存中聚合)。您可以通过这种方式设置开盘价/最高价/最低价/收盘价。

对于大量数据,您真的不想将其全部写入数据库。反正不是同步的。持久存储加数据仓库可能更适合您的选择,但这同样取决于需求、容量等。

这是一个复杂的话题,我只是真正接触过它。希望对您有所帮助。

关于java - 我有哪些选择来存储和查询大量重复的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/416432/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com