Hadoop-基础

简介

Hadoop 是一个分布式计算开源框架,其提供一个分布式文件系统子项目(HDFS)和支持 MapReduce 分布式计算的软件架构。

在有了大量数据之后,那么该如何进行存储和分析这些数据呢?Hadoop 需要解决的问题如下:

  • 硬件故障问题。一旦使用磁盘存储数据,就会遇到磁盘故障;但是为了避免数据丢失,最常见的做法就是复制(replication);系统保存数据的副本(replica),一旦硬件系统出现故障,就立即使用另外保存的副本
  • 以某种方式结合大部分数据来共同完成分析。各种分布式系统允许不同来源的数据进行分析,但其数据的正确性是无法保证的。因此 MapReduce 提出了一个编程模型,该模型抽象出这些硬盘读/写问题并将其作为对一个数据集(由键值对组成)的计算。

架构设计及用途

HDFS 采用主从架构
HDFS 集群是由 一个 Namenode一定数量的 Datanodes 组成。Namenode 是一个中心服务器,负责管理文件系统的名字空间(namespace)即元数据以及客户端对文件的访问;而 Datanode 一般是一个节点部署一个,负责管理所在节点上数据的存储。

hadoop_1_1.jpg

集群中单一 Namenode 的结构大大简化了系统的架构,Namenode 是所有 HDFS 元数据的仲裁者管理者,因此用户数据永远都不会流过 Namenode

HDFS 使用 Java 语言开发,因此任何支持 Java 的机器都可以部署 Namenode 或者 Datanode。一个典型的场景就是一台机器上运行一个 Namenode,而集群的其他机器运行 Datanode 实例,另外这种架构并不排斥一台机器上部署多个 Datanode,只不过这种情况比较少见而已。

文件系统

HDFS 被设计成能够在一个大集群中跨机器可靠地存储超大文件HDFS 将每个文件存储成一系列的数据块,所有的数据块都是相同的大小(默认为 128M,不包含最后一个数据块)。避免数据丢失文件的所有数据块都会有副本,每个文件的数据块大小和副本系数都可配置;应用程序可以指定某个文件的副本数目,其中副本系数可以在文件创建的时候指定,也可以在之后改变。
HDFS 中的文件都是一次性写入,并严格要求在任何时候只能有一个写入者。

hadoop_1_2.jpg

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)模型被抽象出来封装 ClientProtocolDatanodeprotocol 协议,在该设计上,Namenode 不会主动发起 RPC,而是响应来自客户端或 DatanodeRPC 请求。

健壮性

HDFS 的主要目标是即使在出错的情况下也要保证数据存储的可靠性。常见的三种出错情况是:

  • Namenode 出错。
  • Datanode 出错。
  • 网络割裂(network partitions)。

每个 Datanode 节点周期性地向 Namenode 发送心跳信号,因此一旦出现网络割裂就会导致一部分 DatanodeNamenode 失去联系,Namenode 若是定期没有收到心跳信号,就会将这些近期不再发送心跳信号的 Datanode 标记为宕机,不会再将新的读写请求发给它们。Datanode 宕机会导致任何存储在上的数据将不再有效,会引起一些数据块的副本系数低于指定值,然而 Namenode 会不断地检测这些需要复制的数据块,一旦发现副本系数不匹配就会启动复制操作。在下列情况下会启动复制操作:

  • 某个 Datanode 节点失效。
  • 某个副本遭到损坏。
  • Datanode 上的硬盘错误。
  • 文件的副本系数增大。

现实中从某个 Datanode 获取的数据块有可能是损坏的,损坏可能是由 Datanode 的存储设备错误、网络错误或者软件 bug 造成的。为此 HDFS 客户端软件实现了对 HDFS 文件内容的校验checksum 检查。当客户端创建一个新的 HDFS 文件时会计算这个文件每个数据块的校验和,并将校验和作为一个单独的隐藏文件保存在同一个 HDFS 名字空间下,当客户端获取文件内容后,它会检验从 Datanode 获取的数据跟相应的校验和文件中的校验和是否匹配;如果不匹配,客户端可以选择从其他 Datanode 获取该数据块的副本。

