本文通过MetaWeblog自动发布,原文及更新链接:https://extendswind.top/posts/technical/problem_spark_reading_hdfs_serializable

Spark提供了HDFS上一般的文件文件读取接口 sc.textFile(),但在某些情况下HDFS中需要存储自定义格式的文件,需要更加灵活的读取方式。

使用KeyValueTextInputFormat

Hadoop的MapReduce框架下提供了一些InputFormat的实现,其中MapReduce2的接口(org.apache.hadoop.mapreduce下)与先前MapReduce1(org.apache.hadoop.mapred下)有区别,对应于newAPIHadoopFile函数。

使用KeyValueTextInputFormat的文件读取如下

import org.apache.hadoop.mapreduce.lib.input.KeyValueTextInputFormat
import org.apache.hadoop.io.Text val hFile = sc.newAPIHadoopFile("hdfs://hadoopmaster:9000/user/sparkl/README.md",
classOf[KeyValueTextInputFormat], classOf[Text], classOf[Text]) hFile.collect

使用自定义InputFormat

InputFormat是MapReduce框架下将输入的文件解析成字符串的组件,Spark对HDFS中的文件实现自定义读写需要通过InputFormat的子类实现。下面只写简单的思路,具体的可以参考InputFormat和MapReduce相关资料。

InputFormat的修改可以参考TextInputFormat,继承FileInputFormat后,重载createRecordReader返回一个新的继承RecordReader的类,通过新的RecordReader读取数据返回键值对。

打包后注意上传时将jar包一起上传:

