您的位置:首页 > 运维架构

hadoop 2.4编译、安装

2016-04-02 19:26 274 查看

1、hadoop-2.4.0版本编译

环境准备:

操作系统:Red Hat5.8 64bit
内核版本2.6.18-308.el5

1.1安装JDK

JDK版本:jdk1.7.0_60

下载jdk-7u60-linux-x64.gz,并解压tar –zvxf jdk-7u60-linux-x64.gz

配置环境变量

export PATH

export JAVA_HOME=/usr/java/jdk1.7.0_60

export PATH=$PATH:$JAVA_HOME/bin

source /etc/profile

测试下JDK是否安装成功: java –version

1.2安装maven

maven版本:apache-maven-3.1.1

下载地址:http://mirror.bit.edu.cn/apache/maven/maven-3/3.1.1/binaries/apache-maven-3.1.1-bin.zip
解压文件后,同样在/etc/profie里配置环境变量:

export MAVEN_HOME=/usr/maven/apache-maven-3.1.1

export PATH=$PATH:$MAVEN_HOME/bin

修改配置文件:

修改maven目录下的conf/settings.xml文件,在<mirrors></mirros>里添加,原本的不要动:

<mirror>

<id>nexus-osc</id>

<mirrorOf>*</mirrorOf>

<name>Nexusosc</name>

<url>http://maven.oschina.net/content/groups/public/</url>

</mirror>

同样,在<profiles></profiles>内新添加

<profile>

<id>jdk-1.7</id>

<activation>

<jdk>1.7</jdk>

</activation>

<repositories>

<repository>

<id>nexus</id>

<name>local private nexus</name>

<url>http://maven.oschina.net/content/groups/public/</url>

<releases>

<enabled>true</enabled>

</releases>

<snapshots>

<enabled>false</enabled>

</snapshots>

</repository>

</repositories>

<pluginRepositories>

<pluginRepository>

<id>nexus</id>

<name>local private nexus</name>

<url>http://maven.oschina.net/content/groups/public/</url>

<releases>

<enabled>true</enabled>

</releases>

<snapshots>

<enabled>false</enabled>

</snapshots>

</pluginRepository>

</pluginRepositories>

</profile>

验证配置是否成功: mvn –version

1.3安装protoc

protoc版本:protobuf-2.5.0

下载地址:

https://code.google.com/p/protobuf/downloads/list

对protoc进行编译安装前先要装几个依赖包:gcc,gcc-c++,make

yum install gcc

yum intall gcc-c++

yum install make

安装protoc过程

tar -xvf protobuf-2.5.0.tar.bz2

cd protobuf-2.5.0

./configure --prefix=/opt/protoc/

make && make install

配置环境变量

export PROTOC_HOME=/usr/protoc/protoc

export PATH= $PROTOC_HOME/bin

验证安装是否成功:

1.4安装ant

ant版本:apache-ant-1.9.4

下载地址:

http://archive.apache.org/dist/ant/source/apache-ant-1.9.4-src.tar.bz2

解压后,配置环境变量

export ANT_HOME=/usr/ant/apache-ant-1.9.4

export PATH= $ANT_HOME/bin

验证安装是否成功:

1.5安装cmake,openssl-devel,ncurses-devel依赖

yum install cmake

yum install openssl-devel

yum install ncurses-devel

1.6编译hadoop-2.4.0源码

源码下载地址:

http://mirrors.hust.edu.cn/apache/hadoop/common/hadoop-2.4.0/

进入hadoop2.4.0源码目录下编译:

mvn package -Pdist,native -DskipTests –Dtar

第一次编译需要联网,等待1个小时左右,看到这样的信息,就代表完成。

[INFO] Reactor Summary:

[INFO]

[INFO] Apache Hadoop Main................................ SUCCESS [3.709s]

[INFO] Apache Hadoop Project POM......................... SUCCESS [2.229s]

[INFO] Apache Hadoop Annotations......................... SUCCESS [5.270s]

[INFO] Apache Hadoop Assemblies.......................... SUCCESS [0.388s]

[INFO] Apache Hadoop Project Dist POM.................... SUCCESS [3.485s]

[INFO] Apache Hadoop Maven Plugins....................... SUCCESS [8.655s]

