hadoop关于hdfs详细解答

  1. HDFS内容

    1. 大数据的概念及其特征
    2. Hadoop简介及其生态圈
    3. HDFS的内部组件介绍
    4. HDFS的安装模式介绍
      • 独立模式
      • 伪分布式模式
      • 完全分布式的搭建
    5. HDFS的常用命令
    6. HDFS的设计思想
    7. HDFS的体系结构
    8. HDFS的工作机制
    9. HDFS的常用API
    10. HDFS的数据流
    11. HA的搭建
  2. 今日目标

2.1 了解部分

- 大数据的概念、特征、应用领域
- Hadoop出现的原因、发展历史、组成架构、生态圈
- HDFS的fsimage和edit的查看方式
- HDFS的快照管理和配额设置
- HDFS的window环境配置
- HDFS的常用API

2.2 掌握部分

- HDFS的内部组件(重要)
- HDFS的三种安装模式
- HDFS的常用命令
- HDFS的块的概念(重要)
- HDSF的体系结构中的四个组件的作用
- HDFS的工作机制(重要)
- HDFS的数据流(重要)

二. 正课内容

第一章:大数据的概述

1.1 大数据的概念

最近几年,IT行业最火的名词中,少不了"大数据"、“人工智能”、“云计算”、“物联网”、"区块链"等等这些名词。针对于"大数据"这个名词,现在更是全国老百姓,老少皆知的一个词语。但是什么是大数据,除了IT行业的专业人士外,其他人乃至其他行业的人,除了能说出"数据量大"之外,好像真的不能再更深层次的解释了。那么我们来看看下面几个权威机构给出的解释。

维基百科 给出的定义:

数据规模巨大到无法通过人工在合理的时间内达到截取,管理,处理并整理成为人类所解读的信息。

麦肯锡全球研究所 给出的定义:

一种规模大到在获取、存储、管理、分析方面都大大超出了传统数据库软件工具能力范围的数据集合。

研究机构 高德纳(Gartner)给出的定义:

"大数据"是需要新的处理模式才能具有更强的决策力、洞察发现力和流程优化能力来适应海量、高增长率和多样化的信息资产

概念总结:

海量数据,具有高增长率、数据类型多样化、一定时间内无法使用常规软件工具进行捕捉、管理和处理的数据集合。 

1.2 大数据的特征

早在1980年,著名未来学家托夫勒在其所著的《第三次浪潮》中就热情地将“大数据”称颂为“第三次浪潮的华彩乐章”。《自然》杂志在2008年9月推出了名为“大数据”的封面专栏。从2009年开始“大数据”才成为互联网技术行业中的热门词汇。最早应用“大数据”的是世界著名的管理咨询公司麦肯锡公司,它看到了各种网络平台记录的个人海量信息具备潜在的商业价值,于是投入大量人力物力进行调研, 对“大数据”进行收集和分析的设想,在2011年6月发布了关于“大数据”的报告,该报告对“大数据”的影响、关键技术和应用领域等都进行了详尽的分析。麦肯锡的报告得到了金融界的高度重视,而后逐渐受到了各行各业关注。 那么大数据到底有什么特征呢?我们怎么去理解大数据呢?有专业人士总结了4V说法,也有相关机构总结了5V说法,甚至6V说法。不管哪种说法,下面四个特征,是大家普遍认可的。

1. Volume:巨大的数据量				
2. Variety:数据类型多样化
	--(1):结构化的数据
		即有固定格式和有限长度的数据。
	--(2):半结构化的数据
		是一些XML或者HTML的格式的数据。
	--(3):非结构化的数据
		现在非结构化的数据越来越多,就是不定长、无固定格式的数据,例如网页、语音,视频等。
3. Velocity: 数据增长速度快
4. Value:价值密度低

1.3 大数据的应用场景

有不了解大数据的人会问:大数据能做啥?问的好。

大数据本身是一个抽象的概念, 对当前无论是企业还是政府、或是高校等单位来说,是一个面临着数据无法存储、无法计算的状态的形容词。

那么大数据可以做什么呢?

在海量的各种各样类型的价值密度低的数据中,我们要进行的是:数据采集,数据存储,数据清洗,数据分析,数据可视化。

简单一句话,就是大数据让数据产生各种"价值"。可以说,大数据的核心作用就是"数据价值化",这个过程就是大数据要做的主要事情。那么就可以概括成:

- 记录已经发生的一切
- 描述正在发生的一切
- 预测将要发生的一切

大数据技术的战略意义不在于掌握庞大的数据信息,而在于对这些含有意义的数据进行专业化处理。

现在已经应用"大数据"的案例有:

- 预测犯罪
- 预测流感的爆发
- 预测选举
- 根据手机定位和交通数据,规划城市
- 根据库存和需求,实时调价
- 推动医疗信息化发展,远程医疗

1.4 大数据的发展前景

大数据技术目前正处在落地应用的初期,从大数据自身发展和行业发展的趋势来看,大数据未来的前景还是不错的,具体原因有以下几点:

- 大数据本身的价值体现,
	本身的数据价值化就会开辟出很大的市场空间。目前在互联网领域,大数据技术已经得到了较为广泛的应用。 大数据造就了新兴行业
	
- 大数据推动了科技领域的发展
	不仅体现在互联网领域,还体现在金融、教育、医疗等诸多领域,尤其是现在的人工智能。
	
- 大数据产业链的形成
	经过近些年的发展,大数据已经初步形成了一个较为完整的产业链,包括数据采集、整理、传输、存储、分析、呈现和应用,众多企业开始参与到大数据产业链中,并形成了一定的产业规模,相信随着大数据的不断发展,相
	关产业规模会进一步扩大。
	
- 国家大力扶持大数据行业的发展

1.5 企业大数据的一般工作流程

1.5.1 数据源

数据的来源有如下内容:
- 关系型数据库(业务数据)
	* 各种关系表,如订单表、账号表、基本信息表
- 日志文件
	* 用户行为数据(行为数据)
	* 浏览了哪些页面(网页、App、电视机顶盒),导航栏上的哪些选项等等(内容数据)
- 三方数据
    * 第三方的接口提供数据
    * 爬虫等

1.5.2 数据采集或者同步

常用数据采集导入框架:
- sqoop:
	用于RDBMS与HDFS之间数据导入与导出
- flume:
	采集日志文件数据,动态采集日志文件,数据流
	flume采集到的数据,一份给HDFS,用于做离线分析;一份给Kafka,实时处理
- kafka:
	主要用于实时的数据流处理
 	flume与kafka都有类似消息队列的机制,来缓存大数据环境处理不了的数据

1.5.3 数据存储

常用数据存储框架
- HDFS、 HBase、ES

1.5.4 数据清洗

即对数据进行过滤,得到具有一定格式的数据源

常用框架(工具):MapReduce、Hive(ETL)、SparkCore、sparksql等

1.5.5 数据分析

对经过数据清洗后的数据进行分析,得到某个指标

常用框架(工具):MapReduce、Hive、SparkSQL、impala(impa:le)、kylin

1.5.6 数据展示

即将数据分析后的结果展示出来,也可以理解为数据的可视化、以图或者表具体的形式展示出来

常用工具:
metastore、Javaweb、hcharts、echarts

1.6 数据部门的组织架构
管理层:数据部门,运营部门…
数据部门:运维组(hadoop等软件的搭建,集群性能监控,性能优化),数据仓库组(ETL工程师,数据清洗等),数据研发组(算法工程师,推荐系统工程师),可视化组

1.7 云计算的概念(选讲)

1)概念

云计算是以虚拟技术为核心,进行统一管理硬件设施,平台,软件等;它通过网络提供了可伸缩的、廉价的分布式计算能力;它用出租的方式提供给用户,用户只要花低价,在具备网络接入条件的地方,就可以随时随地获得所需的各种IT资源;类似于国家统一管理水,电,煤气等等。

2)云计算的种类

- 公有云:公有云面向所有用户提供服务,只要是注册付费的用户都可以使用
- 私有云:私有云只为特定用户提供服务
- 混合云:混合云综合了公有云和私有云的特点

3)服务的种类

-1. IaaS(基础设施即服务):IaaS将基础设施(计算资源和存储)作为服务出租。

在这种服务模型中,普通用户不用自己构建一个数据中心等硬件设施,而是通过租用的方式,利用 Internet从IaaS服务提供商获得计算机基础设施服务,包括服务器、存储和网络等服务。

举个例子:假如你现在要做一个网站,你肯定要有一台服务器或者虚拟机,要么自己搭建,要么买服务器运营商的。说白了,IaaS就是解决企业硬件问题的,包括服务器、存储设备、网络设备等基础设施。基础设施有了,你就可以搭建环境了。

-2. PaaS(平台即服务):PaaS把平台作为服务出租

举个例子:假如你现在要做一个网站,你不想自己买服务器搭环境,你就直接购买别人的PaaS服务。PaaS一般会为企业解决硬件的租赁问题,以及操作系统的选装,开发测试环境的搭建,及各种编程语言的选装等,提供一个运行的直接用的软件平台。有了PaaS你就可以在上面做开发工作了,当然,一些别的程序及软件还得你自己安装配置。

-3. SaaS(软件即服务)。SaaS把软件作为服务出租。

举个例子:你现在想做一个网站,你不会做,你只要购买别人的成熟软件,配置几下就能使用了。说白了就是卖软件的,你不用租用服务器,开发软件等费时间的工作,你直接购买别人的软件通过互联网就能使用,也不需要本地安装,也就是软件即服务的意思,你出钱,别人出软件服务。

4)云计算的关键技术

-1. 虚拟化

云计算的核心技术之一就是虚拟化技术。所谓虚拟化,是指通过虚拟化技术将一台计算机虚拟为多台逻辑计算机。在一台计算机上同时运行多个逻辑计算机,每个逻辑计算机可运行不同的操作系统,并且应用程序都可以在相互独立的空间内运行而互不影响,从而显著提高计算机的工作效率。

虚拟化的核心软件VMM,是一种运行在物理服务器和操作系统之间的中间层软件。VMM是一种在虚拟环境中的“元”操作系统。他们可以访问服务器上包括CPU、内存、磁盘、网卡在内的所有物理设备。VMM不但协调着这些硬件资源的访问,也同时在各个虚拟机之间施加防护。当服务器启动并执行VMM时,它会加载所有虚拟机客户端的操作系统同时会分配给每一台虚拟机适量的内存,CPU,网络和磁盘。

-2. 分布式存储

云计算的另一大优势就是能够快速、高效地处理海量数据。在数据爆炸的今天,这一点至关重要。为了保证数据的高可靠性,云计算通常会采用分布式存储技术,将数据存储在不同的物理设备中。这种模式不仅摆脱了硬件设备的限制,同时扩展性更好,能够快速响应用户需求的变化。

分布式存储与传统的网络存储并不完全一样,传统的网络存储系统采用集中的存储服务器存放所有数据,存储服务器成为系统性能的瓶颈,不能满足大规模存储应用的需要。分布式网络存储系统采用可扩展的系统结构,利用多台存储服务器分担存储负荷,利用位置服务器定位存储信息,它不但提高了系统的可靠性、可用性和存取效率,还易于扩展。

在当前的云计算领域,Google的GFS和Hadoop开发的开源系统HDFS是比较流行的两种云计算分布式存储系统。

GFS(GoogleFileSystem)技术:谷歌的非开源的GFS(GoogleFileSystem)云计算平台满足大量用户的需求,并行地为大量用户提供服务。使得云计算的数据存储技术具有了高吞吐率和高传输率的特点。

HDFS(HadoopDistributedFileSystem)技术:大部分ICT厂商,包括Yahoo、Intel的“云”计划采用的都是HDFS的数据存储技术。未来的发展将集中在超大规模的数据存储、数据加密和安全性保证、以及继续提高I/O速率等方面
-3. 分布式计算
	问题分解为若干小问题,分配给各个计算机再综合起来
-4. 多租户

1.8 物联网的概念(选讲)

1.8.1 概念

物联网是物物相连的互联网,是互联网的延伸,它利用局部网络或互联网等通信技术把传感器、控制器、机器、
人员和物等通过新的方式连在一起,形成人与物、物与物相连,实现信息化和远程管理控制。

1.8.2 物联网关键技术

物联网是物与物相连的网络,通过为物体加装二维码、RFID标签、传感器等,就可以实现物体身份唯一标识和各
种信息的采集,再结合各种类型网络连接,就可以实现人和物、物和物之间的信息交换。因此,物联网中的关键
技术包括识别和感知技术(二维码、RFID、传感器等)、网络与通信技术、数据挖掘与融合技术等。

1.8.3 扩展

射频识别(RFID)是 Radio Frequency Identification 的缩写。
其原理为阅读器与标签之间进行非接触式的数据通信,达到识别目标的目的。RFID 的应用非常广泛,典型应用有动物晶片、汽车晶片防盗器、门禁管制、停车场管制、生产线自动化、物料管理。

1.9 大数据与云计算、物联网的关系(选讲)

云计算、大数据和物联网代表了IT领域最新的技术发展趋势,三者既有区别又有联系。从云计算和大数据概念的诞生到现在,二者之间的关系非常微妙,既密不可分,又千差万别。因此,我们不能把云计算和大数据割裂开来作为截然不同的两类技术来看待。此外,物联网也是和云计算、大数据相伴相生的技术。

1.9.1 大数据、云计算和物联网的区别。

- 大数据侧重于对海量数据的存储、处理与分析,从海量数据中发现价值,服务于生产和生活;
- 云计算本质上旨在整合和优化各种IT资源并通过网络以服务的方式,廉价地提供给用户;
- 物联网的发展目标是实现物物相连,应用创新是物联网发展的核心。

1.9.2 大数据、云计算和物联网的联系。

从整体上看,大数据、云计算和物联网这三者是相辅相成的。

	物联网的传感器源源不断产生的大量数据,构成了大数据的重要数据来源,没有物联网的飞速发展,就不会带来
	数据产生方式的变革,即由人工产生阶段转向自动产生阶段,大数据时代也不会这么快就到来。同时,物联网需
	要借助于云计算和大数据技术,实现物联网大数据的存储、分析和处理。

第二章:hadoop概述

2.1 为什么要用hadoop

现在的我们,生活在数据大爆炸的年代。国际数据公司已经预测在2020年,全球的数据总量将达到44ZB,经过单位换算后,至少在440亿TB以上,也就是说,全球每人一块1TB的硬盘都存储不下。

扩展:数据大小单位:Byte,KB,MB,GB,TB,PB,EB,ZB,YB,DB,NB

一些数据集的大小更远远超过了1TB,也就是说,数据的存储是一个要解决的问题。同时,硬盘技术也面临一个技术瓶颈,就是硬盘的传输速度(读数据的速度)的提升远远低于硬盘容量的提升。

