1. 背景

近日帮外部门的同事处理一个小需求,就是将HDFS中2018年至今所有存储的sequence序列化文件读取出来,重新保存成文本格式,以便于他后续进行处理。由于同事主要做机器学习方向,对hadoop或spark方面不了解,所以我就想着这么小的需求,简单支持下即可,花个几分钟写了一个脚本提供给他,没想到,过了一天他又找到我,说脚本读取出来的文件大部分有问题…原来自己代码有bug

2. 初始版本

Spark或Hadoop读取sequence文件只需调用相应函数即可。

第一版本的spark程序代码如下:

 package com.ws.test

 import org.apache.hadoop.io.{BytesWritable, Text}
import org.apache.spark.{SparkConf, SparkContext} object Test {
def main(args: Array[String]): Unit = {
if (args.length < 1) {
println("input param error: <method name>")
} else {
args(0) match {
case "deseqData" => deseqData(args)
case _ =>
}
}
} def deseqData(args: Array[String]): Unit ={ if(args.length != 3){
println("input param error: <method name> <input dir> <output dir>")
return
} val conf = new SparkConf()
conf.setAppName(args(0))
val sc = new SparkContext(conf) val inputDir = args(1)
val outputDir = args(2) sc.sequenceFile[Text, BytesWritable](s"hdfs://$inputDir")
.map(data => new String(data._2.getBytes)).saveAsTextFile(outputDir) sc.stop()
}
}

提供的bash脚本如下:

#!/bin/bash

source ~/.bashrc

