第一章:Hadoop 概述与基础概念 第一章:Hadoop 概述与基础概念 1.1 大数据时代的挑战与Hadoop的诞生 在信息技术飞速发展的今天,我们正迈入一个数据爆炸式增长的时代,这就是所谓的大数据时代。各行各业,从互联网、金融、医疗到制造业、零售业,每天都在产生海量的数据。这些数据蕴藏着巨大的价值,能够帮助企业洞察市场趋势、优化运营效率、提升用户体验、甚至驱动创新。然而,传统的数据处理技术在面对如此庞大的数据量时,显得力不从心。 传统数据处理的局限性: 存储瓶颈: 传统数据库和文件系统往往难以存储PB级别甚至更大规模的数据。 计算瓶颈: 单台服务器的计算能力有限,无法在合理的时间内处理海量数据。 扩展性差: 传统系统扩展性受限,难以灵活应对数据量的快速增长。
在信息技术飞速发展的今天,我们正迈入一个数据爆炸式增长的时代,这就是所谓的大数据时代。各行各业,从互联网、金融、医疗到制造业、零售业,每天都在产生海量的数据。这些数据蕴藏着巨大的价值,能够帮助企业洞察市场趋势、优化运营效率、提升用户体验、甚至驱动创新。然而,传统的数据处理技术在面对如此庞大的数据量时,显得力不从心。
传统数据处理的局限性:
存储瓶颈: 传统数据库和文件系统往往难以存储PB级别甚至更大规模的数据。
计算瓶颈: 单台服务器的计算能力有限,无法在合理的时间内处理海量数据。
扩展性差: 传统系统扩展性受限,难以灵活应对数据量的快速增长。
成本高昂: 建设和维护高性能、高容量的传统数据处理系统成本非常高。
为了解决这些挑战,Google 在 2003 年和 2004 年分别发表了两篇具有里程碑意义的论文,分别是关于 Google 文件系统(GFS)和 MapReduce 的论文。这两篇论文阐述了分布式文件系统和分布式计算框架的核心思想,为大数据处理技术的发展指明了方向。
Apache Hadoop 正是在 Google GFS 和 MapReduce 论文的启发下,由 Doug Cutting 和 Mike Cafarella 等人于 2006 年创建的开源项目。Hadoop 旨在构建一个可靠、可扩展、分布式的大数据处理平台,能够经济高效地存储和处理海量数据。Hadoop 的诞生,极大地降低了大数据处理的门槛,使得各行各业都能够利用大数据技术来驱动业务发展。
Hadoop之所以能够在大数据领域占据举足轻重的地位,得益于其一系列核心特性:
高可靠性 (High Reliability): Hadoop 的核心组件 HDFS (Hadoop Distributed File System) 采用数据冗余备份机制,将数据切分成多个数据块并存储在集群中的不同节点上,每个数据块通常会有多个副本。即使集群中部分节点发生故障,数据仍然可以安全访问,保证了数据的高可靠性。
高扩展性 (High Scalability): Hadoop 采用分布式架构,能够轻松地通过增加集群节点来扩展存储和计算能力。它可以处理从 GB 级别到 PB 级别甚至 EB 级别的数据,并且可以随着数据量的增长而线性扩展,满足不断增长的数据处理需求。
分布式存储 (Distributed Storage): Hadoop HDFS 将数据分布式存储在集群中的多台计算机上,突破了单机存储容量的限制,能够存储海量数据。
分布式计算 (Distributed Computing): Hadoop MapReduce 是一种分布式计算框架,可以将大规模的数据处理任务分解成多个小任务,并行地在集群中的多个节点上执行,大大提高了数据处理效率。
成本低廉 (Cost-Effective): Hadoop 可以运行在廉价的商用硬件上,无需昂贵的专用服务器和存储设备,降低了大数据基础设施的建设和维护成本。
开源 (Open Source): Hadoop 是一个开源项目,拥有庞大的社区支持和活跃的开发者群体。用户可以免费使用、修改和分发 Hadoop,并可以从社区获得丰富的资源和支持。
容错性 (Fault Tolerance): Hadoop 设计时就考虑了硬件故障的常态,能够自动检测和处理节点故障。当某个节点发生故障时,Hadoop 可以将该节点上的任务重新分配到其他节点执行,保证了任务的顺利完成和数据的可用性。
灵活性 (Flexibility): Hadoop 不仅可以处理结构化数据,还可以处理半结构化和非结构化数据,例如文本、日志、图像、视频等多种数据类型。
数据局部性 (Data Locality): Hadoop 尽量将计算任务移动到数据所在的节点上执行,减少了数据在网络中的传输,提高了数据处理效率。
Hadoop 架构主要由三个核心组件构成:HDFS (Hadoop Distributed File System)、MapReduce 和 YARN (Yet Another Resource Negotiator)。 这三个组件共同协作,构建了一个完整的大数据处理平台。
HDFS 是 Hadoop 的核心存储组件,是一个分布式文件系统,专门设计用于存储海量数据。它具有高容错性、高吞吐量、高扩展性等特点,能够可靠地存储 PB 级别甚至更大规模的数据。
HDFS 的主要特点和概念:
数据块 (Data Block): HDFS 将文件切分成固定大小的数据块 (默认 128MB),并将这些数据块分布式存储在集群中的多个 DataNode 节点上。数据块是 HDFS 存储的基本单元。
NameNode (名称节点): NameNode 是 HDFS 的核心组件,负责管理文件系统的命名空间 (Namespace) 和元数据 (Metadata)。元数据包括文件和目录的结构信息、每个文件的数据块信息、数据块存储在哪些 DataNode 节点上等。NameNode 存储元数据在内存中,并持久化到磁盘。
DataNode (数据节点): DataNode 是 HDFS 的工作节点,负责存储实际的数据块。DataNode 定期向 NameNode 汇报自身状态和数据块信息,并执行 NameNode 发送的指令,例如数据块的读写、复制、删除等操作。
Secondary NameNode (辅助名称节点): Secondary NameNode 不是 NameNode 的备份,而是辅助 NameNode 进行元数据管理的节点。它定期从 NameNode 获取元数据信息,并将其合并成新的元数据镜像文件,防止 NameNode 故障时元数据丢失过多。
数据冗余 (Replication): 为了保证数据的高可靠性,HDFS 采用数据冗余备份机制。每个数据块通常会有多个副本 (默认 3 个),这些副本会存储在不同的 DataNode 节点上。即使部分 DataNode 节点发生故障,数据仍然可以从其他副本中恢复。
HDFS 架构图 (mermaid graph TD):
HDFS 代码实践 (命令行操作):
Hadoop 提供了 hdfs dfs 命令行工具,用于与 HDFS 进行交互,执行文件和目录操作。
1. 创建目录:
hdfs dfs -mkdir /user/hadoop/input
代码详解:
hdfs dfs: 调用 Hadoop HDFS 命令行工具。
-mkdir: 指定操作为创建目录。
/user/hadoop/input: 要创建的目录路径,路径以 / 开头,表示 HDFS 的根目录。
2. 上传本地文件到 HDFS:
hdfs dfs -put localfile.txt /user/hadoop/input/
代码详解:
hdfs dfs: 调用 Hadoop HDFS 命令行工具。
-put: 指定操作为上传文件。
localfile.txt: 本地文件路径。
/user/hadoop/input/: HDFS 目标目录路径。
3. 从 HDFS 下载文件到本地:
hdfs dfs -get /user/hadoop/input/output.txt local_output.txt
代码详解:
hdfs dfs: 调用 Hadoop HDFS 命令行工具。
-get: 指定操作为下载文件。
/user/hadoop/input/output.txt: HDFS 文件路径。
local_output.txt: 本地目标文件路径。
4. 查看 HDFS 目录内容:
hdfs dfs -ls /user/hadoop/input/
代码详解:
hdfs dfs: 调用 Hadoop HDFS 命令行工具。
-ls: 指定操作为列出目录内容。
/user/hadoop/input/: HDFS 目录路径。
5. 查看 HDFS 文件内容:
hdfs dfs -cat /user/hadoop/input/input.txt
代码详解:
hdfs dfs: 调用 Hadoop HDFS 命令行工具。
-cat: 指定操作为查看文件内容。
/user/hadoop/input/input.txt: HDFS 文件路径。
MapReduce 是 Hadoop 的核心计算组件,是一个用于大规模数据并行处理的编程模型和计算框架。它将复杂的数据处理任务分解成两个主要阶段:Map 阶段 和 Reduce 阶段,并通过分布式并行计算的方式来高效地处理海量数据。
MapReduce 的主要特点和概念:
Map 阶段 (映射阶段): Map 阶段接收输入数据,并将其分割成多个小的数据块。Mapper 函数对每个数据块进行处理,将输入数据转换成键值对 (key-value pairs) 的形式,作为中间结果输出。
Shuffle & Sort 阶段 (混洗和排序阶段): Shuffle & Sort 阶段对 Map 阶段输出的中间结果进行混洗和排序。混洗 (Shuffle) 将具有相同键的键值对数据汇集到同一个 Reducer 节点上,排序 (Sort) 则对每个 Reducer 接收到的数据进行排序,方便后续的 Reduce 阶段处理。
Reduce 阶段 (归约阶段): Reduce 阶段接收 Shuffle & Sort 阶段的输出结果,即经过排序的键值对数据。Reducer 函数对具有相同键的值进行聚合、统计或其他处理,最终输出结果。
JobTracker (作业跟踪器) (在 YARN 架构中已被 ResourceManager 取代): JobTracker (在 Hadoop 1.x 版本中) 负责作业调度和资源管理,接收客户端提交的 MapReduce 作业,并将作业分解成多个 Task (Map Task 和 Reduce Task),分配到不同的 TaskTracker 节点执行。
TaskTracker (任务跟踪器) (在 YARN 架构中已被 NodeManager 取代): TaskTracker (在 Hadoop 1.x 版本中) 运行在集群中的各个节点上,负责执行 JobTracker 分配的 Task,并向 JobTracker 汇报 Task 的执行状态。
MapReduce 工作流程图 (mermaid graph TD):
MapReduce 代码实践 (WordCount 示例 - Python Hadoop Streaming):
Hadoop Streaming 允许使用任何可执行程序(例如 Python、Shell 脚本等)作为 Mapper 和 Reducer,简化了 MapReduce 程序的开发。
1. Mapper 脚本 (mapper.py):
#!/usr/bin/env python import sys for line in sys.stdin: line = line.strip() words = line.split() for word in words: print(f"{word}\t1")
代码详解:
#!/usr/bin/env python: 指定脚本使用 Python 解释器执行。
import sys: 导入 sys 模块,用于访问标准输入。
for line in sys.stdin:: 循环读取标准输入中的每一行数据。
line = line.strip(): 去除行首尾的空白字符。
words = line.split(): 将行数据按照空格分割成单词列表。
for word in words:: 循环遍历单词列表。
print(f"{word}\t1"): 输出每个单词和计数 1,格式为 "word\t1",中间用制表符分隔,作为键值对 (key: word, value: 1) 输出。
2. Reducer 脚本 (reducer.py):
#!/usr/bin/env python import sys current_word = None current_count = 0 word = None for line in sys.stdin: line = line.strip() word, count = line.split('\t', 1) try: count = int(count) except ValueError: continue if current_word == word: current_count += count else: if current_word: print(f"{current_word}\t{current_count}") current_count = count current_word = word if current_word == word: print(f"{current_word}\t{current_count}")
代码详解:
#!/usr/bin/env python: 指定脚本使用 Python 解释器执行。
import sys: 导入 sys 模块,用于访问标准输入。
初始化变量 current_word, current_count, word。
for line in sys.stdin:: 循环读取标准输入中的每一行数据。
line = line.strip(): 去除行首尾的空白字符。
word, count = line.split('\t', 1): 将行数据按照制表符分割成单词和计数。
try...except ValueError: 尝试将计数转换为整数,如果转换失败则跳过当前行。
if current_word == word:: 如果当前单词与之前处理的单词相同,则累加计数。
else:: 如果当前单词与之前处理的单词不同,则先输出之前单词的统计结果,然后更新当前单词和计数。
最后一个 if 语句用于处理最后一个单词的输出。
3. 运行 MapReduce 作业 (命令行):
假设输入文件 input.txt 存储在 HDFS 的 /user/hadoop/input/ 目录下,输出目录为 /user/hadoop/output/。
hadoop jar $HADOOP_HOME/share/hadoop/tools/lib/hadoop-streaming-*.jar \ -input /user/hadoop/input/input.txt \ -output /user/hadoop/output/ \ -mapper mapper.py \ -reducer reducer.py
代码详解:
hadoop jar $HADOOP_HOME/share/hadoop/tools/lib/hadoop-streaming-*.jar: 运行 Hadoop Streaming JAR 包。$HADOOP_HOME 需要替换为 Hadoop 安装目录。
-input /user/hadoop/input/input.txt: 指定输入文件路径为 HDFS 的 /user/hadoop/input/input.txt。
-output /user/hadoop/output/: 指定输出目录路径为 HDFS 的 /user/hadoop/output/。如果目录已存在,需要先删除。
-mapper mapper.py: 指定 Mapper 脚本为 mapper.py。
-reducer reducer.py: 指定 Reducer 脚本为 reducer.py。
运行成功后,结果文件将存储在 HDFS 的 /user/hadoop/output/ 目录下,其中包含了每个单词及其出现的次数。
YARN 是 Hadoop 的资源管理与调度框架,也被称为 Hadoop 2.0 的核心组件。YARN 的引入使得 Hadoop 不再局限于 MapReduce 框架,可以支持多种计算框架 (例如 Spark、Flink 等) 运行在 Hadoop 集群之上,实现了资源共享和多框架协同工作,大大提升了 Hadoop 的灵活性和通用性。
YARN 的主要特点和概念:
ResourceManager (资源管理器): ResourceManager 是 YARN 的核心组件,负责整个集群的资源管理和调度。它接收客户端提交的作业,并分配资源给应用程序运行。ResourceManager 主要由两个组件构成:
Scheduler (调度器): Scheduler 负责资源调度,根据应用程序的资源需求和集群的资源情况,将资源分配给应用程序。YARN 支持多种调度器,例如 FIFO Scheduler、Capacity Scheduler、Fair Scheduler 等。
ApplicationsManager (应用程序管理器): ApplicationsManager 负责管理集群中运行的所有应用程序,包括应用程序的提交、监控、重启等。
NodeManager (节点管理器): NodeManager 运行在集群中的每个节点上,负责管理本节点的资源 (CPU、内存、磁盘、网络等),并接收 ResourceManager 的指令,启动和监控 Container。
ApplicationMaster (应用程序管理器): ApplicationMaster 是每个应用程序的管理者,负责应用程序的生命周期管理。每个应用程序启动时,都会启动一个 ApplicationMaster 进程。ApplicationMaster 向 ResourceManager 申请资源,并将任务分配给 NodeManager 执行,监控任务的执行状态,并在任务失败时进行重试。
Container (容器): Container 是 YARN 的资源分配单位,封装了 CPU、内存、磁盘、网络等资源。每个应用程序的任务都运行在 Container 中。
YARN 架构图 (mermaid graph TD):
YARN 代码实践 (运行 MapReduce 作业 - 示例命令行):
在 YARN 架构下,运行 MapReduce 作业的方式与 Hadoop 1.x 类似,但底层的资源管理和调度由 YARN 负责。
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar wordcount \ /user/hadoop/input/input.txt /user/hadoop/output/
代码详解:
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar wordcount: 运行 Hadoop MapReduce 示例 JAR 包中的 WordCount 程序。
/user/hadoop/input/input.txt: 指定输入文件路径为 HDFS 的 /user/hadoop/input/input.txt。
/user/hadoop/output/: 指定输出目录路径为 HDFS 的 /user/hadoop/output/。
YARN 负责为该 MapReduce 作业分配资源,启动 ApplicationMaster 和 Container,并将 Map Task 和 Reduce Task 分配到 Container 中执行。
Hadoop 生态系统是一个庞大而丰富的体系,除了核心组件 HDFS、MapReduce 和 YARN 之外,还包含了众多基于 Hadoop 构建的上层工具和框架,用于解决各种大数据应用场景的需求。
Hadoop 生态系统中常用的组件包括:
Hive: 基于 Hadoop 的数据仓库工具,提供 SQL-like 的查询语言 (HiveQL),可以将结构化数据映射到 Hadoop 上进行分析和查询。
Pig: 基于 Hadoop 的数据流处理语言和框架,提供 Pig Latin 语言,用于编写复杂的数据转换和分析任务。
HBase: 基于 Hadoop 的 NoSQL 数据库,提供高可靠性、高性能、列式存储的分布式数据库,适用于实时数据访问和随机读写场景。
Spark: 基于 Hadoop 的快速通用计算引擎,提供内存计算能力,比 MapReduce 更快,适用于迭代计算和实时计算场景。
ZooKeeper: 分布式协调服务,为 Hadoop 集群提供配置管理、分布式同步、命名服务等功能。
Sqoop: 数据传输工具,用于在 Hadoop 和关系型数据库之间进行数据导入和导出。
Flume: 分布式、可靠、高可用的海量日志采集系统,用于将日志数据从各种来源采集到 Hadoop 中。
Kafka: 分布式流式处理平台,提供高吞吐量、低延迟的消息队列服务,适用于实时数据流处理场景。
Oozie: 工作流调度系统,用于调度和管理 Hadoop 作业,例如 MapReduce、Pig、Hive 等。
Hadoop 生态系统组件关系图 (mermaid graph TD - 简化版):