`./spark-shell –jars newInputFormat.jar

运行的代码和上面差不多,import相关的包后

val hFile = sc.newAPIHadoopFile("hdfs://hadoopmaster:9000/user/sparkl/README.md",
classOf[NewTextInputFormat], classOf[Text], classOf[Text])

一些坑

序列化问题

在读取文件后使用first或者collect时,出现下面的错误

ERROR scheduler.TaskSetManager: Task 0.0 in stage 2.0 (TID 18) had a not serializable result: org.apache.hadoop.io.IntWritable
Serialization stack:
- object not serializable (class: org.apache.hadoop.io.IntWritable, value: 35)
- element of array (index: 0)
- array (class [Lorg.apache.hadoop.io.IntWritable;, size 1); not retrying
18/12/15 10:40:10 ERROR scheduler.TaskSetManager: Task 2.0 in stage 2.0 (TID 21) had a not serializable result: org.apache.hadoop.io.IntWritable
Serialization stack:
- object not serializable (class: org.apache.hadoop.io.IntWritable, value: 35)
- element of array (index: 0)
- array (class [Lorg.apache.hadoop.io.IntWritable;, size 1); not retrying

当键值对是其它的类型时,还可能出现类似的:

ERROR scheduler.TaskSetManager: Task 0.0 in stage 2.0 (TID 18) had a not serializable result: org.apache.hadoop.io.LongWritable
ERROR scheduler.TaskSetManager: Task 0.0 in stage 2.0 (TID 18) had a not serializable result: org.apache.hadoop.io.Text

此问题略奇怪,都实现了Hadoop的Writable接口,却不能被序列化。某些地方提到Hadoop与Spark没有使用同一套序列化机制,需要在Spark的序列化框架下注册才能使用。

一般更建议在drive程序上收集信息时,首先转换成基本的数据类型:

hFile.filter(k => k._1.toString.contains(“a”)).collect

java.lang.IllegalStateException: unread block data

ERROR executor.Executor: Exception in task 0.3 in stage 0.0 (TID 3)
java.lang.IllegalStateException: unread block data
at java.io.ObjectInputStream$BlockDataInputStream.setBlockDataMode(ObjectInputStream.java:2781)

一个很坑的错误,spark-shell下只出现这个,并未表明真正的错误在哪。在spark的webUI上能够看到相关的运行日志,上面的异常前还有一个异常写的是我重写的InputSplit没有实现Writable接口。此处的坑,InputFormat中用的InputSplit如果需要重写需要实现Writable接口,在MapReduce下使用貌似没有这一要求。

补上之后上传到集群的nodemanager即可。注意,当nodemanager和spark-shell上传的jar包中有相同的类时,nodemanager优先使用了自身的类。

Spark设置自定义的InputFormat读取HDFS文件的更多相关文章

  1. pig 自定义udf中读取hdfs 文件

    最近几天,在研究怎么样把日志中的IP地址转化成具体省份城市. 希望写一个pig udf IP数据库采用的纯真IP数据库文件qqwry.dat,可以从http://www.cz88.net/下载. 这里 ...

  2. Spark读取HDFS文件,文件格式为GB2312,转换为UTF-8

    package iie.udps.example.operator.spark; import scala.Tuple2; import org.apache.hadoop.conf.Configur ...

  3. Spark读取HDFS文件,任务本地化(NODE_LOCAL)

    Spark也有数据本地化的概念(Data Locality),这和MapReduce的Local Task差不多,如果读取HDFS文件,Spark则会根据数据的存储位置,分配离数据存储最近的Execu ...

  4. 记录一次读取hdfs文件时出现的问题java.net.ConnectException: Connection refused

    公司的hadoop集群是之前的同事搭建的,我(小白一个)在spark shell中读取hdfs上的文件时,执行以下指令 >>> word=sc.textFile("hdfs ...

  5. 问题记录:spark读取hdfs文件出错

    错误信息: scala> val file = sc.textFile("hdfs://kit-b5:9000/input/README.txt") 13/10/29 16: ...

  6. 读取hdfs文件之后repartition 避免数据倾斜

    场景一: api:  textFile("hfds://....").map((key,value)).reduceByKey(...).map(实际的业务计算逻辑) 场景:hdf ...

  7. java Api 读取HDFS文件内容

    package dao; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.*; import java ...

  8. 读取hdfs文件内容

    基础环境: cdh2.71 需要注意: url地址参照 <property> <name>dfs.namenode.servicerpc-address</name> ...

  9. 用java api读取HDFS文件

    import java.io.IOException; import java.io.InputStream; import java.security.PrivilegedExceptionActi ...

随机推荐

  1. js 页面技巧

    需要获取页面上固定的某个按钮的属性值.我们需要在页面加载完的第一刻将值存储到定义的变量,防止用户更改页面样式读不出当前元素.如果页面刷新会重置当前属性 <body> <input v ...

  2. 3:基于乐观锁(两种)控制并发: version、external锁

    ES是基于乐观锁进行并发控制的. 如果有并发的业务场景,可以直接使用ES内置乐观锁机制. 使用的时候,java程序需要先Get指定的记录,获取到版本号,然后Put的时候,带着该版本号,请求更新. ES ...

  3. Java文件字符流

    1.字符编码(Character encoding)和编码集(Character set) 字符编码(Character encoding)是将字符转为字节或字节数组的过程. 字符集(Characte ...

  4. 2019年北航OO第三次博客总结

    一.JML语言理论基础及其工具链 1. JML语言理论基础 JML是用于对Java程序进行规格化设计的一种表示语言,是一种行为接口规格语言(Behavior Interface Specificati ...

  5. JavaScript之获取标签

    (1)html <p id="txt">这是P标签</p> <h1 id="txt" style="color: red ...

  6. LINQ to Entities 不识别方法“System.String ToString(System.String)”,因此该方法无法转换为存储表达式。

    来源:https://www.cnblogs.com/hao-1234-1234/p/9112434.html 6  Select的时候,时间无法转换成 年月日  YYMMMdd 报错:LINQ to ...

  7. Mysql中decode函数的几种用法

    1.使用decode判断字符串是否一样 decode(value,if1,then1,if2,then2,if3,then3,...,else) 含义为 IF 条件=值1 THEN RETURN(va ...

  8. 小程序 wx.getSystemInfoSync 获取 windowHeight 不准确的问题

    如果本文对你有用,请爱心点个赞,提高排名,帮助更多的人.谢谢大家!❤ 如果解决不了,可以在文末进群交流. wx.getSystemInfo(OBJECT) 获取系统信息. OBJECT参数说明: 参数 ...

  9. 臀部——哑铃&杠铃

  10. sqlalchemy之基础操作

    原文链接:https://www.cnblogs.com/DragonFire/p/10166527.html