针对小文件的spark wholeTextFiles()
场景:推送过来的数据文件数量很多,并且每个只有10-30M的大小
spark读取hdfs一般都是用textfile(),但是对于这种情况,如果使用textFile默认产生的分区数将与文件数目一致,产生大量的任务。
对应这种小文件,spark提供了一个特殊的api, wholeTextFiles(), wholeTextFiles主要用于处理大量的小文件,源码如下:
/**
* Read a directory of text files from HDFS, a local file system (available on all nodes), or any
* Hadoop-supported file system URI. Each file is read as a single record and returned in a
* key-value pair, where the key is the path of each file, the value is the content of each file.
*
* <p> For example, if you have the following files:
* {{{
* hdfs://a-hdfs-path/part-00000
* hdfs://a-hdfs-path/part-00001
* ...
* hdfs://a-hdfs-path/part-nnnnn
* }}}
*
* Do `val rdd = sparkContext.wholeTextFile("hdfs://a-hdfs-path")`,
*
* <p> then `rdd` contains
* {{{
* (a-hdfs-path/part-00000, its content)
* (a-hdfs-path/part-00001, its content)
* ...
* (a-hdfs-path/part-nnnnn, its content)
* }}}
*
* @note Small files are preferred, large file is also allowable, but may cause bad performance.
* @note On some filesystems, `.../path/*` can be a more efficient way to read all files
* in a directory rather than `.../path/` or `.../path`
* @note Partitioning is determined by data locality. This may result in too few partitions
* by default.
*
* @param path Directory to the input data files, the path can be comma separated paths as the
* list of inputs.
* @param minPartitions A suggestion value of the minimal splitting number for input data.
* @return RDD representing tuples of file path and the corresponding file content
*/
def wholeTextFiles(
path: String,
minPartitions: Int = defaultMinPartitions): RDD[(String, String)] = withScope {
assertNotStopped()
val job = NewHadoopJob.getInstance(hadoopConfiguration)
// Use setInputPaths so that wholeTextFiles aligns with hadoopFile/textFile in taking
// comma separated files as input. (see SPARK-7155)
NewFileInputFormat.setInputPaths(job, path)
val updateConf = job.getConfiguration
new WholeTextFileRDD(
this,
classOf[WholeTextFileInputFormat],
classOf[Text],
classOf[Text],
updateConf,
minPartitions).map(record => (record._1.toString, record._2.toString)).setName(path)
}
wholeTextFiles读取文件,输入参数为路径,并且可以设置为多个路径,多个路径之间以逗号分隔。wholeTextFiles读取数据会生成一个Tuple2,Tuple2的第一个元素是该文件的完整路径名,第二个元素表示该文件的文本内容(context)。比如两行数据:
jack,1011,shanghai
kevin,2022,beijing
返回的文本内容是一行字符串,源数据的每行数据以换行符\n分隔,也即:jack,1011,shanghai\nkevin,2022,beijing
分区数可以自定义,如果不显示指定,则默认分区数定义如下:
def defaultMinPartitions: Int = math.min(defaultParallelism, 2)
也就是在不指定分区的情况下,大部分情况都是以2个分区来处理数据。
样例代码:
处理逻辑可以理解为每个小文件对应一个城市的某个区下的所有道路相关的数据(当然了实际数据并不是,哪个城市有几万个几十万个区)。文件名为区的名字,文件内容为道路的名称以及相关数据,在每行道路数据上加上区的名字。
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.sql.SparkSession;
import org.apache.spark.util.SizeEstimator;
import scala.Tuple2; public class TestWholeTextFiles { public static void main(String[] args) {
SparkConf conf = new SparkConf();
SparkSession spark = SparkSession
.builder()
.appName("TestWholeTextFiles")
.master("local")
.config(conf)
.enableHiveSupport()
.getOrCreate();
JavaSparkContext sc = JavaSparkContext.fromSparkContext(spark.sparkContext());
JavaPairRDD<String, String> javaPairRDD =
sc.wholeTextFiles("hdfs://master01.xx.xx.cn:8020/kong/capacityLusunData_bak"); System.out.println("javaPairRDD分区数:"+javaPairRDD.getNumPartitions());//
JavaRDD<String> map = javaPairRDD.map((Function<Tuple2<String, String>, String>) v1 -> {
int index = v1._1.lastIndexOf("/");
String road_id = v1._1.substring(index+1).split("\\.")[0];
return v1._2.replace("\n", "\\|"+road_id + "\n");
});
System.out.println("mapRDD分区数:"+map.getNumPartitions());//
map.saveAsTextFile("hdfs://master01.xx.xx.cn:8020/kong/data/testwholetextfiles/out");
}
}
1
针对小文件的spark wholeTextFiles()的更多相关文章
- Spark使用CombineTextInputFormat缓解小文件过多导致Task数目过多的问题
目前平台使用Kafka + Flume的方式进行实时数据接入,Kafka中的数据由业务方负责写入,这些数据一部分由Spark Streaming进行流式计算:另一部分数据则经由Flume存储至HDFS ...
- Hadoop对小文件的解决方式
小文件指的是那些size比HDFS的block size(默认64M)小的多的文件.不论什么一个文件,文件夹和block,在HDFS中都会被表示为一个object存储在namenode的内存中, 每一 ...
- Hadoop小文件存储方案
原文地址:https://www.cnblogs.com/ballwql/p/8944025.html HDFS总体架构 在介绍文件存储方案之前,我觉得有必要先介绍下关于HDFS存储架构方面的一些知识 ...
- 如何利用Hadoop存储小文件
**************************************************************************************************** ...
- spark sql/hive小文件问题
针对hive on mapreduce 1:我们可以通过一些配置项来使Hive在执行结束后对结果文件进行合并: 参数详细内容可参考官网:https://cwiki.apache.org/conflue ...
- Spark SQL 小文件问题处理
在生产中,无论是通过SQL语句或者Scala/Java等代码的方式使用Spark SQL处理数据,在Spark SQL写数据时,往往会遇到生成的小文件过多的问题,而管理这些大量的小文件,是一件非常头疼 ...
- Spark:spark df插入hive表后小文件数量多,如何合并?
在做spark开发过程中,时不时的就有可能遇到租户的hive库目录下的文件个数超出了最大限制问题. 一般情况下通过hive的参数设置: val conf = new SparkConf().setAp ...
- 数据算法 --hadoop/spark数据处理技巧 --(17.小文件问题 18.MapReuce的大容量缓存)
十七.小文件问题 十八.MR的大容量缓存 在MR中使用和读取大容量缓存,(也就是说,可能包括数十亿键值对,而无法放在一个商用服务器的内存中).本次提出的算法通用,可以在任何MR范式中使用.(eg:MR ...
- Spark优化之小文件是否需要合并?
我们知道,大部分Spark计算都是在内存中完成的,所以Spark的瓶颈一般来自于集群(standalone, yarn, mesos, k8s)的资源紧张,CPU,网络带宽,内存.Spark的性能,想 ...
随机推荐
- 02-11Android学习进度报告十一
今天我学习了BaseAdapter优化的知识,主要是View方面的优化. 首先是复用复用ConvertView 代码示例: @Override public View getView(int posi ...
- cmake 环境安装与使用
CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程).他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的 ...
- lnmp1.5安装fileinfo扩展
cd /usr/local/src cd lnmp1.-full/src tar xvf php-.tar.bz2 cd php-/ext/fileinfo phpize ./configure -- ...
- ThinkPHP6源码:从Http类的实例化看依赖注入是如何实现的
ThinkPHP 6 从原先的 App 类中分离出 Http 类,负责应用的初始化和调度等功能,而 App 类则专注于容器的管理,符合单一职责原则. 以下源码分析,我们可以从 App,Http 类的实 ...
- MinGW x64 for Windows安装
1. 百度搜索MinGW gcc 或直接登录 MinGW gcc官网 http://www.mingw.org/ 2.选择左侧download链接,进入下载页面 3.下载安装包mingw-get-se ...
- 在javaweb中对于session的使用
1.初次调用session时: String username="student"; HttpSession session=request.getSession(true);// ...
- nginx访问目录是没加/的重定向控制
static 模块提供了root与alias功能:发现目标是目录时:但URI末尾未加/时:会返回301重定向:重定向后会加/ 指令 Syntax: server_name_in_redirect on ...
- docker-compose 快速部署持续集成测试环境 Gitlab+Harbor+Jenkins pipeline 实现 tag run docker Images
环境 测试部署主机IP:192.168.1.1 Jenkins主机IP:192.168.1.2 Harbor主机IP:192.168.1.3 Gitlab主机IP:192.168.0.10 系统信息: ...
- 学习笔记(15)- 保险行业的问答语料 insuranceqa_data
数据概览 ''' pool data are translated Chinese data with Google API from original English data ''' POOL_T ...
- C++11类内static成员变量声明与定义
众所周知,将一个类内的某个成员变量声明为static型,可以使得该类实例化得到的对象实现对象间数据共享. 在C++中,通常将一个类的声明写在头文件中,将这个类的具体定义(实现)写在cpp源文件中. 因 ...