年份硬盘大小传输速率所需时间
19901370MB4.4MB/s5分钟
20101TB100MB/s3小时

可以看到,容量提升了将近1000倍,而传输速度才提升了20倍,读完一个硬盘的所需要的时间相对来说,更长更久了(已经违反了数据价值的即时性)。读数据都花了这么长时间,更不用说写数据了。

对于如何提高读取数据的效率,我们已经想到解决的方法了,那就是将一个数据集存储到多个硬盘里,然后并行读取。比如1T的数据,我们平均100份存储到100个1TB硬盘上,同时读取,那么读取完整个数据集的时间用不上两分钟。至于硬盘剩下的99%的容量,我们可以用来存储其他的数据集,这样就不会产生浪费。解决读取效率问题的同时,我们也解决了大数据的存储问题。

但是,我们同时对多个硬盘进行读/写操作时,又有了新的问题需要解决:

1、硬件故障问题。一旦使用多个硬件,相对来说,个别硬件产生故障的几率就高,为了避免数据丢失,最常见的做法就是复制(replication):文件系统保存数据的多个复本,一旦发生故障,就可以使用另外的复本。

2、读取数据的正确性问题。大数据时代的一个分析任务,就需要结合大部分数据来共同完成分析,因此从一个硬盘上读取的数据要与从其他99个硬盘上读取的数据结合起来使用。那么,在读取过程中,如何保证数据的正确性,就是一个很大的挑战。

针对于上述几个问题,Hadoop为我们提供了一个可靠的且可扩展的存储和分析平台,此外,由于Hadoop运行在商用硬件上且是开源的,因此Hadoop的使用成本是比较低了,在用户的承受范围内。

2.2 Hadoop的简要介绍

Hadoop是Apache基金会旗下一个开源的分布式存储和分析计算平台,使用java语言开发,具有很好的跨平台性,可以运行在商用(廉价)硬件上,用户无需了解分布式底层细节,就可以开发分布式程序,充分使用集群的高速计算和存储

Apache lucene是一个应用广泛的文本搜索系统库。该项目的创始人道格·卡丁在2002年带领团队开发该项目中的子项目Apache Nutch,想要从头打造一个网络搜索引擎系统,在开发的过程中,发现了两个问题,一个是硬件的高额资金投入,另一个是存储问题。

2003年和2004年Google先后发表的《GFS》和《MapReduce》论文,给这个团队提供了灵感,并进行了实现,于是NDFS(Nutch分布式文件系统)和MapReduce相继问世。2006年2月份,开发人员将NDFS和MapReduce移出Nutch形成一个独立的子项目,命名为Hadoop(该名字据Doug Cutting所说,是借用了他的孩子给毛绒玩具取得名字)。

2.3 谷歌的三篇论文

- 2003年发表的《GFS》
	基于硬盘不够大、数据存储单份的安全隐患问题,提出的分布式文件系统用于存储的理论思想。
	· 解决了如何存储大数据集的问题

- 2004年发表的《MapReduce》
 	基于分布式文件系统的计算分析的编程框架模型。移动计算而非移动数据,分而治之。
	· 解决了如何快速分析大数据集的问题

- 2006年发表的《BigTable》
	针对于传统型关系数据库不适合存储非结构化数据的缺点,提出了另一种适合存储大数据集的解决方案

2.4 Hadoop的发展历史

起源于Apache 的Nutch项目
2004年,Nutch开发者开始着手NDFS
2005年,开发人员将NDFS和MapReduce移出Nutch项目,形成一个子项目命名叫做Hadoop

2.5 Hadoop的版本介绍

Hadoop是Apache的一个开源项目,所以很多公司在这个基础上都进行了商业化,加入了自己的特色。Hadoop的发行版中除了有Apache社区提供的hadoop之外,比较出名的公司如cloudera,hortonworks,mapR,华为,DKhadoop等都提供了自己的商业版本,主要是大型公司提供更为专业的技术支持,多数都收费。

- Apache Hadoop(社区版): 原生的Hadoop、开源、免费、社区活跃,更新速度快,适合学习阶段
- Cloudera Hadoop(CDH版):最成型的商业发行版本。有免费版和收费版本。版本划分清晰,版本更新速度快,对生态圈的其他软件做了很好的兼容性,安全性、稳定性都有增强。支持多种安装方式(Cloudera Manager、YUM、RPM、Tarball)
- Hortonworks Hadoop(HDP):完全开源,安装方便,提供了直观的用户安装界面和配置工具

2.6 Hadoop的官网介绍

2.6.1 apache官网地址和如何进入项目列表

2.6.2 找到Hadoop项目

2.6.3 Hadoop的模块和生态圈

2.6.4 Hadoop的历史版本入口

2.6.5 找到Hadoop2.7.6,以及文档入口

2.6.6 老版本官网入口

2.7 Hadoop的组成部分

hadoop2.0以后的四个模块:
    - Hadoop Common:Hadoop模块的通用组件
    - Hadoop Distributed File System:分布式文件系统
    - Hadoop YARN:作业调度和资源管理框架
    - Hadoop MapReduce:基于YARN的大型数据集并行计算处理框架

hadoop3.0新扩展的两个模块:
    - Hadoop Ozone:Hadoop的对象存储机制
    - Hadoop Submarine:Hadoop的机器学习引擎

2.8 Hadoop的生态系统

参考apache官网:http://hadoop.apache.org/

--1. Hbase
	是一个可扩展的分布式数据库,支持大型表格的结构化数据存储。 HBase是Apache的Hadoop项目的子项目。HBase不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库。另一个不同的是HBase基于列的,而不是基于行的模式。

--2. Hive
	数据仓库基础架构,提供数据汇总和临时查询,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。Hive提供的是一种结构化数据的机制,定义了类似于传统关系数据库中的类SQL语言:Hive QL,通过该查询语言,数据分析人员可以很方便地运行数据分析
业务。
--3. Spark
	Hadoop数据的快速和通用计算引擎。 Spark提供了一个简单而富有表现力的编程模型,支持广泛的应用程序,包括ETL,机器学习,流处理和图计算。
	
--4. ZooKeeper
	一个面向分布式应用程序的高性能协调服务,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
	
--5. Sqoop(数据ETL/同步工具)
	Sqoop是SQL-to-Hadoop的缩写,主要用于传统数据库和Hadoop之前传输数据。数据的导入和导出本质上是Mapreduce程序,充分利用了MR的并行化和容错性。

--6. Flume(日志收集工具)
	Cloudera开源的日志收集系统,具有分布式、高可靠、高容错、易于定制和扩展的特点。它将数据从产生、传输、处理并最终写入目标的路径的过程抽象为数据流,在具体的数据流中,数据源支持在Flume中定制数据发送方,从而支持收集各种不同协议数据。同时,Flume数据流提供对日志数据进行简单处理的能力,如过滤、格式转换等。
	
--7. Kafka(分布式消息队列)
	Kafka是Linkedin于2010年12月份开源的消息系统,它主要用于处理活跃的流式数据。这些数据包括网站的pv、用户访问了什么内容,搜索了什么内容等。这些数据通常以日志的形式记录下来,然后每隔一段时间进行一次统计处理。
    
--8. Ambari
	用于供应,管理和监控Apache Hadoop集群的基于Web的工具。Ambari目前已支持大多数Hadoop组件,包括HDFS、MapReduce、Hive、Pig、 Hbase、Zookeper、Sqoop和Hcatalog等。Ambari还提供了一个用于查
看集群健康状况的仪表板,例如热图以及可视化查看MapReduce,Pig和Hive应用程序的功能以及用于诊断其性能特征的功能,以方便用户使用。

--9. Avro
  	数据序列化系统。可以将数据结构或者对象转换成便于存储和传输的格式,其设计目标是用于支持数据密集型应用,适合大规模数据的存储与交换。Avro提供了丰富的数据结构类型、快速可压缩的二进制数据格式、存储持久性数据的文件集、远程调用RPC和简单动态语言集成等功能。

--10. Cassandra
	可扩展的多主数据库,没有单点故障。是一套开源分布式NoSQL数据库系统。

--11. Chukwa
	于管理大型分布式系统的数据收集系统(2000+以上的节点, 系统每天产生的监控数据量在T级别)。它构建在Hadoop的HDFS和MapReduce基础之上,继承了Hadoop的可伸缩性和鲁棒性。Chukwa包含一个强大和灵活的工具集,提供了数据的生成、收集、排序、去重、分析和展示等一系列功能,是Hadoop使用者、集群运营人员和管理人员的必备工具。

--12. Mahout
	Apache旗下的一个开源项目,可扩展的机器学习和数据挖掘库

--13. Pig
	用于并行计算的高级数据流语言和执行框架。它简化了使用Hadoop进行数据分析的要求,提供了一个高层次的、面向领域的抽象语言:Pig Latin。

--14. Tez
	一个基于Hadoop YARN的通用数据流编程框架,它提供了一个强大而灵活的引擎,可执行任意DAG任务来处理批处理和交互式用例的数据Hado™生态系统中的Hive™,Pig™和其他框架以及其他商业软件(例如ETL工具)正在采用Tez,以替代Hadoop™MapReduce作为底层执行引擎。 

--15. Oozie(工作流调度器)
	一个可扩展的工作体系,集成于Hadoop的堆栈,用于协调多个MapReduce作业的执行。它能够管理一个复杂的系统,基于外部事件来执行,外部事件包括数据的定时和数据的出现。

--16. Pig(ad-hoc脚本)
	由yahoo!开源,设计动机是提供一种基于MapReduce的ad-hoc(计算在query时发生)数据分析工具,通常用于进行离线分析。它定义了一种数据流语言—Pig Latin,它是MapReduce编程的复杂性的抽象,Pig平台包括运行环境和用于分析Hadoop数据集的脚本语言(Pig Latin)。

2.9 Hadoop的编译

参考本文最下面的附件1

第三章:安装模式之本地模式

说明:
HDFS的安装模式有三种:
-1. 本地模式(独立模式)
-2. 伪分布式模式
-3. 完全分布式模式(实际生产环境使用)

3.1 本地模式介绍

3.1.1 特点:

运行在单台机器上,没有分布式思想,使用的是本地文件系统

3.1.2. 用途

用于对MapReduce程序的逻辑进行调试,确保程序的正确。由于在本地模式下测试和调试MapReduce程序较为方便,因此,这种模式适宜用在开发阶段。

3.2 平台软件说明

- 操作系统: 		win10/win7
- 虚拟软件:			VMware14
- 虚拟机:			 主机名:hadoop01			ip:192.168.10.101
- 上传路径:	  		/root
- 软件安装路径:	   /usr/local
- Jdk:			   jdk-8u221-linux-x64.tar.gz
- Hadoop:		   hadoop-2.7.6.tar.gz
- 用户:			 root

3.3 环境搭建:Jdk的安装步骤

步骤1)检查一下是否已经安装过或者系统内置JDK,如果有内置的,将其卸载

[root@hadoop01 ~]# rpm -qa | grep jdk     #如果有,请卸载
[root@hadoop01 ~]# rpm -e xxxxxxxx --nodeps      #将查询到的内置jdk强制卸载

步骤2)上传jdk1.8

将jdk-8u221-linux-x64.tar.gz上传到/root目录中

步骤3)解压jdk到/usr/local/下

[root@hadoop01 ~]# tar -zxvf jdk-8u221-linux-x64.tar.gz -C /usr/local

步骤4)更名jdk

[root@hadoop01 ~]# cd /usr/local
[root@hadoop01 local]# mv jdk1.8.0_221/  jdk

步骤5)配置Jdk的环境变量:/etc/profile

[root@hadoop01 local]# vi /etc/profile
.........省略...........
#jdk environment
export JAVA_HOME=/usr/local/jdk
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH

步骤6)使当前窗口生效

[root@hadoop01 local]# source /etc/profile

步骤7)验证jdk环境

[root@hadoop01 local]# java -version
[root@hadoop01 local]# javac	

3.4 hadoop目录结构说明

3.4.1 Hadoop目录结构如下:(可以提前在window系统上解压,看一下)

--1. bin: 			hadoop的二进制执行命令文件存储目录
--2. sbin: 			hadoop的执行脚本存储目录
--3. etc: 			hadoop的配置文件存储目录
--4. lib/libexec:	hadoop的资源库存储目录
--5. share:			hadoop的共享资源、开发工具和案例存储目录
--6. include:		hadoop的工具脚本存储目录

3.5 环境搭建:Hadoop的安装步骤

步骤1) 上传并解压hadoop

将hadoop软件包上传到/root目录下,然后解压到/usr/local/目录下
[root@hadoop01 ~]# tar -zxvf hadoop-2.7.6.tar.gz -C /usr/local/

步骤2)更名hadoop

[root@hadoop01 ~]# cd /usr/local
[root@hadoop01 local]# mv hadoop-2.7.6/ hadoop

步骤3)配置hadoop的环境变量

[root@hadoop01 local]# vi /etc/profile
.........省略..........
#hadoop environment
export HADOOP_HOME=/usr/local/hadoop
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH

步骤4)使当前窗口生效

[root@hadoop01 local]# source /etc/profile

步骤5)验证hadoop

[root@hadoop01 local]# hadoop version

3.6 程序案例演示:grep程序

步骤1) 进入hadoop的根目录

[root@hadoop01 local]# cd $HADOOP_HOME

步骤2) 创建一个目录/input

[root@hadoop01 hadoop]# mkdir input

步骤3) 将$HADOOP_HOME/etc/hadoop/目录下的所有xml文件复制到input目录下

[root@hadoop01 hadoop]# cp ./etc/hadoop/*.xml ./input

步骤4) 使用hadoop自带的grep程序查找input目录下的文件是否有符合正则表达式’dfs[a-z.]'的字符串

[root@hadoop01 hadoop]#	hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.6.jar grep input ./output 'dfs[a-z.]'

命令行内容解析:
--1. 使用hadoop命令运行jar文件
--2. 同时指定具体的jar文件的路径
--3. 使用jar文件里的grep主程序
--4. 统计当前目录下的input目录里的内容,
--5. 将统计结果输出到当前目录下的output目录
--6. 给grep指定一个正则表达式

注意:输出目录是一个不存在的目录,程序会自动生成

步骤5) 进入output目录查看part-r-00000文件

[root@hadoop01 hadoop]# cd ./output
[root@hadoop01 output]# cat part-r-00000

3.7 案例测试_wordcount.

[root@hadoop01 hadoop]#  hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.6.jar wordcount input ./output1

第四章:安装模式之伪分布式集群

4.1 伪分布式模式介绍

