将大型镶木地板文件(5 亿行/1000 列)写入 S3 需要太多时间

Writing large parquet file (500 millions row / 1000 columns) to S3 takes too much time

首先让我介绍一下我的用例,我每天收到 5 亿行,如下所示:

ID |类别

1 | cat1, cat2, cat3, ..., catn

2 | cat1, catx, caty, ..., 另一个类别

输入数据:50 个压缩的 csv 文件,每个文件为 250 MB -> 总计:12.5 GB 压缩

目的是回答以下问题:查找属于 Catx 和 Caty 的所有 ID,查找属于 cat3 而不是 caty 的 ID 等...:即:ids in cat1 U cat2或ids cat3∩catx

假设类别是动态创建的(我每天都有一组新的类别)并且我的业务想要探索所有可能的交集和联合(我们没有一组固定的查询)我想出了以下解决方案:

我写了一个 spark 作业,将日期转换为一个胖稀疏矩阵,其中列是所有可能的类别加上列 ID,对于我设置为 true 的每一行和列,如果 id 属于此类别,则为 false:

ID |类别 1 |类别 2 |类别 3 |...|猫 |猫猫 |目录 |另一个类别 |....

1 |真 |真 |真 |...|真 |假 |假 |假 |....

2 |真|假|假|...|假|真 |真 |真 |....

SQL 可以简单地回答我的问题,例如,如果我想找到属于类别 cat1 和类别 catx 的所有 ID,那么我 运行 以下 sql 查询矩阵:

Select 来自 MyTable 的 ID,其中 cat1 = true 且 catx=true;

我选择将这个稀疏矩阵保存为压缩的parquet文件,我做出这个选择是考虑到稀疏性和查询性质,我认为列存储是最合适的存储格式。

这里描述的用例是我的观察结果,我可能遗漏了一些优化点:

你们对使用 spark 在 S3 上编写大型 parquet 文件有什么反馈吗?

我也想知道您对此解决方案的看法/批评。

感谢和问候。

它结合了 Spark 重新读取内容来做摘要(你可以禁用它)和提交工作的算法来做 rename(),它在 S3 中被一个副本模仿。

请参阅“Apache Spark and object stores了解更多详细信息和一些可以稍微加快您工作速度的开关(禁用摘要,使用较少重命名算法)

即使使用这些,您也会遇到延迟,并且由于 S3 最终是一致的,因此存在产生损坏输出的风险。写入临时 HDFS 文件系统然后在所有工作结束时复制到 S3 是最安全的