Spark使用saveAsLibSVMFile生成多part文件的存储与读取问题咨询
Spark LibSVM格式读写相关问题解答
1. 为什么数据会被拆分存储到多个文件中?如何操作才能将其保存为单个文本文件?
- 多文件生成原因:Spark作为分布式计算框架,RDD默认拆分多个分区分布在不同计算节点,
saveAsLibSVMFile()执行时每个分区会独立写入对应的part-开头文件,分区数量和part文件数量一致,该设计是为了利用多节点IO能力提升写入效率,避免单节点IO瓶颈。 - 保存为单个文件的方法:写入前调用
coalesce(1)将RDD的分区合并为1个后再执行保存操作,示例写法:
注意:仅小数据集推荐该操作,大数据量合并为单分区会导致单节点负载过高,容易出现OOM、写入超时等问题# Python示例,Java/Scala逻辑一致 labeled_point_rdd.coalesce(1).saveAsLibSVMFile("/your/target/dir")
2. 如果保留多part文件的存储形式,该怎样读取这些part-0000*文件?
直接将保存文件的父文件夹路径作为入参传给loadLibSVMFile()即可,Spark会自动扫描路径下所有符合格式的part文件完成加载,无需单独指定每个part文件路径。如果需要加载指定范围内的part文件,也可以传入通配符路径,示例:
// 加载整个目录下的所有文件 val data = MLUtils.loadLibSVMFile(sc, "/your/save/dir") // 仅加载前缀匹配的part文件 val partData = MLUtils.loadLibSVMFile(sc, "/your/save/dir/part-000[0-5]*")
3. 同一工具模块下的MLUtils.util.loadLibSVMFile()要求传入单个文件,但saveAsLibSVMFile()却会生成多个文件,为何会存在这种设计不一致的问题?
该认知是对API能力的误解,不存在设计不一致的问题:
loadLibSVMFile()的入参本身支持三种路径格式:单个文件路径、文件夹路径、带通配符的路径,并非仅支持传入单个文件- 保存接口生成多part文件是分布式场景下的最优设计,适配大规模数据的写入效率需求,加载接口兼容多文件批量读取的能力,两者设计逻辑是完全匹配的
内容的提问来源于stack exchange,提问作者Martin Wunderlich
相关产品推荐
相关产品推荐