[INFO] Apache Hadoop Auth................................ SUCCESS [7.782s]

[INFO] Apache Hadoop Auth Examples....................... SUCCESS [5.731s]

[INFO] Apache Hadoop Common.............................. SUCCESS [1:52.476s]

[INFO] Apache Hadoop NFS................................. SUCCESS [9.935s]

[INFO] Apache Hadoop Common Project...................... SUCCESS [0.110s]

[INFO] Apache Hadoop HDFS................................ SUCCESS [1:58.347s]

[INFO] Apache Hadoop HttpFS.............................. SUCCESS [26.915s]

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

[INFO] Apache Hadoop Tools Dist.......................... SUCCESS [2.306s]

[INFO] Apache Hadoop Tools............................... SUCCESS [0.037s]

[INFO] Apache Hadoop Distribution........................ SUCCESS [21.579s]

[INFO] Apache Hadoop Client.............................. SUCCESS [7.299s]

[INFO] Apache Hadoop Mini-Cluster........................ SUCCESS [7.347s]

[INFO]------------------------------------------------------------------------

[INFO] BUILD SUCCESS

[INFO] ------------------------------------------------------------------------

[INFO] Total time: 11:53.144s

[INFO] Finished at: Fri Nov 22 16:58:32 CST2013

[INFO] Final Memory: 70M/239M

[INFO]------------------------------------------------------------------------

编译后的路径在:hadoop-2.4.0-src/hadoop-dist/target/hadoop-2.4.0.tar.gz

编译完成!

2、Hadoop2.4.0安装

2.1修改主机名

1)hostname master

2)修改/etc/sysconfig/network中的hostname

3)修改/etc/hosts文件中添加IP和主机名称对应关系

修改后记得重启系统。

2.2保证每台主机互相之间能ping通

2.3 SSH免密码登陆

所有机器执行/usr/bin/ssh-keygen-t rsa命令,执行完此命令后会在家目录的.ssh目录下生成id_rsa 私钥和id_rsa.pub公钥。

将所有主机的公钥id_rsa.pub汇总到一个名称为authorized_keys的文件中,并分发到各个主机。

测试配置是否成功:

在每台主机都要ssh其他所有主机(包括ssh自己)进行测试。

2.4安装hadoop集群

2.4.1解压

用root用户解压tar –zxvf hadoop-2.4.0.tar.gz

2.4.2创建hadoop用户、用户组并赋予相应权限

新增用户:useradd hadoop

新增用户组:groupadd hadoop
将文件夹" hadoop-2.4.0"读写权限分配给hadoop用户:

chown–R hadoop:hadoop hadoop-2.4.0

chmod –R770 hadoop-2.4.0

2.4.3配置环境变量

vim /etc/profile

export HADOOP_HOME=/home/hadoop/hadoop-2.4.0

export PATH= $ HADOOP _HOME/bin

source /etc/profile

2.4.4修改配置文件

需修改hadoop-env.sh

yarn-env.sh
slaves
core-site.xml
hdfs-site.xml
mapred-site.xml
yarn-site.xml
1)vimhadoop-env.sh
export JAVA_HOME=/usr/java/jdk1.7.0_60
export HADOOP_OPTS=-Djava.net.preferIPv4Stack=true
2)vimyarn-env.sh
export JAVA_HOME=
/home/hadoop/jdk7
3)vim slaves
添加节点
slave1
slave2
4)vimcore-site.xml
添加
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://master:9000</value>
</property>
<property>
<name>io.file.buffer.size</name>
<value>131072</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/home/hadoop/tmp</value>
<description>Abase for other temporarydirectories.</description>
</property>
<property>
<name>hadoop.proxyuser.hduser.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.hduser.groups</name>
<value>*</value>
</property>
<property>
<name>fs.trash.interval</name>
<value>360</value>
</property>
<property>
<name>dfs.namenode.checkpoint.period</name>
<value>900</value>
</property>
<property>
<name>ipc.client.connection.maxidletime</name>
<value>30000</value>
</property>
</configuration>
5)vimhdfs-site.xml
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>master:9001</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>/home/hadoop/dfs/name,</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>/home/hadoop/dfs/data</value>
</property>
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
<property>
<name>dfs.webhdfs.enabled</name>
<value>true</value>
</property>
<property>
<name>dfs.datanode.max.xcievers</name>
<value>4096</value>
</property>
<property>
<name>dfs.datanode.data.dir.perm</name>
<value>750</value>
</property>
<property>
<name>dfs.blocksize</name>
<value>134217728</value>
</property>
6)vimmapred-site.xml
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapreduce.jobhistory.address</name>
<value>172.16.145.73:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>172.16.145.73:19888</value>
</property>
7)vimyarn-site.xml
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
<value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>
<property>
<name>yarn.resourcemanager.address</name>
<value>master:8032</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>master:8030</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address</name>
<value>master:8031</value>
</property>
<property>
<name>yarn.resourcemanager.admin.address</name>
<value>master:8033</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address</name>
<value>master:8088</value>
</property>

