2010-09-13 108 views
5

我有一个数据转换产品,它允许在数据库中选择表并将源数据库中的行数据转换为目标数据库。如何处理任何数据库上的大量事务?

这是在当前产品(基于Java的工作台和引擎)中一次处理1000行并且并行执行10个线程处理的。这种方法适用于较小的数据集。但是,当我有能力改变庞大的数据集(说一下X万条记录)在同一时间 - 这种方法仍然有效,但

  • 上我的产品上运行,是高负载下的主机的CPU。
  • 源数据库和目标数据库被过多的事务打断,导致其开始放慢速度。 (现在,这可以归因于数据库服务器可能运行在较慢的硬件上)

我开始寻找解决方案,并且我很快就通过请求硬件“加强“在源/目标数据库服务器上。这涉及到购买新的多核CPU和一些额外的RAM。事实证明,升级硬件不仅仅是唯一的问题:需要购买数据库的多个软件许可证 - 这要归功于多核处理器(每个核心许可证)。

因此,球现在在我的球场上,我将不得不想出办法解决这个问题,通过改变我的产品。而且,这里是我需要你帮助的地方。在这一刻,我能想到的一个可能的方法来处理巨大的负荷:

Approach1从源数据库

  1. 读取数据时,它坚持到一个临时介质(文件)。
  2. 通过在分布式环境(更便宜的单核计算机)中运行,通过处理切换到文件持久性的“折衷方案”,将数据转换为持久化文件。 (使用Apache Hadoop之类的东西来处理分布式计算部分)
  3. 将数据写入目标数据库。

这是我现在所能想到的,从建筑的角度来看。 你以前是否处理过这种情况?如果是的话,你是怎么处理的? 感谢您的建议和帮助。

+0

什么是性能瓶颈?你提到了两个候选人:应用程序CPU负载和数据库负载。你能进一步缩小它吗? – oksayt 2010-09-13 15:08:39

+0

@oksayt现在,我主要关心的是数据库负载。我没有这方面的基准,但想法是通过考虑可能的瓶颈来构建更好的产品。 – Jay 2010-09-13 17:07:19

回答

3

有一对夫妇的事情,你可以做不增加你的数据库许可费用:

  • 你的工具是把在重负载下的CPU,假设你的工具是一台机器上运行,是不是运行数据库,增加该机器的CPU功率,或者如果您的工具允许它在多台机器上运行。
  • 活跃交易数量上升的原因之一是每笔交易都需要时间才能完成。您可以通过优化磁盘或放入更快的磁盘来加快速度。

此外,如果您使用插入而不是批量插入,则存在巨大的改进潜力。普通插入的问题在于它将信息写入日志,以便可以回滚事务。

this情况下,我能帮助别人从10小时减少加载时间6分钟 :)

+0

+1绝对大容量插入,如果它没有被使用可以是一个巨大的收益。 – eglasius 2010-09-13 19:20:27

+0

感谢您提供案例研究的链接。我提出这个问题的意图是为我的问题收集所有可能的解决方案。我不希望你太担心数据库事务是瓶颈。如果您可以将分布式计算视为可能的解决方案之一,您会投票选择这样的解决方案吗?如果不是,那么这个问题可能有哪些非数据库方式? – Jay 2010-09-13 20:21:23

+0

除了使用本地关系数据库,您可以使用云名称值对数据存储,但您的瓶颈将是您的互联网连接。您也可以在运行导入时启动多个机器实例,并在导入完成时关闭它们。 – 2010-09-13 20:46:30

0

首先要思考的是,如果您真的需要这些数据量的交易。如果答案是否定的,那么您的数据库产品可能会有一个用于这种大型数据库插入的批量插入选项。我认为最重要的是(在SQL Server中)无论如何都是在操作期间将目标数据库设置为简单恢复模式。事实上,如果你这样做了,很可能你不需要做任何其他的代码修改。

但是,这只有在目标数据库没有被同时用于其他事情时才适用。我会说这是一个基本要求。在OLAP事务处理时,尝试将2500万条记录插入数据库是一个基本的数据库错误。如果这是严格必要的,那么我认为解决方案是使进程非常缓慢(有明显的暂停),以释放资源以便数据库可以继续运行。

+0

您建议如果我忽略事务并找出一种利用通常可供数据库使用的批量插入选项的方法,那么它不会影响数据库的负载?那么,如果您要使用导入实用程序插入2500万条记录,那么您的数据库性能对于当前正在服务的所有请求将不受影响?如果是的话,你是否有这方面的参考资料? – Jay 2010-09-13 17:15:01

+0

我不会说他们没有受到影响,但是操作是针对它正在做的事情进行优化的。我看到你正在尝试使用Oracle和SQLServer。您可以尝试JDBC批量操作,但我不确定驱动程序的功能。以下是一些优化SQL中批量插入的文档:http://msdn.microsoft.com/en-us/library/ms190421%28v=SQL.105%29.aspx – Yishai 2010-09-13 17:53:33

+0

谢谢你的链接,我会检查它。 – Jay 2010-09-13 20:24:17

0

你有使用小型交易进行基准测试吗?否则我不会使用这个交易。从你的授权问题听起来就像你使用的是oracle或sql server。它们都具有批量插入功能,这比交易更适合这一点。

+0

不,我没有对它进行基准测试,或者说,它已被基准测试,只是我现在没有统计数据。是的,我一直在测试我的产品对oracle和sql server。我知道他们有进口/出口的实用性,但问题是,这些有多有效? – Jay 2010-09-13 17:19:58

+0

他们可以非常有效。几年前,我在一台sql server上使用它们来每天晚上将数百万条记录移动到一个报表数据库中。过程花费了大约3个小时,但每个记录都需要进行大量的预处理。 – scphantm 2010-09-13 23:39:22

1

分而治之!

如果DB不能一次(在ETL和“正规”交易),同时处理作业的来源,然后不让它遭受:

  • 将源数据的“镜像”。
  • 在“镜像”上执行ETL。

NB - 当我说“镜子”我只是意味着一个副本,从而使数据的快速,高效复制(有点像“上演” DB) - 另一大/慢/讨厌的ETL过程。这里的想法是优化流程以使源数据库受益。

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

你也可以在目标端做类似的事情(使用另一个“镜像”/临时数据库)。

这种做法是不是从你提出什么不同,但我假设在同类型的两个相同分贝的将是两个最容易管理和最高效的数据之间的直副本。

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

最后一两件事 - 你可以用ETL工具进行实验 - 如果你正在运行

0

使用的Oracle SQL装载机(输入/输出)。将数据导入中间表中,并且一旦将主表重新命名为备份后,一切都顺利将表重命名为主表。请记住,您只应在每次导入/上传后应用约束。你可以从java程序调用sql loader。