Spark将数据拉入RDD或数据框或数据集

uh_*_*boi 7 hadoop apache-spark apache-spark-sql spark-dataframe data-ingestion

当火花通过驱动程序提取数据时,我试图用简单的术语,然后当spark不需要通过驱动程序提取数据时.

我有3个问题 -

  1. 让我们有一个存储在HDFS中的20 TB平面文件文件,并从驱动程序中将其拉入数据框或RDD,使用相应库中的一个开箱即用功能(sc.textfile(path)sc.textfile(path).toDF等).如果驱动程序只运行32 GB内存,它会导致驱动程序有OOM吗?或者至少对司机吉姆进行掉期交易?或者spark和hadoop是否足够聪明,可以将数据从HDFS分发到一个Spark执行器,以便在不通过驱动程序的情况下生成数据帧/ RDD?
  2. 除了外部RDBMS之外,完全相同的问题是1?
  3. 除了特定节点文件系统(只是Unix文件系统,20 TB文件但不是HDFS)之外,与1完全相同的问题?

Zyo*_*oma 5

关于 1

Spark 使用分布式数据结构,如 RDD 和 Dataset(以及 2.0 之前的 Dataframe)。以下是您应该了解的有关此数据结构的事实,以获得问题的答案:

  1. 所有转换操作(如映射、过滤器等)都是惰性的。这意味着除非您需要具体的操作结果(例如减少、折叠或将结果保存到某个文件),否则不会执行任何读取。
  2. 在 HDFS 上处理文件时,Spark 会使用文件分区进行操作。分区是可以处理的最小逻辑数据批。一般情况下,1个分区等于1个HDFS块,分区总数不能小于文件中块的数量。常见(默认)HDFS 块大小为 128Mb
  3. RDD 和数据集中的所有实际计算(包括从 HDFS 读取)都在执行器内部执行,而不是在驱动程序上执行。Driver 创建 DAG 和逻辑执行计划,并将任务分配给执行器以进行进一步处理。
  4. 每个执行器针对特定的数据分区运行先前分配的任务。因此,通常情况下,如果您只为执行器分配一个核心,它同时处理的数据不会超过 128Mb(默认 HDFS 块大小)。

所以基本上当你调用时sc.textFile不会发生实际的读取。所有提到的事实都解释了为什么在处理 20 Tb 数据时也不会发生 OOM。

有一些特殊情况,例如 iejoin操作。但即使在这种情况下,所有执行器也会将其中间结果刷新到本地磁盘以进行进一步处理。

关于2

如果使用 JDBC,您可以决定表有多少个分区。并在表中选择适当的分区键,将数据正确地划分为分区。同时将有多少数据加载到内存中取决于您。

关于3

本地文件的块大小由fs.local.block.size属性控制(我猜默认是32Mb)。因此,它与 1(HDFS 文件)基本相同,只是您将从一台机器和一个物理磁盘驱动器读取所有数据(对于 20TB 文件来说效率极低)。