2.4.5配置其他机器

将在master配置好的hadoop文件传送到其他服务器
scp -r /home/hadoop/hadoop-2.4.0 root@slave1:/home/hadoop/hadoop-2.4.0
scp -r /home/hadoop/hadoop-2.4.0 root@slave2:/home/hadoop/hadoop-2.4.0
配置其他机器用户、用户组及权限
新增用户:useradd hadoop

新增用户组:groupadd hadoop
将文件夹"hadoop"读写权限等分配给hadoop用户:

chown–R hadoop:hadoop hadoop-2.4.0

chmod –R770 hadoop-2.4.0

2.4.6 建立配置文件中所提及的目录

mkdir/home/hadoop/tmp

mkdir/home/hadoop/dfs

mkdir/home/hadoop/dfs/name

mkdir/home/hadoop/dfs/data

2.4.7 启动hadoop

启动前需关闭所有机器的防火墙
chkconfig iptables off
在"master"上使用普通用户hadoop进行进行namenode操作。只需第一次启动时操作,下次启动不需要。
hadoop namenode –format
启动hadoop
start-all.sh
在namenode和datanode使用jps查看启动进程。

3、HDFS体系结构

3.1 namenode

1)记录每个文件数据块在各个datanode上的位置和副本信息
2)协调客户端对文件的访问
3)使用事务日志edits记录hdfs元数据的变化。使用映像文件fsimage存储文件系统的命名空间,包括文件映射,文件属性等信息。

3.2 datanode

1)负责所在物理节点的存储管理
2)一次写入,多次读取
3)文件由数据块组成
4)数据块尽量散步到各个节点

3.3 secondarynamenode

1)定期合并fsimage和edits日志

3.4 读取数据流程

客户端要访问hdfs中的一个文件,首先从namenode获得组成这个文件的数据块位置列表,根据这个列表知道存储数据块的datanode,访问datanode获取数据,在这个过程中,namenode并不参与数据的实际传输。

3.5 Hdfs机制策略

1)冗余副本策略。所有文件都有副本数。
2)机架策略。集群服务器可以放在不同的机架上,一个机架一个交换机,最后通过总的交换机进行数据传输,这样可以防止一旦一个机架失效,防止数据找不到。
3)心跳机制。Namenode周期性从datanode接收心跳信号和块的报告,namenode根据块报告验证元数据,没有按时发送心跳的datanode会被标记为宕机,并且namenode不会再向此机器发送I/O请求。如果datanode失效造成副本数量下降,namenode会检测出这些数据块,并在合适的时机进行重新复制。
4)安全模式。Namenode启动时会先经过一个“安全模式”阶段,安全模式阶段不会产生数据写入。在此阶段namenode收集各个datanode的报告,当数据块达到最小副本数以上时,退出安全模式。当检测到副本数不足的数据块时,该数据块会被复制直到达到最小副本数。
5)回收站。开启回收站模式,删除文件时,文件放入/user/root/trash中,回收站里的文件可以快速恢复。可以设置一个时间阈值,当回收站的文件存放时间超过这个阈值时,释放数据块。
6)元数据保护。映像文件fsimage和日志文件edits可以保存多份,在配置文件中填写多个路径,并用逗号隔开,元数据的副本数会降低namenode的处理速度,但增加元数据安全性。

3.6 HDFS文件操作

3.6.1 命令行方式

1、列出所有HadoopShell支持的命令
$ hadoop fs -help
2、格式化一个新的分布式文件系统:
$ bin/hadoop namenode-format

