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

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

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

这里的挑战就是短时间内积累的大量数据。到目前为止,我的实现重点是定义定期汇总和清除计划,其中原始数据被聚合为天、周、月等。表,但缺点是粒度会过早丢失,并且不同聚合中存储的期间之间的期间不匹配会带来轻微的不便。

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

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

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

因此,我正在部分地接受自己可能必须使用更专有的[可能非 SQL] 数据存储(任何建议都表示赞赏),然后专注于编写伪 JDBC 驱动程序的可能不太复杂的任务,以至少简化与外部工具。

我听到有人提到“位打包文件“作为实现这种数据压缩的机制,但我不知道有任何数据库提供这种功能,而我想做的最后一件事(或者实际上可以做的......)就是编写我自己的数据库。

有什么建议或见解吗?

有帮助吗?

解决方案

我会看一下面向列的数据库 。这种应用程序会很棒

其他提示

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

JPA/Hibernate 不是一个轻量级的解决方案。在大容量应用中,开销不仅很大而且令人望而却步。你真的需要调查一下 网格和集群解决方案. 。这里不再重复各种技术的概述。

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

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

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

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

我经常使用 Coherence,Map 解决方案可能很好,但也可能有问题。相干图可以有监听器,您可以使用这种东西来执行以下操作:

  • 市场价格警报(用户可能希望在价格达到一定水平时收到通知);
  • 衍生品定价(例如,当基础证券改变最后交易价格时,交易所交易的期权定价系统将需要重新定价);
  • 出于对账目的,交易匹配/预订系统可能需要匹配收到的交易通知;
  • ETC。

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

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

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

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

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

现在我听到你问坚持怎么样?坚持是决定所有其他事情的结果。对于这种应用程序,我喜欢 持久化即服务 模型(具有讽刺意味的是,它是关于 Hibernate 的,但它适用于任何事物)。

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

对于大量数据,您并不希望将其全部写入数据库。反正不是同步的。持久存储加上数据仓库可能更适合您,但这又取决于需求、数量等。

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

您可能会觉得听起来很有趣 Michael Stonebraker 在 Money:Tech 上的演讲. 。他谈到了您提到的许多需要的东西,并说明了三大大象(SQL Server、Oracle 和 DB2)如何永远无法满足分笔存储(看起来您正在构建)的需求。他超越了专栏商店,我同意这是正确的方向。他甚至讨论了压缩和速度,这对你来说都是问题。

这里还有一些您可能会感兴趣的链接:

许多支持JDBC的数据库管理系统(例如Oracle)在物理存储引擎中提供压缩。例如,Oracle有一个“压缩”的概念。没有减压开销的表:

http://www.ardentperf的.com /可湿性粉剂内容/上传/ 2007/07 /先进 - 压缩 - datasheet.pdf

感谢您的回答。

Cletus,我很欣赏这个大纲,但我不能做出的一个权衡就是放弃DB的灵活性和与JDBC / Hibernate的兼容性,以允许使用所有可用的工具。此外,虽然我没有明确说明这一点,但我不想强迫我的用户采用[可能昂贵的]商业解决方案。如果他们有Database Brand X,那就让他们使用它。如果他们不在乎,我们建议开源数据库品牌Y.基本上,该应用程序有多个面孔,其中一个是传入数据的存储库,但另一个面是报告源,我真的 don我想进入编写报告生成器的业务。

虽然我还没有真正加载测试,但我对 LucidDB 印象深刻。它是一个面向列的数据库,它提供了良好的查询性能和看似良好的数据压缩。它有一个JDBC驱动程序虽然没有Hibernate方言,但据我所知。它还支持用户定义的转换,简而言之,我认为这将允许我无缝地实现我将重复和连续值压缩成一个“行”的想法,但是将它们吹回到多个“合成”的转换中。查询时的行,都是对查询调用者不可见的。最后,它支持外部表的这个漂亮的功能,其中支持数据库表的其他JDBC可以在LucidDB中面向前端。我认为这对于为其他数据库提供某种程度的支持可能是非常宝贵的。

感谢指针,Javaman。它把我划分为LucidDB。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top