有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在大量重复数据的地方,我可以选择哪些方法来存储和查询大量数据?

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

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(如JasperReports)之外,我想到的几个工具将与Hibernate/POJO集成,但这并没有真正解决聚合函数问题,可能还有一系列其他问题

因此,我在某种程度上让自己不得不使用一个更专有的[可能是非SQL]数据存储(任何建议都值得赞赏),然后专注于编写一个伪JDBC驱动程序以至少简化与外部工具的集成这一可能不太复杂的任务

我听到有人提到一种称为“位压缩文件”的机制来实现这种数据压缩,但我不知道有哪个数据库提供了这一点,以及我最不想做的事情(或者可以做,真的……)我正在写我自己的数据库

有什么建议或见解吗


共 (5) 个答案

  1. # 1 楼答案

    Hibernate(或任何JPA解决方案)是用于此作业的错误工具

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

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

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

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

    1. 基于地图的解决方案,如一致性或陶土;及
    2. 基于Javaspaces的解决方案,如GigaSpaces

    我经常使用连贯性,贴图解决方案可能很好,但也可能有问题。一致性贴图上可以有监听器,您可以使用这种方式执行以下操作:

    • 市场价格警报(当价格达到一定水平时,用户可能需要通知)
    • 衍生工具定价(例如,当标的证券改变最后交易价格时,交易所交易期权定价系统将希望重新定价)
    • 交易匹配/预订系统可能希望匹配收到的交易通知,以便进行对账
    • 等等

    所有这些都可以通过侦听器完成,但在一致性方面,例如,侦听器必须便宜,这会导致像一个映射有一个侦听器,而不是将某些内容写入另一个映射,这可能会持续一段时间。此外,修改缓存条目可能会有问题(尽管也有处理此类问题的机制;我指的是关闭市场价格警报以避免再次触发的情况)

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

    考虑两种经典排队结构:

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

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

    现在我听到你问,坚持到底怎么样?坚持是决定所有其他事情的结果。对于这种应用程序,我喜欢Persistence as a Service模型(讽刺的是,它写的是Hibernate,但它适用于任何东西)

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

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

    这是一个复杂的话题,我只真正触及了它。希望这对你有帮助

  2. # 2 楼答案

    你可能会发现听Michael Stonebraker's presentation at Money:Tech很有趣。他提到了您所需要的一些东西,并举例说明了三巨头(SQL Server、Oracle和DB2)将永远无法满足tick Store(看起来您正在构建)的需要。他超越了专栏商店,我同意这是正确的方向。他甚至还讨论了压缩和速度这两个问题

    以下是一些您可能会感兴趣的链接:

  3. # 5 楼答案

    谢谢你的回答

    Cletus,我很欣赏这个大纲,但我不能做的一个折衷是放弃DB灵活性和与JDBC/Hibernate的兼容性,允许使用所有可用的工具。此外,尽管我没有明确说明这一点,但我不想强迫我的用户采用[可能昂贵的]商业解决方案。如果他们有数据库品牌X,让他们使用它。如果他们不在乎,我们推荐开源数据库品牌Y。基本上,应用程序有多个面,其中一个面是传入数据的存储库,另一个面是报告源,我真的不想从事编写报告生成器的工作

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

    谢谢你的指点,贾瓦曼。它把我分到了路西达