前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站:https://www.captainai.net/dongkelun

前言

本文讲如何用spark读取gz类型的压缩文件,以及如何解决我遇到的各种问题。

1、文件压缩

下面这一部分摘自Spark快速大数据分析:
  在大数据工作中,我们经常需要对数据进行压缩以节省存储空间和网络传输开销。对于大多数Hadoop输出格式来说,我们可以指定一种压缩编解码器来压缩数据。
  选择一个输出压缩编解码器可能会对这些数据以后的用户产生巨大影响。对于像Spark 这样的分布式系统,我们通常会尝试从多个不同机器上一起读入数据。要实现这种情况,每个工作节点都必须能够找到一条新记录的开端。有些压缩格式会使这变得不可能,而必须要单个节点来读入所有数据,这就很容易产生性能瓶颈。可以很容易地从多个节点上并行读取的格式被称为“可分割”的格式。下表列出了可用的压缩选项。

格式 可分割 平均压缩速度 文本文件压缩效率 Hadoop压缩编解码器 纯Java实现 原生 备注
gzip org.apache.hadoop.io.compress.GzipCodec
lzo 是(取决于所使用的库) 非常快 中等 com.hadoop.compression.lzo.LzoCodec 需要在每个节点上安装LZO
bzip2 非常高 org.apache.hadoop.io.compress.Bzip2Codec 为可分割版本使用纯Java
zlib 中等 org.apache.hadoop.io.compress.DefaultCodec Hadoop 的默认压缩编解码器
Snappy 非常快 org.apache.hadoop.io.compress.SnappyCodec Snappy 有纯Java的移植版,但是在Spark/Hadoop中不能用

  尽管Spark 的textFile() 方法可以处理压缩过的输入,但即使输入数据被以可分割读取的方式压缩,Spark 也不会打开splittable。因此,如果你要读取单个压缩过的输入,最好不要考虑使用Spark 的封装,而是使用newAPIHadoopFile 或者hadoopFile,并指定正确的压缩编解码器。

关于上面一段话的个人测试:选取一个大文件txt,大小为1.5G,写spark程序读取hdfs上的该文件然后写入hive,经测试在多个分区的情况下,txt执行时间最短,因为在多个机器并行执行,而gz文件是不可分割的,即使指定分区数目,但依然是一个分区,一个task,即在一个机器上执行,bzip2格式的文件虽然是可分割的,即可以按照指定的分区分为不同的task在多个机器上执行,但是执行时间长,比gz时间还长,经过四次改变bzip2的分区,发现最快的时间和gz时间是一样的,如果指定一个分区的话,比gz要慢很多,我想这样就可以更好的理解:"尽管Spark 的textFile() 方法可以处理压缩过的输入,但即使输入数据被以可分割读取的方式压缩,Spark 也不会打开splittable"这句话了。

  • 注:上面主要证明不管是可分割的bzip2还是不可分割的gz都比txt慢,至于bzip2比gz慢的原因,是因为我分配的Executor数量较少,经后续测试,根据集群的cpu合理分配executor的个数的情况下,txt的时间缩短到1分钟,bzip2缩短到1.3分钟,而对gz重新分区(reparation)缩短到2分钟,可以看到在合理分配资源的情况下,bzip2比gz快不少,但依然赶不上txt,当然这也的结果可能受文件大小和集群资源的限制,所以根据自己的实际需求测试再决定用哪个即可。

2、代码

代码很简单,用textFile()即可,假设,我的数据名为data.txt.gz,我把它放在hdfs上的/tmp/dkl路径下那么代码为:

val path = "hdfs://ambari.master.com:8020/tmp/dkl/data.txt.gz"
val data = sc.textFile(path)

注:把数据放在hdfs的命令为

hadoop fs -put data.tar.gz /tml/dkl

3、一些小问题

3.1 数据

首先造几个数据吧,先创建一个txt,名字为data.txt,内容如下

1            张三            上海        2018-05-25
2            张三            上海        2018-05-25
3            张三            上海        2018-05-25
4            张三            上海        2018-05-25
5            张三            上海        2018-05-25

3.2 如何压缩

那么如如何打包为gz格式的压缩文件呢,分两种
一、 在windows上打包,如果不想在Linux服务器上用命令打包,那么可以直接用windows上的软件打包(win上常见的zip,rar格式,spark是不支持的),我用7-zip软件压缩,大家可百度7-zip或直接在https://www.7-zip.org/下载安装,压缩格式选gzip即可。
二、 在Linux上压缩,可通过下面的命令
1、保留原文件

