如何从Parquet文件文件夹读取最近3天的数据?
精准读取指定日期的Parquet文件,避免全量扫描
当然可以!你完全不用先读取整个100GB的文件夹再过滤——Spark支持通过路径通配符和动态生成匹配路径的方式,直接只加载最近3天的文件,能大幅减少IO开销和内存占用。
核心思路:利用文件名的日期规律构建匹配路径
你的文件名格式是user_YYYY-MM-DD_{checked/unchecked}_products.parquet,日期部分是关键标识。我们可以动态生成最近3天的日期字符串,然后构造对应的文件匹配模式,让Spark只扫描符合条件的文件。
具体实现(Scala代码)
import java.time.LocalDate import java.time.format.DateTimeFormatter // 计算最近3天的日期(包含当前日期,可根据需求调整天数) val recentDays = (0 to 2).map(days => LocalDate.now().minusDays(days)) // 定义日期格式化器,和文件名中的日期格式保持一致 val dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") // 生成每个日期对应的文件匹配路径 val targetPaths = recentDays.map { date => s"path/to/folder/user_${date.format(dateFormatter)}_*.parquet" } // 读取所有匹配的文件 val df = spark.read.parquet(targetPaths: _*)
为什么这个方法高效?
Spark在执行read.parquet时,会先解析你传入的路径模式,只扫描符合模式的文件,不会遍历整个文件夹下的所有文件。相比全量读取后再过滤,这种方式能提前排除绝大多数无效数据(尤其是你的文件夹还在持续增量增长),性能提升非常明显。
可选优化方案(长期)
如果你的数据写入流程可以调整,建议把文件夹改成按日期分区的结构,比如:
path/to/folder/ ├─ date=2018-03-15/ │ ├─ checked_products.parquet │ └─ unchecked_products.parquet ├─ date=2018-03-14/ │ ├─ checked_products.parquet │ └─ unchecked_products.parquet
这种情况下,你可以直接用Spark的分区过滤:
val df = spark.read.parquet("path/to/folder") .filter("date >= date_sub(current_date(), 3)")
Spark会自动将过滤条件下推到文件扫描阶段,同样不会读取无关分区的文件,而且代码更简洁易维护。
注意事项
- 注意时区一致性:如果文件名中的日期是UTC时间,记得在代码中调整
LocalDate的时区(比如用ZonedDateTime),避免日期匹配错误。 - 确保日期格式完全匹配:文件名中的日期是
yyyy-MM-dd,代码中的格式化器也要保持一致,否则会匹配不到文件。
内容的提问来源于stack exchange,提问作者Markus
相关产品推荐
相关产品推荐

