[转]hadoop使用中的几个小细节(一)
转自:http://rdc.taobao.com/blog/dw/archives/244
最近在hadoop实际使用中有以下几个小细节分享:
1 中文问题
从url中解析出中文,但hadoop中打印出来仍是乱码?我们曾经以为hadoop是不支持中文的,后来经过查看源代码,发现hadoop仅仅是不支持以gbk格式输出中文而己。
这是TextOutputFormat.class中的代码,hadoop默认的输出都是继承自FileOutputFormat来的,FileOutputFormat的两个子类一个是基于二进制流的输出,一个就是基于文本的输出TextOutputFormat。
public class TextOutputFormat<K, V> extends FileOutputFormat<K, V> {
protected static class LineRecordWriter<K, V>
implements RecordWriter<K, V> {
private static final String utf8 = “UTF-8″;//这里被写死成了utf-8
private static final byte[] newline;
static {
try {
newline = “\n”.getBytes(utf8);
} catch (UnsupportedEncodingException uee) {
throw new IllegalArgumentException(”can’t find ” + utf8 + ” encoding”);
}
}
…
public LineRecordWriter(DataOutputStream out, String keyValueSeparator) {
this.out = out;
try {
this.keyValueSeparator = keyValueSeparator.getBytes(utf8);
} catch (UnsupportedEncodingException uee) {
throw new IllegalArgumentException(”can’t find ” + utf8 + ” encoding”);
}
}
…
private void writeObject(Object o) throws IOException {
if (o instanceof Text) {
Text to = (Text) o;
out.write(to.getBytes(), 0, to.getLength());//这里也需要修改
} else {
out.write(o.toString().getBytes(utf8));
}
}
…
}
可以看出hadoop默认的输出写死为utf-8,因此如果decode中文正确,那么将Linux客户端的character设为utf-8是可以看到中文的。因为hadoop用utf-8的格式输出了中文。
因为大多数数据库是用gbk来定义字段的,如果想让hadoop用gbk格式输出中文以兼容数据库怎么办?
我们可以定义一个新的类:
public class GbkOutputFormat<K, V> extends FileOutputFormat<K, V> {
protected static class LineRecordWriter<K, V>
implements RecordWriter<K, V> {
//写成gbk即可
private static final String gbk = “gbk”;
private static final byte[] newline;
static {
try {
newline = “\n”.getBytes(gbk);
} catch (UnsupportedEncodingException uee) {
throw new IllegalArgumentException(”can’t find ” + gbk + ” encoding”);
}
}
…
public LineRecordWriter(DataOutputStream out, String keyValueSeparator) {
this.out = out;
try {
this.keyValueSeparator = keyValueSeparator.getBytes(gbk);
} catch (UnsupportedEncodingException uee) {
throw new IllegalArgumentException(”can’t find ” + gbk + ” encoding”);
}
}
…
private void writeObject(Object o) throws IOException {
if (o instanceof Text) {
// Text to = (Text) o;
// out.write(to.getBytes(), 0, to.getLength());
// } else {
out.write(o.toString().getBytes(gbk));
}
}
…
}
然后在mapreduce代码中加入conf1.setOutputFormat(GbkOutputFormat.class)
即可以gbk格式输出中文。
2 关于计算过程中的压缩和效率的对比问题
之前曾经介绍过对输入文件采用压缩可以提高部分计算效率。现在作更进一步的说明。
为什么压缩会提高计算速度?这是因为mapreduce计算会将数据文件分散拷贝到所有datanode上,压缩可以减少数据浪费在带宽上的时间,当这些时间大于压缩/解压缩本身的时间时,计算速度就会提高了。
hadoop的压缩除了将输入文件进行压缩外,hadoop本身还可以在计算过程中将map输出以及将reduce输出进行压缩。这种计算当中的压缩又有什么样的效果呢?
测试环境:35台节点的hadoop cluster,单机2 CPU,8 core,8G内存,redhat 2.6.9, 其中namenode和second namenode各一台,namenode和second namenode不作datanode
输入文件大小为2.5G不压缩,records约为3600万条。mapreduce程序分为两个job:
job1:map将record按user字段作key拆分,reduce中作外连接。这样最后reduce输出为87亿records,大小540G
job2:map读入这87亿条数据并输出,reduce进行简单统计,最后的records为2.5亿条,大小16G
计算耗时54min
仅对第二个阶段的map作压缩(第一个阶段的map输出并不大,没有压缩的必要),测试结果:计算耗时39min
可见时间上节约了15min,注意以下参数的不同。
不压缩时:
Local bytes read=1923047905109
Local bytes written=1685607947227
压缩时:
Local bytes read=770579526349
Local bytes written=245469534966
本地读写的的数量大大降低了
至于对reduce输出的压缩,很遗憾经过测试基本没有提高速度的效果。可能是因为第一个job的输出大多数是在本地机上进行map,不经过网络传输的原因。
附:对map输出进行压缩,只需要添加jobConf.setMapOutputCompressorClass(DefaultCodec.class)
3 关于reduce的数量设置问题
reduce数量究竟多少是适合的。目前测试认为reduce数量约等于cluster中datanode的总cores的一半比较合适,比如cluster中有32台datanode,每台8 core,那么reduce设置为128速度最快。因为每台机器8 core,4个作map,4个作reduce计算,正好合适。
附小测试:对同一个程序
reduce num=32,reduce time = 6 min
reduce num=128, reduce time = 2 min
reduce num=320, reduce time = 5min
相关推荐
深入学习Hadoop源码,我们可以探讨以下几个关键知识点: 1. **Hadoop架构**:理解Hadoop的分布式文件系统(HDFS)和MapReduce计算模型,以及YARN资源调度器的工作原理。 2. **HDFS**:研究HDFS的数据块、副本策略...
《Hadoop源码分析 第一章 Hadoop脚本》 Hadoop是大数据处理领域中的一个核心框架,它为...只有深入理解Hadoop的每一个细节,才能更好地利用这一强大工具解决实际问题。通过不断学习和实践,你将成为驾驭Hadoop的专家。
Hadoop是一个由Apache基金会开发的分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序,充分利用集群的威力进行高速运算和存储。Hadoop实现了一个分布式文件系统(Hadoop Distributed ...
总的来说,使用Kerberos与Hadoop-3.3.4结合,可以构建一个安全可靠的大数据处理环境。在实际操作中,管理员需要深入了解Kerberos的工作原理和Hadoop的配置细节,以确保系统的稳定性和安全性。同时,定期维护和更新...
Hadoop主要由以下几个部分组成: 1. **Hadoop Common**:这是Hadoop的核心部分,包括文件系统(HDFS)和远程过程调用(RPC)等基础服务。 2. **HDFS (Hadoop Distributed File System)**:提供了一个高吞吐量的可靠...
RPC允许一个程序在某个网络中的计算机上执行另一个计算机上的程序,而无需了解底层网络协议和操作系统细节。吴超老师的这个小测试例子是关于Hadoop中RPC协议的应用,它可以帮助我们深入理解RPC的工作原理以及在...
在安装Hadoop之前,我们需要了解以下几个核心概念: 1. **HDFS(Hadoop Distributed File System)**:Hadoop的核心组件之一,是一个分布式文件系统,能够将大量数据分布在多台服务器上,提供高容错性和高可用性。 ...
Hadoop具有以下几个重要的组件和概念: 1. Hadoop分布式文件系统(HDFS):HDFS是Hadoop的一个核心组件,它是一个分布式文件存储系统,能够存储非常大量的数据。HDFS的设计考虑到了高容错性,能够为数据保存多个...
从程序员的角度来看,使用Hadoop进行开发需要遵循以下几个步骤: 1. 定义Mapper类和Reducer类,分别处理输入数据和进行数据归约。 2. 定义Job,即整个MapReduce任务,包括输入输出格式、Mapper类、Reducer类以及...
在深入探讨Hadoop的知识点时,我们可以从以下几个方面进行: 1. **Hadoop概述**:Hadoop是一个开源的分布式计算框架,由Apache软件基金会维护。它允许在廉价硬件上处理和存储大量数据,主要由两个核心组件构成:...
在 Hadoop MapReduce 中实现决策树,通常分为以下几个步骤: - **预处理**:清洗和转换数据,将其转化为适合 MapReduce 模型的格式。 - **Map 阶段**:每个 Map 任务处理一部分数据,计算每个特征在当前子集上的...
它有以下几个核心组成部分: 1. Hadoop Common:包含Hadoop的基本库,这些库支持其他Hadoop模块。 2. HDFS(Hadoop Distributed File System):一种分布式文件系统,提供高吞吐量的数据访问,适合大规模数据集的...
具体来说,调优策略大致可以分为以下几个方面: 1. 配置参数调优:合理配置Hadoop和Hive的参数是调优的一个重要步骤。这包括了控制Map任务的数量、合理设置Reduce任务的数量、压缩中间数据以及减少磁盘IO。配置参数...
Hadoop的源代码分析可以从以下几个关键点开始: 1. **HDFS架构**:HDFS是一个分布式文件系统,设计用于在廉价硬件上运行。它的核心思想是数据本地化,即数据应该存储在处理它的节点附近,以提高效率。HDFS中的主要...
Hadoop选择使用商用硬件而不是超级计算机或高端服务器,主要有以下几个原因: - **成本效益**:商用硬件虽然单机性能较低,但价格便宜,通过集群的方式可以有效降低成本。 - **容错机制**:由于单个节点的可靠性较...
原始的K-Means算法包括以下几个步骤: 1. **初始化**:随机选择K个数据点作为初始质心。 2. **分配数据点**:将每个数据点分配给最近的质心所在的簇。 3. **更新质心**:对于每个簇,计算所有数据点的平均值作为新...
MapReduce 是 Hadoop 的核心组件,提供了一个编程模型,可以在一个由几十台上百台的 PC 组成的不可靠集群上并发地、分布式地处理大量的数据集。 MapReduce 的抽象层次较低,需要手工编写代码来完成,使用上难以上手...
本文将从以下几个关键点详细解读Hadoop平台性能优化的知识点。 首先,了解Hadoop平台的性能依赖于基于MapReduce模型的应用程序。MapReduce模型将复杂的分布式任务简化为两个主要操作:Map(映射)和Reduce(归约)...
传统方法的局限性主要体现在以下几个方面: - **计算能力限制**:单台服务器的计算能力有限,难以处理大规模数据。 - **编程难度**:分布式计算通常需要高度专业化的编程技能,这增加了开发的难度和成本。 Hadoop...