gzip –c data.txt > data.txt.gz

2、不保留原文件,默认生成的文件名为原文件名.gz,即data.txt.gz

gzip data.txt

压缩完了之后,跑一下程序测试一下

data.take(3).foreach(println)
1            张三            上海        2018-05-25
2            张三            上海        2018-05-25
3            张三            上海        2018-05-25

根据结果看没问题。
三、 说明
在Linux上用tar命令压缩,spark虽然可以读,但是第一行会有文件信息

tar -zcvf data.tar.gz data.txt

3.3 文件编码问题

别人给我的原文件是.rar,那我需要将其解压之后得到txt,然后按照上述方式压缩为.gz,然后上传到hdfs,进行代码测试,打印前几条发现乱码,查了一下发现原文件是gbk编码的,且sc.textFile()不能指定编码,只能读取utf8格式,其他格式就会乱码。

注意:因为实际情况下解压后的txt文件很大,windows是直接打不开的,所以不能通过打开文件修改编码的方法去解决。

3.3.1 构建测试gbk格式的文件

1、windows上可以用记事本打开,另存为,编码选择ANSI即可

2、Linux可以通过下面的命令修改

iconv -f utf8 -t gbk data.txt > data_gbk.txt

测试一下输出,发现确实乱码了(直接测试txt即可)

1            ����            �Ϻ�        2018-05-25
2            ����            �Ϻ�        2018-05-25
3            ����            �Ϻ�        2018-05-25

3.3.2 代码解决

通过如下代码测试即可
定义方法

import org.apache.spark.rdd.RDD
import org.apache.spark.SparkContext
import org.apache.hadoop.io.LongWritable
import org.apache.hadoop.mapred.TextInputFormat
import org.apache.hadoop.io.Text
def transfer(sc: SparkContext, path: String): RDD[String] = {sc.hadoopFile(path, classOf[TextInputFormat], classOf[LongWritable], classOf[Text], 1).map(p => new String(p._2.getBytes, 0, p._2.getLength, "GBK"))
}

测试方法

transfer(sc, path3).take(3).foreach(println)

参考:Spark Scala 读取GBK文件的方法

3.3.3 Linux命令

可直接通过Linux命令转换txt的编码格式,再压缩,这样代码就不用修改
其实在3.2.1中已经涉及到了
1、通过Linux自带的命令iconv
iconv不能覆盖原来的文件,只能生成新的文件之后,再通过mv命令去覆盖

iconv -f gbk -t utf8 data_gbk.txt > data_new.txt

2、通过enca
enca可以直接覆盖原来的文件,这样如果不想改变来的文件名,就少一步mv操作了,enca不是子系统自带的,需要自己下载安装,可在http://dl.cihar.com/enca/下载最新版本。

#下载&解压
wget http://dl.cihar.com/enca/enca-1.19.tar.gz
tar -zxvf enca-1.19.tar.gz
cd enca-1.19
#编译安装
./configure
make
make install

安装好了之后通过下面的命令转换即可

enca -L zh_CN -x UTF-8 data_gbk.txt

转换编码格式之后,在通过程序测试即可。

参考:linux 下的文件编码格式转换

3.4 rdd换df

由于文件过大,不能直接打开看也没用垃圾数据,造成格式问题,如果有垃圾数据,在rdd转df的过程中会产生异常,这里记录一下我碰见的问题。

1、首先可以先打印出前几行数据查看一下该文件的大体格式

2、碰到的一个一个异常
代码用的旧版spark(1.6版本) 将rdd动态转为dataframe里面的方法。