3、将集群置于安全模式(dfs.namenode.safemode.threshold-pct选项配置)
$ bin/hadoop dfsadmin-safemode enter
4、退出安全模式
$ bin/hadoop dfsadmin -safemode leave
5、显示Datanode列表及使用情况
$ bin/hadoop dfsadmin -report

6、查看文件目录文件
$ hadoop fs -ls /
7、创建一个名为 /test1
的目录

$ bin/hadoop fs -mkdir /test1
8、查看名为 /hadoop_test.txt
的文件内容
$ bin/hadoop fs -cat /hadoop_test.txt
9、删除文件

$hadoop fs -rm /hadoop_test1.txt

10、上传文件

$hadoop fs -put /home/tmp/upload/hadoop_test1.txt /

11、下载文件

$hadoop fs -get / hadoop_test1.txt /home/tmp/download

12、显示文件大小
$hadoop fs –du /
13、显示文件系统大小
$hadoop fs –df /
14、显示目录数量
$hadoop fs –count /
15、清空回收站
$hadoop fs –expunge
16、设置文件副本数
$hadoop fs –setrep5 /hadoop_test1.txt

3.6.2 API方式

代码:
package dealfiles;

importjava.io.IOException;
importjava.io.InputStream;
import java.net.URI;

importorg.apache.hadoop.conf.Configuration;
importorg.apache.hadoop.fs.FileSystem;
importorg.apache.hadoop.fs.Path;
importorg.apache.hadoop.io.IOUtils;

public class hdfs_test {

public static void main(String[] args) throws Exception {
if (args[0].equals("read")) {

readFile(args[1]);
} else if (args[0].equals("upload")) {

uploadFile(args[1]);
} else if (args[0].equals("download")) {

downloadFile(args[1]);
}

else {
System.out.println("请输入正确操作");
}
}

/***
* 加载配置文件
* **/
static Configuration conf = new Configuration();
static String uri = "hdfs://172.16.145.73:9000/";

/***
*
* 读取HDFS某个文件夹的所有文件,并打印
*
* **/
public static void readFile(String string) throws Exception {

String path = "hdfs://172.16.145.73:9000/";
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(URI.create(uri), conf);
InputStream in = null;
try {
in = fs.open(new Path(path + string));
IOUtils.copyBytes(in, System.out, 4096, false);
} finally {
IOUtils.closeStream(in);
}

}

/**
* 从HDFS上下载文件或文件夹到本地
*
* **/
public static void downloadFile(String string1) throwsException {

FileSystem fs = FileSystem.get(URI.create(uri), conf);
Path p1 = newPath("hdfs://172.16.145.73:9000/" + string1);
Path p2 = new Path("/home/tmp/download/");
fs.copyToLocalFile(p1, p2);
fs.close();//
释放资源
System.out.println("下载文件夹或文件成功.....");

}

/***
* 上传本地文件到 HDFS上
*
* **/
public static void uploadFile(String string1)
throws Exception {
// 加载默认配置
FileSystem fs = FileSystem.get(URI.create(uri), conf);
// 本地文件
Path src = new Path("/home/tmp/upload/" +string1);
// HDFS为止
Path dst = newPath("hdfs://172.16.145.73:9000/tmp");
try {
fs.copyFromLocalFile(src, dst);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("上传成功........");

fs.close();//
释放资源

}

}

3.6.3 WEB监控HDFS文件系统

地址:http://master:50070/

3.6.4 集群的扩容

1)在新节点上安装好hadoop
2)将namenode的有关配置文件复制到该节点
3)修改所有节点的slaves配置文件,增加该节点
4)全部重新设置ssh免密码登录
5)单独启动该节点的hdfs服务和yarn服务
6)运行start-balancer.sh进行数据负载均衡

4、Map-Reduce

4.1 mapreduce模型

含有两个模型,map和reduce。Map可以理解为数据准备及数据预处理,reduce接收map传过来的数据进行相应计算。
找出每一年的最高气温。

4.2 API方式

需求:终端日数据表,统计同一用户同一终端出现的次数。
代码:
Mapper:
package mapreduce;

importjava.io.IOException;

importorg.apache.hadoop.io.IntWritable;
importorg.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

