Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/417.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在任何数据库上处理大型事务的方法?_Java_Design Patterns_Architecture_Hardware - Fatal编程技术网

Java 在任何数据库上处理大型事务的方法?

Java 在任何数据库上处理大型事务的方法?,java,design-patterns,architecture,hardware,Java,Design Patterns,Architecture,Hardware,我有一个数据转换产品,它允许选择数据库中的表,并将源数据库中的行数据转换为目标数据库 在当前产品(基于java的工作台和引擎)中,可以通过一次处理1000行并并行处理10个线程来处理这一问题。这种方法适用于较小的数据集。但是,当我必须一次性转换巨大的数据集(比如说大约X百万条记录)时,这种方法仍然有效,但是 我的产品运行的主机CPU负载很重 源数据库和目标数据库中的事务太多,导致它们开始减速。(现在,这可能是因为数据库服务器可能运行在较慢的硬件上。) 我开始寻找解决方案,并通过请求源/目标数

我有一个数据转换产品,它允许选择数据库中的表,并将源数据库中的行数据转换为目标数据库

在当前产品(基于java的工作台和引擎)中,可以通过一次处理1000行并并行处理10个线程来处理这一问题。这种方法适用于较小的数据集。但是,当我必须一次性转换巨大的数据集(比如说大约X百万条记录)时,这种方法仍然有效,但是

  • 我的产品运行的主机CPU负载很重
  • 源数据库和目标数据库中的事务太多,导致它们开始减速。(现在,这可能是因为数据库服务器可能运行在较慢的硬件上。)
我开始寻找解决方案,并通过请求源/目标数据库服务器机器上的硬件“增强”来快速解决这一问题。比如说,这涉及到购买一个新的多核CPU和一些额外的RAM。事实证明,升级硬件并不是唯一的问题:需要为数据库购买多个软件许可证——这要归功于多核处理器(每个核心许可证)

所以,现在是我的问题了,我必须想办法解决这个问题,对我的产品进行修改。这就是我需要你帮助的地方。此时,我可以想到一种处理巨大负载的可能方法:

方法1

  • 从源数据库读取数据,将其持久化到临时介质(文件)
  • 转换持久化文件中的数据,方法是在分布式环境(更便宜的单核计算机)中运行数据,然后处理切换到文件持久化的“折衷移动”。(使用类似ApacheHadoop的东西来处理分布式计算部分)
  • 将数据写入目标数据库 从建筑的角度来看,这就是我现在能想到的全部。 你以前处理过这种情况吗?如果是,您是如何处理的?
    感谢您的建议和帮助

    这里要考虑的第一件事是您是否真的需要为这么多的数据进行事务处理。如果答案是否定的,那么您的数据库产品可能有一个批量插入选项,它是为这种大型数据库插入而设计的

    编辑(进一步评论):我认为最划算的做法(无论如何,在SQL Server中)是在操作期间将目标数据库设置为简单恢复模式。事实上,如果您这样做了,那么很可能不需要进行任何其他代码更改


    但是,只有当目标数据库没有同时用于其他事情时,这才合适。我认为这是一项基本要求。当OLAP事务处于活动状态时,试图将2500万条记录插入数据库是一个基本的数据库错误。如果这是绝对必要的,那么我认为解决方案是使流程非常缓慢(有明显的停顿),以便释放资源,使数据库能够继续运行。

    您是否使用较小规模的事务对其进行了基准测试?否则我就不会使用事务来处理这个问题。从您的许可问题来看,您似乎正在使用oracle或sql server。它们都具有大容量插入功能,这比事务更适合此功能。

    在不增加数据库许可证成本的情况下,您可以做以下几件事:

    • 您的工具将CPU置于繁重的负载下,假设您的工具在未运行数据库的机器上运行,请增加该机器上的CPU电源,或者如果您的工具允许它在多台机器上运行
    • 活动事务数量增加的原因之一是每个事务都需要时间来完成。您可以通过优化磁盘或安装更快的磁盘来加快速度
    另外,如果您使用insert而不是bulkinsert,则有巨大的改进潜力。普通插入的问题是,它将信息写入日志,以便可以回滚事务

    如果我能够帮助某人将加载时间从10小时减少到6分钟:)

    分而治之

    如果源数据库不能同时处理两个作业(ETL和“常规”事务),那么不要让它受到影响:

    • 将源数据复制到“镜像”中
    • 在“镜像”上执行ETL
    注意-当我说“镜像”时,我只是指允许快速高效复制数据的拷贝(有点像“暂存”DB)而不是另一个大/慢/讨厌的ETL过程。这里的想法是优化流程,使源数据库受益

    然后,您可以优化目标数据库的ETL,使目标数据库受益;因为您已经将源和目标分开,所以更容易优化整个流程的读取/插入部分

    您可能也可以在目标端执行类似的操作(使用另一个“镜像”/“暂存数据库”)

    这种方法与您建议的方法没有太大区别,但我假设在相同类型的两个相同db之间直接复制数据将是最容易管理和最有效的

    之后,你可以开始应用其他人可以提出的一些建议


    最后一件事-您可以尝试使用ETL工具-如果您正在运行

    ,请使用oracle sql loader(导入/导出)。导入中间表中的数据,一切正常后,在将主表重命名为备份后,将该表重命名为主表。请记住,您应该仅在每次导入/上载后应用约束。您可以从java程序调用sql loader。

    性能瓶颈是什么?您已经提到了两个候选者:应用程序CPU负载和数据库