spark将数据拉入rdd、Dataframe或数据集

qnyhuwrf  于 2021-05-29  发布在  Hadoop
关注(0)|答案(1)|浏览(414)

我试着简单地说,当spark通过驱动程序获取数据,然后spark不需要通过驱动程序获取数据。
我有三个问题-
让我们有一天,你有一个20 tb的平面文件存储在hdfs和驱动程序,你把它拉到一个Dataframe或一个rdd,使用各自的库的开箱即用的功能之一( sc.textfile(path) 或者 sc.textfile(path).toDF 等)。如果驱动程序运行时只有32GB内存,会不会导致驱动程序有oom?或者至少在司机吉姆身上有交换?或者spark和hadoop是否足够聪明,可以将hdfs中的数据分发到spark执行器中,从而在不经过驱动程序的情况下生成dataframe/rdd?
与1完全相同的问题,除了来自外部rdbms?
除了特定的节点文件系统(只有unix文件系统,一个20tb的文件而不是hdfs)之外,与1完全相同的问题是什么?

bkhjykvo

bkhjykvo1#

关于1

spark采用分布式数据结构,如rdd和dataset(以及2.0之前的dataframe)。以下是您应该了解的有关此数据结构的事实,以获得问题的答案:
所有的转换操作(如Map、过滤器等)都是惰性的。这意味着除非您需要操作的具体结果(如减少、折叠或将结果保存到某个文件),否则不会执行读取。
在hdfs上处理文件时,spark使用文件分区进行操作。分区是可以处理的数据的最小逻辑批处理。通常一个分区等于一个hdfs块,并且分区的总数永远不能少于文件中的块数。常用(默认)hdfs块大小为128mb
rdd和dataset中的所有实际计算(包括从hdfs读取)都在执行器内部执行,而不是在驱动程序上执行。驱动程序创建一个dag和逻辑执行计划,并将任务分配给执行者进行进一步处理。
每个执行器针对特定的数据分区运行先前分配的任务。因此,通常情况下,如果您只将一个内核分配给执行器,它将同时处理不超过128mb(默认hdfs块大小)的数据。
所以基本上当你调用 sc.textFile 没有实际读数。所有提到的事实都解释了为什么在处理20 tb的数据时oom不会发生。
有一些特殊情况,如。 join 操作。但即使在这种情况下,所有执行器也会将中间结果刷新到本地磁盘以进行进一步处理。

关于2

在jdbc的情况下,您可以决定您的表有多少个分区。并在表中选择适当的分区键,以便将数据正确地拆分为分区。它取决于你有多少数据将被加载到一个内存在同一时间。

关于3

本地文件的块大小由 fs.local.block.size 属性(我想默认情况下是32mb)。因此,它基本上与1(hdfs文件)相同,只是您将从一台机器和一个物理磁盘驱动器读取所有数据(对于20tb文件来说,这是非常低效的)。

相关问题