if (assertnotnull(input[0, org.apache.spark.sql.Row, true]).isNullAt) null else staticinvoke(class org.apache.spark.unsafe.types.UTF8String, StringType, fromString, validateexternaltype(getexternalrowfield(assertnotnull(input[0, org.apache.spark.sql.Row, true])....

原因是因为文件里有一行数据为垃圾数据,这行数据的列数和列名的个数不一样导致的,可以在代码中过滤掉这样数据即可。

.filter(_.length == colName.length)

Spark读取压缩文件相关推荐

  1. Spark 读取CSV文件为RDD

    Spark 读取CSV文件为RDD 1 准备数据 在开始之前,假设我们在文件夹"c:/tmp/files"中有以下带有逗号分隔文件内容的 CSV 文件名,我使用这些文件来演示示例. ...

  2. python 读取压缩文件

    一.python如何读取压缩文件tar.gz? 在读取文件之前首先要先解压缩,然后将解压后的文件放在一个临时的文件夹中,接下来读取文件. *注:tgz与tar.gz是同样的格式 二.将列表转化为字符串 ...

  3. python读取压缩文件时乱码,zipfile解压缩包,出现中文乱码问题问题

    python读取压缩文件时乱码,zipfile解压缩包,出现中文乱码问题问题 问题描述--python 使用zipfile模块 读取并且解压缩包,出现中文乱码问题 问题原因 python 使用这个模块 ...

  4. Spark 读取csv文件quote配置无效

    在进行数据清洗时,使用spark 读取csv文件时,遭遇到数据列中存在 \n的字符 原始数据: names "小红\n小明" 解析后数据: index names 1 小红 2 小 ...

  5. Spark读取本地文件和HDFS文件

    前言 旁边的实习生又一脸懵逼了:Spark有bug,明明我本地/data目录下有test.txt文件,但运行就报错: Caused by: java.io.FileNotFoundException: ...

  6. spark 读取本地文件

    1 背景 基于spark 开发程序 数据放在本地文件中,为text格式 本文语言案例为java 2   步骤 2.1 搭建工程 ​​​​​​​ 基于maven搭建spark工程_this is a b ...

  7. spark读取PMML文件

    使用python训练模型生成PMML文件,然后用spark读取 import com.ubiai.zhyx.utils.SparkHelper import org.apache.spark.ml.T ...

  8. python读取压缩文件的大小_python查看zip包中文件及大小的方法

    python查看zip包中文件及大小的方法 本文实例讲述了python查看zip包中文件及大小的方法.分享给大家供大家参考.具体实现方法如下: #!/usr/bin/env python import ...

  9. python读取压缩文件的指定后缀的文件_python打包压缩、读取指定目录下的指定类型文件...

    下面通过代码给大家介绍python打包压缩指定目录下的指定类型文件,具体代码如下所示: import os import datetime import tarfile import fnmatch ...

最新文章

  1. 交换机应用之端口模式(access、trunk和hybird)、是否标记(tag、untag)、端口缺省vlan(pvid、native id)...
  2. java替换list中元素,Java 实例 - List 元素替换
  3. ​GB28181心跳机制探讨和技术实现
  4. ElasticSearch经典面试题
  5. 服务器块格式不正确的是什么,c#-服务器标签格式不正确.(databinder.eval)
  6. python编程入门书籍-零基础学习Python编程,这8本书必看!
  7. Disk Expert Pro for Mac(磁盘分析管理工具)
  8. java 视频截图_Java Web 中使用ffmpeg实现视频转码、视频截图
  9. goodFeaturesToTrack——Shi-Tomasi角点检测
  10. python数星星问题
  11. 明峰医疗IPO终止:亏损超过14亿元,王瑶法、潘华素夫妇为实控人
  12. 深入探索 Android 网络优化(二、网络优化基础篇)上
  13. org.xml.sax.SAXParseException: 在实体引用中, 实体名称必须紧跟在 '' 后面
  14. 理解pem pfx文件
  15. 207399-07-3,IR-780;IR-808;1558079-49-4,IR-825
  16. matlab的打印输出方式
  17. 忙里偷闲第三弹:开发成绩查询微信公众号
  18. Voltus任命全球投资者关系负责人
  19. win2003serve IIS6.0搭载多个站点
  20. 小建中汤与先天性结肠黑斑息肉

热门文章

  1. Python语法之函数
  2. pygame小游戏框架
  3. 北理工计算机贾云,徐畅_北京理工大学计算机学院
  4. EasyUI的插入一行到某行和添加一行
  5. G20线上视频会议,各国直播间场景
  6. 11. 将学生的学号及平均成绩定义为一个视图(s_g),学号用sno表示,平均成绩用gavg表示。
  7. 回归模型的score得分为负_SPSS中 回归 B值为负数什么意思
  8. 物理像素、CSS像素、dip、dpr、ppi、dpi
  9. KYC功能介绍:为客户提供新的机会
  10. TCP、UDP、SCTP概述