简介
Hadoop
是一个分布式计算开源框架,其提供一个分布式文件系统子项目(HDFS
)和支持 MapReduce
分布式计算的软件架构。
在有了大量数据之后,那么该如何进行存储和分析这些数据呢?Hadoop
需要解决的问题如下:
- 硬件故障问题。一旦使用磁盘存储数据,就会遇到磁盘故障;但是为了避免数据丢失,最常见的做法就是复制(
replication
);系统保存数据的副本(replica
),一旦硬件系统出现故障,就立即使用另外保存的副本。 - 以某种方式结合大部分数据来共同完成分析。各种分布式系统允许不同来源的数据进行分析,但其数据的正确性是无法保证的。因此
MapReduce
提出了一个编程模型,该模型抽象出这些硬盘读/写问题并将其作为对一个数据集(由键值对组成)的计算。
架构设计及用途
HDFS
采用主从架构。HDFS
集群是由 一个 Namenode
和 一定数量的 Datanodes
组成。Namenode
是一个中心服务器,负责管理文件系统的名字空间(namespace
)即元数据以及客户端对文件的访问;而 Datanode
一般是一个节点部署一个,负责管理所在节点上数据的存储。
集群中单一 Namenode
的结构大大简化了系统的架构,Namenode
是所有 HDFS
元数据的仲裁者和管理者,因此用户数据永远都不会流过 Namenode
。
HDFS
使用 Java
语言开发,因此任何支持 Java
的机器都可以部署 Namenode
或者 Datanode
。一个典型的场景就是一台机器上运行一个 Namenode
,而集群的其他机器运行 Datanode
实例,另外这种架构并不排斥一台机器上部署多个 Datanode
,只不过这种情况比较少见而已。
文件系统
HDFS
被设计成能够在一个大集群中跨机器可靠地存储超大文件。HDFS
将每个文件存储成一系列的数据块,所有的数据块都是相同的大小(默认为 128M
,不包含最后一个数据块)。避免数据丢失文件的所有数据块都会有副本,每个文件的数据块大小和副本系数都可配置;应用程序可以指定某个文件的副本数目,其中副本系数可以在文件创建的时候指定,也可以在之后改变。HDFS
中的文件都是一次性写入,并严格要求在任何时候只能有一个写入者。
HDFS
暴露了文件系统的名字空间,用户能够以文件的形式在上面存储数据。从内部看,一个文件其实被分成一个或多个数据块,这些块存储在一组 Datanode
上。Namenode
执行文件系统的名字空间操作,比如 打开、关闭、重命名文件 或 目录;同时也负责确定数据块到具体 Datanode
节点的映射。Datanode
负责处理文件系统客户端的读写请求;其在 Namenode
的统一调度下进行数据块的创建、删除 和 复制。
Namenode
负责维护文件系统的名字空间,任何对文件系统名字空间或属性的修改都将被 Namenode
记录下来,另外还可以设置 HDFS
保存的文件的副本数目。文件副本的数目称为文件的副本系数,该信息也是由 Namenode
保存的。
数据副本复制
如何存放数据块副本是 HDFS
可靠性和性能的关键,优化的副本存放策略是 HDFS
区分于其他大部分分布式文件系统的重要特性(该特性需要做大量的调优,并需要经验的积累)。HDFS
目前采用一种被称为机架感知(rack-aware
)的策略来改进数据的 可靠性、可用性 和 网络带宽的利用率。目前实现的副本存放策略只是在这个方向上的第一步,实现这个策略的短期目标是验证它在生产环境下的有效性,观察它的行为,为实现更先进的策略打下测试和研究的基础。
而大型 HDFS
实例一般运行在跨越多个机架的计算机组成的集群上,不同机架上的两台机器之间的通讯需要经过交换机。在大多数情况下,同一个机架内的两台机器间的带宽会比不同机架的两台机器间的带宽大。
由于 Namenode
全权管理数据块的复制,因此会周期性地从集群中的每个 Datanode
接收心跳信号和块状态报告(Blockreport
);接收到心跳信号意味着该 Datanode
节点工作正常,而块状态报告包含该 Datanode
上所有数据块的列表。
另外为了降低整体的带宽消耗和读取延时,HDFS
会尽量让读取程序读取离它最近的数据副本。如果在读取程序的同一个机架上有一个副本,那么就读取该副本;但是若一个集群跨越多个数据中心,那么客户端也将首先读本地数据中心的副本。
当一个文件的副本系数被减小后,Namenode
会选择过剩的副本删除,在下次心跳检测时会将该信息传递给 Datanode
,收到消息后随即移除相应的数据块,集群中的空闲空间增大。
所有的 HDFS
通讯协议都是建立在 TCP/IP
协议之上。客户端通过一个可配置的 TCP
端口连接到 Namenode
,通过 ClientProtocol
协议与 Namenode 交互,而 Datanode
则是使用 DatanodeProtocol
协议与 Namenode
交互。一个远程过程调用(RPC
)模型被抽象出来封装 ClientProtocol
和 Datanodeprotocol
协议,在该设计上,Namenode
不会主动发起 RPC
,而是响应来自客户端或 Datanode
的 RPC
请求。
健壮性
HDFS
的主要目标是即使在出错的情况下也要保证数据存储的可靠性。常见的三种出错情况是:
Namenode
出错。Datanode
出错。- 网络割裂(
network partitions
)。
每个 Datanode
节点周期性地向 Namenode
发送心跳信号,因此一旦出现网络割裂就会导致一部分 Datanode
跟 Namenode
失去联系,Namenode
若是定期没有收到心跳信号,就会将这些近期不再发送心跳信号的 Datanode
标记为宕机,不会再将新的读写请求发给它们。Datanode
宕机会导致任何存储在上的数据将不再有效,会引起一些数据块的副本系数低于指定值,然而 Namenode
会不断地检测这些需要复制的数据块,一旦发现副本系数不匹配就会启动复制操作。在下列情况下会启动复制操作:
- 某个
Datanode
节点失效。 - 某个副本遭到损坏。
Datanode
上的硬盘错误。- 文件的副本系数增大。
现实中从某个 Datanode
获取的数据块有可能是损坏的,损坏可能是由 Datanode
的存储设备错误、网络错误或者软件 bug
造成的。为此 HDFS
客户端软件实现了对 HDFS
文件内容的校验和 checksum
检查。当客户端创建一个新的 HDFS
文件时会计算这个文件每个数据块的校验和,并将校验和作为一个单独的隐藏文件保存在同一个 HDFS
名字空间下,当客户端获取文件内容后,它会检验从 Datanode
获取的数据跟相应的校验和文件中的校验和是否匹配;如果不匹配,客户端可以选择从其他 Datanode
获取该数据块的副本。
FsImage
和 Editlog
是 HDFS
的核心数据结构,如果这些文件损坏那么整个 HDFS
实例都将失效。因此 Namenode
可以配置成支持多个 FsImage
和 Editlog
的副本,任何对核心数据结构的修改都将同步到它们的所有副本上。尽管这种多副本的同步操作可能会降低 Namenode
每秒处理的名字空间事务数量,但是代价依旧是可以接受的,因为即使 HDFS
的应用是数据密集的,但是并非元数据密集的,因此当 Namenode
重启的时候会选取最近的完整的 FsImage
和 Editlog
来使用。
Namenode
是 HDFS
集群中的单点故障(single point of failure
)所在,因此如果 Namenode
机器故障,是需要手工干预的。
搭建集群
在大多数情况下,副本系数是 3
,HDFS
的存放策略是将一个副本存放在本地机架的节点上,一个副本放在同一机架的另一个节点上,最后一个副本放在不同机架的节点上。
这种策略减少了机架间的数据传输,提高了写操作的效率,同时由于机架的错误远远比节点的错误少,所以这个策略不会影响到数据的可靠性和可用性。与此同时数据块因为放在两个(不是三个)不同的机架上,所以此策略可以减少读取数据时需要的网络传输总带宽。在这种策略下,副本并不是均匀分布在不同的机架上,三分之一的副本在一个节点上,三分之二的副本在一个机架上,其他副本均匀分布在剩下的机架中,这一策略在不损害数据可靠性和读取性能的情况下改进了写数据的性能。
环境准备
三台机器
三台机器包含一台Namenode
机器和两台Datanode
机器,机器都拥有自己的内网IP
。1
2
3namenode 10.250.0.1
datanode1 10.250.0.2
datanode2 10.250.0.3全部机器创建相同的用户名和组
1
2
3
4
5groupadd hadoop
useradd hadoop -g hadoop
passwd hadoop
mkdir /home/hadoop
chown -R hadoop:hadoop /home/hadoopJava
环境1
2
3
4~ java -version
java version "1.8.0_192"
Java(TM) SE Runtime Environment (build 1.8.0_192-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.192-b12, mixed mode)
下载及配置
下载
jar
包
下载这部分就靠自己去网上寻找了,这里就不进行说明。修改默认配置
进入到conf
文件下。hadoop.sh
1
export JAVA_HOME=/etc/java-config-2/current-system-vm
hdfs-site.xml
1
2
3
4
5
6
7
8
9
10<configuration>
<property>
<name>dfs.data.dir</name>
<value>/hadoop/conan/data</value>
</property>
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
</configuration>core-site.xml
1
2
3
4
5
6<configuration>
<property>
<name>fs.default.name</name>
<value>hdfs://10.250.0.1:9000</value>
</property>
</configuration>mapred-site.xml
1
2
3
4
5
6<configuration>
<property>
<name>mapred.job.tracker</name>
<value>10.250.0.1:9001</value>
</property>
</configuration>masters
1
10.250.0.1
slaves
1
210.250.0.2
10.250.0.3
同步配置
1 | # 进入到 hadoop 解压的目录下 |
启动 Namenode
节点
1 | # 进入到 bin 目录下 |
检查是否成功
jps
1
2
3
49362 Jps
7756 SecondaryNameNode
7531 JobTracker
7357 NameNodenetstat -nl
1
2
3
4
5
6
7
8
9
10
11
12
13
14Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:5666 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:8649 0.0.0.0:* LISTEN
tcp6 0 0 :::50070 :::* LISTEN
tcp6 0 0 :::22 :::* LISTEN
tcp6 0 0 :::39418 :::* LISTEN
tcp6 0 0 :::32895 :::* LISTEN
tcp6 0 0 10.250.0.1:9000 :::* LISTEN
tcp6 0 0 10.250.0.1:9001 :::* LISTEN
tcp6 0 0 :::50090 :::* LISTEN
tcp6 0 0 :::51595 :::* LISTEN
tcp6 0 0 :::50030 :::* LISTEN
udp 0 0 127.0.0.1:8649 0.0.0.0:*hadoop
1
2
3
4
5
6# 进入到 bin 目录下
bin/hadoop fs -mkdir /test
bin/hadoop fs -copyFormLocal README.txt /test
bin/hadoop fs -ls /test
# Found 1 items
# -rw-r--r-- 2 hadoop supergroup 1006 2022-02-01 12:05 /test/README.txt
常用命令
Web
接口
NameNode
和 DataNode
各自启动了一个内置的 Web
服务器,显示了集群当前的基本状态和信息。
在默认配置下 NameNode
的首页地址是 http://namenode-name:50070/
,这个页面列出了集群里的所有 DataNode
和集群的基本状态,同时该 Web
接口也可以用来浏览整个文件系统(使用 Namenode
首页的 Browse the file system
链接)。
Shell
命令
Hadoop
包括一系列的类 sh
的命令,这些命令可直接和 HDFS
以及其他 Hadoop
支持的文件系统进行交互,支持大多数普通文件系统的操作,比如复制文件、改变文件权限等。另外还支持一些 HDFS
特有的操作,比如改变文件副本数目。
所有的 Hadoop
命令均由 bin/hadoop
脚本引发,若不指定参数运行 Hadoop
脚本会打印所有命令的描述。用法:
1 | hadoop [--config confdir] [COMMAND] [GENERIC_OPTIONS] [COMMAND_OPTIONS] |
DFSSh
运行一个常规的文件系统客户端,HDFS
以文件和目录的形式组织用户数据,提供了一个命令行接口 DFSSh
让用户与 HDFS
中的数据进行交互。用法:
1 | hadoop fs [GENERIC_OPTIONS] [COMMAND_OPTIONS] |
bin/hadoop fs -help
命令列出所有 Hadoop Sh
支持的命令。bin/hadoop fs -help command-name
命令能显示关于某个命令的详细信息。
cat
将路径指定文件的内容输出到stdout
。用法:1
hadoop fs -cat URI [URI …]
chgrp
改变文件所属的组。使用-R
将使改变在目录结构下递归进行,并且命令的使用者必须是文件的所有者或者超级用户。用法:1
hadoop fs -chgrp [-R] GROUP URI [URI …]
chmod
改变文件的权限。使用-R
将使改变在目录结构下递归进行,并且命令的使用者必须是文件的所有者或者超级用户。用法:1
hadoop fs -chmod [-R] <MODE[,MODE]... | OCTALMODE> URI [URI …]
chown
改变文件的拥有者。使用-R
将使改变在目录结构下递归进行,并且命令的使用者必须是超级用户。用法:1
hadoop fs -chown [-R] [OWNER][:[GROUP]] URI [URI ]
ls
展示文件信息。如果参数是文件则展示文件信息;如果是目录则展示子目录的列表。用法:1
hadoop fs -ls <args>
lsr
ls
命令的递归版本,类似于-R
。用法:1
hadoop fs -lsr <args>
du
显示目录中所有文件的大小,或者当只指定一个文件时,显示此文件的大小。用法:1
hadoop fs -du URI [URI …]
dus
显示文件的大小。用法:1
hadoop fs -dus <args>
mkdir
接受路径指定的作为参数,然后创建这些目录。其行为类似于mkdir -p
会自动创建路径中的各级父目录。用法:1
hadoop fs -mkdir <paths>
cp
将文件从源路径复制到目标路径。这个命令允许有多个源路径,但是目标路径必须是一个目录。用法:1
hadoop fs -cp URI [URI …] <dest>
copyFromLocal
除了限定源路径是一个本地文件外,其余参数和put
命令相似。用法:1
hadoop fs -copyFromLocal <localsrc> URI
copyToLocal
除了限定目标路径是一个本地文件外,其余参数和get
命令类似。用法:1
hadoop fs -copyToLocal [-ignorecrc] [-crc] URI <localdst>
mv
将文件从源路径移动到目标路径。这个命令允许有多个源路径,但是目标路径必须是一个目录,另外不支持在不同的文件系统间移动文件。用法:1
hadoop fs -mv URI [URI …] <dest>
movefromLocal
将本地文件上传到HDFS
,之后本地文件会被删除(可以理解为剪切)。用法:1
hdfs fs -moveFromLocal <src> <dst>
get
复制文件到本地系统。可用-ignorecrc
选项复制CRC
校验失败的文件;使用-crc
选项复制文件以及CRC
信息。用法:1
hadoop fs -get [-ignorecrc] [-crc] <src> <localdst>
getmerge
接受一个源目录和一个目标文件作为输入,然后将源目录中的文件合并到本地文件中。addnl
选项是可选的,用于指定在每个文件结尾添加一个换行符。用法:1
hadoop fs -getmerge <src> <localdst> [addnl]
put
从本地文件系统中复制单个或多个源路径到目标文件系统,另外也支持从标准输入中读取输入写入目标文件系统。用法:1
hadoop fs -put <localsrc> ... <dst>
localsrc
为-
表示从标准输入中读取输入。rm
删除指定的文件。只删除非空目录和文件。用法:1
hadoop fs -rm URI [URI …]
rmr
rm
的递归版本。用法:1
hadoop fs -rmr URI [URI …]
touchz
创建一个0
字节的空文件。用法:1
hadoop fs -touchz URI [URI …]
setrep
改变一个文件的副本系数。-R
选项用于递归改变目录下所有文件的副本系数。用法:1
hadoop fs -setrep [-R] <path>
stat
返回指定路径的统计信息。用法:1
hadoop fs -stat URI [URI …]
tail
将文件尾部1K
字节的内容输出到stdout
。支持-f
选项。用法:1
hadoop fs -tail [-f] URI
test
检查文件。用法:1
hadoop fs -test -[ezd] URI
其中
-[ezd]
选项分别代表:-e
,检查文件是否存在。如果存在则返回0
。-z
,检查文件是否是0
字节。如果是则返回0
。-d
,如果路径是个目录,则返回1
,否则返回0
。
text
将源文件输出为文本格式。允许的格式是zip
和TextRecordInputStream
。用法:1
hadoop fs -text <src>
expunge
清空回收站。用法:1
hadoop fs -expunge
DFSAdmin
运行一个 HDFS
的 dfsadmin
客户端。DFSAdmin
命令用来管理 HDFS
集群,这些命令只有管理员才能使用。用法:
1 | hadoop dfsadmin [GENERIC_OPTIONS] [-report] [-safemode enter | leave | get | wait] [-refreshNodes] [-finalizeUpgrade] [-upgradeProgress status | details | force] [-metasave filename] [-setQuota <quota> <dirname>...<dirname>] [-clrQuota <dirname>...<dirname>] [-help [cmd]] |
bin/hadoop dfsadmin
命令支持一些 HDFS
管理相关的操作。bin/hadoop dfsadmin -help
命令能列出所有当前支持的命令。
report
报告 HDFS 的基本统计信息,当然有些信息也可以在NameNode Web
服务首页看到。safemode enter | leave | get | wait
虽然通常并不需要,但是管理员可以手动让NameNode
进入或离开安全模式。refreshNodes
重新读取hosts
和exclude
文件,更新允许连接到Namenode
但是退出或加入的Datanode
的集合。finalizeUpgrade
删除上一次升级时制作的集群备份。终结HDFS
的升级操作,Datanode
删除前一个版本的工作目录并且之后Namenode
也这样做,这个操作会结束整个升级过程。upgradeProgress status | details | force
请求当前系统的升级状态,状态的细节,或者强制升级操作进行。metasave filename
保存Namenode
的主要数据结构到hadoop.log.dir
属性指定的目录下的文件中。setQuota <quota> <dirname>...<dirname>
为每个目录设定配额,目录配额应该是一个长整型整数,强制限定了目录树下的名字个数。clrQuota <dirname>...<dirname>
清除每一个目录的配额设定。
fsck
fsck
命令来检查系统中的各种不一致状况,运行 HDFS
文件系统检查工具。这个命令被设计来报告各种文件存在的问题,比如文件缺少数据块或者副本数目不够,另外不同于在本地文件系统上传统的 fsck
工具,这个命令并不会修正它检测到的错误。一般来说 NameNode
会自动修正大多数可恢复的错误。用法:
1 | hadoop fsck [GENERIC_OPTIONS] <path> [-move | -delete | -openforwrite] [-files [-blocks [-locations | -racks]]] |
<path>
检查的起始目录。move
移动受损文件到/lost+found
。delete
删除受损文件。openforwrite
打印出写打开的文件。files
打印出正被检查的文件。blocks
打印出块信息报告。locations
打印出每个块的位置信息。racks
打印出data-node
的网络拓扑结构。
jar
运行 jar
文件。可以将 Map Reduce
代码写到 jar
文件中,然后使用这个命令执行。用法:
1 | hadoop jar <jar> [mainClass] args... |
job
用于和 Map Reduce
作业交互和命令。用法:
1 | hadoop job [GENERIC_OPTIONS] [-submit <job-file>] | [-status <job-id>] | [-counter <job-id> <group-name> <counter-name>] | [-kill <job-id>] | [-events <job-id> <from-event-#> <#-of-events>] | [-history [all] <jobOutputDir>] | [-list [all]] | [-kill-task <task-id>] | [-fail-task <task-id>] |
submit
提交作业。status
打印map
和reduce
完成百分比和所有计数器。counter
打印计数器的值。kill
杀死指定作业。events
打印给定范围内jobtracker
接收到的事件细节。history
打印作业的细节、失败及被杀死原因的细节。更多的关于一个作业的细节比如成功的任务,做过的任务尝试等信息可以通过指定[all]
选项查看。list
显示所有作业。-list
只显示将要完成的作业。kill-task
杀死任务。被杀死的任务不会不利于失败尝试。fail-task
使任务失败。被失败的任务会对失败尝试不利。
pipes
运行 pipes
作业。用法:
1 | hadoop pipes [-conf <path>] [-jobconf <key=value>, <key=value>, ...] [-input <path>] [-output <path>] [-jar <jar file>] [-inputformat <class>] [-map <class>] [-partitioner <class>] [-reduce <class>] [-writer <class>] [-program <executable>] [-reduces <num>] |
conf
作业的配置。jobconf
增加/覆盖作业的配置项。input
输入目录。output
输出目录。jar
Jar
文件名。inputformat
InputFormat
类。map
Java Map
类。partitioner
Java Partitioner
reduce
Java Reduce
类。writer
Java RecordWriter
program
可执行程序的URI
。reduces
reduce
个数。
安全模式
NameNode
启动时会从 fsimage
和 edits
日志文件中装载文件系统的状态信息,然后等待各个 DataNode
向它报告各自的数据块状态,这样 NameNode
在副本充足的情况下就不会过早地开始复制数据块。
在开始时这个阶段 NameNode
处于安全模式,其本质上是 HDFS
集群的一种只读模式,此时集群不允许任何对文件系统或者数据块修改的操作,通常 NameNode
在开始阶段完成后会自动地退出安全模式。但若是需要可以通过 bin/hadoop dfsadmin -safemode
命令显式地将 HDFS
置于安全模式,另外 NameNode
首页也会显示当前是否处于安全模式。
常见组件介绍
Hive
是基于 Hadoop
的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,通过类 SQL
语句快速实现简单的 MapReduce
统计,不必开发专门的 MapReduce
应用,并且十分适合数据仓库的统计分析。
Spark
是专为大规模数据处理而设计的快速通用计算引擎。
HBase
是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用 HBase
技术可在廉价 PC Server
上搭建起大规模结构化存储集群。
Pig
是一个基于 Hadoop
的大规模数据分析工具,它提供的 SQL-LIKE
语言叫 Pig Latin
,该语言的编译器会把类 SQL
的数据分析请求转换为一系列经过优化处理的 MapReduce
运算。
Sqoop
和 DataX
Sqoop
是一个用来将 Hadoop
和关系型数据库中的数据相互转移的工具。它可以将一个关系型数据库中的数据导进到 Hadoop
的 HDFS
中,也可以将 HDFS
的数据导进到关系型数据库中。DataX
是阿里巴巴开源的离线数据同步工具,支持各种异构数据源之间高效的数据同步。
Hue
是一个基于 WEB
的监控和管理系统,实现对 HDFS
、MapReduce/YARN
、HBase
、Hive
、Pig
的操作和管理。
Ambari
是一种基于 Web
的工具,支持 Hadoop
集群的供应、管理和监控。
引用
个人备注
此博客内容均为作者学习所做笔记,侵删!
若转作其他用途,请注明来源!