离线计算系统之Hadoop入门

 

1. HADOOP背景介绍

1.1 什么是HADOOP

  1. HADOOP是apache旗下的一套开源软件平台,官网: http://hadoop.apache.org
  2. HADOOP提供的功能:利用服务器集群,根据用户的自定义业务逻辑,对海量数据进行分布式处理
  3. HADOOP的核心组件有
    1. HDFS(分布式文件系统)Hadoop Distributed File System
    2. YARN(运算资源调度系统)Yet Another Resource Management
    3. MAPREDUCE(分布式运算编程框架)-- 计算向数据移动
  4. 广义上来说,HADOOP通常是指一个更广泛的概念——HADOOP生态圈

1.2 HADOOP产生背景

  1. HADOOP最早起源于Nutch。Nutch的设计目标是构建一个大型的全网搜索引擎,包括网页抓取、索引、查询等功能,但随着抓取网页数量的增加,遇到了严重的可扩展性问题——如何解决数十亿网页的存储和索引问题。
  2. 2003年、2004年谷歌发表的两篇论文为该问题提供了可行的解决方案,以及2006关于BigTable的论文,并成为引爆大数据时代的三篇论文(https://blog.csdn.net/lixinkuan328/article/details/81839824)。

——分布式文件系统(GFS),可用于处理海量网页的存储

——分布式计算框架MAPREDUCE,可用于处理海量网页的索引计算问题。

——Bigtable发布于2006年,启发了无数的NoSQL数据库,比如:Cassandra、HBase等等

 

     3.Nutch的开发人员完成了相应的开源实现HDFS和MAPREDUCE,并从Nutch中剥离成为独立项目HADOOP,到2008年1月,HADOOP成为Apache顶级项目,迎来了它的快速发展期。

1.3 HADOOP在大数据、云计算中的位置和关系

  1. 云计算是分布式计算、并行计算、网格计算、多核计算、网络存储、虚拟化、负载均衡等传统计算机技术和互联网技术融合发展的产物。借助IaaS(基础设施即服务)、PaaS(平台即服务)、SaaS(软件即服务)等业务模式,把强大的计算能力提供给终端用户。
  2. 现阶段,云计算的两大底层支撑技术为“虚拟化”和“大数据技术
  3. 而HADOOP则是云计算的PaaS层的解决方案之一,并不等同于PaaS,更不等同于云计算本身。

 

1.4 国内外HADOOP应用案例介绍

1、HADOOP应用于数据服务基础平台建设

 

2、HADOOP用于用户画像

 

3、HADOOP用于网站点击流日志数据挖掘

1.5 HADOOP生态圈以及各组成部分的简介

重点组件:

HDFS:分布式文件系统

MAPREDUCE:分布式运算程序开发框架

HIVE:基于大数据技术(文件系统+运算框架)的SQL数据仓库工具

HBASE:基于HADOOP的分布式海量数据库

ZOOKEEPER:分布式协调服务基础组件

Mahout:基于mapreduce/spark/flink等分布式运算框架的机器学习算法库

Oozie:工作流调度框架

Sqoop:数据导入导出工具

Flume:日志数据采集框架

 

2 分布式系统概述

注:由于大数据技术领域的各类技术框架基本上都是分布式系统,因此,理解hadoop、storm、spark等技术框架,都需要具备基本的分布式系统概念

 

2.1 分布式软件系统(Distributed Software Systems)

  • 该软件系统会划分成多个子系统或模块,各自运行在不同的机器上,子系统或模块之间通过网络通信进行协作,实现最终的整体功能
  • 比如分布式操作系统、分布式程序设计语言及其编译(解释)系统、分布式文件系统和分布式数据库系统等。

 

2.2 分布式软件系统举例:solrcloud

  1. 一个solrcloud集群通常有多台solr服务器
  2. 每一个solr服务器节点负责存储整个索引库的若干个shard(数据分片)
  3. 每一个shard又有多台服务器存放若干个副本互为主备用
  4. 索引的建立和查询会在整个集群的各个节点上并发执行
  5. solrcloud集群作为整体对外服务,而其内部细节可对客户端透明

总结:利用多个节点共同协作完成一项或多项具体业务功能的系统就是分布式系统。

 

2.3 分布式应用系统模拟开发

需求:可以实现由主节点将运算任务发往从节点,并将各从节点上的任务启动;

程序清单:

AppMaster

AppSlave/APPSlaveThread

Task

程序运行逻辑流程:

 

3. 离线数据分析流程介绍

注:本环节主要感受数据分析系统的宏观概念及处理流程,初步理解hadoop等框架在其中的应用环节,不用过于关注代码细节

 

一个应用广泛的数据分析系统:“web日志数据挖掘”

3.1 需求分析

3.1.1 案例名称

网站或APP点击流日志数据挖掘系统”。PV-Page View

一般中型的网站(10W的PV以上),每天会产生1G以上Web日志文件。大型或超大型的网站,可能每小时就会产生10G的数据量。

具体来说,比如某电子商务网站,在线团购业务。每日PV数100w,独立IP数5w。用户通常在工作日上午10:00-12:00和下午15:00-18:00访问量最大。日间主要是通过PC端浏览器访问,休息日及夜间通过移动设备访问较多。网站搜索浏量占整个网站的80%,PC用户不足1%的用户会消费,移动用户有5%会消费。

对于日志的这种规模的数据,用HADOOP进行日志分析,是最适合不过的了。

3.1.2 案例需求描述

“Web点击流日志”包含着网站运营很重要的信息,通过日志分析,我们可以知道网站的访问量,哪个网页访问人数最多,哪个网页最有价值,广告转化率、访客的来源信息,访客的终端信息等。

 

3.1.3 数据来源

本案例的数据主要由用户的点击行为记录

获取方式:在页面预埋一段js程序,为页面上想要监听的标签绑定事件,只要用户点击或移动到标签,即可触发ajax请求到后台servlet程序,用log4j记录下事件信息,从而在web服务器(nginx、tomcat等)上形成不断增长的日志文件。

形如:


58.215.204.118 - - [18/Sep/2013:06:51:35 +0000] "GET /wp-includes/js/jquery/jquery.js?
ver=1.10.2 HTTP/1.1" 304 0 "http://blog.fens.me/nodejs-socketio-chat/" "Mozilla/5.0 
(Windows NT 5.1; rv:23.0) Gecko/20100101 Firefox/23.0"

 

3.2 数据处理流程

3.2.1 流程图解析

本案例跟典型的BI系统极其类似,整体流程如下:

但是,由于本案例的前提是处理海量数据,因而,流程中各环节所使用的技术则跟传统BI完全不同,后续课程都会一一讲解:

  1. 数据采集:定制开发采集程序,或使用开源框架FLUME
  2. 数据预处理:定制开发mapreduce程序运行于hadoop集群
  3. 数据仓库技术:基于hadoop之上的Hive
  4. 数据导出:基于hadoop的sqoop数据导入导出工具
  5. 数据可视化:定制开发web程序或使用kettle等产品
  6. 整个过程的流程调度:hadoop生态圈中的oozie工具或其他类似开源产品

 

3.2.2 项目技术架构图

3.2.3 项目相关截图

  1. Mapreudce程序运行

 

  1. 在Hive中查询数据

 

  1. 将统计结果导入mysql
./sqoop export --connect jdbc:mysql://localhost:3306/weblogdb --username root --password 
root  --table t_display_xx  --export-dir /user/hive/warehouse/uv/dt=2014-08-03

3.3 项目最终效果

经过完整的数据处理流程后,会周期性输出各类统计指标的报表,在生产实践中,最终需要将这些报表数据以可视化的形式展现出来,本案例采用web程序来实现数据可视化

效果如下所示:

 

4. 集群搭建

4.1 HADOOP集群搭建

4.1.1集群简介

HADOOP集群具体来说包含两个集群:HDFS集群和YARN集群,两者逻辑上分离,但物理上常在一起

HDFS集群:

负责海量数据的存储,集群中的角色主要有 NameNode / DataNode

YARN集群:

负责海量数据运算时的资源调度,集群中的角色主要有 ResourceManager /NodeManager

部署图如下:

4.1.2服务器准备

本案例使用虚拟机服务器来搭建HADOOP集群,所用软件及版本:

  • Vmware 11.0
  • Centos  6.5  64bit

 

4.1.3网络环境准备

  • 采用NAT方式联网
  • 网关地址:192.168.18.1
  • 五个服务器节点IP地址:192.168.18.101、192.168.18.102、192.168.18.103、192.168.18.104、192.168.18.105
  • 子网掩码:255.255.255.0

4.1.4服务器系统设置

  • 添加HADOOP用户:useradd  HADOOP  (sudo useradd lxk)
  • 切换用户:su  HADOOP    
  • 为HADOOP用户分配sudoer权限:vi /etc/sudoers
  • 同步时间:ntpdate ntp.api.bz
  • 设置主机名(C:\Windows\System32\drivers\etc\hosts)
192.168.18.101       node01
192.168.18.102       node02
192.168.18.103       node03
192.168.18.104       node04
192.168.18.105       node05
  • 配置内网域名映射(vi  /etc/hosts):同上
  • 配置ssh免密登陆
ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
  • 配置防火墙(临时关闭)
service iptables stop     //临时关闭防火墙
service iptables status

 

4.1.5 Jdk环境安装

  • 上传jdk安装包:jdk-7u79-linux-x64.rpm
  • 规划安装目录  /root/
  • rpm安装: rpm -i jdk-7u79-linux-x64.rpm
  • 查看安装目录: whereis java     /usr/java/jdk1.7.0_79
  • 配置环境变量:  vi + /etc/profile  添加之后,使生效: .  /etc/profile
export JAVA_HOME=/usr/java/jdk1.7.0_79
PATH=$PATH:$JAVA_HOME/bin

扩展:
1、拷贝本机/home/administrator/test整个目录至远程主机192.168.1.100的/root目录下
scp -r /home/administrator/test/ [email protected]:/root/

2、拷贝单个文件至远程主机
scp /home/administrator/Desktop/old/driver/test/test.txt [email protected]:/root/

3、远程文件/文件夹下载
192.168.62.10上面的/root/文件夹,下载到本地的/home/administrator/Desktop/new/下,使用远程端的root登陆scp -r [email protected]:/root/ /home/administrator/Desktop/new/

 

4.1.6 HADOOP安装部署

  • 上传HADOOP安装包(hadoop-2.6.5.tar.gz)
  • 规划安装目录  /root/
  • 解压安装包:   tar zxvf  hadoop-2.6.5.tar.gz  -C /opt/huawei/
  • 修改配置文件 : vi + /etc/profile  添加之后,使生效: .  /etc/profile
export HADOOP_HOME=/opt/huawei/hadoop-2.6.5

PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

二次配置JAVA_HOME 环境变量,新增;export JAVA_HOME=/usr/java/jdk1.7.0_79/

        vi hadoop-env.sh  
        vi mapred-env.sh 
        vi yarn-env.sh

配置core-site.xml,vi  core-site.xml

<property>
        <name>fs.defaultFS</name>
        <value>hdfs://node02:9000</value>
    </property>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/var/huawei/hadoop/local</value>
    </property>

配置hdfs-site.xml,vi  hdfs-site.xml

<configuration>

<property>

      <name>dfs.namenode.name.dir</name>

      <value>/home/hadoop/data/name</value>

</property>

<property>

     <name>dfs.datanode.data.dir</name>

      <value>/home/hadoop/data/data</value>

</property>

 <property>
        <name>dfs.replication</name>
        <value>1</value>
    </property>
    <property>
        <name>dfs.namenode.secondary.http-address</name>
        <value>node02:50090</value>
    </property>

</configuration>

配置mapred-site.xmlvi  mapred-site.xml

<configuration>

<property>

<name>mapreduce.framework.name</name>

<value>yarn</value>

</property>

</configuration>

 

配置yarn-site.xmlvi  yarn-site.xml

<configuration>

<property>

<name>yarn.resourcemanager.hostname</name>

<value>hadoop01</value>

</property>

 

<property>

<name>yarn.nodemanager.aux-services</name>

<value>mapreduce_shuffle</value>

</property>

</configuration>

配置slaves文件,vi  salves

hdp-node-01

hdp-node-02

hdp-node-03

 

4.1.7 启动集群

初始化HDFS:hdfs namenode -format  (只能格式化一次,再次启动集群不要执行)

启动HDFS:单机启动--sbin/start-dfs.sh ; 集群启动--sbin/start-dfs.sh

启动YARN:sbin/start-yarn.sh

角色进程查看:jps


帮助: hdfs 


hdfs dfs     

查看web UI: IP:50070
     创建目录:hdfs dfs  -mkdir -p  /user/root
     查看目录:  hdfs dfs -ls   /   

      创建文件夹: hdfs dfs -mkdir -p /user/root
     上传文件: hdfs dfs -put  hadoop-2.6.5.tar.gz   /user/root                
     停止集群:stop-dfs.sh


1、上传文件到HDFS4.1.8
测试

从本地上传一个文本文件到hdfs的/wordcount/input目录下

[HADOOP@hdp-node-01 ~]$ HADOOP fs -mkdir -p /wordcount/input

[HADOOP@hdp-node-01 ~]$ HADOOP fs -put /home/HADOOP/somewords.txt  /wordcount/input

 

2、运行一个mapreduce程序

在HADOOP安装目录下,运行一个示例mr程序

cd $HADOOP_HOME/share/hadoop/mapreduce/

hadoop jar mapredcue-example-2.6.1.jar wordcount /wordcount/input  /wordcount/output

 

5 集群使用初步

5.1 HDFS使用

1、查看集群状态:   hdfs dfsadmin -report

命令:  

2、上传文件到HDFS

  • 查看HDFS中的目录信息 :hdfs dfs -ls /  或者    hadoop  fs  –ls  /

  • 上传文件:hdfs dfs -put hadoop-2.6.5.tar.gz /user/root   或者:   hadoop  fs  -put  ./ scala-2.10.6.tgz  to  /    ?
  • 从HDFS下载文件:  hadoop  fs  -get  /yarn-site.xml

 

 

5.2 MAPREDUCE使用

mapreduce是hadoop中的分布式运算编程框架,只要按照其编程规范,只需要编写少量的业务逻辑代码即可实现一个强大的海量数据并发处理程序

5.2.1 Demo开发——wordcount

1、需求

从大量(比如T级别)文本文件中,统计出每一个单词出现的总次数

2、mapreduce实现思路

Map阶段:

  1. 从HDFS的源数据文件中逐行读取数据
  2. 将每一行数据切分出单词
  3. 为每一个单词构造一个键值对(单词,1)
  4. 将键值对发送给reduce

Reduce阶段:

  1. 接收map阶段输出的单词键值对
  2. 将相同单词的键值对汇聚成一组
  3. 对每一组,遍历组中的所有“值”,累加求和,即得到每一个单词的总次数
  4. 将(单词,总次数)输出到HDFS的文件中

3、具体编码实现

(1)定义一个mapper

package cn.lxk.bigdata.mr.wcdemo;

import java.io.IOException;

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

/**
 * KEYIN: 默认情况下,是mr框架所读到的一行文本的起始偏移量,Long,
 * 但是在hadoop中有自己的更精简的序列化接口,所以不直接用Long,而用LongWritable
 * 
 * VALUEIN:默认情况下,是mr框架所读到的一行文本的内容,String,同上,用Text
 * 
 * KEYOUT:是用户自定义逻辑处理完成之后输出数据中的key,在此处是单词,String,同上,用Text
 * VALUEOUT:是用户自定义逻辑处理完成之后输出数据中的value,在此处是单词次数,Integer,同上,用IntWritable
 * 
 *
 */

public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {

	/**
	 * map阶段的业务逻辑就写在自定义的map()方法中 maptask会对每一行输入数据调用一次我们自定义的map()方法
	 */
	@Override
	protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {

		// 将maptask传给我们的文本内容先转换成String
		String line = value.toString();
		// 根据空格将这一行切分成单词
		String[] words = line.split(" ");

		// 将单词输出为<单词,1>
		for (String word : words) {
			// 将单词作为key,将次数1作为value,以便于后续的数据分发,可以根据单词分发,以便于相同单词会到相同的reduce task
			context.write(new Text(word), new IntWritable(1));
		}
	}
}


(2)定义一个reducer

package cn.lxk.bigdata.mr.wcdemo;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

/**
 * KEYIN, VALUEIN 对应 mapper输出的KEYOUT,VALUEOUT类型对应
 * 
 * KEYOUT, VALUEOUT 是自定义reduce逻辑处理结果的输出数据类型 KEYOUT是单词 VLAUEOUT是总次数
 * 
 * @author
 *
 */
public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> {

	/**
	 * <angelababy,1><angelababy,1><angelababy,1><angelababy,1><angelababy,1>
	 * <hello,1><hello,1><hello,1><hello,1><hello,1><hello,1> <banana,1>
	 * <banana,1><banana,1><banana,1><banana,1><banana,1> 入参key,是一组相同单词kv对的key
	 */
	@Override
	protected void reduce(Text key, Iterable<IntWritable> values, Context context)
			throws IOException, InterruptedException {

		int count = 0;
		/*
		 * Iterator<IntWritable> iterator = values.iterator();
		 * while(iterator.hasNext()){ count += iterator.next().get(); }
		 */

		for (IntWritable value : values) {

			count += value.get();
		}
		context.write(key, new IntWritable(count));
	}
}


(3)定义一个主类,用来描述job并提交job

package cn.lxk.bigdata.mr.wcdemo;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

/**
 * 相当于一个yarn集群的客户端 需要在此封装我们的mr程序的相关运行参数,指定jar包 最后提交给yarn
 * 
 * @author
 *
 */
public class WordCountRunner {
	// 把业务逻辑相关的信息(哪个是mapper,哪个是reducer,要处理的数据在哪里,输出的结果放哪里。。。。。。)描述成一个job对象
	// 把这个描述好的job提交给集群去运行
	public static void main(String[] args) throws Exception {
		Configuration conf = new Configuration();
		Job wcjob = Job.getInstance(conf);
		
		// 指定我这个job所在的jar包
		// wcjob.setJar("/home/hadoop/wordcount.jar");
		wcjob.setJarByClass(WordCountRunner.class);
		wcjob.setMapperClass(WordCountMapper.class);
		wcjob.setReducerClass(WordCountReducer.class);
		
		// 设置我们的业务逻辑Mapper类的输出key和value的数据类型
		wcjob.setMapOutputKeyClass(Text.class);
		wcjob.setMapOutputValueClass(IntWritable.class);
		
		// 设置我们的业务逻辑Reducer类的输出key和value的数据类型
		wcjob.setOutputKeyClass(Text.class);
		wcjob.setOutputValueClass(IntWritable.class);
		
		// 指定要处理的数据所在的位置
		FileInputFormat.setInputPaths(wcjob, "hdfs://node02:9000/wordcount/input/test.txt");
		// 指定处理完成之后的结果所保存的位置
		FileOutputFormat.setOutputPath(wcjob, new Path("hdfs://node02:9000/wordcount/output/"));

		// 向yarn集群提交这个job
		boolean res = wcjob.waitForCompletion(true);
		System.exit(res ? 0 : 1);
	}
}


5.2.2 程序打包运行

  1. 将程序打包
  2. 准备输入数据

vi  /home/hadoop/test.txt

cd

Hello tom

Hello jim

Hello ketty

Hello world

Ketty tom

在hdfs上创建输入数据文件夹:

  • hdfs dfs -mkdir -p  /wordcount/input

将words.txt上传到hdfs上

  • hdfs dfs -put  test.txt /wordcount/input

 

  1. 将程序jar包上传到集群的任意一台服务器上
  2. 使用命令启动执行wordcount程序jar包  
  • $ hadoop jar wordcount.jar cn.lxk.bigdata.mr.wcdemo.WordCountRunner /wordcount/input /wordcount/out

 

  1. 查看执行结果

$ hadoop fs -cat /wordcount/output/part-r-00000

猜你喜欢

转载自blog.csdn.net/lixinkuan328/article/details/94839324