Spark SQL(Java)-连接X个文件的廉价方法?

Spark SQL(Java)-连接X个文件的廉价方法?,java,apache-spark,join,Java,Apache Spark,Join,我目前正在做一个项目,我正在阅读19个不同的拼花地板文件,并加入一个ID。其中一些文件每个消费者有多行,一些没有 我有一个密钥文件,其中有一列是我加入的,另一列是我需要的(用户名),我需要其他文件的所有列 我为每个拼花地板文件创建一个不同的读取器,读入文件并将其转换为spark数据集,其结构如下: GenericStructure1 record; int id; public class Set implements Serializable { long id; Strin

我目前正在做一个项目,我正在阅读19个不同的拼花地板文件,并加入一个ID。其中一些文件每个消费者有多行,一些没有

我有一个密钥文件,其中有一列是我加入的,另一列是我需要的(用户名),我需要其他文件的所有列

我为每个拼花地板文件创建一个不同的读取器,读入文件并将其转换为spark数据集,其结构如下:

GenericStructure1 record;
int id;
public class Set implements Serializable {
    long id;
    String userName;
    List<GenericStructure1> set1;
    List<GenericStructure19> set19;
}
然后,我像这样加入所有这些创建的数据集(想象所有19个):

其中Set.class如下所示:

GenericStructure1 record;
int id;
public class Set implements Serializable {
    long id;
    String userName;
    List<GenericStructure1> set1;
    List<GenericStructure19> set19;
}
公共类集实现可序列化{
长id;
字符串用户名;
列表集1;
清单19;
}

这对100张唱片来说效果很好,但当我尝试升级到5毫米拼花地板文件的一部分(比如75K唱片)时,它会在内存中翻腾和燃烧,直到最终耗尽。在生产过程中,我需要让它能够以百万计的速度运行,所以它被75K的内存所阻塞这一事实是一个真正的问题。唯一的问题是,我没有看到一个简单的方法来优化它,这样它就可以处理这种工作负载。有人知道一种廉价的方法来连接上面所示的大量数据吗?

我能够让它工作。在这个问题中,我提到一个keyDataset,它在所有不同的数据集中都有所有可能的键。我没有尝试将其与所有其他文件直接连接起来,而是广播keyDataset,并在为每个数据集创建通用数据帧后与之连接

Dataset<Row> set1RowDataset = set1Dataset
        .groupBy(keyDataset.col(joinColumn))
        .agg(collect_set(set1Dataset.col("record")).as("set1s"))
        .select(
                keyDataset.col("id"),
                col("set1"));
就性能而言,我不确定将groupBy与join分开进行会带来多大的影响,但我的内存保持不变,在洗牌过程中Spark不再严重溢出磁盘。我能够在本地运行这个,正如我上面提到的,以前失败过。我还没有用完整的拼花文件在集群上尝试过,但这是我的下一步

我以此为例:

好吧,加入19个数据集可能会非常昂贵。。。当您加入2个75k记录表时,您可以得到75ˆ2=5625000000条记录,因此19将是75ˆ19可能变成4.23e92。。。那可能是很多唱片,即使是Spark。。。也许你能把他们联合起来?你的唱片是什么样子的?谢谢你的回复!我确实尝试过创建一个联合,但它抱怨我的GenericStructure专栏的类型。我似乎记得一种将数据从行转换到列的方法。如果我能做到这一点,那么所有的专栏都会很长,也许它会停止抱怨。我知道的时候会更新的。抓起那个。我在想joinWith,但它不是这样做的。感谢jgp,我确实想出了一个解决方案。我在集群上运行了这个程序,能够处理超过5mm的拼花地板输入文件,而没有任何内存问题。我们最近在生产测试环境中执行了这个程序。当尝试运行超过300mm的完整填充时,它会失败,并出现驱动程序内存错误。当我们找到解决方案时,我将更新上面的代码。它现在正在我们的生产测试环境中运行,但由于密钥文件太大而无法广播,因此必须删除广播。因此,它在本地运行时会有很多混乱,但在集群上运行得非常好。