public class MapClassextends Mapper<Object, Text, Text, IntWritable> {
private Text record = new Text();
private static final IntWritable recbytes = newIntWritable(1);

public void map(Object key, Text value, Context context)
throws IOException, InterruptedException {
String line = value.toString();
// 采用 line读取每一行
// key 就是行号,value
就是行内容,
// 按行key-value
存放每行 user_id
和 dm_model
内容
if (line == null || line.equals(""))
return;
String[] words = line.split(",");
if (words == null || words.equals(""))
return;
String user_dm = words[1]+":"+words[6];
record.clear();
record.set(newStringBuffer().append(user_dm).toString());
context.write(record, recbytes);
// 输出日志级别统计结果,通过user_id+dm_model作为结果输出

}
}

Partitioner:
package mapreduce;

importorg.apache.hadoop.io.IntWritable;
importorg.apache.hadoop.io.Text;
importorg.apache.hadoop.mapreduce.Partitioner;

public classPartitionerClass extends Partitioner<Text, IntWritable> {
public int getPartition(Text key, IntWritable value, intnumPartitions) {
//return new Long(key.getDepartureNode()).hashCode() %numPartitions;

if (numPartitions >= 2)// Reduce
个数
if (key.toString().startsWith("18"))//判断user_id,分配到不同的Reduce
return 0;
else
return 1;
else
return 0;
}

}

Reducer:
package mapreduce;

importjava.io.IOException;

importorg.apache.hadoop.io.IntWritable;
importorg.apache.hadoop.io.Text;
importorg.apache.hadoop.mapreduce.Reducer;

public class ReduceClassextends Reducer<Text, IntWritable, Text, IntWritable> {
private IntWritable result = new IntWritable();

public void reduce(Text key, Iterable<IntWritable>values, Context context)
throws IOException, InterruptedException {

int num = 0;
for (IntWritable val : values) { //遍历整个value,进行计数加1操作
num = num + val.get();
}
result.set(num);
context.write(key, result);//
输出最后的汇总结果
}
}

Job:
package mapreduce;

import java.io.File;
importjava.text.SimpleDateFormat;
import java.util.Date;
import org.apache.hadoop.conf.Configuration;
importorg.apache.hadoop.conf.Configured;
importorg.apache.hadoop.fs.Path;
importorg.apache.hadoop.io.IntWritable;
importorg.apache.hadoop.io.Text;
importorg.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapreduce.Job;
importorg.apache.hadoop.mapreduce.lib.input.FileInputFormat;
importorg.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
importorg.apache.hadoop.util.Tool;
importorg.apache.hadoop.util.ToolRunner;

public class JobClassextends Configured implements Tool {
public static void main(String[] args) {
try {
int res;
res = ToolRunner.run(new Configuration(), newJobClass(), args);
System.exit(res);
} catch (Exception e) {
e.printStackTrace();
}
}

public int run(String[] args) throws Exception {
if (args == null || args.length < 2) {
System.out.println("需要输入和输出路径");
return 1;
}
String inputpath = args[0];
String outputpath = args[1];
Job job = new Job(new Configuration());//设置配置文件
job.setJarByClass(JobClass.class);//指定job的Class
job.setJobName("JobClass");//设置任务名
job.setOutputKeyClass(Text.class);//
输出的 key
类型
job.setOutputValueClass(IntWritable.class); //
输出的 value
类型

job.setMapperClass(MapClass.class);//指定Mapper的class
job.setCombinerClass(ReduceClass.class);//指定combiner的class
job.setReducerClass(ReduceClass.class);//指定Reducer的class
job.setPartitionerClass(PartitionerClass.class);//指定Partitioner的class
job.setNumReduceTasks(2);//需要有两个 Reduce
来工作
FileInputFormat.setInputPaths(job, newPath(inputpath));// hdfs
中的输入路径
FileOutputFormat.setOutputPath(job, newPath(outputpath));// hdfs
中输出路径
Date startTime = new Date();
System.out.println("Job
开始: " + startTime);
job.waitForCompletion(true);
Date end_time = new Date();
System.out.println("Job
结束: " + end_time);
System.out.println("共用时"
+ (end_time.getTime() -startTime.getTime()) / 1000
+ " seconds.");
return 0;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: