Hadoop
第一章 大数据的概述
1.1 大数据的概念
最近几年,IT行业最火的名词中,少不了"大数据"、“人工智能”、“云计算”、“物联网”、"区块链"等等这些名词。针对于**“大数据”**这个名词,现在更是全国老百姓,老少皆知的一个词语。但是什么是大数据,除了IT行业的专业人士外,其他人乃至其他行业的人,除了能说出"数据量大"之外,好像真的不能再更深层次的解释了。那么我们来看看下面几个权威机构给出的解释。
**维基百科 **给出的定义:
数据规模巨大到无法通过人工在合理的时间内达到截取,管理,处理并整理成为人类所解读的信息。
**麦肯锡全球研究所 **给出的定义:
一种规模大到在获取、存储、管理、分析方面都大大超出了传统数据库软件工具能力范围的数据集合。
**研究机构 **高德纳(Gartner)给出的定义:
"大数据"是需要新的处理模式才能具有更强的决策力、洞察发现力和流程优化能力来适应海量、高增长率和多样化的信息资产
概念总结:
海量数据,具有高增长率、数据类型多样化、一定时间内无法使用常规软件工具进行捕捉、管理和处理的数据集合。
1.2 大数据的特征
早在1980年,著名未来学家托夫勒在其所著的《第三次浪潮》中就热情地将“大数据”称颂为“第三次浪潮的华彩乐章”。《自然》杂志在2008年9月推出了名为“大数据”的封面专栏。从2009年开始“大数据”才成为互联网技术行业中的热门词汇。最早应用“大数据”的是世界著名的管理咨询公司麦肯锡公司,它看到了各种网络平台记录的个人海量信息具备潜在的商业价值,于是投入大量人力物力进行调研, 对“大数据”进行收集和分析的设想,在2011年6月发布了关于“大数据”的报告,该报告对“大数据”的影响、关键技术和应用领域等都进行了详尽的分析。麦肯锡的报告得到了金融界的高度重视,而后逐渐受到了各行各业关注。 那么大数据到底有什么特征呢?我们怎么去理解大数据呢?有专业人士总结了4V说法,也有相关机构总结了5V说法,甚至6V说法。不管哪种说法,下面四个特征,是大家普遍认可的。
- Volume : 巨大的数据量
-
Variety : 数据类型多样化
- 结构化的数据 : 即具有固定格式和有限长度的数据
- 半结构化的数据 : 是一些xml或者html格式的数据
- 非结构化的数据 : 现在非结构化的数据越来越多,就是不定长、无固定格式的数据,例如网页、语音、视频等
- Velocity : 数据增长速度快
- Value : 价值密度低,商业价值高
1.3 大数据的应用场景
有不了解大数据的人会问:**大数据能做啥?**问的好。
大数据本身是一个抽象的概念, 对当前无论是企业还是政府、或是高校等单位来说,是一个面临着数据无法存储、无法计算的状态的形容词。
那么大数据可以做什么呢?
在海量的各种各样类型的价值密度低的数据中,我们要进行的是:数据采集,数据存储,数据清洗,数据分析,数据可视化。
简单一句话,就是大数据让数据产生各种"价值"。可以说,大数据的核心作用就是"数据价值化",这个过程就是大数据要做的主要事情。那么就可以概括成:
- 记录已经发生的一切
- 描述正在发生的一切
- 预测将要发生的一切
大数据技术的战略意义不在于掌握庞大的数据信息,而在于对这些含有意义的数据进行专业化处理。
现在已经应用"大数据"的案例有:
- 预测犯罪
- 预测流感的爆发
- 预测选举
- 根据手机定位和交通数据,规划城市
- 根据库存和需求,实时调价
- 推动医疗信息化发展,远程医疗
1.4 大数据的发展前景
大数据技术目前正处在落地应用的初期,从大数据自身发展和行业发展的趋势来看,大数据未来的前景还是不错的,具体原因有以下几点:
- 大数据本身的价值体现,
本身的数据价值化就会开辟出很大的市场空间。目前在互联网领域,大数据技术已经得到了较为广泛的应用。 大数据造就了新兴行业
- 大数据推动了科技领域的发展
不仅体现在互联网领域,还体现在金融、教育、医疗等诸多领域,尤其是现在的人工智能。
- 大数据产业链的形成
经过近些年的发展,大数据已经初步形成了一个较为完整的产业链,包括数据采集、整理、传输、存储、分析、呈现和应用,众多企业开始参与到大数据产业链中,并形成了一定的产业规模,相信随着大数据的不断发展,相
关产业规模会进一步扩大。
- 国家大力扶持大数据行业的发展
第二章 Hadoop概述
2.1 为什么要用hadoop
现在的我们,生活在数据大爆炸的年代。2020年,全球的数据总量达到44ZB,经过单位换算后,至少在440亿TB以上,也就是说,全球每人一块1TB的硬盘都存储不下。
扩展: 数据大小单位,从小到大分别是: byte、kb、mb、Gb、Tb、PB、EB、ZB、DB、NB...
单位之间的转换都是满足1024
一些数据集的大小更远远超过了1TB,也就是说,数据的存储是一个要解决的问题。同时,硬盘技术也面临一个技术瓶颈,就是硬盘的传输速度(读数据的速度)的提升远远低于硬盘容量的提升。我们看下面这个表格:
可以看到,容量提升了将近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的发展历史
2.5 Hadoop的组成部分
hadoop2.0以后的四个模块:
- Hadoop Common:Hadoop模块的通用组件
- Hadoop Distributed File System:分布式文件系统
- Hadoop YARN:作业调度和资源管理框架
- Hadoop MapReduce:基于YARN的大型数据集并行计算处理框架
hadoop3.0新扩展的两个模块:
- Hadoop Ozone:Hadoop的对象存储机制
- Hadoop Submarine:Hadoop的机器学习引擎
2.6. Hadoop的生态系统
第三章 Hadoop集群安装
3.1 集群规划
集群规划 | 规划 |
---|---|
操作系统 | Mac、Windows |
虚拟软件 | Parallels Desktop(Mac)、VMWare(Windows) |
虚拟机 | 主机名: qianfeng01, IP地址: 192.168.10.101 主机名: qianfeng02, IP地址: 192.168.10.102 主机名: qianfeng03, IP地址: 192.168.10.103 |
软件包上传路径 | /root/softwares |
软件包安装路径 | /usr/local |
JDK | Jdk-8u221-linux-x64.tar.gz |
Hadoop | hadoop-2.7.6.tar.gz |
用户 | root |
3.1.1 服务器规划
因为搭建一个服务器集群需要至少一主两从,一共三台服务器,而且这三台服务器上很多配置和环境变量是重复的,所以我们可以配置好一些文件,省去我们后期的操作,主要包括下面的配置和环境:
- 安装对应的jdk和hadoop(hadoop有1x、2x、3x),并且分别配置jdk和hadoop的环境变量,并且使其环境变量生效
- 关闭防火墙,并关闭防火墙的自启动
- 确保/etc/hosts文件配置了IP和hosts的映射关系
- 确保三台机器的网络配置通畅(NAT模式、静态IP、主机名的配置),我们克隆服务器的时候,mac地址会重复,因此我们需要重新生成一下mac地址,这里要关闭DHCP(动态主机配置协议)
- 确保配置了三台机器的免密登录认证,生成自己的公钥和私钥
- 确保所有的机器时间同步,虚拟机关机的时候,时间会静止
- 新的centos虚拟机上只有vi,没有vim,介意的可以安装vim,vim用户体验更好一点。centos安装:
yum -y install vim*
;ubuntu安装:sudo apt-get install vim-gtk
3.1.2 安装三台虚拟机
使用VMware安装三台centos,其中第一台需要手动创建,二三台直接复制第一台即可(右键虚拟机- - -管理- - -克隆),然后需要更改网络配置,随机生成新的mac地址,使用桥接模式配置网络
- 需要保证可以相互ping通,在同一子网段下
使用ssh工具连接三台服务器,这里使用FinalShell
3.2 安装JDK
3.2.1 检查一下是否已经安装过或者系统内置JDK,如果有内置的,将其卸载
[root@qianfeng01 ~]# rpm -qa | grep jdk # 如果有,请卸载
[root@qianfeng01 ~]# rpm -e xxxxxxxx --nodeps # 将查询到的内置jdk强制卸载
3.2.2 上传jdk1.8和hadoop2.6.7
将jdk-8u221-linux-x64.tar.gz上传到/root目录中
3.2.3 解压jdk和hadoop到/usr/local/下
[root@qianfeng01 ~]# tar -zxvf jdk-8u221-linux-x64.tar.gz -C /usr/local
3.2.4 更名jdk和hadoop
[root@qianfeng01 ~]# cd /usr/local
[root@qianfeng01 local]# mv jdk1.8.0_221/ jdk
3.2.5 配置Jdk的环境变量:/etc/profile
[root@qianfeng01 local]# vi /etc/profile
.........省略...........
#jdk environment
export JAVA_HOME=/usr/local/jdk
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
3.2.6 使当前窗口生效
[root@qianfeng01 local]# source /etc/profile
3.2.7 验证jdk环境
[root@qianfeng01 local]# java -version
[root@qianfeng01 local]# javac
3.3. 完全分布式环境需求及安装
1. 三台机器的防火墙必须是关闭的
2. 确保三台机器的网络配置通常(NAT模式、静态IP、主机名的配置)
3. 确保/etc/hosts文件配置了IP和hosts的映射关系
4. 确保配置了三台机器的免密登录认证
5. 确保所有的机器时间同步
6. JDK和Hadoop的环境变量配置
3.3.1 关闭防火墙
systemctl stop firewalld #关闭防火墙
systemctl disable firewalld
systemctl stop NetworkManager
systemctl disable NetworkManager
systemctl disable firewalld.service #关闭防火墙自启动
#最好也把selinux关闭掉,这是linux系统的一个安全机制,进入文件中将SELINUX设置为disabled
[root@qianfeng01 ~]# vi /etc/selinux/config
.........
SELINUX=disabled
.........
3.3.2 静态IP和主机名配置
--1. 配置静态IP(确保NAT模式)
[root@qianfeng01 ~]# vi /etc/sysconfig/network-scripts/ifcfg-ens33
............
BOOTPROTO=static # 将dhcp改为static,固定主机ip和主机名的映射
............
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@qianfeng01 ~]# systemctl restart network
或者
[root@qianfeng01 ~]# service network restart
--3. 修改主机名(如果修改过,请略过这一步)
[root@localhost ~]# hostnamectl set-hostname qianfeng01
或者
[root@localhost ~]# vi /etc/hostname
qianfeng01
3.3.3 配置/etc/hosts文件
[root@qianfeng01 ~]# vi /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.10.101 qianfeng01 #添加本机的静态IP和本机的主机名之间的映射关系
192.168.10.102 qianfeng02
192.168.10.103 qianfeng03
3.3.4 免密登录认证
-1. 使用rsa加密技术,生成公钥和私钥。一路回车即可
[root@qianfeng01 ~]# cd ~
[root@qianfeng01 ~]# ssh-keygen -t rsa
-2. 进入~/.ssh目录下,使用ssh-copy-id命令
[root@qianfeng01 ~]# cd ~/.ssh
[root@qianfeng01 .ssh]# ssh-copy-id root@qianfeng01
-3. 进行验证
[hadoop@qianfeng01 .ssh]# ssh qianfeng01
#下面的第一次执行时输入yes后,不提示输入密码就对了
[hadoop@qianfeng01 .ssh]# ssh localhost
[hadoop@qianfeng01 .ssh]# ssh 0.0.0.0
注意:三台机器提前安装好的情况下,需要同步公钥文件。如果使用克隆技术。那么使用同一套密钥对就方便多了。
3.3.5 时间同步
# 1 选择集群中的某一台机器作为时间服务器,例如qianfeng01
# 2 保证这台服务器安装了ntp.x86_64。
# 3 保证ntpd 服务运行......
[root@qianfeng01 ~]# sudo service ntpd start
# 开机自启动:
[root@qianfeng01 ~]# chkconfig ntpd on
# 4 配置相应文件:
[root@qianfeng01 ~]# vi /etc/ntp.conf
# Hosts on local network are less restricted.
# restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
# 添加集群中的网络段位
restrict 192.168.10.0 mask 255.255.255.0 nomodify notrap
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
# server 0.centos.pool.ntp.org iburst 注释掉
# server 1.centos.pool.ntp.org iburst 注释掉
# server 2.centos.pool.ntp.org iburst 注释掉
# server 3.centos.pool.ntp.org iburst 注释掉
server 127.127.1.0 -master作为服务器
# 5 其他机器要保证安装ntpdate.x86_64
# 6 其他机器要使用root定义定时器
*/1 * * * * /usr/sbin/ntpdate -u qianfeng01
3.3.6 Hadoop安装与环境变量配置
# 1. 上传和解压两个软件包
[root@qianfeng01 ~]# tar -zxvf jdk-8u221-linux-x64.tar.gz -C /usr/local/
[root@qianfeng01 ~]# tar -zxvf hadoop-2.7.6.tar.gz -C /usr/local/
# 2. 进入local里,给两个软件更名
[root@qianfeng01 ~]# cd /usr/local/
[root@qianfeng01 local]# mv 1.8.0_221/ jdk
[root@qianfeng01 local]# mv hadoop-2.7.6/ hadoop
# 3. 配置环境变量
[hadoop@qianfeng01 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
3.4. Hadoop的配置文件
3.4.1. 概述
我们需要通过配置若干配置文件,来实现Hadoop集群的配置信息
(这里Hadoop2.x和3.x配置信息略有不同,本文主要以2.x为主)。需要配置的文件有:
hadoop-env.sh
yarn-env.sh
core-site.xml
hdfs-site.xml
mapred-site.xml
yarn-site.xml
在Hadoop安装完成后,会在$HADOOP_HOME/share路径下,有若干个*-default.xml文件,
这些文件中记录了默认的配置信息。同时,在代码中,我们也可以设置Hadoop的配置信息。
这些位置配置的Hadoop,优先级为: 代码设置 > *-site.xml > *-default.xml
集群规划:
+--------------+---------------------+
| Node | Applications |
+--------------+---------------------+
| qianfeng01 | NameNode |
| | DataNode |
| | ResourceManager |
| | NodeManagere |
+--------------+---------------------+
| qianfeng02 | SecondaryNameNode |
| | DataNode |
| | NodeManager |
+--------------+---------------------+
| qianfeng03 | DataNode |
| | NodeManager |
+--------------+---------------------+
3.4.2. core-site.xml
[root@qianfeng01 ~]# cd $HADOOP_HOME/etc/hadoop
[root@qianfeng01 hadoop]# vi core-site.xml
<configuration>
<!-- hdfs的地址名称:schame,ip,port-->
<!-- 在Hadoop1.x的版本中,默认使用的端口是9000。
在Hadoop2.x的版本中,默认使用端口是8020 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://qianfeng01:8020</value>
</property>
<!-- hdfs的基础路径,被其他属性所依赖的一个基础路径 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/usr/local/hadoop/tmp</value>
</property>
</configuration>
3.4.3. hdfs-site.xml
[root@qianfeng01 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>qianfeng02:50090</value>
</property>
<!-- namenode守护进程的http地址:主机名和端口号。参考守护进程布局-->
<property>
<name>dfs.namenode.http-address</name>
<value>qianfeng01:50070</value>
</property>
</configuration>
3.4.4. mapred-site.xml
[root@qianfeng01 hadoop]# cp mapred-site.xml.template mapred-site.xml
[root@qianfeng01 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>qianfeng01:10020</value>
</property>
<!-- 配置作业历史服务器的http地址-->
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>qianfeng01:19888</value>
</property>
</configuration>
3.4.5 yarn-site.xml
[root@qianfeng01 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>qianfeng01</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>qianfeng01:8032</value>
</property>
<!--配置resourcemanager的scheduler的内部通讯地址-->
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>qianfeng01:8030</value>
</property>
<!--配置resoucemanager的资源调度的内部通讯地址-->
<property>
<name>yarn.resourcemanager.resource-tracker.address</name>
<value>qianfeng01:8031</value>
</property>
<!--配置resourcemanager的管理员的内部通讯地址-->
<property>
<name>yarn.resourcemanager.admin.address</name>
<value>qianfeng01:8033</value>
</property>
<!--配置resourcemanager的web ui 的监控页面-->
<property>
<name>yarn.resourcemanager.webapp.address</name>
<value>qianfeng01:8088</value>
</property>
</configuration>
3.4.6 hadoop-env.sh
[root@qianfeng01 hadoop]# vi hadoop-env.sh
# The java implementation to use.
export JAVA_HOME=/usr/local/jdk
3.4.7 yarn-env.sh
[root@qianfeng01 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
3.4.8 slaves
此文件用于指定datanode守护进程所在的机器节点主机名 ,3.x中是workers,配置不一样
[root@qianfeng01 hadoop]# vi slaves
qianfeng01
qianfeng02
qianfeng03
3.4.9 分发到另外两台节点
# 同步Hadoop到另外两台节点
[root@qianfeng01 ~]# cd /usr/local
[root@qianfeng02 local]# scp -r hadoop qianfeng02:$PWD
[root@qianfeng02 local]# scp -r hadoop qianfeng03:$PWD
# 同步profile到另外两台节点
[root@qianfeng01 ~]# scp /etc/profile qianfeng02:/etc
[root@qianfeng01 ~]# scp /etc/profile qianfeng03:/etc
# 检查slave节点上的jdk是否已安装
# 检查是否同步了/etc/hosts文件
3.5 格式化与启动
3.5.1 格式化集群
**1)**在qianfeng01机器上运行命令
[root@qianfeng01 ~]# hdfs namenode -format
**2)**格式化的相关信息解读
--1. 生成一个集群唯一标识符:clusterid
--2. 生成一个块池唯一标识符:blockPoolId
--3. 生成namenode进程管理内容(fsimage)的存储路径:
默认配置文件属性hadoop.tmp.dir指定的路径下生成dfs/name目录
--4. 生成镜像文件fsimage,记录分布式文件系统根路径的元数据
--5. 其他信息都可以查看一下,比如块的副本数,集群的fsOwner等。
参考图片:
3) 目录里的内容查看
3.5.2 启动集群
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]
**2) ** 启动HDFS
使用start-dfs.sh,启动 hdfs。参考图片
启动过程解析:
- 启动集群中的各个机器节点上的分布式文件系统的守护进程
一个namenode和resourcemanager以及secondarynamenode
多个datanode和nodemanager
- 在namenode守护进程管理内容的目录下生成edit日志文件
- 在每个datanode所在节点下生成${hadoop.tmp.dir}/dfs/data目录,参考下图:
注意!
如果哪台机器的相关守护进程没有开启,那么,就查看哪台机器上的守护进程对应的日志log文件,
注意,启动脚本运行时提醒的日志后缀是*.out,而我们查看的是*.log文件。
此文件的位置:${HADOOP_HOME}/logs/里
3) jps查看进程
--1. 在qianfeng01上运行jps指令,会有如下进程
namenode
datanode
--2. 在qianfeng02上运行jps指令,会有如下进程
secondarynamenode
datanode
--3. 在qianfeng03上运行jps指令,会有如下进程
datanode
**4) **启动yarn
使用start-yarn.sh脚本,参考图片
jps查看
--1. 在qianfeng01上运行jps指令,会多出有如下进程
resoucemanager
nodemanager
--2. 在qianfeng02上运行jps指令,会多出有如下进程
nodemanager
--3. 在qianfeng03上运行jps指令,会多出有如下进程
nodemanager
5) webui查看
HDFS: http://192.168.10.101:50070
YARN: http://192.168.10.101:8088
第四章 HDFS的Shell命令
HDFS其实就是一个分布式的文件系统,我们可以使用一些命令来操作这个分布式文件系统上的文件。
- 访问HDFS的命令:
hadoop dfs --- 已过时
hdfs dfs
- 小技巧
1. 在命令行中输入hdfs,回车后,就会提示hdfs后可以使用哪些命令,其中有一个是dfs。
2. 在命令行中输入hdfs dfs,回车后,就会提示dfs后可以添加的一些常用shell命令。
- 注意事项
分布式文件系统的路径在命令行中,要从/开始写,即绝对路径。
4.1 创建目录
[-mkdir [-p] <path> ...] #在分布式文件系统上创建目录 -p,多层级创建
调用格式: hdfs dfs -mkdir (-p) /目录
例如:
- hdfs dfs -mkdir /data
- hdfs dfs -mkdir -p /data/a/b/c
4.2 上传指令
[-put [-f] [-p] [-l] <localsrc> ... <dst>] #将本地文件系统的文件上传到分布式文件系统
调用格式:hdfs dfs -put /本地文件 /分布式文件系统路径
注意: 直接写/是省略了文件系统的名称hdfs://ip:port。
例如:
- hdfs dfs -put /root/a.txt /data/
- hdfs dfs -put /root/logs/* /data/
其他指令:
[-moveFromLocal <localsrc> ... <dst>] #将本地文件系统的文件上传到分布式文件系统
[-copyFromLocal [-f] [-p] [-l] <localsrc> ... <dst>]
4.3 创建空文件
hdfs dfs [generic options] -touchz <path> ...
调用格式:hdfs dfs touchz /hadooptest.txt
4.4 向分布式文件系统中的文件里追加内容
[-appendToFile <localsrc> ... <dst>]
调用格式:hdfs dfs -appendToFile 本地文件 hdfs上的文件
注意:不支持在中间随意增删改操作
4.5 查看指令
[-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.6 下载指令
[-copyToLocal [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
注意:本地路径的文件夹可以不存在
[-moveToLocal <src> <localdst>]
注意:从hdfs的某个路径将数据剪切到本地,已经被遗弃了
[-get [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
调用格式:同copyToLocal
4.7 合并下载
hdfs dfs [generic options] -getmerge [-nl] <src> <localdst>
调用格式:hdfs dfs -getmerge hdfs上面的路径 本地的路径
实例:hdfs dfs -getmerge /hadoopdata/*.xml /root/test.test
4.8 移动hdfs中的文件(更名)
hdfs dfds [generic options] -mv <src> ... <dst>
调用格式:hdfs dfs -mv /hdfs的路径1 /hdfs的另一个路径2
实例:hfds dfs -mv /aaa /bbb 这里是将aaa整体移动到bbb中
4.9 复制hdfs中的文件到hdfs的另一个目录
hdfs dfs [generic options] -cp [-f] [-p | -p[topax]] <src> ... <dst>
调用格式:hdfs dfs -cp /hdfs路径_1 /hdfs路径_2
4.10 删除命令
[-rm [-f] [-r|-R] [-skipTrash] <src> ...]
注意:如果删除文件夹需要加-r
[-rmdir [--ignore-fail-on-non-empty] <dir> ...]
注意:必须是空文件夹,如果非空必须使用rm删除
4.11 查看磁盘利用率和文件大小
[-df [-h] [<path> ...]] 查看分布式系统的磁盘使用情况
[-du [-s] [-h] <path> ...] #查看分布式系统上当前路径下文件的情况 -h:human 以人类可读的方式显示
4.12 修改权限的
跟本地的操作一致,-R是让子目录或文件也进行相应的修改
[-chgrp [-R] GROUP PATH...]
[-chmod [-R] <MODE[,MODE]... | OCTALMODE> PATH...]
[-chown [-R] [OWNER][:[GROUP]] PATH...]
4.13 修改文件的副本数
[-setrep [-R] [-w] <rep> <path> ...]
调用格式:hadoop fs -setrep 3 / 将hdfs根目录及子目录下的内容设置成3个副本
注意:当设置的副本数量与初始化时默认的副本数量不一致时,集群会作出反应,比原来多了会自动进行复制.
4.14 查看文件的状态
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,只有文件才有副本和大小
4.15 测试
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
第五章 HDFS的块的概念
5.1 传统型分布式文件系统的缺点
现在想象一下这种情况:有四个文件 0.5TB的file1,1.2TB的file2,50GB的file3,100GB的file4;有7个服务器,每个服务器上有10个1TB的硬盘。
在存储方式上,我们可以将这四个文件存储在同一个服务器上(当然大于1TB的文件需要切分)。那么缺点也就暴露了出来:
第一、负载不均衡。
因为文件大小不一致,势必会导致有的节点磁盘的利用率高,有的节点磁盘利用率低。
第二、网络瓶颈问题。
一个过大的文件存储在一个节点磁盘上,当有并行处理时,每个线程都需要从这个节点磁盘上读取这个文件的内容,那么就会出现网络瓶颈,不利于分布式的数据处理。
5.2 HDFS的块
HDFS与其他普通文件系统一样,同样引入了块(Block)的概念,并且块的大小是固定的。但是不像普通文件系统那样小,而是根据实际需求可以自定义的。块是HDFS系统当中的最小存储单位,在hadoop2.0中默认大小为128MB(hadoop1.x中的块大小为64M)。在HDFS上的文件会被拆分成多个块,每个块作为独立的单元进行存储。多个块存放在不同的DataNode上,整个过程中 HDFS系统会保证一个块存储在一个数据节点上 。但值得注意的是,如果某文件大小或者文件的最后一个块没有到达128M,则不会占据整个块空间 。
我们来看看HDFS的设计思想:以下图为例,来进行解释。
5.3 HDFS的块大小
HDFS上的块大小为什么会远远大于传统文件?
1. 目的是为了最小化寻址开销时间。
在I/O开销中,机械硬盘的寻址时间是最耗时的部分,一旦找到第一条记录,剩下的顺序读取效率是非常高的,因此以块为单位读写数据,可以尽量减少总的磁盘寻道时间。
HDFS寻址开销不仅包括磁盘寻道开销,还包括数据块的定位开销,当客户端需要访问一个文件时,首先从名称节点获取组成这个文件的数据块的位置列表,然后根据位置列表获取实际存储各个数据块的数据节点的位置,最后,数据节点根据数据块信息在本地Linux文件系统中找到对应的文件,并把数据返回给客户端,设计成一个比较大的块,可以减少每个块儿中数据的总的寻址开销,相对降低了单位数据的寻址开销
磁盘的寻址时间为大约在5~15ms之间,平均值为10ms,而最小化寻址开销时间普遍认为占1秒的百分之一是最优的,那么块大小的选择就参考1秒钟的传输速度,比如2010年硬盘的传输速率是100M/s,那么就选择块大小为128M。
2. 为了节省内存的使用率
一个块的元数据大约150个字节。1亿个块,不论大小,都会占用20G左右的内存。因此块越大,集群相对存储的数据就越多。所以暴漏了HDFS的一个缺点,不适合存储小文件。
不适合存储小文件解释:
1. 从存储能力出发(固定内存)
因为HDFS的文件是以块为单位存储的,且如果文件大小不到128M的时候,是不会占用整个块的空间的。但是,这个块依然会在内存中占用150个字节的元数据。因此,同样的内存占用的情况下,大量的小文件会导致集群的存储能力不足。
例如: 同样是128G的内存,最多可存储9.2亿个块。如果都是小文件,例如1M,则集群存储的数据大小为9.2亿*1M = 877TB的数据。但是如果存储的都是128M的文件,则集群存储的数据大小为109.6PB的数据。存储能力大不相同。
2. 从内存占用出发(固定存储能力)
同样假设存储1M和128M的文件对比,同样存储1PB的数据,如果是1M的小文件存储,占用的内存空间为1PB/1Mb*150Byte = 150G的内存。如果存储的是128M的文件存储,占用的内存空间为1PB/128M*150Byte = 1.17G的内存占用。可以看到,同样存储1PB的数据,小文件的存储比起大文件占用更多的内存。
5.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>
5.5 块的存储位置
在hdfs-site.xml
中我们配置过下面这个属性,这个属性的值就是块在linux系统上的存储位置
<!-- 确定DFS数据节点应该将其块存储在本地文件系统的何处-->
<property>
<name>dfs.datanode.data.dir</name>
<value>file://${hadoop.tmp.dir}/dfs/data</value>
</property>
5.6 HDFS的优点
1. 高容错性(硬件故障是常态):数据自动保存多个副本,副本丢失后,会自动恢复
2. 适合大数据集:GB、TB、甚至PB级数据、千万规模以上的文件数量,1000以上节点规模。
3. 数据访问: 一次性写入,多次读取;保证数据一致性,安全性
4. 构建成本低:可以构建在廉价机器上。
5. 多种软硬件平台中的可移植性
6. 高效性:Hadoop能够在节点之间动态地移动数据,并保证各个节点的动态平衡,因此处理速度非常快。
7. 高可靠性:Hadoop的存储和处理数据的能力值得人们信赖.
5.7 HDFS的缺点
1. 不适合做低延迟数据访问:
HDFS的设计目标有一点是:处理大型数据集,高吞吐率。这一点势必要以高延迟为代价的。因此HDFS不适合处理用户要求的毫秒级的低延迟应用请求
2. 不适合小文件存取:
一个是大量小文件需要消耗大量的寻址时间,违反了HDFS的尽可能减少寻址时间比例的设计目标。第二个是内存有限,一个block元数据大内存消耗大约为150个字节,存储一亿个block和存储一亿个小文件都会消耗20G内存。因此相对来说,大文件更省内存。
3. 不适合并发写入,文件随机修改:
HDFS上的文件只能拥有一个写者,仅仅支持append操作。不支持多用户对同一个文件的写操作,以及在文件任意位置进行修改
第六章 HDFS的体系结构
6.1 体系结构解析
HDFS采用的是master/slaves这种主从的结构模型来管理数据,这种结构模型主要由四个部分组成,分别是Client(客户端)、Namenode(名称节点)、Datanode(数据节点)和SecondaryNameNode。
真正的一个HDFS集群包括一个Namenode和若干数目的Datanode。
Namenode是一个中心服务器,负责管理文件系统的命名空间 (Namespace),它在内存中维护着命名空间的最新状态,同时并持久性文件(fsimage和edit)进行备份,防止宕机后,数据丢失。namenode还负责管理客户端对文件的访问,比如权限验证等。
集群中的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也可以在一台机器上,只不过实际部署中,通常不会这么做的
6.2 开机启动HDFS的过程
6.2.1 非第一次启动集群
我们应该知道,在启动namenode之前,内存里是没有任何有关于元数据的信息的。那么启动集群的过程是怎样的呢?下面来叙述一下:
第一步:
Namenode在启动时,会先加载name目录下最近的fsimage文件.
将fsimage里保存的元数据加载到内存当中,这样内存里就有了之前检查点里存储的所有元数据。但是还少了从最近一次检查时间点到关闭系统时的部分数据,也就是edit日志文件里存储的数据。
第二步:
加载剩下的edit日志文件
将从最近一次检查点到目前为止的所有的日志文件加载到内存里,重演一次客户端的操作,这样,内存里就是最新的文件系统的所有元数据了。
第三步:
进行检查点设置(满足条件会进行)
namenode会终止之前正在使用的edit文件,创建一个空的edit日志文件。然后将所有的未合并过的edit日志文件和fsimage文件进行合并,产生一个新的fsimage.
第四步:
处于安全模式下,等待datanode节点的心跳反馈,当收到99.9%的块的至少一个副本后,退出安全模式,开始转为正常状态。
6.2.2 第一次启动集群
6.3 SecondaryNameNode的工作机制
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再进行更名操作。
第七章 HDFS的读写流程
7.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
7.2 写流程的详解
写操作:
- hdfs dfs -put ./file02 /file02
- hdfs dfs -copyFromLocal ./file02 /file02
- FSDataOutputStream fsout = fs.create(path);fsout.write(byte[])
- fs.copyFromLocal(path1,path2)
1. 客户端通过对DistributedFileSystem对象调用create()方法来新建文件
2. DistributedFileSystem对namenode创建一个RPC调用,在文件系统的命名空间中新建一个文件,此时该文件中还没有相应的数据块
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)
第八章 Zookeeper的概述
8.1 Zookeeper是什么
1. zookeeper是一个为分布式应用程序提供的一个分布式开源协调服务框架。是Google的Chubby的一个开源实现,是Hadoop和Hbase的重要组件。主要用于解决分布式集群中应用系统的一致性问题。
2. 提供了基于类似Unix系统的目录节点树方式的数据存储。
3. 可用于维护和监控存储的数据的状态的变化,通过监控这些数据状态的变化,从而达到基于数据的集群管理
4. 提供了一组原语(机器指令),提供了java和c语言的接口
8.2 Zookeeper的特点
1. 也是一个分布式集群,一个领导者(leader),多个跟随者(follower).
2. 集群中只要有半数以上的节点存活,Zookeeper集群就能正常服务。
3. 全局数据一致性:每个server保存一份相同的数据副本,client无论连接到哪个server,数据都是一致的。
4. 更新请求按顺序进行:来自同一个client的更新请求按其发送顺序依次执行
5. 数据更新的原子性:一次数据的更新要么成功,要么失败
6. 数据的实时性:在一定时间范围内,client能读到最新数据。
8.3 Zookeeper的数据模型
Zookeeper的数据模型采用的与Unix文件系统类似的层次化的树形结构。我们可以将其理解为一个具有高可用特征的文件系统。这个文件系统中没有文件和目录,而是统一使用"节点"(node)的概念,称之为znode。znode既可以作为保存数据的容器(如同文件),也可以作为保存其他znode的容器(如同目录)。所有的znode构成了一个层次化的命名空间。
- Zookeeper 被设计用来实现协调服务(这类服务通常使用小数据文件),而不是用于大容量数据存储,因此一个znode能存储的数据被限制在1MB以内,
- 每个znode都可以通过其路径唯一标识。
8.4 Zookeeper的应用场景
1. 统一配置管理
2. 统一集群管理
3. 服务器节点动态上下线感知
4. 软负载均衡等
5. 分布式锁
6. 分布式队列
第九章 Zookeeper的安装
9.1. 安装与环境变量的配置
1. 将zookeeper-3.4.10.tar.gz上传到/root中
2. 解压
[root@qianfeng01 ~]# tar -zxvf zookeeper-3.4.10.tar.gz -C /opt/apps/
3. 更名zookeeper
[root@qianfeng01 ~]# cd /opt/apps/
[root@qianfeng01 local]# mv zookeeper-3.4.10 zookeeper
4. 配置环境变量
[root@qianfeng01 local]# vi /etc/profile
.........省略......
export ZOOKEEPER_HOME=/opt/apps/zookeeper
export PATH=$ZOOKEEPER_HOME/bin:$PATH
5. 使当前会话生效
[root@qianfeng01 local]# source /etc/profile
6. 检查如下:
如果只检查环境变量是否配置成功,只需要使用tab键进行补全zk,是否zookeeper的相关脚本提示即可。
9.2. 集群模式的配置
9.2.1 Zookeeper的服务进程布局
qianfeng01 QuorumPeerMain
qianfeng02 QuorumPeerMain
qianfeng03 QuorumPeerMain
9.2.2 修改zoo.cfg文件
[root@qianfeng01 local]# cd ./zookeeper/conf/
[root@qianfeng01 conf]# cp zoo_sample.cfg zoo.cfg #复制出zoo.cfg文件
[root@qianfeng01 conf]# vi zoo.cfg
tickTime=2000 # 定义的时间单元(单位毫秒),下面的两个值都是tickTime的倍数。
initLimit=10 # follower连接并同步leader的初始化连接时间。
syncLimit=5 # 心跳机制的时间(正常情况下的请求和应答的时间)
dataDir=/usr/local/zookeeper/zkData # 修改zookeeper的存储路径,zkData目录一会要创建出来
clientPort=2181 # 客户端连接服务器的port
server.1=qianfeng01:2888:3888 # 添加三个服务器节点
server.2=qianfeng02:2888:3888
server.3=qianfeng03:2888:3888
解析Server.id=ip:port1:port2
id: 服务器的id号,对应zkData/myid文件内的数字
ip: 服务器的ip地址
port1: follower与leader交互的port
port2: 选举期间使用的port
注意:此配置文件中,不支持汉字注释
9.2.3 添加myid
# 在$ZOOKEEPER_HOME/zkData目录下添加myid文件,内容为server的id号
[root@qianfeng01 conf]# cd ..
[root@qianfeng01 zookeeper]# mkdir zkData
[root@qianfeng01 zookeeper]# cd zkData
[root@qianfeng01 zkData]# echo "1" >> myid
9.2.4 搭建其他两个server节点的环境
**1)**使用scp命令将zookeeper环境 复制到qianfeng02和qianfeng03中
[root@qianfeng01 zkData]# cd /usr/local
[root@qianfeng01 apps]# scp -r zookeeper qianfeng02:/usr/local
[root@qianfeng01 apps# scp -r zookeeper qianfeng03:/usr/local
2) 使用scp命令拷贝/etc/profile到两台机器上(别忘记source一下)
[root@qianfeng01 apps]# scp /etc/profile qianfeng02:/etc/
[root@qianfeng01 apps]# scp /etc/profile qianfeng03:/etc/
3) 修改qianfeng02的myid文件的内容为2
[root@qianfeng01 ~]# ssh qianfeng02
[root@qianfeng02 ~]# echo "2" > /opt/apps/zookeeper/zkData/myid
4) 修改qianfeng03的myid文件的内容为3
[root@qianfeng02 ~]# ssh qianfeng03
[root@qianfeng03 ~]# echo "3" > /opt/apps/zookeeper/zkData/myid
9.2.5 启动zookeeper
**1)**三台机器上都启动zookeeper的服务 (注意保证防火墙是关闭的)
[root@qianfeng01 ~]# zkServer.sh start
再查看一下状态
[root@qianfeng01 ~]# zkServer.sh status
2) 启动客户端的操作:
zkCli.sh [-server] [ ip:port]
reg:
[root@qianfeng01 ~]# zkCli.sh #启动客户端,连接本地服务进程
[root@qianfeng01 ~]# zkCli.sh -server qianfeng02:2181 #启动客户端,连接qianfeng02上的服务进程
第十章 Zookeeper的Shell操作
命令 | 描述 | 示例 |
---|---|---|
ls | 查看某个目录包含的所有文件 | ls / |
ls2 | 查看某个目录包含的所有文件,与ls不同的是它查看到time、version等信息 | ls2 / |
create | 创建znode,并需要设置初始内容 | create /test “test” create -e /test “test” |
get | 获取znode的数据 | get /test |
set | 修改znode的内容 | set /test “test2” |
delete | 删除znode | delete /test |
quit | 退出客户端 | |
help | 帮助命令 |
第十一章 YARN的概述
为克服Hadoop 1.0中HDFS和MapReduce存在的各种问题而提出的,针对Hadoop 1.0中的MapReduce在扩展性和多框架支持方面的不足,提出了全新的资源管理框架YARN.
Apache YARN(Yet another Resource Negotiator的缩写)是Hadoop集群的资源管理系统,负责为计算程序提供服务器计算资源,相当于一个分布式的操作系统平台,而MapReduce等计算程序则相当于运行于操作系统之上的应用程序。
yarn被引入Hadoop2,最初是为了改善MapReduce的实现,但是因为具有足够的通用性,同样可以支持其他的分布式计算模式,比如Spark,Tez等计算框架。
第十二章 YARN的架构及组件
12.1. MapReduce 1.x的简介
第一代Hadoop,由分布式存储系统HDFS和分布式计算框架MapReduce组成,其中,HDFS由一个NameNode和多个DataNode组成,MapReduce由一个JobTracker和多个TaskTracker组成,对应Hadoop版本为Hadoop 1.x和0.21.X,0.22.x。
1) MapReduce1的角色
-1.Client :作业提交发起者。
-2.JobTracker :初始化作业,分配作业,与TaskTracker通信,协调整个作业。
-3.TaskTracker :保持JobTracker通信,在分配的数据片段上执行MapReduce任务。
2) MapReduce执行流程
**步骤1)**提交作业
编写MapReduce程序代码,创建job对象,并进行配置,比如输入和输出路径,压缩格式等,然后通过JobClinet来提交作业。
**步骤2)**作业的初始化
客户端提交完成后,JobTracker会将作业加入队列,然后进行调度,默认的调度方法是FIFO调试方式。
**步骤3)**任务的分配
TaskTracker和JobTracker之间的通信与任务的分配是通过心跳机制完成的。
TaskTracker会主动向JobTracker询问是否有作业要做,如果自己可以做,那么就会申请到作业任务,这个任务可以是MapTask也可能是ReduceTask。
**步骤4)**任务的执行
申请到任务后,TaskTracker会做如下事情:
-1. 拷贝代码到本地
-2. 拷贝任务的信息到本地
-3. 启动JVM运行任务
**步骤5)**状态与任务的更新
任务在运行过程中,首先会将自己的状态汇报给TaskTracker,然后由TaskTracker汇总告之JobTracker。任务进度是通过计数器来实现的。
步骤6) 作业的完成
JobTracker是在接受到最后一个任务运行完成后,才会将任务标记为成功。此时会做删除中间结果等善后处理工作。
12.2. YARN的设计思想
yarn的基本思想是将资源管理和作业调度/监视功能划分为单独的守护进程。其思想是拥有一个全局ResourceManager (RM),以及每个应用程序拥有一个ApplicationMaster (AM)。应用程序可以是单个作业,也可以是一组作业
一个ResourceManager和多个NodeManager构成了yarn资源管理框架。他们是yarn启动后长期运行的守护进程,来提供核心服务。
ResourceManager,是在系统中的所有应用程序之间仲裁资源的最终权威,即管理整个集群上的所有资源分配,内部含有一个Scheduler(资源调度器)
NodeManager,是每台机器的资源管理器,也就是单个节点的管理者,负责启动和监视容器(container)资源使用情况,并向ResourceManager及其 Scheduler报告使用情况
container:即集群上的可使用资源,包含cpu、内存、磁盘、网络等
ApplicationMaster(简称AM)实际上是框架的特定的库,每启动一个应用程序,都会启动一个AM,它的任务是与ResourceManager协商资源,并与NodeManager一起执行和监视任务
**扩展)**YARN与MapReduce1的比较
12.3. YARN的配置
yarn属于hadoop的一个组件,不需要再单独安装程序,hadoop中已经存在配置文件的设置,本身就是一个集群,有主节点和从节点。
注意<value></value>之间的值不能有空格
在mapred-site.xml中的配置如下:
<!--用于执行MapReduce作业的运行时框架-->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!--历史任务的内部通讯地址-->
<property>
<name>MapReduce.jobhistory.address</name>
<value>qianfeng01:10020</value>
</property>
<!--历史任务的外部监听页面-->
<property>
<name>MapReduce.jobhistory.webapp.address</name>
<value>qianfeng01:19888</value>
</property>
在yarn-site.xml中的配置如下:
<!--配置resourcemanager的主机-->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>qianfeng01</value>
</property>
<!--配置yarn的shuffle服务-->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!--指定shuffle对应的类 -->
<property>
<name>yarn.nodemanager.aux-services.MapReduce_shuffle.class</name>
<value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>
<!--配置resourcemanager的scheduler的内部通讯地址-->
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>qianfeng01:8030</value>
</property>
<!--配置resoucemanager的资源调度的内部通讯地址-->
<property>
<name>yarn.resourcemanager.resource-tracker.address</name>
<value>qianfeng01:8031</value>
</property>
<!--配置resourcemanager的内部通讯地址-->
<property>
<name>yarn.resourcemanager.address</name>
<value>qianfeng01:8032</value>
</property>
<!--配置resourcemanager的管理员的内部通讯地址-->
<property>
<name>yarn.resourcemanager.admin.address</name>
<value>qianfeng01:8033</value>
</property>
<!--配置resourcemanager的web ui 的监控页面-->
<property>
<name>yarn.resourcemanager.webapp.address</name>
<value>qianfeng01:8088</value>
</property>
1) 日志位置
jps:当启动进程时出错了解决步骤:可以查看日志
如果是hdfs上的问题,则查看对应的日志
less 或 tail -1000 $HADOOP_HOME/logs/hadoop-{user.name}-{jobname}-{hostname}.log
如果是yarn,则查看
less 或 tail -1000 $HADOOP_HOME/logs/yarn-{user.name}-{jobname}-{hostname}.log
2) 历史服务
如果需要查看YARN的作业历史,需要打开历史服务:
1. 停止当前的YARN进程
stop-yarn.sh
2. 在yarn-site.xml中添加配置
<!-- 开启日志聚集功能 -->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<!-- 日志信息保存在文件系统上的最长时间,单位为秒-->
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>640800</value>
</property>
3. 分发到其他节点
4. 启动YARN进程
start-yarn.sh
5. 开启历史服务
mr-jobhistory-server.sh start historyserver
第十三章 YARN的执行原理
在MR程序运行时,有五个独立的进程:
- YarnRunner:用于提交作业的客户端程序
- ResourceManager:yarn资源管理器,负责协调集群上计算机资源的分配
- NodeManager:yarn节点管理器,负责启动和监视集群中机器上的计算容器(container)
- Application Master:负责协调运行MapReduce作业的任务,他和任务都在容器中运行,这些容器由资源管理器分配并由节点管理器进行管理。
- HDFS:用于共享作业所需文件。
整个过程如下图描述:
1. 调用waitForCompletion方法每秒轮询作业的进度,内部封装了submit()方法,用于创建JobCommiter实例,并且调用其的submitJobInternal方法。提交成功后,如果有状态改变,就会把进度报告到控制台。错误也会报告到
控制台
2. JobCommiter实例会向ResourceManager申请一个新应用ID,用于MapReduce作业ID。这期间JobCommiter也会进行检查输出路径的情况,以及计算输入分片。
3. 如果成功申请到ID,就会将运行作业所需要的资源(包括作业jar文件,配置文件和计算所得的输入分片元数据文件)上传到一个用ID命名的目录下的HDFS上。此时副本个数默认是10.
4. 准备工作已经做好,再通知ResourceManager调用submitApplication方法提交作业。
5. ResourceManager调用submitApplication方法后,会通知Yarn调度器(Scheduler),调度器分配一个容器,在节点管理器的管理下在容器中启动 application master进程。
6. application master的主类是MRAppMaster,其主要作用是初始化任务,并接受来自任务的进度和完成报告。
7. 然后从HDFS上接受资源,主要是split。然后为每一个split创建MapTask以及参数指定的ReduceTask,任务ID在此时分配
8. 然后Application Master会向资源管理器请求容器,首先为MapTask申请容器,然后再为ReduceTask申请容器。(5%)
9. 一旦ResourceManager中的调度器(Scheduler),为Task分配了一个特定节点上的容器,Application Master就会与NodeManager进行通信来启动容器。
10. 运行任务是由YarnChild来执行的,运行任务前,先将资源本地化(jar文件,配置文件,缓存文件)
11. 然后开始运行MapTask或ReduceTask。
12. 当收到最后一个任务已经完成的通知后,application master会把作业状态设置为success。然后Job轮询时,知道成功完成,就会通知客户端,并把统计信息输出到控制台
第十四章 YARN的案例测试
MapReduce:
[root@qianfeng01 mapreduce]# hadoop jar hadoop-mapreduce-examples-2.7.6.jar wordcount /input /output
INFO client.RMProxy: Connecting to ResourceManager at qianfeng01/192.168.10.101:8032
INFO input.FileInputFormat: Total input paths to process : 1
INFO mapreduce.JobSubmitter: number of splits:1
INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1617775349214_0003
INFO impl.YarnClientImpl: Submitted application application_1617775349214_0003
INFO mapreduce.Job: The url to track the job: http://qianfeng01:8088/proxy/application_1617775349214_0003/
INFO mapreduce.Job: Running job: job_1617775349214_0003
INFO mapreduce.Job: Job job_1617775349214_0003 running in uber mode : false
INFO mapreduce.Job: map 0% reduce 0%
INFO mapreduce.Job: map 100% reduce 0%
INFO mapreduce.Job: map 100% reduce 100%
INFO mapreduce.Job: Job job_1617775349214_0003 completed successfully
INFO mapreduce.Job: Counters: 49
File System Counters
FILE: Number of bytes read=111
FILE: Number of bytes written=245331
FILE: Number of read operations=0
FILE: Number of large read operations=0
FILE: Number of write operations=0
HDFS: Number of bytes read=218
HDFS: Number of bytes written=69
HDFS: Number of read operations=6
HDFS: Number of large read operations=0
HDFS: Number of write operations=2
Job Counters
Launched map tasks=1
Launched reduce tasks=1
Data-local map tasks=1
Total time spent by all maps in occupied slots (ms)=3359
Total time spent by all reduces in occupied slots (ms)=3347
Total time spent by all map tasks (ms)=3359
Total time spent by all reduce tasks (ms)=3347
Total vcore-milliseconds taken by all map tasks=3359
Total vcore-milliseconds taken by all reduce tasks=3347
Total megabyte-milliseconds taken by all map tasks=3439616
Total megabyte-milliseconds taken by all reduce tasks=3427328
Map-Reduce Framework
Map input records=3
Map output records=21
Map output bytes=203
Map output materialized bytes=111
Input split bytes=99
Combine input records=21
Combine output records=9
Reduce input groups=9
Reduce shuffle bytes=111
Reduce input records=9
Reduce output records=9
Spilled Records=18
Shuffled Maps =1
Failed Shuffles=0
Merged Map outputs=1
GC time elapsed (ms)=126
CPU time spent (ms)=1250
Physical memory (bytes) snapshot=451137536
Virtual memory (bytes) snapshot=4204822528
Total committed heap usage (bytes)=282591232
Shuffle Errors
BAD_ID=0
CONNECTION=0
IO_ERROR=0
WRONG_LENGTH=0
WRONG_MAP=0
WRONG_REDUCE=0
File Input Format Counters
Bytes Read=119
File Output Format Counters
Bytes Written=69
第十五章 YARN的Web UI查看
使用8088端口,可以查看YARN任务的WebUI文章来源:https://www.toymoban.com/news/detail-471334.html
文章来源地址https://www.toymoban.com/news/detail-471334.html
到了这里,关于Hadoop详细入门知识的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!