FsImageEditlogHDFS 的核心数据结构,如果这些文件损坏那么整个 HDFS 实例都将失效。因此 Namenode 可以配置成支持多个 FsImageEditlog 的副本,任何对核心数据结构的修改都将同步到它们的所有副本上。尽管这种多副本的同步操作可能会降低 Namenode 每秒处理的名字空间事务数量,但是代价依旧是可以接受的,因为即使 HDFS 的应用是数据密集的,但是并非元数据密集的,因此当 Namenode 重启的时候会选取最近的完整的 FsImageEditlog 来使用。

NamenodeHDFS 集群中的单点故障(single point of failure所在,因此如果 Namenode 机器故障,是需要手工干预的。


搭建集群

在大多数情况下,副本系数是 3HDFS 的存放策略是将一个副本存放在本地机架的节点上,一个副本放在同一机架的另一个节点上,最后一个副本放在不同机架的节点上。
这种策略减少了机架间的数据传输,提高了写操作的效率,同时由于机架的错误远远比节点的错误少,所以这个策略不会影响到数据的可靠性和可用性。与此同时数据块因为放在两个(不是三个)不同的机架上,所以此策略可以减少读取数据时需要的网络传输总带宽。在这种策略下,副本并不是均匀分布在不同的机架上,三分之一的副本在一个节点上,三分之二的副本在一个机架上,其他副本均匀分布在剩下的机架中,这一策略在不损害数据可靠性和读取性能的情况下改进了写数据的性能。

环境准备

  1. 三台机器
    三台机器包含一台 Namenode 机器和两台 Datanode 机器,机器都拥有自己的内网 IP

    1
    2
    3
    namenode    10.250.0.1
    datanode1 10.250.0.2
    datanode2 10.250.0.3
  2. 全部机器创建相同的用户名和组

    1
    2
    3
    4
    5
    groupadd hadoop
    useradd hadoop -g hadoop
    passwd hadoop
    mkdir /home/hadoop
    chown -R hadoop:hadoop /home/hadoop
  3. Java 环境

    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)

下载及配置

  1. 下载 jar
    下载这部分就靠自己去网上寻找了,这里就不进行说明。

  2. 修改默认配置
    进入到 conf 文件下。

  3. hadoop.sh

    1
    export JAVA_HOME=/etc/java-config-2/current-system-vm
  4. 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>
  5. 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>
  6. 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>
  7. masters

    1
    10.250.0.1
  8. slaves

    1
    2
    10.250.0.2
    10.250.0.3

同步配置

1
2
3
# 进入到 hadoop 解压的目录下
scp -r ./hadoop hadoop@10.250.0.2:/hadoop/conan
scp -r ./hadoop hadoop@10.250.0.3:/hadoop/conan

启动 Namenode 节点

1
2
3
# 进入到 bin 目录下
bin/hadoop namenode -format
bin/start-all.sh

检查是否成功

  1. jps

    1
    2
    3
    4
    9362 Jps
    7756 SecondaryNameNode
    7531 JobTracker
    7357 NameNode
  2. netstat -nl

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Proto 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:*
  3. 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 接口

NameNodeDataNode 各自启动了一个内置的 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 命令能显示关于某个命令的详细信息。

  1. cat
    将路径指定文件的内容输出到 stdout。用法:

    1
    hadoop fs -cat URI [URI …]
  2. chgrp
    改变文件所属的组。使用 -R 将使改变在目录结构下递归进行,并且命令的使用者必须是文件的所有者或者超级用户。用法:

    1
    hadoop fs -chgrp [-R] GROUP URI [URI …]
  3. chmod
    改变文件的权限。使用 -R 将使改变在目录结构下递归进行,并且命令的使用者必须是文件的所有者或者超级用户。用法:

    1
    hadoop fs -chmod [-R] <MODE[,MODE]... | OCTALMODE> URI [URI …]
  4. chown
    改变文件的拥有者。使用 -R 将使改变在目录结构下递归进行,并且命令的使用者必须是超级用户。用法:

    1
    hadoop fs -chown [-R] [OWNER][:[GROUP]] URI [URI ]
  5. ls
    展示文件信息。如果参数是文件则展示文件信息;如果是目录则展示子目录的列表。用法:

    1
    hadoop fs -ls <args>
  6. lsr
    ls 命令的递归版本,类似于 -R。用法:

    1
    hadoop fs -lsr <args>
  7. du
    显示目录中所有文件的大小,或者当只指定一个文件时,显示此文件的大小。用法:

    1
    hadoop fs -du URI [URI …]
  8. dus
    显示文件的大小。用法:

    1
    hadoop fs -dus <args>
  9. mkdir
    接受路径指定的作为参数,然后创建这些目录。其行为类似于 mkdir -p 会自动创建路径中的各级父目录。用法:

    1
    hadoop fs -mkdir <paths>
  10. cp
    将文件从源路径复制到目标路径。这个命令允许有多个源路径,但是目标路径必须是一个目录。用法:

    1
    hadoop fs -cp URI [URI …] <dest>
  11. copyFromLocal
    除了限定源路径是一个本地文件外,其余参数和 put 命令相似。用法:

    1
    hadoop fs -copyFromLocal <localsrc> URI
  12. copyToLocal
    除了限定目标路径是一个本地文件外,其余参数和 get 命令类似。用法:

    1
    hadoop fs -copyToLocal [-ignorecrc] [-crc] URI <localdst>
  13. mv
    将文件从源路径移动到目标路径。这个命令允许有多个源路径,但是目标路径必须是一个目录,另外不支持在不同的文件系统间移动文件。用法:

    1
    hadoop fs -mv URI [URI …] <dest>
  14. movefromLocal
    将本地文件上传到 HDFS,之后本地文件会被删除(可以理解为剪切)。用法:

    1
    hdfs fs -moveFromLocal <src> <dst>
  15. get
    复制文件到本地系统。可用 -ignorecrc 选项复制 CRC 校验失败的文件;使用 -crc 选项复制文件以及 CRC 信息。用法:

    1
    hadoop fs -get [-ignorecrc] [-crc] <src> <localdst>
  16. getmerge
    接受一个源目录和一个目标文件作为输入,然后将源目录中的文件合并到本地文件中。addnl 选项是可选的,用于指定在每个文件结尾添加一个换行符。用法:

    1
    hadoop fs -getmerge <src> <localdst> [addnl]
  17. put
    从本地文件系统中复制单个或多个源路径到目标文件系统,另外也支持从标准输入中读取输入写入目标文件系统。用法:

    1
    hadoop fs -put <localsrc> ... <dst>

    localsrc- 表示从标准输入中读取输入。

  18. rm
    删除指定的文件。只删除非空目录和文件。用法:

    1
    hadoop fs -rm URI [URI …]
  19. rmr
    rm 的递归版本。用法:

    1
    hadoop fs -rmr URI [URI …]
  20. touchz
    创建一个 0 字节的空文件。用法:

    1
    hadoop fs -touchz URI [URI …]
  21. setrep
    改变一个文件的副本系数。-R 选项用于递归改变目录下所有文件的副本系数。用法:

    1
    hadoop fs -setrep [-R] <path>
  22. stat
    返回指定路径的统计信息。用法:

    1
    hadoop fs -stat URI [URI …]
  23. tail
    将文件尾部 1K 字节的内容输出到 stdout。支持 -f 选项。用法:

    1
    hadoop fs -tail [-f] URI
  24. test
    检查文件。用法:

    1
    hadoop fs -test -[ezd] URI

    其中 -[ezd] 选项分别代表:

    • -e,检查文件是否存在。如果存在则返回 0
    • -z,检查文件是否是 0 字节。如果是则返回 0
    • -d,如果路径是个目录,则返回 1,否则返回 0
  25. text
    将源文件输出为文本格式。允许的格式是 zipTextRecordInputStream。用法:

    1
    hadoop fs -text <src>
  26. expunge
    清空回收站。用法:

    1
    hadoop fs -expunge
DFSAdmin

