如何有效利用10台以上的计算机导入数据

时间:2011-04-12 08:01:15

标签: database star-schema

我们有包含> 200,000,000行的平面文件(CSV),我们将其导入具有23个维度表的星型模式。最大的维度表有300万行。目前我们在一台计算机上运行导入过程,大约需要15个小时。由于时间太长,我们希望利用40台计算机之类的东西进行导入。

我的问题

我们如何才能有效利用40台计算机进行导入。主要担心的是,在所有节点上复制维度表需要花费大量时间,因为它们需要在所有节点上相同。这可能意味着如果我们将来使用1000台服务器进行导入,由于服务器之间广泛的网络通信和协调,它实际上可能比使用单一服务器慢。

有没有人有建议?

修改

以下是CSV文件的简化:

"avalue";"anothervalue"
"bvalue";"evenanothervalue"
"avalue";"evenanothervalue"
"avalue";"evenanothervalue" 
"bvalue";"evenanothervalue"
"avalue";"anothervalue"

导入后,表格如下所示:

dimension_table1

id  name
1   "avalue"
2   "bvalue"

dimension_table2

id  name
1   "anothervalue"
2   "evenanothervalue"

事实表

  dimension_table1_ID       dimension_table2_ID
    1                      1
    2                      2
    1                       2
    1                       2              
    2                       2
    1                       1

8 个答案:

答案 0 :(得分:10)

您可以考虑使用64位哈希函数为每个字符串生成bigint ID,而不是使用顺序ID。

使用64位哈希码,您可以在哈希表中存储2 ^(32 - 7)或超过3000万个项目,然后发生碰撞的可能性为0.0031%。

这将允许您在所有节点上拥有相同的ID,在“dispatch”和“merge”阶段之间的服务器之间无需任何通信。

您甚至可以增加位数以进一步降低碰撞几率;只是,您将无法在64位整数数据库字段中生成结果哈希值。

请参阅:

http://en.wikipedia.org/wiki/Fowler_Noll_Vo_hash

http://code.google.com/p/smhasher/wiki/MurmurHash

http://www.partow.net/programming/hashfunctions/index.html

答案 1 :(得分:3)

将CSV数据加载到数据库中的速度很慢,因为它需要读取,拆分和验证数据。

所以你应该尝试的是:

  1. 在每台计算机上设置本地数据库。这将消除网络延迟。

  2. 在每台计算机上加载不同部分的数据。尝试为每台计算机提供相同的块。如果由于某种原因这不容易,请给每台计算机,比如说,10,000行。完成后,给他们下一个块。

  3. 使用数据库工具转储数据

  4. 将所有转储加载到单个数据库

  5. 确保您的加载程序工具可以将数据导入已包含数据的表中。如果您无法执行此操作,请检查数据库文档中的“远程表”。许多数据库允许从本地可见的另一个DB服务器创建表。

    这允许您运行insert into TABLE (....) select .... from REMOTE_SERVER.TABLE

    之类的命令

    如果您需要主键(并且您应该),则在导入本地数据库期间也会出现分配PK的问题。我建议将PK添加到CSV文件中。

    [编辑] 检查完修改后,您应该尝试以下操作:

    1. 编写一个小程序,在CSV文件的第一和第二列中提取唯一值。这可能是一个简单的脚本,如:

       cut -d";" -f1 | sort -u | nawk ' { print FNR";"$0 }'
      

      这是一个非常便宜的过程(即使对于大文件也要几分钟)。它为您提供了ID值文件。

    2. 编写一个程序,读取新的ID值文件,将它们缓存在内存中,然后读取巨大的CSV文件,并用ID替换这些值。

      如果ID值文件太大,只需对小文件执行此步骤,然后将大量文件加载到所有40个每机器数据库中。

    3. 将大文件拆分为40个块并在每台机器上加载每个文件。

      如果你有大量的ID值文件,你可以使用在每台机器上创建的表来替换剩下的所有值。

    4. 使用备份/恢复或远程表来合并结果。

      或者,更好的是,将数据保存在40台计算机上,并使用并行计算中的算法来分割工作并合并结果。这就是谷歌可以在几毫秒内从数十亿网页创建搜索结果的方式。

    5. 请参阅here for an introduction

答案 2 :(得分:2)

这是一个非常通用的问题,不考虑数据库后端。在无法处理负载的数据库后端上使用40或1000台计算机进行解雇将不会给您带来任何帮助。这个问题确实是广泛的,以特定的方式回答它。你应该首先在组织内部与人员取得联系,然后再提出更具体的问题。

答案 3 :(得分:2)

假设有N台计算机,每个X文件大约有50GB文件,目标是在最后有1个包含所有内容的数据库。

问题:现在需要15个小时。你知道这个过程的哪个部分花费的时间最长吗? (读取数据,清理数据,保存表中的读取数据,索引......您将数据插入到未编制索引的表中并在之后编制索引,对吗?)