1.特点
	- 在一台机器上安装,使用的是分布式思想,即分布式文件系统,非本地文件系统。
	- Hdfs涉及到的相关守护进程(namenode,datanode,secondarynamenode)都运行在一台机器上,都是独立的java进程。
2. 用途
	比Standalone mode 多了代码调试功能,允许检查内存使用情况,HDFS输入输出,以及其他的守护进程交
	互。

4.2 平台软件说明

- 操作系统: 		win10/win7
- 虚拟软件:			VMware14
- 虚拟机:			 主机名:hadoop01			ip:192.168.10.101
- 软件包存储路径:	  ~
- 软件安装路径:	   /usr/local/	
- Jdk:			   jdk-8u221-linux-x64.tar.gz
- Hadoop:		   hadoop-2.7.6.tar.gz
- 用户:			  root

4.3 伪分布式环境需求及搭建

4.3.1 环境需求:

--1. 确保防火墙是关闭的.
--2. NAT模式和静态IP的确定 (192.168.10.101)
--3. 确保/etc/hosts文件里 ip和hostname的映射关系
--4. 确保免密登陆localhost有效
--5. jdk和hadoop的环境变量配置

4.3.2 防火墙关闭确认

[root@hadoop01 ~]# systemctl stop firewalld
[root@hadoop01 ~]# systemctl disable firewalld.service
[root@hadoop01 ~]# systemctl stop NetworkManager
[root@hadoop01 ~]# systemctl disable NetworkManager

#最好也把selinux关闭掉,这是linux系统的一个安全机制,进入文件中将SELINUX设置为disabled
[root@hadoop01 ~]# vi /etc/selinux/config
.........
SELINUX=disabled			
.........

4.3.3 配置/etc/hosts文件

-- 进入hosts文件,配置一下ip和hostname
[root@hadoop01 ~]# vi /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.10.101 hadoop01     <====添加本机的静态IP和本机的主机名之间的映射关系      

4.3.4 确保ssh对localhost的免密登陆认证有效

-1. 使用rsa加密技术,生成公钥和私钥。一路回车即可
[root@hadoop01 ~]# ssh-keygen -t rsa				
-2. 进入~/.ssh目录下,使用ssh-copy-id命令
[root@hadoop01 .ssh]# ssh-copy-id  root@localhost
-3. 进行验证,去掉第一次的询问(yes/no)
[hadoop@hadoop01 .ssh]# ssh localhost

4.3.5 安装Jdk和Hadoop,配置相关环境变量

-1. 上传和解压两个软件包
[root@hadoop01 ~]# tar -zxvf jdk-8u221-linux-x64.tar.gz -C /usr/local/
[root@hadoop01 ~]# tar -zxvf hadoop-2.7.6.tar.gz -C /usr/local/

-2. 进入local里,给两个软件更名
[root@hadoop01 ~]# cd /usr/local/
[root@hadoop01 local]# mv 1.8.0_221/  jdk
[root@hadoop01 local]# mv hadoop-2.7.6/ hadoop

-3. 配置环境变量
[hadoop@hadoop01 local]# vi /etc/profile

.....省略...........

#java environment
export JAVA_HOME=/usr/local/jdk
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH

#hadoop environment
export HADOOP_HOME=/usr/local/hadoop
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH

4.4 伪分布式相关文件的配置

4.4.1 core-site.xml的配置

[root@hadoop01 ~]# cd $HADOOP_HOME/etc/hadoop
[root@hadoop01 hadoop]# vi core-site.xml

<configuration>
    <!-- 配置分布式文件系统的schema和ip以及port,默认8020-->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://localhost/</value>
    </property>
</configuration>
	
扩展: hadoop1.x的默认端口是9000,hadoop2.x的默认端口是8020,使用哪一个都可以

4.4.2 hdfs-site.xml的配置:

[root@hadoop01 hadoop]# vi hdfs-site.xml
<configuration>
    <!-- 配置副本数,注意,伪分布模式只能是1。-->
    <property>
        <name>dfs.replication</name>
        <value>1</value>
    </property>
</configuration>

4.4.3 hadoop-env.sh的配置:指定jdk的环境

[root@hadoop01 hadoop]# vi hadoop-env.sh
................
# The java implementation to use.
export JAVA_HOME=/usr/local/jdk
..................

4.5 格式化NameNode

4.5.1 格式化命令

[root@hadoop01 hadoop]# hdfs namenode -format

4.6 启动HDFS

4.6.1 启动伪分布式

[root@hadoop01 hadoop]# start-dfs.sh

4.6.2 jps命令查看守护进程

从上图我们可以看到,启动脚本会开启分布式文件系统上的相关进程:

namenode
datanode
secondarynamenode

4.7 WebUI_50070

可以在浏览器上输入:192.168.10.101:50070 来查看一下伪分布式集群的信息
--1. 浏览一下页面上提示的ClusterID,BlockPoolID
--2. 查看一下活跃节点(Live Nodes)的个数,应该是1个

Compiled:编译     hadoop是由kshvachk工具集成的
Cluster ID:集群id
Block Pool ID:datanode节点的block池的id,每个datanode节点的都要一样

4.8 程序案例演示:wordcount程序

4.8.1 准备要统计的两个文件,存储到/root/data/下

--1. 创建data目录
[root@hadoop01 hadoop]# mkdir ~/data
--2. 将以下两个文件上传到data目录下
- poetry1.txt
- poetry2.txt 

4.8.2 在hdfs上创建存储目录

[root@hadoop01 hadoop]# hdfs dfs -mkdir /input

4.8.3 将本地文件系统上的上传到hdfs上,并在web上查看一下

[root@hadoop01 hadoop]$ hdfs dfs -put ~/data/poetry* /input/

4.8.4 运行自带的单词统计程序wordcount

[root@hadoop01 hadoop]# cd $HADOOP_HOME
[root@hadoop01 hadoop]# hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.6.jar  wordcount /input /out

4.8.5 查看webui

4.8.6 查看part-r-00000文件

[root@hadoop01 hadoop]# hdfs dfs -cat /out/part-r-00000

第五章:安装模式之完全分布式集群(重点)

5.1 完全分布式模式介绍

完全分布式,指的是在真实环境下,使用多台机器,共同配合,来构建一个完整的分布式文件系统。
在真实环境中,hdfs中的相关守护进程也会分布在不同的机器中,比如:
-1. namenode守护进程尽可能的单独部署在一台硬件性能相对来说比较好的机器中。
-2. 其他的每台机器上都会部署一个datanode守护进程,一般的硬件环境即可。
-3. secondarynamenode守护进程最好不要和namenode在同一台机器上。

5.2 平台软件说明

- 操作系统: 		win10/win7
- 虚拟软件:			VMware14
- 虚拟机:			 
					主机名     	IP
					hadoop01		192.168.10.101
                  	hadoop02		192.168.10.102
                  	hadoop03		192.168.10.103
- 软件包存储路径:	  /root/
- 软件安装路径:	   /usr/local/	
- Jdk:			   jdk-8u221-linux-x64.tar.gz
- Hadoop:		   hadoop-2.7.6.tar.gz
- 用户:			  root

切记,切记,切记:
实际生产环境中,我们不会使用root用户来搭建和管理hdfs,而是使用普通用户。这里为了方便学习,我们才使用的root用户。

注意,注意,注意:
1.如果你是从伪分布式过来的,最好先把伪分布式的相关守护进程关闭:stop-all.sh
2.删除原来伪分布式的相关设置
如果原来使用的是默认路径,现在已经没有用了
如果原来使用的跟现在全分布式路径一样,因为这里跟之前的初始化的内容不一样,而且这个文件要让系统自动生成
综上:要删除掉namenode和datanode的目录

5.3 守护进程布局

我们搭建hdfs的完全分布式,顺便搭建一下yarn。hdfs和yarn的相关守护进程的布局如下:

hadoop01:	namenode,datanode,ResourceManager,nodemanager
hadoop02:	datanode,nodemanager,secondarynamenode
hadoop03:	datanode,nodemanager

5.4 完全分布式环境需求和搭建(重点)

5.4.1 环境需求说明:

时间同步:

[root@hadoop01 ~]#ntpdate ntp1.aliyun.com

s

-1. 三台机器的防火墙必须是关闭的.
-2. 确保三台机器的网络配置畅通(NAT模式,静态IP,主机名的配置)
-3. 确保/etc/hosts文件配置了ip和hostname的映射关系
-4. 确保配置了三台机器的免密登陆认证(克隆会更加方便)
-5. 确保所有机器时间同步
-6. jdk和hadoop的环境变量配置

5.4.2 关闭防火墙

[root@hadoop01 ~]# systemctl stop firewalld
[root@hadoop01 ~]# systemctl disable firewalld
[root@hadoop01 ~]# systemctl stop NetworkManager
[root@hadoop01 ~]# systemctl disable NetworkManager

#最好也把selinux关闭掉,这是linux系统的一个安全机制,进入文件中将SELINUX设置为disabled
[root@hadoop01 ~]# vi /etc/selinux/config
.........
SELINUX=disabled			
.........

情况说明: 如果安装好三台机器,三台机器的防火墙都需要单独关闭和设置开机不启动。如果准备使用克隆方式,只关闭hadoop01机器即可。下面的配置也是如此。

5.4.3 静态IP和主机名配置

--1. 配置静态IP(确保NAT模式)
[root@hadoop01 ~]# vi /etc/sysconfig/network-scripts/ifcfg-ens33
............
BOOTPROTO=static			#将dhcp改为static
............
ONBOOT=yes					#将no改为yes
IPADDR=192.168.10.101		#添加IPADDR属性和ip地址
PREFIX=24					#添加NETMASK=255.255.255.0或者PREFIX=24	
GATEWAY=192.168.10.2		#添加网关GATEWAY
DNS1=114.114.114.114         #添加DNS1和备份DNS
DNS2=8.8.8.8

--2. 重启网络服务
[root@hadoop01 ~]# systemctl restart network
或者
[root@hadoop01 ~]# service network restart

--3. 修改主机名(如果修改过,请略过这一步)
[root@localhost ~]# hostnamectl set-hostname hadoop01
或者
[root@localhost ~]# vi /etc/hostname
hadoop01

注意:配置完ip和主机名后,最好reboot一下

5.4.4 配置/etc/hosts文件

[root@hadoop01 ~]#  vi /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.10.101 hadoop01  #添加本机的静态IP和本机的主机名之间的映射关系 
192.168.10.102 hadoop02
192.168.10.103 hadoop03

5.4.5 免密登陆认证

-1. 使用rsa加密技术,生成公钥和私钥。一路回车即可
[root@hadoop01 ~]# cd ~
[root@hadoop01 ~]# ssh-keygen -t rsa	

-2. 进入~/.ssh目录下,使用ssh-copy-id命令
[root@hadoop01 ~]# cd ~/.ssh			
[root@hadoop01 .ssh]# ssh-copy-id  root@hadoop01

-3. 进行验证	
[hadoop@hadoop01 .ssh]# ssh hadoop01
#下面的第一次执行时输入yes后,不提示输入密码就对了
[hadoop@hadoop01 .ssh]# ssh localhost
[hadoop@hadoop01 .ssh]# ssh 0.0.0.0

注意:三台机器提前安装好的情况下,需要同步公钥文件。如果使用克隆技术。那么使用同一套密钥对就方便多了。

5.4.6 时间同步

可以参考Linux文档中的时间同步或者搭建局域网时间服务器。

5.4.7 安装Jdk和Hadoop,配置相关环境变量

-1. 上传和解压两个软件包
[root@hadoop01 ~]# tar -zxvf jdk-8u221-linux-x64.tar.gz -C /usr/local/
[root@hadoop01 ~]# tar -zxvf hadoop-2.7.6.tar.gz -C /usr/local/

-2. 进入local里,给两个软件更名
[root@hadoop01 ~]# cd /usr/local/
[root@hadoop01 local]# mv 1.8.0_221/  jdk
[root@hadoop01 local]# mv hadoop-2.7.6/ hadoop

-3. 配置环境变量
[hadoop@hadoop01 local]# vi /etc/profile

.....省略...........

#java environment
export JAVA_HOME=/usr/local/jdk
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH

#hadoop environment
export HADOOP_HOME=/usr/local/hadoop
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH

5.5 Hadoop的配置文件

5.5.1 提取四个默认配置文件

第一步:将hadoop安装包解压到pc端的一个目录下,然后在hadoop-2.7.6目录下创建一个default目录,用于存储默认配置文件。

第二步:进入hadoop的share目录中的doc子目录,搜索default.xml。将以下四个默认的xml文件copy到default目录中,方便以后查看

5.5.2 $HADOOP_HOME/etc/hadoop/目录下的用户自定义配置文件

- core-site.xml
- hdfs-site.xml
- mapred-site.xml   复制mapred-site.xml.template而来
- yarn-site.xml 

5.5.3 属性的优先级

代码中的属性>xxx-site.xml>xxx-default.xml

5.6 完全分布式文件配置(重点)

配置前说明:
1.我们先在hadoop01机器节点上配置hadoop的相关属性。
2.在<value></value>之间的值不能有空格

5.6.1 配置core-site.xml文件

[root@hadoop01 ~]# cd $HADOOP_HOME/etc/hadoop/
[root@hadoop01 hadoop]# vi core-site.xml
<configuration>
     <!-- hdfs的地址名称:schame,ip,port-->
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://hadoop01:8020</value>
    </property>
     <!-- hdfs的基础路径,被其他属性所依赖的一个基础路径 -->
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/usr/local/hadoop/tmp</value>
    </property>
</configuration>

参考:core-default.xml

5.6.2 再配置hdfs-site.xml文件

[root@hadoop01 hadoop]# vi hdfs-site.xml
<configuration>
    <!-- namenode守护进程管理的元数据文件fsimage存储的位置-->
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file://${hadoop.tmp.dir}/dfs/name</value>
    </property>
    <!-- 确定DFS数据节点应该将其块存储在本地文件系统的何处-->
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file://${hadoop.tmp.dir}/dfs/data</value>
    </property>
    <!-- 块的副本数-->
    <property>
        <name>dfs.replication</name>
        <value>3</value>
    </property>
    <!-- 块的大小(128M),下面的单位是字节-->
    <property>
        <name>dfs.blocksize</name>
        <value>134217728</value>
    </property>
    <!-- secondarynamenode守护进程的http地址:主机名和端口号。参考守护进程布局-->
    <property>
        <name>dfs.namenode.secondary.http-address</name>
        <value>hadoop02:50090</value>
    </property>
  	<!-- namenode守护进程的http地址:主机名和端口号。参考守护进程布局-->
	<property>
  	  <name>dfs.namenode.http-address</name>
  	  <value>hadoop01:50070</value>
	</property>  