运行一个 HDFSdfsadmin 客户端。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 命令能列出所有当前支持的命令。

  1. report
    报告 HDFS 的基本统计信息,当然有些信息也可以在 NameNode Web 服务首页看到。

  2. safemode enter | leave | get | wait
    虽然通常并不需要,但是管理员可以手动让 NameNode 进入或离开安全模式。

  3. refreshNodes
    重新读取 hostsexclude 文件,更新允许连接到 Namenode 但是退出或加入的 Datanode 的集合。

  4. finalizeUpgrade
    删除上一次升级时制作的集群备份。终结 HDFS 的升级操作,Datanode 删除前一个版本的工作目录并且之后 Namenode 也这样做,这个操作会结束整个升级过程。

  5. upgradeProgress status | details | force
    请求当前系统的升级状态,状态的细节,或者强制升级操作进行。

  6. metasave filename
    保存 Namenode 的主要数据结构到 hadoop.log.dir 属性指定的目录下的文件中。

  7. setQuota <quota> <dirname>...<dirname>
    为每个目录设定配额,目录配额应该是一个长整型整数,强制限定了目录树下的名字个数。

  8. clrQuota <dirname>...<dirname>
    清除每一个目录的配额设定。

fsck

fsck 命令来检查系统中的各种不一致状况,运行 HDFS 文件系统检查工具。这个命令被设计来报告各种文件存在的问题,比如文件缺少数据块或者副本数目不够,另外不同于在本地文件系统上传统的 fsck 工具,这个命令并不会修正它检测到的错误。一般来说 NameNode 会自动修正大多数可恢复的错误。用法:

1
hadoop fsck [GENERIC_OPTIONS] <path> [-move | -delete | -openforwrite] [-files [-blocks [-locations | -racks]]]
  1. <path>
    检查的起始目录。

  2. move
    移动受损文件到 /lost+found

  3. delete
    删除受损文件。

  4. openforwrite
    打印出写打开的文件。

  5. files
    打印出正被检查的文件。

  6. blocks
    打印出块信息报告。

  7. locations
    打印出每个块的位置信息。

  8. 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>]
  1. submit
    提交作业。

  2. status
    打印 mapreduce 完成百分比和所有计数器。

  3. counter
    打印计数器的值。

  4. kill
    杀死指定作业。

  5. events
    打印给定范围内 jobtracker 接收到的事件细节。

  6. history
    打印作业的细节、失败及被杀死原因的细节。更多的关于一个作业的细节比如成功的任务,做过的任务尝试等信息可以通过指定 [all] 选项查看。

  7. list
    显示所有作业。-list 只显示将要完成的作业。

  8. kill-task
    杀死任务。被杀死的任务不会不利于失败尝试。

  9. 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>]
  1. conf
    作业的配置。

  2. jobconf
    增加/覆盖作业的配置项。

  3. input
    输入目录。

  4. output
    输出目录。

  5. jar
    Jar 文件名。

  6. inputformat
    InputFormat 类。

  7. map
    Java Map 类。

  8. partitioner
    Java Partitioner

  9. reduce
    Java Reduce 类。

  10. writer
    Java RecordWriter

  11. program
    可执行程序的 URI

  12. reduces
    reduce 个数。

安全模式

NameNode 启动时会从 fsimageedits 日志文件中装载文件系统的状态信息,然后等待各个 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 运算。

SqoopDataX

Sqoop 是一个用来将 Hadoop 和关系型数据库中的数据相互转移的工具。它可以将一个关系型数据库中的数据导进到 HadoopHDFS 中,也可以将 HDFS 的数据导进到关系型数据库中。
DataX 是阿里巴巴开源的离线数据同步工具,支持各种异构数据源之间高效的数据同步。

Hue

是一个基于 WEB 的监控和管理系统,实现对 HDFSMapReduce/YARNHBaseHivePig 的操作和管理。

Ambari

是一种基于 Web 的工具,支持 Hadoop 集群的供应、管理和监控。


引用


个人备注

此博客内容均为作者学习所做笔记,侵删!
若转作其他用途,请注明来源!