apache-spark - 并行将数据写入 parquet 格式
问题描述
我有一个相对巨大的本地表(约 15 亿行),我试图使用 AWS Glue 以镶木地板格式将其拉入 AWS S3。我正在使用 spark JDBC 读取表并将其写入 S3。问题是我不能一次性从源表中提取所有数据,因为源数据库会耗尽内存并抱怨。为了解决这个问题,我使用谓词选项并行下推过滤器,这可以很好地提取 2 亿左右的数据块。但是当我尝试将此数据帧写入 S3 时,需要将近半个小时才能完成:
df = spark.read.jdbc(url=host_url,
table="TABLENAME",
predicates=predicates,
properties= {
"user" : username,
"password" : password
}
)
所以我想做的是按顺序从DB阶段读取:
Read Part 1 from DB --> Read Part 2 from DB --> Read Part 3 from DB
然后将所有数据并行写入S3
Write Part 1 || Write Part 2 || Write Part 3
我有两个问题:
- 我不知道 Spark 何时真正将这些查询发送到 DB。我知道当我定义如上所示的数据框时不是这样,所以我无法弄清楚如何序列化阶段 1。
- 我环顾四周,找不到将多个数据帧并行写入镶木地板分区的选项。我应该只使用 python 将数据帧并行化为拼花写入操作语句吗?这样做是否可取?
解决方案
Spark 会在应用操作后立即读取数据,因为您只是在读取和写入 s3,因此在触发写入时会读取数据。
Spark 没有针对从 rdbms 读取批量数据进行优化,因为它只建立到数据库的单个连接。如果您想坚持阅读火花,请尝试将fetchsize属性增加到 100000,默认值为 1000。
对于数据的并行处理,您可以尝试利用 python 多处理并执行并行读取和写入
Thread 1
Read 1 -> Write 1
Thread 2
Read 2 -> Write 2
但是第一次尝试执行只是顺序执行
Read 1 -> Write 1 -> Read 2 -> Write 2
我建议的另一种方法是使用 DMS 或 SCT 一次将所有数据传输到 s3。
DMS 可以在 s3 中以 parquet 格式转储数据,并且速度非常快,因为它针对迁移任务本身进行了优化。
如果您不想使用 DMS,您可以编写一个可以通过瞬态 EMR 集群触发的 sqoop 导入作业。Sqoop 还能够以 parquet 格式导入数据。
Glue 最适合转换现有数据和迁移大数据,您应该借助其他服务。
推荐阅读
- android - 断言失败:布尔表达式不能为空 [Flutter] [Android Studio]
- javascript - 当用户单击卡片时尝试显示卡片详细信息但收到我传入的道具的“未定义”错误
- swift - 使用对象和数组静态创建字典并获取它们的值
- java - 如何连接到 2 个 linux 服务器以使用 talend 复制文件
- javascript - 为什么我只能调用这个函数一次?
- excel - 将即时窗口中的内容输出到工作表中
- javascript - 当用户在文本区域中超过一定数量的字符时如何实现错误消息弹出
- javascript - 如何从 div 中制作所谓的蒙版
- azure - 我需要一个查询来使用 KQL 在 Azure 中测量网络带宽利用率
- google-chrome-devtools - 如何在 Chrome DevTools 的 Coverage 选项卡中按使用百分比对所有资产进行排序?