</configuration>

参考:hdfs-default.xml

5.6.3 然后配置mapred-site.xml文件

如果只是搭建hdfs,只需要配置core-site.xml和hdfs-site.xml文件就可以了,但是我们过两天要学习的MapReduce是需要YARN资源管理器的,因此,在这里,我们提前配置一下相关文件。

[root@hadoop01 hadoop]# cp mapred-site.xml.template  mapred-site.xml
[root@hadoop01 hadoop]# vi mapred-site.xml
<configuration>
    <!-- 指定mapreduce使用yarn资源管理器-->
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
    <!-- 配置作业历史服务器的地址-->
    <property>
        <name>mapreduce.jobhistory.address</name>
        <value>hadoop01:10020</value>
    </property>
    <!-- 配置作业历史服务器的http地址-->
    <property>
        <name>mapreduce.jobhistory.webapp.address</name>
        <value>hadoop01:19888</value>
    </property>
</configuration>

参考:mapred-default.xml

5.6.4 配置yarn-site.xml文件

[root@hadoop01 hadoop]# vi yarn-site.xml
<configuration>
    <!-- 指定yarn的shuffle技术-->
    <property>
        <name>yarn.nodemanager.aux-services</name>
       <value>mapreduce_shuffle</value>
    </property>
    <!-- 指定resourcemanager的主机名-->
    <property>
        <name>yarn.resourcemanager.hostname</name>
        <value>hadoop01</value>
    </property> 
    <!--下面的可选-->
    <!--指定shuffle对应的类 -->
	<property> 
	<name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name>
     <value>org.apache.hadoop.mapred.ShuffleHandler</value> 
	</property>

	<!--配置resourcemanager的内部通讯地址-->
	<property>
	<name>yarn.resourcemanager.address</name>
	<value>hadoop01:8032</value>
	</property>

	<!--配置resourcemanager的scheduler的内部通讯地址-->
	<property>
	<name>yarn.resourcemanager.scheduler.address</name>
	<value>hadoop01:8030</value>
	</property>

	<!--配置resoucemanager的资源调度的内部通讯地址-->
	<property>
	<name>yarn.resourcemanager.resource-tracker.address</name>
	<value>hadoop01:8031</value>
	</property>

	<!--配置resourcemanager的管理员的内部通讯地址-->
	<property>
	<name>yarn.resourcemanager.admin.address</name>
	<value>hadoop01:8033</value>
	</property>

	<!--配置resourcemanager的web ui 的监控页面-->
	<property>
	<name>yarn.resourcemanager.webapp.address</name>
	<value>hadoop01:8088</value>
	</property>
</configuration>

参考:yarn-default.xml

5.6.5 配置hadoop-env.sh脚本文件

[root@hadoop01 hadoop]# vi hadoop-env.sh
.........
# The java implementation to use.
export JAVA_HOME=/usr/local/jdk
.........

5.6.6 配置slaves文件

此文件用于指定datanode守护进程所在的机器节点主机名

[root@hadoop01 hadoop]# vi slaves
hadoop01
hadoop02
hadoop03

5.6.7 配置yarn-env.sh文件,

此文件可以不配置,不过,最好还是修改一下yarn的jdk环境比较好

[root@hadoop01 hadoop]# vi yarn-env.sh
.........
# some Java parameters
export JAVA_HOME=/usr/local/jdk
if [ "$JAVA_HOME" != "" ]; then
  #echo "run java in $JAVA_HOME"
  JAVA_HOME=$JAVA_HOME
fi
.........

5.7 另外两台机器配置说明

当把hadoop01机器上的hadoop的相关文件配置完毕后,我们有以下两种方式来选择配置另外几台机器的hadoop.

方法1:“scp”进行同步

提示:本方法适用于多台虚拟机已经提前搭建出来的场景。

--1. 同步hadoop到slave节点上
[root@hadoop01 ~]# cd /usr/local
[root@hadoop01 local]# scp -r ./hadoop hadoop02:/usr/local/
[root@hadoop01 local]# scp -r ./hadoop hadoop03:/usr/local/

--2. 同步/etc/profile到slave节点上
[root@hadoop01 local]# scp /etc/profile hadoop02:/etc/
[root@hadoop01 local]# scp /etc/profile hadoop03:/etc/

--3. 如果slave节点上的jdk也没有安装,别忘记同步jdk。
--4. 检查是否同步了/etc/hosts文件

方法2:克隆hadoop01虚拟机

提示:本方法适用于还没有安装slave虚拟机的场景。通过克隆hadoop01节点的方式,来克隆一个hadoop02和hadoop03机器节点,这种方式就不用重复安装环境和配置文件了,效率非常高,节省了大部分时间(免密认证的秘钥对都是相同的一套)。

--1. 打开一个新克隆出来的虚拟机,修改主机名
[root@hadoop01 ~]# hostnamectl set-hostname hadoop02 
--2. 修改ip地址
[root@hadoop01 ~]# vi /etc/sysconfig/network-scripts/ifcfg-ens33
.........省略.........
IPADDR=192.168.10.102				<==修改为hadoop02对应的ip地址
.........省略........
--3. 重启网络服务
[root@hadoop01 ~]# systemctl restart network
--4. 其他新克隆的虚拟机重复以上1~3步
--5. 免密登陆的验证
	从hadoop01机器上,连接其他的每一个节点,验证免密是否好使,同时去掉第一次的询问步骤

--6. 建议:每台机器在重启网络服务后,最好reboot一下。

5.8 格式化NameNode

1)在hadoop01机器上运行命令

[root@hadoop01 ~]# hdfs namenode -format

2)格式化的相关信息解读

--1. 生成一个集群唯一标识符:clusterid
--2. 生成一个块池唯一标识符:blockPoolId
--3. 生成namenode进程管理内容(fsimage)的存储路径:
	默认配置文件属性hadoop.tmp.dir指定的路径下生成dfs/name目录
--4. 生成镜像文件fsimage,记录分布式文件系统根路径的元数据

--5. 其他信息都可以查看一下,比如块的副本数,集群的fsOwner等。

参考图片:

3)目录里的内容查看

5.9 启动集群

5.9.1 启动脚本和关闭脚本介绍

1. 启动脚本
	-- start-dfs.sh			:用于启动hdfs集群的脚本
	-- start-yarn.sh		:用于启动yarn守护进程
	-- start-all.sh			:用于启动hdfs和yarn
2. 关闭脚本
	-- stop-dfs.sh			:用于关闭hdfs集群的脚本
	-- stop-yarn.sh			:用于关闭yarn守护进程
	-- stop-all.sh			:用于关闭hdfs和yarn
3. 单个守护进程脚本
	-- hadoop-daemons.sh	:用于单独启动或关闭hdfs的某一个守护进程的脚本
	-- hadoop-daemon.sh		:用于单独启动或关闭hdfs的某一个守护进程的脚本
	reg:
		hadoop-daemon.sh [start|stop] [namenode|datanode|secondarynamenode]
	
	-- yarn-daemons.sh	:用于单独启动或关闭hdfs的某一个守护进程的脚本
	-- yarn-daemon.sh		:用于单独启动或关闭hdfs的某一个守护进程的脚本
	reg:
		yarn-daemon.sh [start|stop] [resourcemanager|nodemanager]

5.9.2 启动hdfs

1)使用start-dfs.sh,启动 hdfs。参考图片

2)启动过程解析:

- 启动集群中的各个机器节点上的分布式文件系统的守护进程
  一个namenode和resourcemanager以及secondarynamenode
  多个datanode和nodemanager
- 在namenode守护进程管理内容的目录下生成edit日志文件
- 在每个datanode所在节点下生成${hadoop.tmp.dir}/dfs/data目录,参考下图:

注意,注意,注意

如果哪台机器的相关守护进程没有开启,那么,就查看哪台机器上的守护进程对应的日志log文件,注意,启动脚本运行时提醒的日志后缀是*.out,而我们查看的是*.log文件。此文件的位置:${HADOOP_HOME}/logs/里

3)jps查看进程

--1. 在hadoop01上运行jps指令,会有如下进程
	namenode
	datanode
--2. 在hadoop02上运行jps指令,会有如下进程
	secondarynamenode
	datanode
--3. 在hadoop03上运行jps指令,会有如下进程
	datanode   

5.9.3 启动yarn

1)使用start-yarn.sh脚本,参考图片

2)jps查看

--1. 在hadoop01上运行jps指令,会多出有如下进程
	resoucemanager
	nodemanager
--2. 在hadoop02上运行jps指令,会多出有如下进程
	nodemanager
--3. 在hadoop03上运行jps指令,会多出有如下进程
	nodemanager 

5.9.4 webui查看

1. http://192.168.10.101:50070
2. http://192.168.10.101:8088

5.10 程序案例演示:wordcount

1) 准备要统计的两个文件,存储到~/data/下

--1. 创建data目录
[root@hadoop01 hadoop]# mkdir ~/data
--2. 将以下两个文件上传到data目录下
- poetry1.txt
- poetry2.txt 

2) 在hdfs上创建存储目录

[root@hadoop01 hadoop]# hdfs dfs -mkdir /input

3) 将本地文件系统上的上传到hdfs上,并在web上查看一下

[root@hadoop01 hadoop]$ hdfs dfs -put ~/data/poetry* /input/

4) 运行自带的单词统计程序wordcount

[root@hadoop01 hadoop]# cd $HADOOP_HOME
[root@hadoop01 hadoop]# hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.6.jar  wordcount /input /output

5) 查看webui

6) 查看part-r-00000文件

[root@hadoop01 hadoop]# hdfs dfs -cat /output/part-r-00000

5.11 启动脚本的解读(选讲)

1. start-all.sh
2. start-dfs.sh
3. hadoop-daemon.sh
参考我的博客:https://blog.csdn.net/Michael__One/article/details/86141142

5.12 集群守护进程不能开启的情况

1. 格式化集群时,报错原因
	- 当前用户使用不当
	- /etc/hosts里的映射关系填写错误
	- 免密登录认证异常
	- jdk环境变量配置错误
	- 防火墙没有关闭
	- 配置文件出错
2. namenode进程没有启动的原因:
	- 当前用户使用不当
	- 重新格式化时,忘记删除${hadoop.tmp.dir}目录下的内容
	- 网络震荡,造成edit日志文件的事务ID序号不连续
	- 配置文件出错
3. datanode出现问题的原因
	- /etc/hosts里的映射关系填写错误
	- 免密登录异常
	- 重新格式化时,忘记删除${hadoop.tmp.dir}目录下的内容,造成datanode的唯一标识符不在新集群中。
4. 上述问题暴力解决办法:重新格式化
   	如果想重新格式化,那么先关闭集群的守护进程,再删除每台机器上的${hadoop.tmp.dir}指定路径下的所有内容,然后再格式化:最好也把logs目录下的内容也清空,因为日志内容已经是前一个废弃集群的日志信息了,留着也无用。

5.13 HDFS的常用shell命令

注意:访问hdfs系统的指令:
hadoop dfs --- 已过时
hadoop fs -- 使用范围更大
hdfs dfs --范围相对较小
hadoop fs 和 hdfs dfs之间没有太大的区别


--1. 在命令行中输入hdfs,回车后,就会提示hdfs后可以使用哪些命令,其中有一个是dfs。
--2. 在命令行中输入hdfs dfs,回车后,就会提示dfs后可以添加的一些常用shell命令

常用shell命令分类如下:

注意:分布式文件系统的路径在命令行中 要从/开始写,即绝对路径

--1. 创建目录
[-mkdir [-p] <path> ...]	#在分布式文件系统上创建目录  -p,多层级创建
调用格式:hdfs dfs -mkdir (-p)  /目录

--2. 上传指令
[-put [-f] [-p] [-l] <localsrc> ... <dst>]   #将本地文件系统的文件上传到分布式文件系统
调用格式:hdfs dfs -put /本地文件  /分布式文件系统路径
注意:
直接写/是省略了文件系统的名称hdfs://ip:port。  

[-moveFromLocal <localsrc> ... <dst>]		#将本地文件系统的文件上传到分布式文件系统
[-copyFromLocal [-f] [-p] [-l] <localsrc> ... <dst>]


--3. 查看指令
[-ls [-d] [-h] [-R] [<path> ...]]		#查看分布式文件系统的目录里内容
调用格式:hdfs dfs -ls /
[-cat [-ignoreCrc] <src> ...]	    	#查看分布式文件系统的文件内容	
调用格式:hdfs dfs -cat /xxx.txt
[-tail [-f] <file>]						#查看分布式文件系统的文件内容	
调用格式:hdfs dfs -tail /xxx.txt
注意:默认最多查看1000行


