[英]Spark read partitions - Resource cost analysis
當使用spark.read.json("/A=1/B=2/C=3/D=4/E=5/")
類的東西讀取 Spark 中按列分區的數據時,將只允許掃描文件夾 E=5。
但是假設我有興趣通過所有數據源讀取C = my_value
分區。 指令將是spark.read.json("/*/*/C=my_value/")
。
在所描述的場景中計算會發生什么? Spark 只會列出 A 和 B 的分區值? 或者它也會掃描所有葉子(實際文件)?
感謝您提出一個有趣的問題。 阿帕奇星火采用Hadoop的FileSystem
抽象處理通配符模式。 在源代碼中,它們被稱為glob 模式
org.apache.hadoop.fs.FileSystem#globStatus(org.apache.hadoop.fs.Path)
方法用於返回“與路徑模式匹配的路徑數組”。 這個函數然后調用org.apache.hadoop.fs.Globber#glob
來找出 glob 模式的確切文件匹配算法。 globStatus 由org.apache.spark.sql.execution.datasources.DataSource#checkAndGlobPathIfNecessary
。 您可以添加一些斷點以查看它在后台是如何工作的。
但長話短說:
在所描述的場景中計算會發生什么? Spark 只會列出 A 和 B 的分區值? 或者它也會掃描所有葉子(實際文件)?
Spark 會將您的 glob 分成 3 部分 ["*", "*", "C=my_value"]。 稍后,它將使用 Hadoop org.apache.hadoop.fs.FileSystem#listStatus(org.apache.hadoop.fs.Path)
方法列出各個級別的文件。 對於每個文件,它將構建一個路徑並嘗試將其與當前模式匹配。 匹配的文件將作為“候選”保留,僅在最后一步被過濾掉,此時算法將查找“C=my_value”。
除非你有很多文件,否則這個操作應該不會傷害到你。 也許這就是為什么你應該保留更少但更大的文件的原因之一(著名的“小文件太多”的數據工程問題)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.