Hadoop概念
Hadoop实现了一个分布式文件系统( Distributed File System),其中一个组件是HDFS。HDFS有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上;而且它提供高吞吐量(high throughput)来访问应用程序的数据,适合那些有着超大数据集(large data set)的应用程序。
Hadoop服务组件
hadoop组件介绍
Hadoop Common
是Hadoop体系最底层的一个模块,为Hadoop各个子模块提供各种工具,比如系统配置工具Configuration、远程调用RPC、序列化机制和日志操作等等,是其他模块的基础。
HDFS
是Hadoop分布式文件系统缩写,它是Hadoop的基石。HDFS是一个具备高度容错性的文件系统,适合部署在廉价的机器上,它能提供高吞吐量的数据访问,非常适合大规模数据集上的应用。
YARN
是统一资源管理和调度平台。它解决了上一代Hadoop资源利用率低和不能兼容异构的计算框架等多种问题。提供了资源隔离方案和双调度器的实现。
MapReduce
是一种编程模型,利用函数式编程思想,将对数据集的过程分为Map和Reduce两个阶段。MapReduce的这种编程模型非常适合进行分布式计算。Hadoop提供MapReduce的计算框架,实现了这种编程模型,用户可以通过Java\C++\Python\PHP等多种语言进行编程。
Spark
是加州伯克利大学AMP实验室开发的新一代计算框架,对迭代计算有很大优势,与MapReduce相比性能提升明显,并且可以和Yarn集成,并且还提供了SparkSQL组件。
HBase
来源于Google的Bigtable论文,HBase是一个分布式的,面向列族的开源数据库。采用了Bigtable的数据模型--列族。HBase擅长大规模数据的随机、实时读写访问。
Zookeeper
作为一个分布式服务框架,是基于Fast Paxos算法实现,解决分布式系统中一致性的问题。提供了配置维护,名字服务,分布式同步,组服务等。
Hive最早是facebook开发并使用的,是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张表,提供简单的SQL查询功能。并将SQL转为MapReduce作业运行。其有点就是学习成本低。降低了Hadoop的使用门槛。
Pig
与Hive类似,也是对大数据集进行分析和评估的工具,不同于Hive的是Pig提供了一种高层的,面向领域的抽象语言Pig Latin.同样Pig也可以将Pig Latin转化为MapReduce作业。相比与SQL,Pig Latin更加灵活,但学习成本更高。
Impala
是Cloudera公司开发,可以对存储HDFS、HBase的海量数据提供交互查询的SQL接口。除了和Hive使用相同的统一存储平台,Impala也使用相同的元数据,SQL语法,ODBC驱动程序和用户界面。Impala还提供了一个熟悉的面向批量或者实时查询的统一平台。Impala的特点是查询非常迅速,其性能大幅度领先于Hive。Impala并不是基于MapReduce的,它的定位是OLAP,是Google的新三驾马车之一Dremel的开源实现。
Mahout
是一个机器学习和数据挖掘库,它利用MapReduce编程模型实现k-means,Native,Bayes,Collaborative Filtering等经典的机器学习算法,并使其具有良好的可扩展性。
Flume
是Cloudera提供的一个高可用,高可靠,分布式的海量日志采集、聚合和传输系统,Flume支持在日志系统中定制各类数据发送方,用于数据收集,同时Flume提供对数据进行简单处理并写到各个数据接收方的能力。
Sqoop
是SQL to Hadoop的缩写,主要作用在于结构化的数据存储与Hadoop之间进行数据双向交换,也就是说,Sqoop可以将关系型数据库的数据导入到HDFS、Hive、也可以从HDFS、Hive导出到关系型数据库中。Sqoop利用了Hadoop的优点,整个导入导出都是由MapReduce计算框架实现并行化,非常高效。
Kafka
是一种高吞吐量的分布式发布订阅消息系统。具有分布式、高可用的特性,在大数据系统里被广泛使用,如果把大数据系统比作一台机器,那么kafka就是前端总线,它连接了平台中的各个组件。
Hadoop工作原理
HDFS ( Hadoop Distributed File System)即 Hadoop 分布式文件系统,它的设计目标是把超大数据集存储到集群中的多台普通商用计算机上,并提供高可靠性和高吞吐量的服务。
HDFS 是参考 Google 公司的 GFS 实现的,不管是 Google 公司的计算平台还是 Hadoop 计算平台,都是运行在大量普通商用计算机上的,这些计算机节点很容易出现硬件故障,而这两种计算平台都将硬件故障作为常态,通过软件设计来保证系统的可靠性。
HDFS 的数据是分块地存储在每个节点上,当某个节点出现 故障时,HDFS 相关组件能快速检测节点故障并提供容错机制完成数据的自动恢复。
HDFS主要由3个组件构成:NameNode、SecondaryNameNode 和 DataNode。HDFS是以Master/Slave模式运行的。
其中NameNode和 SecondaryNameNode运行在Master节点上,而DataNode运行在Slave节点上,所以HDFS集群一般由一个NameNode、一个 SecondaryNameNode 和许多 DataNode 组成,其架构如下图所示。
在 HDFS 中,文件是被分成块来进行存储的,一个文件可以包含许多个块,每个块存储在不同的 DataNode 中。从上图中可知,当一个客户端请求读取一个文件时,它需要先从 NameNode 中获取文件的元数据信息,然后从对应的数据节点上并行地读取数据块。
NameNode
NameNode 是主服务器,负责管理文件系统的命名空间以及客户端对文件的访问。当客户端请求数据时,仅仅从 NameNode 中获取文件的元数据信息,具体的数据传输不经过 NameNode,而是直接与具体的 DataNode 进行交互。
文件的元数据信息记录了文件系统中的文件名和目录名,以及它们之间的层级关系,同时也记录了每个文件目录的所有者及其权限,甚至还记录每个文件由哪些块组成,这些元数据信息记录在文件 fsimage 中,当系统初次启动时,NameNode 将读取 fsimage 中的信息并保存到内存中。
这些块的位置信息是由 NameNode 启动后从每个 DataNode 获取并保存在内存当中的,这样既减少了 NameNode 的启动时间,又减少了读取数据的查询时间,提高了整个系统的效率。
SecondaryNameNode
从字面上来看SecondaryNameNode 很容易被当作是 NameNode 的备份节点,其实不然。可以通过下图看 HDFS 中 SecondaryNameNode 的作用。
NameNode 管理着元数据信息,元数据信息会定期保存到edits 和 fsimage 文件中。其中的 edits 保存操作日志信息,在 HDFS 运行期间,新的操作日志不会立即与 fsimage 进行合并,也不会存到 NameNode 的内存中,而是会先写到 edits 中。
当edits 文件达到一定域值或间隔一段时间后触发 SecondaryNameNode 进行工作,这个时间点称为checkpoint。
SecondaryNameNode 的角色就是定期地合并edits 和 fsimage 文件,其合并步骤如下。
在进行合并之前,SecondaryNameNode 会通知 NameNode 停用当前的 editlog 文件, NameNode 会将新记录写入新的 editlog.new 文件中。
SecondaryNameNode 从 NameNode 请求并复制 fsimage 和 edits 文件。SecondaryNameNode 把 fsimage 和 edits 文件合并成新的 fsimage 文件,并命名为 fsimage.ckpto
NameNode 从 SecondaryNameNode 获取 fsimage.ckpt,并替换掉 fsimage,同时用 edits.new 文件替换旧的 edits 文件。更新checkpoint 的时间。
最终fsimage 保存的是上一个 checkpoint 的元数据信息,而 edits 保存的是从上个 checkpoint 开始发生的 HDFS 元数据改变的信息。
DataNode
DataNode 是 HDFS 中的工作节点,也是从服务器,它负责存储数据块,也负责为客户端提供数据块的读写服务,同时也响应 NameNode 的相关指令,如完成数据块的复制、删除等。
DataNode 会定期发送心跳信息给 NameNode,告知 NameNode 当前节点存储的文件块信息。当客户端给 NameNode 发送读写请求时,NameNode 告知客户端每个数据块所在的 DataNode 信息,然后客户端直接与 DataNode 进行通信,减少 NameNode 的系统开销。
当DataNode 在执行块存储操作时,DataNode 还会与其他 DataNode 通信,复制这些块到其他 DataNode 上实现冗余。
HDFS分块&副本机制
在 HDFS 中,文件最终是以数据块的形式存储的,而副本机制极大程度上避免了宕机所造成的数据丢失,可以在数据读取时进行数据校验。
分块机制
HDFS 中数据块大小默认为 64MB,而一般磁盘块的大小为 512B,HDFS 块之所以这么大,是为了最小化寻址开销。
如果块足够大,从磁盘传输数据的时间会明显大于寻找块的地址的时间,因此,传输一个由多个块组成的大文件的时间取决于磁盘传输速率。
随着新一代磁盘驱动器传输速率的提升,寻址开销会更少,在更多情况下 HDFS 使用更大的块。当然块的大小不是越大越好,因为 Hadoop 中一个 map 任务一次通常只处理一个块中的数据,如果块过大,会导致整体任务数量过小,降低作业处理的速度。HDFS按块存储好处:
- 文件可以任意大,不会受到单个节点的磁盘容量的限制。理论上讲,HDFS 的存储容量是无限的。
- 简化文件子系统的设计。将系统的处理对象设置为块,可以简化存储管理,因为块大小固定,所以每个文件分成多少个块,每个 DataNode 能存多少个块,都很容易计算。同时系统中 NameNode 只负责管理文件的元数据,DataNode只负责数据存储,分工明确,提高了系统的效率。
- 有利于提高系统的可用性。HDFS 通过数据备份来提供数据的容错能力和高可用性,而按照块的存储方式非常适合数据备份。同时块以副本方式存在多个 DataNode 中,有利于负载均衡,当某个节点处于繁忙状态时,客户端还可以从其他节点获取这个块的副本。
副本机制
HDFS 中数据块的副本数默认为 3,当然可以设置更多的副本数,这些副本分散存储在集群中,副本的分布位置直接影响 HDFS 的可靠性和性能。
一个大型的分布式文件系统都是需要跨多个机架的,如下图中,HDFS 涉及两个机架。
如果把所有副本都存放在不同的机架上,可以防止机架故障从而导致数据块不可用,同时在多个客户端访问文件系统时很容易实现负载均衡。如果是写数据,各个数据块需要同步到不同机架上,会影响写数据的效率。
在HDFS 默认 3 个副本情况下,会把第一个副本放到机架的一个节点上,第二副本放在同一 个机架的另一个节点上,第三个副本放在不同的机架上。这种策略减少了跨机架副本的个数,提高了数据块的写性能,也可以保证在一个机架出现故障时,仍然能正常运转。
HDFS读写机制
前面讲到客户端读、写文件是与 NameNode 和 DataNode 通信的,下面详细介绍 HDFS 中读写文件的过程。
读文件
HDFS 通过 RPC 调用 NameNode 获取文件块的位置信息,并且对每个块返回所在的 DataNode 的地址信息,然后再从 DataNode 获取数据块的副本。HDFS 读文件的过程如图所示。
读文件操作步骤如下:
- 客户端发起文件读取的请求。
- NameNode 将文件对应的数据块信息及每个块的位置信息,包括每个块的所有副本的位置信息(即每个副本所在的 DataNode 的地址信息)都传送给客户端。
- 客户端收到数据块信息后,直接和数据块所在的 DataNode 通信,并行地读取数据块。
在客户端获得 NameNode 关于每个数据块的信息后,客户端会根据网络拓扑选择与它最近的 DataNode 来读取每个数据块。当与 DataNode 通信失败时,它会选取另一个较近的 DataNode,同时会对出故障的 DataNode 做标记,避免与它重复通信,并发送 NameNode 故障节点的信息。
写文件
当客户端发送写文件请求时,NameNode 负责通知 DataNode 创建文件,在创建之前会检查客户端是否有允许写入数据的权限。通过检测后,NameNode 会向 edits 文件写入一条创建文件的操作记录。
HDFS 中写文件的过程如图所示。
写文件操作步骤如下:
- 客户端在向 NameNode 发送写请求之前,先将数据写入本地的临时文件中。
- 待临时文件块达到系统设置的块大小时,开始向 NameNode 请求写文件。
- NameNode 在此步骤中会检查集群中每个 DataNode 状态信息,获取空闲的节点,并在检查客户端权限后创建文件,返回客户端一个数据块及其对应 DataNode 的地址列表。列表中包含副本存放的地址。
- 客户端在获取 DataNode 相关信息后,将临时文件中的数据块写入列表中的第一个 DataNode,同时第一个 DataNode 会将数据以副本的形式传送至第二个 DataNode,第二个节点也会将数据传送至第三个 DataNode。DataNode 以数据包的形式从客户端接收数据,并以流水线的形式写入和备份到所有的 DataNode 中,每个 DataNode 收到数据后会向前一个节点发送确认信息。 最终数据传输完毕,第一个 DataNode 会向客户端发送确认信息。
- 当客户端收到每个 DataNode 的确认信息时,表示数据块已经持久化地存储在所有 DataNode 当中,接着客户端会向 NameNode 发送确认信息。如果在第(4 )步中任何一个 DataNode 失败,客户端会告知 NameNode,将数据备份到新的 DataNode 中。
环境准备
10.168.1.121 namenode、secondary namenode、resource manager
10.168.1.122 datanode、nodemanager
10.168.1.123 datanode、nodemanager
HDFS:存储数据,提供分析的数据
NameNode/DataNode
YARN:提供程序运行的资源
ResourceManager/NodeManager
配置好hosts解析
[root@node1 ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 10.168.1.121 node1 10.168.1.122 node2 10.168.1.123 node3 10.168.1.124 node4
ntp时间同步
ntpdate pool.ntp.org
关闭防火墙,selinux
[root@node1 ~]# sed -i '/SELINUX/s/enforcing/disabled/g' /etc/selinux/config [root@node1 ~]# setenforce 0 [root@node1 ~]# systemctl stop firewalld.service [root@node1 ~]# systemctl disable firewalld.service
配置免秘钥
[root@node1 ~]# ssh-keygen -t rsa -N '' -f /root/.ssh/id_rsa -q [root@node1 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@node1 [root@node1 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@node2 [root@node1 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@node3
配置节点JAVA环境
[root@node1 ~]# tar -xvzf jdk1.8.0_131.tar.gz [root@node1 ~]# mkdir -p /usr/java/ [root@node1 ~]# \mv jdk1.8.0_131 /usr/java/ [root@node1 ~]# cat>>/etc/profile<<EOF > export JAVA_HOME=/usr/java/jdk1.8.0_131/ > export HADOOP_HOME=/data/hadoop/ > export JAVA_LIBRARY_PATH=/data/hadoop/lib/native/ > export PATH=\$PATH:\$HADOOP_HOME/bin/:\$JAVA_HOME/bin > EOF [root@node1 ~]# source /etc/profile [root@node1 ~]# java -version java version "1.8.0_131" Java(TM) SE Runtime Environment (build 1.8.0_131-b11) Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
hadoop部署
[root@node1 ~]# tar -xzvf hadoop-3.2.2.tar.gz [root@node1 ~]# mkdir -p /data/ [root@node1 ~]# \mv hadoop-3.2.2/ /data/hadoop/ [root@node1 ~]# ls -l /data/hadoop/ 总用量 184 drwxr-xr-x. 2 1000 1000 203 1月 3 18:11 bin drwxr-xr-x. 3 1000 1000 20 1月 3 17:29 etc drwxr-xr-x. 2 1000 1000 106 1月 3 18:11 include drwxr-xr-x. 3 1000 1000 20 1月 3 18:11 lib drwxr-xr-x. 4 1000 1000 4096 1月 3 18:11 libexec -rw-rw-r--. 1 1000 1000 150569 12月 5 2020 LICENSE.txt -rw-rw-r--. 1 1000 1000 21943 12月 5 2020 NOTICE.txt -rw-rw-r--. 1 1000 1000 1361 12月 5 2020 README.txt drwxr-xr-x. 3 1000 1000 4096 1月 3 17:29 sbin drwxr-xr-x. 4 1000 1000 31 1月 3 18:46 share
node1-hadoop配置
编辑/data/hadoop/etc/hadoop/core-site.xml
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>fs.default.name</name> <value>hdfs://node1:9000</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/tmp/hadoop-${user.name}</value> <description>A base for other temporary directories.</description> </property> </configuration>
编辑/data/hadoop/etc/hadoop/mapred-site.xml
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>mapred.job.tracker</name> <value>node1:9001</value> </property> </configuration>
编辑/data/hadoop/etc/hadoop/hdfs-site.xml
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>dfs.name.dir</name> <value>/data/hadoop/data_name1,/data/hadoop/data_name2</value> </property> <property> <name>dfs.data.dir</name> <value>/data/hadoop/data_1,/data/hadoop/data_2</value> </property> <property> <name>dfs.replication</name> <value>2</value> </property> </configuration>
修改/data/hadoop/etc/hadoop/hadoop-env.sh 添加JAVA变量
[root@node1 ~]# echo "export JAVA_HOME=/usr/java/jdk1.8.0_131/" >> /data/hadoop/etc/hadoop/hadoop-env.sh
修改/data/hadoop/etc/hadoop/workers
[root@node1 ~]# cat>/data/hadoop/etc/hadoop/workers<<EOF > node1 > node2 > node3 > EOF
修改Hadoop默认默认启动、关闭脚本,添加root执行权限
[root@node1 sbin]# for i in `ls start*.sh stop*.sh`;do sed -i "1a\HDFS_DATANODE_USER=root\nHDFS_DATANODE_SECURE_USER=root\nHDFS_NAMENODE_USER=root\nHDFS_SECONDARYNAMENODE_USER=root\nYARN_RESOURCEMANAGER_USER=root\n\YARN_NODEMANAGER_USER=root" $i ;done
将Node1部署完成的hadoop所有文件、目录同步至node2和node3节点
[root@node1 sbin]# for i in `seq 2 3`;do rsync -aP --delete /data/hadoop/ root@node$i:/data/hadoop/ ;done
启动hadoop
在启动hadoop之前,我们需要做一步非常关键的步骤,需要在Namenode上执行初始化命令,初始化name目录和数据目录。
初始化集群
[root@node1 sbin]# hadoop namenode -format
启动所有服务
[root@node1 sbin]# /data/hadoop/sbin/start-all.sh Starting namenodes on [node1] 上一次登录:六 7月 3 18:03:13 CST 2021从 172.16.0.27pts/0 上 Starting datanodes 上一次登录:六 7月 3 18:57:12 CST 2021pts/0 上 node3: WARNING: /data/hadoop/logs does not exist. Creating. node2: WARNING: /data/hadoop/logs does not exist. Creating. Starting secondary namenodes [node1] 上一次登录:六 7月 3 18:57:15 CST 2021pts/0 上 Starting resourcemanager 上一次登录:六 7月 3 18:57:21 CST 2021pts/0 上 Starting nodemanagers 上一次登录:六 7月 3 18:57:28 CST 2021pts/0 上
停止所有服务
[root@node1 sbin]# /data/hadoop/sbin/stop-all.sh
kill方式停止服务
ps -ef|grep hadoop|grep java |grep -v grep |awk '{print $2}'|xargs kill -9 sleep 2
Hadoop集群验证
分别查看3个节点Hadoop服务进程和端口信息,命令操作如下: #查看服务进程; ps -ef|grep -aiE hadoop #查看服务监听端口; netstat -ntpl #执行JPS命令查看JAVA进程; jps #查看Hadoop日志内容; tail -fn 100 /data/hadoop/logs/*
node1
[root@node1 sbin]# jps 8752 SecondaryNameNode 8997 ResourceManager 8503 DataNode 9500 Jps 9133 NodeManager 8366 NameNode
node2
[root@node2 ~]# jps 8017 Jps 7801 DataNode 7918 NodeManager
node3
[root@node3 ~]# jps 7842 DataNode 7959 NodeManager 8058 Jps
Hadoop WEB测试
网页访问http://10.168.1.121:9870/
访问hadoop集群web地址http://10.168.1.121:8088
hadoop搭建完成
ok
hadoop(HDFS)使用方式
web页面上使用,
注意:注意目录权限,本地解析
Permission denied: user=dr.who, access=WRITE, inode="/":root:supergroup:drwxr-xr-x
我先给个777测试一下
[root@node1 sbin]# hadoop fs -chmod -R 777 /
评论