--4. 下载指令
[-copyToLocal [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
	注意:本地路径的文件夹可以不存在
[-moveToLocal <src> <localdst>]
	注意:从hdfs的某个路径将数据剪切到本地,还没有被实现
[-get [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
	调用格式:同copyToLocal

--5. 删除指令
[-rm [-f] [-r|-R] [-skipTrash] <src> ...]
	注意:如果删除文件夹需要加-r
[-rmdir [--ignore-fail-on-non-empty] <dir> ...]
	注意:必须是空文件夹,如果非空必须使用rm删除
--6. 查看磁盘利用率和文件大小
[-df [-h] [<path> ...]] 查看分布式系统的磁盘使用情况
[-du [-s] [-h] <path> ...]	#查看分布式系统上当前路径下文件的情况	-h:human 以人类可读的方式显示


--7. 向分布式文件系统中的文件里追加内容
[-appendToFile <localsrc> ... <dst>]
调用格式:hdfs dfs -appendToFile  本地文件     hdfs上的文件
注意:不支持在中间随意增删改操作

--8. 修改权限的,跟本地的操作一致,-R是让子目录或文件也进行相应的修改
[-chgrp [-R] GROUP PATH...]
[-chmod [-R] <MODE[,MODE]... | OCTALMODE> PATH...]
[-chown [-R] [OWNER][:[GROUP]] PATH...]

--9. 修改文件的副本数
[-setrep [-R] [-w] <rep> <path> ...]
调用格式:hadoop fs -setrep  3 /   将hdfs根目录及子目录下的内容设置成3个副本
注意:当设置的副本数量与初始化时默认的副本数量不一致时,集群会作出反应,比原来多了会自动进行复制.

--10. 查看文件的状态
hdfs dfs [generic options] -stat [format] <path> ...
命令的作用:当向hdfs上写文件时,可以通过dfs.blocksize配置项来设置文件的block的大小。这就导致了hdfs上的不同的文件block的大小是不相同的。有时候想知道hdfs上某个文件的block大小,可以预先估算一下计算的task的个数。stat的意义:可以查看文件的一些属性。
调用格式:hdfs dfs -stat [format] 文件路径
format的形式:
%b:打印文件的大小(目录大小为0)
%n:打印文件名
%o:打印block的size
%r:打印副本数
%y:utc时间 yyyy-MM-dd HH:mm:ss
%Y:打印自1970年1月1日以来的utc的微秒数
%F:目录打印directory,文件打印regular file

注意:
1)当使用-stat命令但不指定format时,只打印创建时间,相当于%y
2)-stat 后面只跟目录,%r,%o等打印的都是0,只有文件才有副本和大小
--11. 测试  
hdfs dfs [generic options] -test -[defsz] <path>    
参数说明: -e:文件是否存在  存在返回0    -z:文件是否为空  为空返回0   -d:是否是路径(目录) ,是返回0
调用格式:hdfs dfs -test -d 文件 
实例:hdfs dfs -test -d /shelldata/111.txt  && echo "OK"  || echo "no"
解释:测试当前的内容是否是文件夹 ,如果是返回ok,如果不是返回no
--12. 创建空文件
hdfs dfs [generic options] -touchz <path> ...   
调用格式:hdfs dfs touchz  /hadooptest.txt
--13. 显示当前文件夹及子文件夹的数量   子文件的数量以及 总大小
hdfs dfs [generic options] -count [-q] [-h] <path> ...   
调用格式:hdfs dfs  -count   /hadoop
--14. 合并下载
hdfs dfs [generic options] -getmerge [-nl] <src> <localdst>
调用格式:hdfs dfs -getmerge  hdfs上面的路径   本地的路径    
实例:hdfs dfs -getmergo /hadoopdata/*.xml /root/test.test
--15. 移动hdfs中的文件(更名)
hdfs dfds [generic options] -mv <src> ... <dst>   
调用格式:hdfs dfs -mv /hdfs的路径1  /hdfs的另一个路径2    
实例:hfds dfs -mv /aaa   /bbb  这里是将aaa整体移动到bbb中
--16. 复制hdfs中的文件到hdfs的另一个目录
hdfs dfs [generic options] -cp [-f] [-p | -p[topax]] <src> ... <dst>
调用格式:hdfs dfs -cp /hdfs路径_1  /hdfs路径_2
--17.设置Hadoop回收站trash:  当我们不小心删掉文件时,还有后悔药吃.
--17.1 修改core-site.xml文件
注意:我们需要在namenode和datanode同时设置垃圾回收,如果namenode可以使用,
  datanode 的无效,如果namenode的失效了,会自动调用datanode的设置

<property>
  <name>fs.trash.interval</name>
  <!-- 1440分钟后检查点会被清除,如果为0,垃圾回收站不会启用. -->
  <value>1440</value>
</property>
<property>  
    <name>fs.trash.checkpoint.interval</name>  
    <value>0</value> 
</property>

解释:
一:检查点:
执行下面的语句后出现的.Trash/190907043825就是检查点
[root@hadoop01 sbin]# hadoop fs -ls /user/root/.Trash/
19/09/07 05:15:42 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Found 2 items
drwx------   - root supergroup          0 2019-09-07 04:36 /user/root/.Trash/190907043825
drwx------   - root supergroup          0 2019-09-07 05:15 /user/root/.Trash/Current
二:fs.trash.interval	
分钟数,当超过这个分钟数后检查点会被删除。如果为零,回收站功能将被禁用。默认是0.单位分钟。这里我设置的是1天(60*24) 
删除数据rm后,会将数据move到当前文件夹下的.Trash/current目录
三:fs.trash.checkpoint.interval	
检查点创建的时间间隔(单位为分钟)。其值应该小于或等于fs.trash.interval。如果为零,则将该值设置为fs.trash.interval的值。
四:删除过程分析
这里的Deletion interval表示检查点删除时间间隔(单位为分钟)
这里的Emptier interval表示在运行线程来管理检查点之前,NameNode需要等待多长时间(以分钟为单位),即检查点创建时间间隔.NameNode删除超过fs.trash.interval的检查点,并为/user/${username}/.Trash/Current创建一个新的检查点。该频率由fs.trash.checkpoint.interval的值确定,且不得大于Deletion interval。这确保了在emptier窗口内回收站中有一个或多个检查点。
[root@hadoop01 sbin]# hadoop fs -rm -r /hadoop4.txt
19/09/07 05:15:24 INFO fs.TrashPolicyDefault: Namenode trash configuration: Deletion interval = 1440 minutes, Emptier interval = 0 minutes.
Moved: 'hdfs://hadoop01:9000/hadoop4.txt' to trash at: hdfs://hadoop01:9000/user/root/.Trash/Current

例如:
fs.trash.interval = 120 (deletion interval = 2 hours)
fs.trash.checkpoint.interval = 60 (emptier interval = 1 hour)

说明:
这导致NameNode为Current目录下的垃圾文件每小时创建一个新的检查点,并删除已经存在超过2个小时的检查点。

在回收站生命周期结束后,NameNode从HDFS命名空间中删除该文件。删除文件会导致与文件关联的块被释放。请注意,用户删除文件的时间与HDFS中相应增加可用空间的时间之间可能存在明显的时间延迟,即用户删除文件,HDFS可用空间不会立马增加,中间有一定的延迟。

五:expunge  清空回收站
要想使用这个命令,首先得有回收站,即fs.trash.interval的值不能为0
当我们执行expunge命令时,其实是会立刻创建一个新的检查点,并将/.Trash/Current中的内容立刻放入这个检查点.
实例: [root@hadoop01 sbin]# hadoop fs -expunge 
19/09/07 05:15:58 INFO fs.TrashPolicyDefault: Namenode trash configuration: Deletion interval = 1440 minutes, Emptier interval = 0 minutes.
19/09/07 05:15:58 INFO fs.TrashPolicyDefault: Created trash checkpoint: /user/root/.Trash/190907051558

六:如果想绕过垃圾回收站并立即从文件系统中删除文件。可以执行  hadoop fs  -rm -skipTrash
[root@hadoop01 sbin]# hadoop fs -rm -skipTrash /hadoop111.txt
19/09/07 05:50:13 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Deleted /hadoop111.txt


--17.2.测试 
1)新建目录input
[root@hadoop01:/data/soft]# hadoop fs -mkdir /input

2)上传文件
[root@hadoop01:/data/soft]# hadoop fs -copyFromLocal /data/soft/file0* /input

3)删除目录input
[root@hadoop01 data]# hadoop fs -rmr /input 
Moved to trash: hdfs://hadoop01:9000/user/root/input

4)参看当前目录
[root@hadoop01 data]# hadoop fs -ls 
Found 2 items 
drwxr-xr-x - root supergroup 0 2011-02-12 22:17 /user/root/.Trash
发现input删除,多了一个目录.Trash

5)恢复刚刚删除的目录
[root@hadoop01 data]# hadoop fs -mv /user/root/.Trash/Current/user/root/input /user/root/input

6)检查恢复的数据
[root@hadoop01 data]# hadoop fs -ls input 
Found 2 items 
-rw-r--r-- 3 root supergroup 22 2011-02-12 17:40 /user/root/input/file01 
-rw-r--r-- 3 root supergroup 28 2011-02-12 17:40 /user/root/input/file02
 
7)删除.Trash目录(清理垃圾)
[root@hadoop01 data]# hadoop fs -rmr .Trash 
Deleted hdfs://hadoop01:9000/user/root/.Trash

第六章:HDFS块的概念(重点)

6.1 传统型分布式文件系统的缺点

现在想象一下这种情况:有四个文件 0.5TB的file1,1.2TB的file2,50GB的file3,100GB的file4;有7个服务器,每个服务器上有10个1TB的硬盘。

在存储方式上,我们可以将这四个文件存储在同一个服务器上(当然大于1TB的文件需要切分),我们需要使用一个文件来记录这种存储的映射关系吧。用户是可以通过这种映射关系来找到节点硬盘相应的文件的。那么缺点也就暴露了出来:

第一、负载不均衡。

因为文件大小不一致,势必会导致有的节点磁盘的利用率高,有的节点磁盘利用率低。

第二、网络瓶颈问题。

一个过大的文件存储在一个节点磁盘上,当有并行处理时,每个线程都需要从这个节点磁盘上读取这个文件的内容,那么就会出现网络瓶颈,不利于分布式的数据处理。

6.2 HDFS的块

HDFS与其他普通文件系统一样,同样引入了块(Block)的概念,并且块的大小是固定的。但是不像普通文件系统那样小,而是根据实际需求可以自定义的。块是HDFS系统当中的最小存储单位,在hadoop2.0中默认大小为128MB(hadoop1.x中的块大小为64M)。在HDFS上的文件会被拆分成多个块,每个块作为独立的单元进行存储。多个块存放在不同的DataNode上,整个过程中 HDFS系统会保证一个块存储在一个数据节点上 。但值得注意的是 如果某文件大小或者文件的最后一个块没有到达128M,则不会占据整个块空间 。

6.3 HDFS的块大小

HDFS上的块大小为什么会远远大于传统文件?

1. 目的是为了最小化寻址开销时间。
	在I/O开销中,机械硬盘的寻址时间是最耗时的部分,一旦找到第一条记录,剩下的顺序读取效率是非常高的,因此以块为单位读写数据,可以尽量减少总的磁盘寻道时间。  
	HDFS寻址开销不仅包括磁盘寻道开销,还包括数据块的定位开销,当客户端需要访问一个文件时,首先从名称节点获取组成这个文件的数据块的位置列表,然后根据位置列表获取实际存储各个数据块的数据节点的位置,最后,数据节点根据数据块信息在本地Linux文件系统中找到对应的文件,并把数据返回给客户端,设计成一个比较大的块,可以减少每个块儿中数据的总的寻址开销,相对降低了单位数据的寻址开销
	磁盘的寻址时间为大约在5~15ms之间,平均值为10ms,而最小化寻址开销时间普遍认为占1秒的百分之一是最优的,那么块大小的选择就参考1秒钟的传输速度,比如2010年硬盘的传输速率是100M/s,那么就选择块大小为128M。

2. 为了节省内存的使用率
	一个块的元数据大约150个字节。1亿个块,不论大小,都会占用20G左右的内存。因此块越大,集群相对存储的数据就越多。所以暴漏了HDFS的一个缺点,不适合存储小文件(杀鸡用牛刀的感觉)

6.4 块的相关参数设置

当然块大小在默认配置文件hdfs-default.xml中有相关配置,我们可以在hdfs-site.xml中进行重置
<property>
    <name>dfs.blocksize</name>
    <value>134217728</value>
    <description>默认块大小,以字节为单位。可以使用以下后缀(不区分大小写):k,m,g,t,p,e以重新指定大小(例如128k, 512m, 1g等)</description>
</property>

<property>
    <name>dfs.namenode.fs-limits.min-block-size</name>
    <value>1048576</value>
    <description>以字节为单位的最小块大小,由Namenode在创建时强制执行时间。这可以防止意外创建带有小块的文件降低性能。</description>
</property>

<property>
    <name>dfs.namenode.fs-limits.max-blocks-per-file</name>
    <value>1048576</value>
    <description>每个文件的最大块数,由写入时的Namenode执行。这可以防止创建降低性能的超大文件</description>
</property>

6.5 HDFS块的存储位置

在hdfs-site.xml中我们配置过下面这个属性,这个属性的值就是块在linux系统上的存储位置

<!-- 确定DFS数据节点应该将其块存储在本地文件系统的何处-->
<property>
    <name>dfs.datanode.data.dir</name>
    <value>file://${hadoop.tmp.dir}/dfs/data</value>
</property>

自己可以去实际目录里看一下哦

6.6 HDFS的优点

1. 高容错性(硬件故障是常态,高可靠性):数据自动保存多个副本,副本丢失后,会自动恢复
2. 适合大数据集:GB、TB、甚至PB级数据、千万规模以上的文件数量,1000以上节点规模。
3. 数据访问: 一次性写入,多次读取;保证数据一致性,安全性
4. 构建成本低:可以构建在廉价机器上。
5. 多种软硬件平台中的可移植性 
6. 高效性:Hadoop能够在节点之间动态地移动数据,并保证各个节点的动态平衡,因此处理速度非常快。

6.7 HDFS的缺点

1. 不适合做低延迟数据访问:
	HDFS的设计目标有一点是:处理大型数据集,高吞吐率。这一点势必要以高延迟为代价的。因此HDFS不适合处理用户要求的毫秒级的低延迟应用请求
2. 不适合小文件存取:
	一个是大量小文件需要消耗大量的寻址时间,违反了HDFS的尽可能减少寻址时间比例的设计目标。第二个是内存有限,一个block元数据大内存消耗大约为150个字节,存储一亿个block和存储一亿个小文件都会消耗20G内存。因此相对来说,大文件更省内存
3. 不适合并发写入,文件随机修改:
	HDFS上的文件只能拥有一个写者,仅仅支持append操作。不支持多用户对同一个文件的写操作,以及在文件任意位置进行修改

第七章:Hadoop的重新编译(选讲)

7.1 重新编译的原因

在安装hadoop之前,大多数人都会选择在Linux系统上将hadoop重新编译一下,然后使用新编译的*.tar.gz文件进行安装。

那么为什么hadoop要再次编译一下呢?

你会发现网上很多人都说:官网提供编译好的只有32位的,没有提供64位的,其实这种解释不是很合理。而实际原因是因为Hadoop对于机器上的某些组件,提供了自己的本地实现。这些组件接口本应保存在hadoop的一个独立的动态链接的库里(Linux下对应[.so]文件,window下对应[.dlI]文件)。

针对于每一个CPU处理器,都对应一个自己的动态库(.so文件),这样才能最好的提高工作性能。说白了,就是重新编译hadoop,生成对应cpu的.so文件,更好的调用Native本地代码。

参考:官网文档说明如下,地址: http://hadoop.apache.org/docs/r1.0.4/cn/native_libraries.html

7.2 编译前环境准备

- CentOS 6.5 64位
	# 准备一台Linux虚拟机,必须是64位系统,硬盘50G以上最好,内存4G以上最好。
- jdk-8u172-linux-x64.tar.gz
	# jdk 1.7+最好
- apache-ant-1.10.1-bin.tar.gz
	# 编译所必需的软件,用于打包
- apache-maven-3.2.5-bin.tar.gz
	# 编译所必需的软件,用于联网下载依赖的jar包
- hadoop-2.7.6-src.tar.gz
	# hadoop的源码包
- protobuf-2.5.0.tar.gz
	# 编译所必需的软件,用于hadoop的通信
- findbugs-3.0.1.tar.gz
	# 编译非必需的软件,

7.3 必要的软件包

建议:最好重新安装一台新的Linux虚拟机,最好使用桌面版,以下所必须的软件包会提前安装一些。

安装好64位的Linux虚拟机后,最好使用root用户一直操作,避免不必要的麻烦。而Linux环境下必须要有以下的安装包环境,否则会编译不成功。

[root@demo ~]# yum -y install gcc*
[root@demo ~]# yum install autoconf automake libtool cmake
[root@demo ~]# yum -y install openssl-devel
[root@demo ~]# yum -y install ncurses-devel
[root@demo ~]# yum install lzo-devel zlib-devel bzip2
[root@demo ~]# yum -y install libs*
[root@demo ~]# yum install fuse-devel

上传安装包:

将所需要的安装包,如jdk,ant,maven,hadoop,protobuf,findbugs上传到 /root/目录下

解压软件包:

将所需要的安装包,统一解压到/usr/local/目录下

7.4 安装jdk,ant,maven、findbugs

7.4.1 解压操作

[root@demo ~]# cd /root
[root@demo ~]# tar -zxvf jdk-8u172-linux-x64.tar.gz -C /usr/local/
[root@demo ~]# tar -zxvf apache-ant-1.10.1-bin.tar.gz -C /usr/local/
[root@demo ~]# tar -zxvf apache-maven-3.2.5-bin.tar.gz -C /usr/local/

#顺便解压一下protobuf、findbugs
[root@demo ~]# tar -zxvf protobuf-2.5.0.tar.gz -C /usr/local/
[root@demo ~]# tar -zxvf findbugs-3.0.1.tar.gz -C /usr/local/

7.4.2 更名操作

将解压包ant,maven,jdk,findbugs进行更名操作,方便配置环境变量

[root@demo ~]# cd /usr/local
[root@demo local]# mv apache-ant-1.10.1/ ant
[root@demo local]# mv apache-maven-3.2.5/ maven
[root@demo local]# mv jdk1.8.0_172/ jdk
[root@demo local]# mv findbugs-3.0.1/ findbugs

7.4.3 配置环境变量

在/etc/profile文件里,配置jdk、maven、ant、findbugs的环境变量,并source

[root@demo local]# vi /etc/profile
............................
...........省略..............
............................
# java environment
export JAVA_HOME=/usr/local/jdk
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH

# java environment
export MAVEN_HOME=/usr/local/maven
export PATH=$MAVEN_HOME/bin:$PATH

# java environment
export ANT_HOME=/usr/local/ant
export PATH=$ANT_HOME/bin:$PATH

# java environment
export FINDBUGS_HOME=/usr/local/findbugs
export PATH=$FINDBUGS_HOME/bin:$PATH

# 配置一下maven的使用内存,过小很容易出错
export MAVEN_OPTS="-Xms512m -Xmx1024m"

7.4.4 保存退出,source配置文件,校验环境变量

[root@demo local]# source /etc/profile
[root@demo01 conf]# java -version
java version "1.8.0_172"
......
[root@demo01 conf]# mvn -version
Apache Maven 3.2.5 (12a6b3acb947671f09b81f49094c53f426d8cea1; 2014-12-15T01:29:23+08:00)
......
[root@demo01 conf]# ant -version
Apache Ant(TM) version 1.10.1 compiled on February 2 2017
[root@demo01 conf]# findbugs -version
3.0.1

7.4.5 配置maven的远程下载仓库

[root@demo local]# cd maven/conf/
[root@demo conf]# pwd
/usr/local/maven/conf
[root@demo conf]# ls
logging  settings.xml
[root@demo conf]# vi  settings.xml
...........省略.............
<mirrors>
    <!-- mirror
     |
  	 ...........省略.............
  	 |
        <mirror>
        <id>mirrorId</id>
        <mirrorOf>repositoryId</mirrorOf>
        <name>Human Readable Name for this Mirror.</name>
        <url>http://my.repository.com/repo/path</url>
        </mirror>
     -->
    <mirror>
        <id>alimaven</id>
        <mirrorOf>central</mirrorOf>
        <name>aliyun maven</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    </mirror>
</mirrors>

7.5 编译protobuf并安装

7.5.1 依次运行以下命令

刚才已经顺便将protobuf 解压到/usr/local/目录下,我们只需要进入protobuf-2.5.0内,然后运行如下命令

[root@demo local]# cd protobuf-2.5.0
[root@demo protobuf-2.5.0]# ./configure
.............................
......这个过程是配置一些信息.....
.............................
[root@demo protobuf-2.5.0]# make
.............................
......这个过程是编译过程.....
.............................
[root@demo protobuf-2.5.0]# make install
.............................
......这个过程是安装.....
.............................
[root@demo01 protobuf-2.5.0]# protoc --version
libprotoc 2.5.0
[root@demo01 protobuf-2.5.0]# which protoc
/usr/local/bin/protoc

7.5.2 一些说明

1)运行 ./configure 脚本时,有的是yes,有的是no. 不用担心的,这是正常情况

2)运行 protoc --version 的意义是,验证protobufs是否安装成功,出现版本号,表示安装成功

3)运行 which protoc 的意义是,验证命令protoc的位置,亦可知类似rpm安装,相关文件已经被安装到各个系统目录下了。

7.6 编译hadoop

7.6.1 进入包内,开始编译

刚才也已经顺便将hadoop的源码解压到/usr/local/目录下了,我们只需要进入hadoop-2.7.6-src内,然后运行如下命令

[root@demo01 local]# cd hadoop-2.7.6-src/
[root@demo01 hadoop-2.7.6-src]# pwd
/usr/local/hadoop-2.7.6-src
[root@demo01 hadoop-2.7.6-src]# pwd
[root@demo01 hadoop-2.7.6-src]# mvn clean package -DskipTests -Pdist,native -Dtar
# clean 指令可以省略,这就开始编译了,期间可能会卡住,如果卡住,你可以通过切换网络,来唤醒。
# 也可以Ctrl +C 停掉,重来。
# 耐心等待就是了,我来回重试了5、6次,最后终于成功了

............
............

[INFO] Executed tasks
[INFO]
[INFO] --- maven-jar-plugin:2.5:jar (default-jar) @ hadoop-dist ---
[INFO] Building jar: /usr/local/hadoop-2.7.6-src/hadoop-dist/target/hadoop-dist-2.7.6.jar
[INFO]
[INFO] --- maven-source-plugin:2.3:jar-no-fork (hadoop-java-sources) @ hadoop-dist ---
[INFO] Building jar: /usr/local/hadoop-2.7.6-src/hadoop-dist/target/hadoop-dist-2.7.6-sources.jar
[INFO]
[INFO] --- maven-source-plugin:2.3:test-jar-no-fork (hadoop-java-sources) @ hadoop-dist ---
[INFO] Building jar: /usr/local/hadoop-2.7.6-src/hadoop-dist/target/hadoop-dist-2.7.6-test-sources.jar
[INFO]
[INFO] --- maven-enforcer-plugin:1.3.1:enforce (dist-enforce) @ hadoop-dist ---
[INFO]
[INFO] --- maven-site-plugin:3.4:attach-descriptor (attach-descriptor) @ hadoop-dist ---
[INFO]
[INFO] --- maven-antrun-plugin:1.7:run (tar) @ hadoop-dist ---
[INFO] Executing tasks

main:
     [exec] $ tar cf hadoop-2.7.6.tar hadoop-2.7.6
     [exec] $ gzip -f hadoop-2.7.6.tar
     [exec]
     [exec] Hadoop dist tar available at: /usr/local/hadoop-2.7.6-src/hadoop-dist/target/hadoop-2.7.6.tar.gz
     [exec]
[INFO] Executed tasks
[INFO]
[INFO] --- maven-javadoc-plugin:2.8.1:jar (module-javadocs) @ hadoop-dist ---
[INFO] Building jar: /usr/local/hadoop-2.7.6-src/hadoop-dist/target/hadoop-dist-2.7.6-javadoc.jar
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] Apache Hadoop Main ................................. SUCCESS [  1.773 s]
[INFO] Apache Hadoop Build Tools .......................... SUCCESS [  1.451 s]
[INFO] Apache Hadoop Project POM .......................... SUCCESS [  1.589 s]
[INFO] Apache Hadoop Annotations .......................... SUCCESS [  4.349 s]
[INFO] Apache Hadoop Assemblies ........................... SUCCESS [  0.327 s]
[INFO] Apache Hadoop Project Dist POM ..................... SUCCESS [  1.937 s]
[INFO] Apache Hadoop Maven Plugins ........................ SUCCESS [  5.171 s]
[INFO] Apache Hadoop MiniKDC .............................. SUCCESS [  8.022 s]
[INFO] Apache Hadoop Auth ................................. SUCCESS [  9.413 s]
[INFO] Apache Hadoop Auth Examples ........................ SUCCESS [  4.439 s]
[INFO] Apache Hadoop Common ............................... SUCCESS [01:55 min]
[INFO] Apache Hadoop NFS .................................. SUCCESS [  7.738 s]
[INFO] Apache Hadoop KMS .................................. SUCCESS [ 14.134 s]
[INFO] Apache Hadoop Common Project ....................... SUCCESS [  0.683 s]
[INFO] Apache Hadoop HDFS ................................. SUCCESS [02:50 min]
[INFO] Apache Hadoop HttpFS ............................... SUCCESS [ 24.433 s]
[INFO] Apache Hadoop HDFS BookKeeper Journal .............. SUCCESS [  8.507 s]
[INFO] Apache Hadoop HDFS-NFS ............................. SUCCESS [  4.588 s]
[INFO] Apache Hadoop HDFS Project ......................... SUCCESS [  0.069 s]
[INFO] hadoop-yarn ........................................ SUCCESS [  0.044 s]
[INFO] hadoop-yarn-api .................................... SUCCESS [ 41.577 s]
[INFO] hadoop-yarn-common ................................. SUCCESS [ 35.038 s]
[INFO] hadoop-yarn-server ................................. SUCCESS [  0.058 s]
[INFO] hadoop-yarn-server-common .......................... SUCCESS [ 11.435 s]
[INFO] hadoop-yarn-server-nodemanager ..................... SUCCESS [ 18.826 s]
[INFO] hadoop-yarn-server-web-proxy ....................... SUCCESS [  3.912 s]
[INFO] hadoop-yarn-server-applicationhistoryservice ....... SUCCESS [  7.949 s]
[INFO] hadoop-yarn-server-resourcemanager ................. SUCCESS [ 21.419 s]
[INFO] hadoop-yarn-server-tests ........................... SUCCESS [  5.771 s]
[INFO] hadoop-yarn-client ................................. SUCCESS [  7.311 s]
[INFO] hadoop-yarn-server-sharedcachemanager .............. SUCCESS [  4.433 s]
[INFO] hadoop-yarn-applications ........................... SUCCESS [  0.046 s]
[INFO] hadoop-yarn-applications-distributedshell .......... SUCCESS [  3.278 s]
[INFO] hadoop-yarn-applications-unmanaged-am-launcher ..... SUCCESS [  2.377 s]
[INFO] hadoop-yarn-site ................................... SUCCESS [  0.075 s]
[INFO] hadoop-yarn-registry ............................... SUCCESS [  5.904 s]
[INFO] hadoop-yarn-project ................................ SUCCESS [  4.507 s]
[INFO] hadoop-mapreduce-client ............................ SUCCESS [  0.212 s]
[INFO] hadoop-mapreduce-client-core ....................... SUCCESS [ 21.254 s]
[INFO] hadoop-mapreduce-client-common ..................... SUCCESS [ 17.577 s]
[INFO] hadoop-mapreduce-client-shuffle .................... SUCCESS [  4.050 s]
[INFO] hadoop-mapreduce-client-app ........................ SUCCESS [  9.112 s]
[INFO] hadoop-mapreduce-client-hs ......................... SUCCESS [  5.926 s]
[INFO] hadoop-mapreduce-client-jobclient .................. SUCCESS [  7.732 s]
[INFO] hadoop-mapreduce-client-hs-plugins ................. SUCCESS [  3.217 s]
[INFO] Apache Hadoop MapReduce Examples ................... SUCCESS [  6.516 s]
[INFO] hadoop-mapreduce ................................... SUCCESS [  3.110 s]
[INFO] Apache Hadoop MapReduce Streaming .................. SUCCESS [  4.672 s]
[INFO] Apache Hadoop Distributed Copy ..................... SUCCESS [  8.030 s]
[INFO] Apache Hadoop Archives ............................. SUCCESS [  3.393 s]
[INFO] Apache Hadoop Rumen ................................ SUCCESS [  6.558 s]
[INFO] Apache Hadoop Gridmix .............................. SUCCESS [  4.535 s]
[INFO] Apache Hadoop Data Join ............................ SUCCESS [  2.872 s]
[INFO] Apache Hadoop Ant Tasks ............................ SUCCESS [  2.313 s]
[INFO] Apache Hadoop Extras ............................... SUCCESS [  3.247 s]
[INFO] Apache Hadoop Pipes ................................ SUCCESS [  6.611 s]
[INFO] Apache Hadoop OpenStack support .................... SUCCESS [  4.971 s]
[INFO] Apache Hadoop Amazon Web Services support .......... SUCCESS [05:17 min]
[INFO] Apache Hadoop Azure support ........................ SUCCESS [01:30 min]
[INFO] Apache Hadoop Client ............................... SUCCESS [  7.925 s]
[INFO] Apache Hadoop Mini-Cluster ......................... SUCCESS [  1.025 s]
[INFO] Apache Hadoop Scheduler Load Simulator ............. SUCCESS [  7.912 s]
[INFO] Apache Hadoop Tools Dist ........................... SUCCESS [  9.626 s]
[INFO] Apache Hadoop Tools ................................ SUCCESS [  0.095 s]
[INFO] Apache Hadoop Distribution ......................... SUCCESS [ 42.031 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 19:24 min
[INFO] Finished at: 2019-11-14T21:08:44+08:00
[INFO] Final Memory: 119M/494M
[INFO] ------------------------------------------------------------------------

欧耶,终于成功了。截图如下:

7.7 成功编译后

成功编译后,发布包位于hadoop-dist目录下的target里,

我们可以看到两个文件:一个是hadoop-2.7.6.tar.gz,一个是hadoop-dist-2.7.6.javadoc.jar。

使用ll -h 参数查看一下他们的大小:一个是190M,一个是381M。

我们就可以愉快的使用这个hadoop-2.7.6.tar.gz二进制包进行安装测试hadoop了哦。

第八章:HDFS的体系结构

8.1 体系结构解析

HDFS采用的是master/slaves这种主从的结构模型来管理数据,这种结构模型主要由四个部分组成,分别是Client(客户端)、Namenode(名称节点)、Datanode(数据节点)和SecondaryNameNode。

真正的一个HDFS集群包括一个Namenode和若干数目的Datanode。

Namenode是一个中心服务器,负责管理文件系统的命名空间 (Namespace ),它在内存中维护着命名空间的最新状态,同时并持久性文件(fsimage)进行备份,防止宕机后,数据丢失。namenode还负责管理客户端对文件的访问,比如权限验证,并以edit日志文件来持久保存。

集群中的Datanode一般是一个节点运行一个Datanode进程,真正负责管理客户端的读写请求,在Namenode的统一调度下进行数据块的创建、删除和复制等操作。数据块实际上都是保存在Datanode本地的Linux文件系统中的。每个Datanode会定期的向Namenode发送数据,报告自己的状态(我们称之为心跳机制)。没有按时发送心跳信息的Datanode会被Namenode标记为“宕机”,不会再给他分配任何I/O请求。 

用户在使用Client进行I/O操作时,仍然可以像使用普通文件系统那样,使用文件名去存储和访问文件,只不过,在HDFS内部,一个文件会被切分成若干个数据块,然后被分布存储在若干个Datanode上。

比如,用户在Client上需要访问一个文件时,HDFS的实际工作流程如此:客户端先把文件名发送给Namenode,Namenode根据文件名找到对应的数据块信息及其每个数据块所在的Datanode位置,然后把这些信息发送给客户端。之后,客户端就直接与这些Datanode进行通信,来获取数据(这个过程,Namenode并不参与数据块的传输)。这种设计方式,实现了并发访问,大大提高了数据的访问速度。

HDFS集群中只有唯一的一个Namenode,负责所有元数据的管理工作。这种方式保证了Datanode不会脱离Namenode的控制,同时,用户数据也永远不会经过Namenode,大大减轻了Namenode的工作负担,使之更方便管理工作。通常在部署集群中,我们要选择一台性能较好的机器来作为Namenode。当然,一台机器上也可以运行多个Datanode,甚至Namenode和Datanode也可以在一台机器上,只不过实际部署中,通常不会这么做的

secondaryname守护进程是用于辅助namenode守护进程的。帮助namenode减轻负担, 果namenode宕机了,secondaryname守护进程不能充当namenode来管理集群。

8.2 HDFS进程之NameNode

- namenode进程只有一个(HA除外)
- 管理HDFS的命名空间,并以fsimage和edit进行持久化保存。
- 在内存中维护数据块的映射信息(块文件与datanode的对应关系),此映射关系数据不会保存到磁盘上。   
- 实施副本冗余策略(当发现块的实际副本数小于配置数时,会启动复制块的线程,直到个数达到配置数)
- 处理客户端的访问请求

8.3 HDFS进程之DataNode

- 存储真正的数据(块进行存储)
- 执行数据块的读写操作
- 心跳机制(3秒)

8.4 HDFDS进程之SecondaryNamennode

- 帮助NameNode合并fsimage和edits文件
- 不能实时同步,不能作为热备份节点

8.5 HDFS的Client接口

- HDFS实际上提供了各种语言操作HDFS的接口。
- 与NameNode进行交互,获取文件的存储位置(读/写两种操作)
- 与DataNode进行交互,写入数据,或者读取数据
- 上传时分块进行存储,读取时分片进行读取

8.6 映像文件fsimage

命名空间指的就是文件系统树及整棵树内的所有文件和目录的元数据,每个Namenode只能管理唯一的一命名空间。HDFS暂不支持软链接和硬连接。Namenode会在内存里维护文件系统的元数据,同时还使用fsimage和edit日志两个文件来辅助管理元数据,并持久化到本地磁盘上。

- fsimage
	命名空间镜像文件,它是文件系统元数据的一个完整的永久检查点,内部维护的是最近一次检查点的文件系统树和整棵树内部的所有文件和目录的元数据,如修改时间,访问时间,访问权限,副本数据,块大小,文件的块列表信息等等。
	fsimage默认存储两份,是最近的两次检查点
	

- 使用XML格式查看fsimage文件:
	[root@hadoop01 current]# hdfs oiv -i  【fsimage_xxxxxxx】 -o  【目标文件路径】 -p  XML
	案例如下:
	[root@hadoop01 current]# hdfs oiv -i fsimage_00000000052 -o ~/fs52.xml  -p  XML

8.7 日志文件edit

集群正常运行时,客户端的所有更新操作(如打开、关闭、创建、删除、重命名等)除了在内存中维护外,还会被写到edit日志文件中,而不是直接写入fsimage映像文件。

因为对于分布式文件系统而言,fsimage映像文件通常都很庞大,如果客户端所有的更新操作都直接往fsimage文件中添加,那么系统的性能一定越来越差。相对而言,edit日志文件通常都要远远小于fsimage,一个edit日志文件最大64M,更新操作写入到EditLog是非常高效的。

那么edit日志文件里存储的到底是什么信息呢,我们可以将edit日志文件转成xml文件格式,进行查看

查看editlog文件的方式:

[root@hadoop01 current]# hdfs oev -i 【edits_inprogress_xxx】 -o 【目标文件路径】-p XML

参考xml文件后,我们可以知道日志文件里记录的内容有:

1. 行为代码:比如 打开、创建、删除、重命名、关闭
2. 事务id
3. inodeid
4. 副本个数
5. 修改时间
6. 访问时间
7. 块大小
8. 客户端信息
9. 权限等
10. 块id等

第九章:HDFS的工作机制(重点)

9.1 开机启动Namenode过程

namenode启动(根据客户端的请求记录fsimage和edits,在内存中进行增删改查)

9.1.1 非第一次启动集群的启动流程

我们应该知道,在启动namenode之前,内存里是没有任何有关于元数据的信息的。那么启动集群的过程是怎样的呢?下面来叙述一下:

第一步:Namenode在启动时,会先加载name目录下最近的fsimage文件.
	将fsimage里保存的元数据加载到内存当中,这样内存里就有了之前检查点里存储的所有元数据。但是还少了从最近一次检查时间点到关闭系统时的部分数据,也就是edit日志文件里存储的数据。

第二步:加载剩下的edit日志文件
	将从最近一次检查点到目前为止的所有的日志文件加载到内存里,重演一次客户端的操作,这样,内存里就是最新的文件系统的所有元数据了。

第三步:进行检查点设置(满足条件会进行)
		namenode会终止之前正在使用的edit文件,创建一个空的edit日志文件。然后将所有的未合并过的edit日志文件和fsimage文件进行合并,产生一个新的fsimage.

第四步:处于安全模式下,等待datanode节点的心跳反馈,当收到99.9%的块的至少一个副本后,退出安全模式,开始转为正常状态。

注意:格式化集群后,第一次启动集群的特点,

小知识:

(1) 滚动编辑日志(前提必须启动集群)
    1.可以强制滚动
    [bigdata@hadoop102 current]$ hdfs dfsadmin -rollEdits
    2.可以等到edits.inprogress满64m生成edits文件
    3.可以等操作数量达到100万次
    4.时间到了,默认1小时
    注意:在2,3,4时发生滚动,会进行checkpoint
(2) 镜像文件什么时候产生
    可以在namenode启动时加载镜像文件和编辑日志
    也可以在secondarynamenode生成的fsimage.chkpoint文件重新替换namenode原来的fsimage文件时
(3) namenode目录说明

9.2 安全模式介绍

Namenode启动时,首先要加载fsimage文件到内存,并逐条执行editlog文件里的事务操作,在这个期间一但在内存中成功建立文件系统元数据的映像,就会新创建一个fsimage文件(该操作不需要SecondaryNamenode)和一个空的editlog文件。在这个过程中,namenode是运行在安全模式下的,Namenode的文件系统对于客户端来说是只读的,文件修改操作如写,删除,重命名等均会失败。

系统中的数据块的位置并不是由namenode维护的,而是以块列表的形式存储在datanode中。在系统的正常操作期间,namenode会在内存中保留所有块位置的映射信息。在安全模式下,各个datanode会向namenode发送最新的块列表信息,如果满足“最小副本条件”,namenode会在30秒钟之后就退出安全模式,开始高效运行文件系统.所谓的最小副本条件指的是在整个文件系统中99.9%的块满足最小副本级别(默认值:dfs.replication.min=1)。

PS:启动一个刚刚格式化完的集群时,HDFS还没有任何操作呢,因此Namenode不会进入安全模式。

9.2.1 查看namenode是否处于安全模式:

[root@hadoop01 current]# hdfs dfsadmin -safemode get  
Safe mode is ON

9.2.2 管理员可以随时让Namenode进入或离开安全模式,这项功能在维护和升级集群时非常关键

[root@hadoop01 current]# hdfs dfsadmin -safemode enter
Safe mode is ON
[root@hadoop01 current]# hdfs dfsadmin -safemode leave
Safe mode is OFF

9.2.3 将下面的属性的值设置为大于1,将永远不会离开安全模式

<property>
    <name>dfs.namenode.safemode.threshold-pct</name>
    <value>0.999f</value>
</property>

9.2.4 有时,在安全模式下,用户想要执行某条命令,特别是在脚本中,此时可以先让安全模式进入等待状态

[root@hadoop01 current]# hdfs dfsadmin -safemode wait
# command to read or write a file

9.3 DataNode与NameNode通信(心跳机制)

1. hdfs是hadoop01/slave结构,hadoop01包括namenode和resourcemanager,slave包括datanode和nodemanager
2. hadoop01启动时会开启一个IPC服务,等待slave连接
3. slave启动后,会主动连接IPC服务,并且每隔3秒链接一次,这个时间是可以调整的,设置heartbeat,这个每隔一段时间连接一次的机制,称为心跳机制。Slave通过心跳给hadoop01汇报自己信息,hadoop01通过心跳下达命令。
4. Namenode通过心跳得知datanode状态。Resourcemanager通过心跳得知nodemanager状态
5. 当hadoop01长时间没有收到slave信息时,就认为slave挂掉了。

注意:3秒一汇报,5分一检查,超长时间计算结果:默认为10分钟30秒 宣布宕机,

属性:dfs.namenode.heartbeat.recheck-interval 的默认值为5分钟  #Recheck的时间单位为毫秒
属性:dfs.heartbeat.interval 的默认值时3秒	#heartbeat的时间单位为秒 
      
计算公式:2*recheck+10*heartbeat

9.4 SecondayNamenode的工作机制(检查点机制)

SecondaryNamenode,是HDFS集群中的重要组成部分,它可以辅助Namenode进行fsimage和editlog的合并工作,减小editlog文件大小,以便缩短下次Namenode的重启时间,能尽快退出安全模式。

两个文件的合并周期,称之为检查点机制(checkpoint),是可以通过hdfs-default.xml配置文件进行修改的:

<property>
    <name>dfs.namenode.checkpoint.period</name>
    <value>3600</value>
    <description>两次检查点间隔的秒数,默认是1个小时</description>
</property>		 
<property>
    <name>dfs.namenode.checkpoint.txns</name>
    <value>1000000</value>
    <description>txid执行的次数达到100w次,也执行checkpoint</description>
</property>		 
<property>
    <name>dfs.namenode.checkpoint.check.period</name>
    <value>60</value>
    <description>60秒一检查txid的执行次数</description>
</property>

通过上图,可以总结如下:

1. SecondaryNamenode请求Namenode停止使用正在编辑的editlog文件,Namenode会创建新的editlog文件(小了吧),同时更新seed_txid文件。
2. SecondaryNamenode通过HTTP协议获取Namenode上的fsimage和editlog文件。
3. SecondaryNamenode将fsimage读进内存当中,并逐步分析editlog文件里的数据,进行合并操作,然后写入新文件fsimage_x.ckpt文件中。
4. SecondaryNamenode将新文件fsimage_x.ckpt通过HTTP协议发送回Namenode。
5. Namenode再进行更名操作。

9.5 网络拓扑

在进行副本冗余策略时,我们是否应该考虑网络带宽问题呢?答案是肯定的,网络带宽是很稀缺的资源。(希望5G时代能解决这个问题,嘎嘎)。因此在副本冗余时,这些副本存储在哪个工作节点上,存储在哪个机架上?HDFS又怎么知道哪个机架远,哪个机架近呢。

衡量不同节点之间的带宽,实际上很难实现,HDFS采用了一个较为简单的方式:把网络看成一颗树,两个节点之间的距离是他们到最近共同祖先的距离总和。

假设有两个数据中心,如下图

距离有这四种情况:  
Distance(/d1/r1/n1, /d1/r1/n1)=0(同一节点上的进程)  
Distance(/d1/r1/n1, /d1/r1/n2)=2(同一机架上的不同节点)      	
Distance(/d1/r1/n1, /d1/r2/n3)=4(同一数据中心不同机架上的节点)    
Distance(/d1/r1/n1, /d2/r3/n4)=6(不同数据中心的节点)
带宽依次递减。

9.6 机架感知

如何想让HDFS知道自己的网络拓扑情况,那就是另外一个配置策略了,即机架感知。默认情况下,机架感知策略是关闭的。 需要进行对net.topology.script.file.name进行设置。如果不设置,namenode就会将datanode注册属于/default-rack机架。

使用了机架感知策略的副本存放:

第一个副本在client所处的节点上。如果客户端在集群外,随机选一个。
第二个副本与第一个副本不相同机架,随机一个节点进行存储
第三个副本与第二个副本相同机架,不同节点。

9.7 节点动态上线

9.7.1 属性说明

在hdfs-site.xml里有一个属性,用于指定所有在线主机名和要上线的主机名的文件	

<property>
    <name>dfs.hosts</name>
    <value></value>
    <description>命名包含允许连接到namenode的主机列表的文件。必须指定文件的完整路径名。如果值为空,则允许所有主机</description>
</property>

9.7.2 动态上线步骤:

准备工作:准备一台配置了jdk和hadoop的新主机hadoop04。如果克隆的话,别忘记删除${hadoop.tmp.dir}指定的目录和logs目录

第一步:修改dfs.hosts属性,指定文件include的全路径

<property>
    <name>dfs.hosts</name>
    <value>/usr/local/hadoop/etc/hadoop/include</value>
</property>

注意:include这个文件名,可以自定义。

第二步:将待上线的主机名(hadoop04)添加到dfs.hosts指定的文件内

[root@hadoop01 hadoop]# touch include 			#创建文件
[root@hadoop01 hadoop]# vi include
hadoop01
hadoop02
hadoop03
slave3	#将要上线的主机名

注意:dfs.hosts指定的文件中必须存储所有的在线主机名

第三步:在namenode上刷新节点:

[root@hadoop01 hadoop]# hadoop dfsadmin -refreshNodes。

第四步:在要上线的节点上重启 datanode

[root@hadoop01 hadoop]# hadoop-daemon.sh start datanode.

第四步:通过hadoop dfsadmin -report 或者web界面,可以看到, 节点已经上线。

第五步:最后修改slaves,添加上新主机名。以便集群重启时,带上此节点。

[root@hadoop01 hadoop]# vi slaves
hadoop01
hadoop02
hadoop03
slave3   #添加此节点

9.8 节点动态下线

9.8.1 属性说明

在hdfs-site.xml里有一个属性,用于指定存储将要退役的主机名的文件

<property>
	<name>dfs.hosts.exclude</name>
	<value></value>
	<description>命名包含不允许连接到namenode的主机列表的文件。必须指定文件的完整路径名。如果该值为空,则不排除任何主机</description>
</property>

9.8.2 下线步骤

第一步:修改dfs.hosts.exclude属性,指定文件exclude的全路径

<property>
	<name>dfs.hosts.exclude</name>
	<value>/usr/local/hadoop/etc/hadoop/exclude</value>
</property>

注意:dexclude这个文件名,可以自定义。

第二步:将待下线的主机名(hadoop01)加入到dfs.hosts.exclude指定的文件中

[root@hadoop01 hadoop]# touch exclude	#创建exclude文件
[root@hadoop01 hadoop]# vi exclude
hadoop01

第三步:在namenode节点上刷新节点:

[root@hadoop01 hadoop]# hadoop dfsadmin -refreshNodes

第四步:通过hadoop dfsadmin -report或者web界面,进行查看。

此时,该datanode状态转化为Decommission In Progress。表示该datanode正在退役中,进行数据块的转移。
因此会花上一段时间。需要等待......  
当decommission进程完成数据移动, datanode状态会转变为Decommissioned, 然后datanode会自动停止datanode进程。 然后你可以看见dead nodes下多了一个你想要下线的节点。  

第五步:然后删除include 和 exclude 中该节点的hosts, 重新刷新hadoop dfsadmin -refreshNodes。

第六步:最后别忘了删除slaves中该节点的配置, 防止下次集群重启时,namenode傻乎乎的启动这个退役的节点。

注意: 当你下线一个datanode节点, 有可能该节点长时间处于Decommission In Progress 状态, 一直不能转变成Decommissioned。 请你用hadoop fsck / 检查下是否有些块少于指定的块数, 特别注意那些mapreduce的临时文件。 将这些删除, 并且从垃圾箱移除, 该节点就可以顺利下线, 这是我想到的解决办法。

第十章:数据流(重点)

10.1 读流程的详解

读操作:  
	- hdfs dfs -get /file02 ./file02
	- hdfs  dfs -copyToLocal  /file02 ./file02
	- FSDataInputStream fsis = fs.open("/input/a.txt");
	- fsis.read(byte[] a)
	- fs.copyToLocal(path1,path2)	






1. 客户端通过调用FileSystem对象的open()方法来打开希望读取的文件,对于HDFS来说,这个对象是DistributedFileSystem,它通过使用远程过程调用(RPC)来调用namenode,以确定文件起始块的位置

2. 对于每一个块,NameNode返回存有该块副本的DataNode地址,并根据距离客户端的远近来排序。

3. DistributedFileSystem实例会返回一个FSDataInputStream对象(支持文件定位功能)给客户端以便读取数据,接着客户端对这个输入流调用read()方法

4. FSDataInputStream随即连接距离最近的文件中第一个块所在的DataNode,通过对数据流反复调用read()方法,可以将数据从DataNode传输到客户端

5. 当读取到块的末端时,FSInputStream关闭与该DataNode的连接,然后寻找下一个块的最佳DataNode

6. 客户端从流中读取数据时,块是按照打开FSInputStream与DataNode的新建连接的顺序读取的。它也会根据需要询问NameNode来检索下一批数据块的DataNode的位置。一旦客户端完成读取,就对FSInputStream调用close方法

注意:在读取数据的时候,如果FSInputStream与DataNode通信时遇到错误,会尝试从这个块的最近的DataNode读
取数据,并且记住那个故障的DataNode,保证后续不会反复读取该节点上后续的块。FInputStream也会通过校验和
确认从DataNode发来的数据是否完整。如果发现有损坏的块,FSInputStream会从其他的块读取副本,并且将损坏
的块通知给NameNode

10.2 写流程的详解

写操作: 
	- hdfs dfs -put ./file02 /file02
	- hdfs  dfs -copyFromLocal  ./file02 /file02
	- FSDataOutputStream fsout = fs.create(path);fsout.write(byte[])
	- fs.copyFromLocal(path1,path2)
	
	问题:如果机器不超过3块,那么namenode是否还会给client一个3个副本的地址
	在发送数据包的同时data会把消息传给ack ,报告正在传输的packet如果传输失败,就会回流到data 中
	只要有一份完成了,就认为本次传输时成功的。






1. 客户端通过对DistributedFileSystem对象调用create()方法来新建文件

2. DistributedFileSystem对namenode创建一个RPC调用,调用namenode守护进程的create方法,在文件系统的命名空间中新建一个文件,此时该文件中还没有相应的数据块

3. namenode执行各种不同的检查,以确保这个文件不存在以及客户端有新建该文件的权限。如果检查通过,namenode就会为创建新文件记录一条事务记录(否则,文件创建失败并向客户端抛出一个IOException异常)。DistributedFileSystem向客户端返回一个FSDataOuputStream对象,由此客户端可以开始写入数据,

4. 在客户端写入数据时,FSOutputStream将它分成一个个的数据包(packet),并写入一个内部队列,这个队列称为“数据队列”(data queue)。DataStreamer线程负责处理数据队列,它的责任是挑选出合适存储数据复本的一组datanode,并以此来要求namenode分配新的数据块。这一组datanode将构成一个管道,以默认复本3个为例,所以该管道中有3个节点.DataStreamer将数据包流式传输到管道中第一个datanode,该datanode存储数据包并将它发送到管道中的第2个datanode,同样,第2个datanode存储该数据包并且发送给管道中的第三个datanode。DataStreamer在将一个个packet流式传输到第一个Datanode节点后,还会将此packet从数据队列移动到另一个队列确认队列(ack queue)中。

5. datanode写入数据成功之后,会为ResponseProcessor线程发送一个写入成功的信息回执,当收到管道中所有的datanode确认信息后,ResponseProcessoer线程会将该数据包从确认队列中删除。

如果任何datanode在写入数据期间发生故障,则执行以下操作:

1. 首先关闭管道,把确认队列中的所有数据包都添加回数据队列的最前端,以确保故障节点下游的datanode不会漏掉任何一个数据包
2. 为存储在另一正常datanode的当前数据块制定一个新标识,并将该标识传送给namenode,以便故障datanode在恢复后可以删除存储的部分数据块
3. 从管道中删除故障datanode,基于两个正常datanode构建一条新管道,余下数据块写入管道中正常的datanode
4. namenode注意到块复本不足时,会在一个新的Datanode节点上创建一个新的复本。

注意:在一个块被写入期间可能会有多个datanode同时发生故障,但概率非常低。只要写入了dfs.namenode.replication.min的复本数(默认1),写操作就会成功,并且这个块可以在集群中异步复制,直到达到其目标复本数dfs.replication的数量(默认3)

第十一章:IDE远程管理HDFS

11.1 windows环境配置

11.1.1 解压hadoop-2.7.6.tar.gz到本地磁盘,如下图:

11.1.2 配置环境变量

- HADOOP_HOME:	D:\apps\hadoop-2.7.6
- PATH: %HADOOP_HOME%\bin 和 %HADOOP_HOME%\sbin

11.1.3 由于Hadoop是在32位系统上编译的,并且对windows支持不好,所以需要把64的编译本地库文件(下图的两个文件),放入bin目录中。

11.1.4 验证环境变量是否生效:

C:\Users\Michael>hadoop version

11.1.5 如果报错:Error: JAVA_HOME is incorrectly set

那就找到etc/hadoop/下的hadoop-env.cmd,修改JAVA_HOME的内容如下格式即可
set JAVA_HOME=C:\PROGRA~1\Java\jdk1.8.0_221

如果还不好用,那么重新装一个JDK,路径上别带空格

11.2 HDFS的资源jar包提取

为了方便开发,我们可以将相关的jar提取出来。

1. 在hadoop-2.7.6目录下创建以上目录(参考图片)
2. 进入share目录中的doc子目录,搜索default.xml。将四个默认的xml文件copy到_default目录中,方便以后查看
3. 进入share目录中,搜索*.jar。将搜索到的所有jar文件copy到_jars目录下,重复的跳过。大约208个jar包左右。
4. 在_jars目录中,搜索test,将搜索到的jar包剪切到_tests目录下。这是一些关于程序测试的jar包,提取出来。大约36个左右
5. 在_jars目录中,搜索source,将搜索到的jar包剪切到_sources目录下。这些jar包是hadoop的源码包。想看源码的可以使用,大约28个
6. 此时,_jars目录中剩下的都是hadoop的相关api的jar包,大约144个。

11.3 API之文件系统对象

@Test
public void testGetFileSystem() throws IOException {
    //创建配置对象,用于加载配置信息(四个默认的配置文件:core-default.xml,hdfs-default.xml,mapred-default.xml,yarn-default.xml)
    Configuration conf = new Configuration();
    //修改fs.defaultFS属性的值
    conf.set("fs.defaultFS","hdfs://192.168.10.101:8020");
    //使用FileSystem类的静态方法get(Configuration conf);返回fs.defaultFS定义的文件系统
    FileSystem fs = FileSystem.get(conf);
    System.out.println("文件系统对象的类型名:"+fs.getClass().getName());
}

11.4 API之文件上传

@Test
public void testFileUpload() throws IOException {
    Configuration conf = new Configuration();
    conf.set("fs.defaultFS","hdfs://192.168.10.101:8020");
    FileSystem fs = FileSystem.get(conf);
    //将本地的一个文件D:/file1,上传到HDFS上 /file1
    //1. 使用Path描述两个文件
    Path localPath = new Path("D:/file1");
    Path hdfsPath = new Path("/file1");
    //2.调用上传方法
    fs.copyFromLocalFile(localPath,hdfsPath);
    //3.关闭
    fs.close();
    System.out.println("上传成功");
}

11.5 API之文件下载

@Test
public void testFileDownload() throws IOException {
    Configuration conf = new Configuration();
    conf.set("fs.defaultFS","hdfs://192.168.10.101:8020");
    FileSystem fs = FileSystem.get(conf);
    //从HDFS上下载一个文件/file1,下载到本地 D:/file2
    //1. 使用Path描述两个文件
    Path hdfsfile = new Path("/file1");
    Path local = new Path("D:/file2");
    //2. 调用下载方法进行下载
    fs.copyToLocalFile(hdfsfile,local);
    fs.close();
    System.out.println("下载成功");
}

11.6 API之创建目录

@Test
public void testMkdir() throws IOException {
    Configuration conf = new Configuration();
    conf.set("fs.defaultFS","hdfs://192.168.10.101:8020");
    FileSystem fs = FileSystem.get(conf);

    //1. 测试创建目录,描述一个目录
    Path hdfsfile = new Path("/dir1");
    //2. 调用创建目录的方法
    fs.mkdirs(hdfsfile);
    fs.close();
    System.out.println("创建成功");
}

11.7 API之删除目录

@Test
public void testDelete() throws IOException {
    Configuration conf = new Configuration();
    conf.set("fs.defaultFS","hdfs://192.168.10.101:8020");
    FileSystem fs = FileSystem.get(conf);

    //1. 测试删除目录,描述一个目录
    Path hdfsfile = new Path("/dir1");
    //2. 调用创建目录的方法
    fs.delete(hdfsfile,true);
    fs.close();
    System.out.println("删除成功");
}

11.8 API之重命名

@Test
public void testRename() throws IOException {
    Configuration conf = new Configuration();
    conf.set("fs.defaultFS","hdfs://192.168.10.101:8020");
    FileSystem fs = FileSystem.get(conf);

    //1. 测试重命名,将file1改为file01
    Path oldName = new Path("/file1");
    Path newName = new Path("/file01");
    //2.调用重命名方法
    fs.rename(oldName,newName);
    fs.close();
    System.out.println("命名成功");
}

11.9 IOUtil上传文件

@Test
public void putFile() throws IOException, URISyntaxException {		
    //1 连接HDFS 文件系统	
    Configuration conf=new Configuration();		
    //获得文件系统
    FileSystem fs=FileSystem.get(new URI("hdfs://182.168.10.101:8020"),conf);
    // 创建输入流,读取输入文件		
    FileInputStream input=new FileInputStream(new File("c://a.txt"));
    // 创建输出流
    FSDataOutputStream out=fs.create(new Path("/gg.txt"));
    //IO的流拷贝
    IOUtils.copyBytes(input, out, conf);
    //关闭资源
    IOUtils.closeStream(input);
    IOUtils.closeStream(out);
    System.out.println("上传完毕");
}

11.10 IOUtil下载文件

@Test
public void getFile() throws IOException, URISyntaxException {
	// 1 连接HDFS 文件系统
	Configuration conf = new Configuration();
	// 获得文件系统
	FileSystem fs = FileSystem.get(new URI("hdfs://192.168.10.101:8020"), conf);
	// 获取输入流 从HDFS上读取
	FSDataInputStream  input=fs.open(new Path("/gg.txt"));
	// 获取输出流
	FileOutputStream out=new FileOutputStream(new File("c://gg.txt"));
	//流拷贝
	IOUtils.copyBytes(input, out, conf);
	//关闭流
	IOUtils.closeStream(input);
	IOUtils.closeStream(out);		
	System.out.println("下载完成");
}

11.11 API之文件状态

@Test
public void testFileStatus() throws IOException {
    Configuration conf = new Configuration();
    conf.set("fs.defaultFS","hdfs://192.168.10.101:8020");
    FileSystem fs = FileSystem.get(conf);
    //1. 描述你要读取的文件 /file02
    Path path = new Path("/file02");
    //获取文件的状态信息
    RemoteIterator<LocatedFileStatus> it = fs.listLocatedStatus(path);
    while(it.hasNext()){
        // 取出对象
        LocatedFileStatus status = it.next();
        System.out.println("name:"+status.getPath());
        //获取位置
        BlockLocation[] locate = status.getBlockLocations();
        for(BlockLocation bl:locate){
            System.out.println("当前块的所有副本位置:"+Arrays.toString(bl.getHosts()));
            System.out.println("当前块大小:"+bl.getLength());
            System.out.println("当前块的副本的ip地址信息:"+Arrays.toString(bl.getNames()));
        }
        System.out.println("系统的块大小:"+status.getBlockSize());
        System.out.println("文件总长度:"+status.getLen());
    }
}
  • 1
    点赞
  • 3
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

一个人的小样

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值