要在N台计算机中分配这份工作,我会做类似的事情(这是一种背后的设计):

  • 拥有“中央”或主数据库。使用它来整理整个过程,并保留最终的完整仓库。
  • 它包含所有X文件和所有N-1(不计算自身)“工人”数据库​​
  • 的列表
  • 每个工作者数据库都以某种方式链接到主数据库(具体取决于您未指定的RDBMS)
  • 启动并运行时,“就绪”工作线程数据库会轮询主数据库以查找要处理的文件。 master数据库将文件发送到工作系统,确保一次不会有多个文件被处理。 (必须跟踪加载给定文件的成功/失败;注意超时(工作失败),管理重试。)
  • Worker数据库具有星型模式的本地实例。分配文件时,它会清空架构并从该文件加载数据。 (对于可伸缩性,可能值得一次加载几个文件?)“第一阶段”数据清理是在这里完成的,用于包含在该文件中的数据。
  • 加载后,master数据库会更新为该工作人员的“ready flagy”,并进入等待模式。
  • 主数据库拥有自己的已完成加载数据的工作数据库的待办事项列表。它依次处理每个等待工作者集;当一个工人集处理完毕后,工人会被设置回“检查是否有另一个要处理的文件”模式。
  • 在进程开始时,将清除master数据库中的星型模式。加载的第一个集可能只是逐字复制。
  • 对于第二组及以上,必须阅读并“合并”数据 - 抛出冗余条目,通过一致的维度合并数据等。适用于所有数据的业务规则,不仅是一次一套,必须是现在也完成了。这将是“第二阶段”数据清理。
  • 再次,对每个工作人员数据库重复上述步骤,直到所有文件都已上传。

优点:

  • 将数据从文件读取/转换为数据库并进行“第一阶段”清理将在N台计算机上进行扩展。
  • 理想情况下,主数据库的工作量很小(“第二阶段”,合并数据集)

限制:

  • 首先将大量数据读入工作人员数据库,然后再通过网络再次读取(尽管采用DBMS本机格式)
  • 主数据库是一个可能的阻塞点。一切都要经过这里。

快捷方式:

  • 当工作站“检入”新文件时,它似乎可以刷新已经加载到主文件中的本地数据存储,并将基于此的数据清理注意事项添加到其“第一阶段”工作中(即知道代码5484J已经加载,因此可以将其过滤掉而不会将其传递回主数据库。)
  • 其他RDBMS的SQL Server表分区或类似的物理实现技巧可能会起到很好的效果。
  • 可能有其他快捷方式,但这完全取决于正在实施的业务规则。

不幸的是,如果没有进一步的信息或对所涉及的系统和数据的理解,人们无法判断这个过程是否会比“全部一箱”解决方案更快或更慢。在一天结束时,它很大程度上依赖于您的数据:它是否提交“分而治之”技术,还是必须通过单个处理实例运行?

答案 4 :(得分:2)

最简单的事情是让一台计算机负责分发新的维度项ID。每个维度可以有一个。如果维度处理计算机位于同一网络上,您可以让它们广播该ID。这应该足够快。

您计划使用哪种数据库使用23维星图?导入可能不是唯一的性能瓶颈。您可能希望在分布式主内存系统中执行此操作。这避免了很多物质化问题。

您应该调查是否存在高度相关的维度。

一般来说,对于尺寸较大的23维星型方案,标准关系数据库(SQL Server,PostgreSQL,MySQL)在数据仓库问题上表现极差。为了避免必须进行全表扫描,关系数据库使用物化视图。有23个尺寸,你买不起它们。分布式主内存数据库可能能够足够快地进行全表扫描(2004年,我在Delphi中的奔腾4 3 GHz上做了大约800万行/秒/线程)。 Vertica可能是另一种选择。

另一个问题:拉链时文件有多大?这为您可以进行的标准化量提供了良好的一阶估计。

[编辑]我看了你的其他问题。对于PostgreSQL(或MySQL或SQL服务器)来说,这看起来不太匹配。你愿意等多久查询结果?

答案 5 :(得分:1)

鲮,

我建议你在数据库之外通过sussrising数据FIRST来消除大量的工作。我在Solaris unix环境中工作。我会倾向于一个korn-shell脚本,cut将文件放到更可管理的块中,然后将这些块平均地存放到我的两个OTHER服务器上。我使用nawk脚本处理块(nawk有一个有效的哈希表,它们称之为“关联数组”)来计算不同的值(维度表)和Fact表。只需将每个新名称与一个incrementor-for-dimension关联起来,然后写下Fact。

如果您通过命名管道执行此操作,您可以“动态”推送,远程处理和回读数据,而“主机”计算机就在那里直接将其加载到表格中。

请记住,无论你使用200,000,000行数据做什么(它有多少千兆?),都需要一些时间。听起来像是在享受一些乐趣。阅读其他人如何提出解决这个问题的方法很有意思......古老的格言“有不止一种方法可以做到这一点!”从未如此真实。祝你好运!

干杯。基思。

答案 6 :(得分:0)

另一方面,您可以使用适用于Windows Server的Windows Hyper-V云计算插件:http://www.microsoft.com/virtualization/en/us/private-cloud.aspx

答案 7 :(得分:0)

似乎您的实现效率非常低,因为它的加载速度低于1 MB /秒(50GB / 15小时)。

在现代单一服务器上正确实施(2x Xeon 5690 CPU + RAM足以支持哈希表中加载的所有维度+ 8GB),应该至少提高10倍的速度,即至少10MB /秒。