if [[ $# -ne  ]];then
echo "$(date +'%Y-%m-%d %H:%M:%S') input param error: <file input path> <file output path>"
exit
fi SPARK_BIN_DIR=/home/hadoop/spark/spark-1.5.-bin-hadoop2./bin
HADOOP_BIN_PATH=/home/hadoop/hadoop-2.3.-cdh5.0.0/bin $HADOOP_BIN_PATH/hadoop fs -rm -r $
if [ $? -ne ];then
echo "$(date +'%Y-%m-%d %H:%M:%S') output file dir does not exist in hdfs"
fi runJob(){
echo "$(date +'%Y-%m-%d %H:%M:%S') spark task begins!"
nohup $SPARK_BIN_DIR/spark-submit --class com.ws.test.Test --master yarn --num-executors --driver-memory 7192M --executor-memory 7192M --queue default run.jar deseqData $ $ >> log >& &
if [ $? -ne ];then
echo "$(date +'%Y-%m-%d %H:%M:%S') spark task running error"
exit
fi pid=$!
echo "$(date +'%Y-%m-%d %H:%M:%S') spark task processId is $pid, wait to finish..."
wait $pid
if [ $? -ne ];then
echo "$(date +'%Y-%m-%d %H:%M:%S') spark task running exception"
exit
fi
tail -f log
echo "$(date +'%Y-%m-%d %H:%M:%S') spark task finished!"
} runJob $ $

执行./run.sh /crawler/data/2018-04-04/0/data1522774524.799569.seq /crawler/wstest执行解析任务即可

提取的结果如下:

那些@符号是什么鬼…

3. 优化版本

由于导出的数据存在问题,遂优化了一版,不同之处如下:

 sc.sequenceFile[Text, BytesWritable](s"hdfs://$inputDir")
// .map(data => new String(data._2.getBytes))
.map(data => {
val value = data._2
value.setCapacity(value.getLength)
new String(value.getBytes)
}).saveAsTextFile(outputDir)

打包重新运行bash脚本,得到的结果如下图:

终于正常了,长舒一口气…,but为什么这样呢?

4. 原因分析

当你把byte[]数据保存为BytesWritable后,通过BytesWritable.getBytes()再获取到的数据不一定是原数据,可能变长了很多,这是因为BytesWritable采用自动内存增长算法,你保存数据长度为size时,它可能将数据保存到了长度为capacity(capacity>size)的buffer中。此时,使用BytesWritable.getBytes()得到的数据最后一些字符是多余的。如果里面保存的是protocol buffer序列化后的字符串,则将无法反序列化。

此时可以使用BytesWritable.setCapacity(bytesWritable.getLength())将后面多于空间剔除。

工作采坑札记:1. Hadoop中的BytesWritable误区的更多相关文章

  1. 工作采坑札记:4. Hadoop获取InputSplit文件信息

    1. 场景 基于客户的数据处理需求,客户分发诸多小数据文件,文件每行代表一条记录信息,且每个文件以"类型_yyyyMMdd_批次号"命名.由于同一条记录可能存在于多个文件中,且处于 ...

  2. 工作采坑札记:2. Hadoop中MultipleInputs的使用陷阱

    1. 背景 近日在一个Hadoop项目中使用MultipleInputs增加多输入文件时,发现相同路径仅会加载一次,导致后续的统计任务严重失真.本博文旨在记录异常的排查及解决方案. 2. 情景重现 ( ...

  3. 工作采坑札记:3. Spark中es-hadoop插件异常解决

    1. Es-Hadoop异常: org.elasticsearch.hadoop.EsHadoopException: Could not write all entries [615/300864] ...

  4. 工作采坑札记: 4. linux指定目录使用df和du的统计结果相差很大

    1. 背景 近日,线上的服务出现异常,调用服务返回的JSON格式数据不完整,导致客户端解析异常,因此记录了本次的填坑之旅(nnd)... 2. 排查过程 2.1 服务器分析 登录到服务所在linux服 ...

  5. python+selenium自动化登录dnf11周年活动界面领取奖励登录部分采坑总结[1]

    背景: Dnf的周年庆活动之一,游戏在6月22日 06:00~6月23日 06:00之间登陆过游戏后可以于6月25日 16:00~7月04日 06:00领取奖励 目标:连续四天自动运行脚本,自动领取所 ...

  6. Hadoop环境搭建--Docker完全分布式部署Hadoop环境(菜鸟采坑吐血整理)

    系统:Centos 7,内核版本3.10 本文介绍如何从0利用Docker搭建Hadoop环境,制作的镜像文件已经分享,也可以直接使用制作好的镜像文件. 一.宿主机准备工作 0.宿主机(Centos7 ...

  7. rabbitmq在ios中实战采坑

    1. rabbitmq在ios中实战采坑 1.1. 问题 ios使用rabbitmq连接,没过多久就断开,并报错.且用android做相同的步骤并不会报错,错误如下 Received connecti ...

  8. mybatis中集成sharing-jdbc采坑

    1. mybatis中集成sharing-jdbc采坑 1.1. 错误信息 Caused by: org.apache.ibatis.binding.BindingException: Invalid ...

  9. Cloudera Manager 5.9 和 CDH 5.9 离线安装指南及个人采坑填坑记

    公司的CDH早就装好了,一直想自己装一个玩玩,最近组了台电脑,笔记本就淘汰下来了,加上之前的,一共3台,就在X宝上买了CPU和内存升级了下笔记本,就自己组了个集群. 话说,好想去捡垃圾,捡台8核16线 ...

随机推荐

  1. samba多用户

    注意的点 1:安装 服务器  yum install -y samba* 客户端  yum install -y samba-client  cifs-utils 服务器端和客户端网络能ping通 2 ...

  2. OAuth实现腾讯微博第三方登录

    前言 还是得弱弱的写下这个技术的背后,大概是这个样子的,看到OAuth这个单词,我就想到了权限这个词,不知道为什么,又想起了第三方登录这个技术,于是自己脑补了一下,应该这两个东西是有关系的.再就是去动 ...

  3. Mysql(Linux服务器)root用户密码忘记重置方法

    MySQL是非常常见的开源数据库,使用者众多,若是不小心忘记了安装在服务器的mysql密码,无法登陆,应该如何重置呢?方法很简单,现在和大家分享下.(系统环境:CentOs 6.5  软件:Mysql ...

  4. Oracle复制表

    Oracle复制表分为只复制表结构或者结构和数据均复制两种: 只复制表结构 create table newTableName as select * from oldTableName where ...

  5. luogu1891 疯狂lcm ??欧拉反演?

    link 给定正整数N,求LCM(1,N)+LCM(2,N)+...+LCM(N,N). 多组询问,1≤T≤300000,1≤N≤1000000 \(\sum_{i=1}^nlcm(i,n)\) \( ...

  6. 雷林鹏分享:jQuery EasyUI 数据网格 - 添加查询功能

    jQuery EasyUI 数据网格 - 添加查询功能 本实例演示如何从数据库得到数据,并将它们显示在数据网格(datagrid)中.然后演示如何根据用户输入的搜索关键词搜寻显示结果. 创建数据网格( ...

  7. P4332 [SHOI2014]三叉神经树(LCT)

    Luogu4332 LOJ2187 题解 代码-Tea 题意 : 每个点有三个儿子 , 给定叶节点的权值\(0\)或\(1\)且支持修改 , 非叶子节点的权值为当有\(>=2\)个儿子的权值为\ ...

  8. P2906 [USACO08OPEN]牛的街区Cow Neighborhoods

    传送门 曼哈顿距离好像不好直接算,我们可以把牛的坐标转化一下以方便计算距离 (x,y) --> (x+y,x-y) 那么距离就可以表示成 $max(\left |x_1-x_2  \right ...

  9. Jury Jeopardy (这是一道单纯的模拟题)

    Description What would a programming contest be without a problem featuring an ASCII-maze? Do not de ...

  10. PHP漏洞全解—————9、文件上传漏洞

    本文主要介绍针对PHP网站文件上传漏洞.由于文件上传功能实现代码没有严格限制用户上传的文件后缀以及文件类型,导致允许攻击者向某个可通过 Web 访问的目录上传任意PHP文件,并能够将这些文件传递给 P ...