source /etc/profile 命令,确保系统读取最新的环境配置。tar -zxvf 包名 -C 解压路径 进行解压。例如:tar -zxvf hadoop-3.1.3.tar.gz -C /opt/module/,将Hadoop安装包解压至指定目录。java -version 查看Java版本信息,确认JDK已正确安装。hadoop version 显示Hadoop版本,测试其可用性。ssh [用户名]@[目标IP] 登录远程主机,如:ssh user@192.168.1.100;完成操作后输入 exit 退出会话。jps 可列出当前所有正在运行的Java程序,常用于判断Hadoop服务是否启动成功。rm -rf 文件夹名称 强制递归删除指定文件夹及其内部所有数据,请谨慎操作。xsync 文件名 实现跨机器同步,例如:xsync /root/myhadoop.sh,适用于集群环境下的配置传播。1. 启动Hadoop集群
# 进入Hadoop安装目录
cd /home/hadoop/hadoop-3.1.3
# 启动全部Hadoop服务
./sbin/start-all.sh
# 检查各守护进程是否运行
jps
[此处为图片1]
2. 在本地创建用于测试的数据文件
# 新建存储目录
mkdir /home/hadoop/files
cd /home/hadoop/files
# 创建并写入文本内容
echo "Hello Hadoop Hello MapReduce" > file.txt
3. 将本地文件上传至HDFS分布式文件系统
# 切换到Hadoop主目录
cd /home/hadoop/hadoop-3.1.3
# 在HDFS中创建输入目录结构
./bin/hdfs dfs -mkdir /input
./bin/hdfs dfs -mkdir /input/wordcount
# 上传本地file.txt到HDFS指定路径
./bin/hdfs dfs -put /home/hadoop/files/file.txt /input/wordcount/
# 验证上传结果
./bin/hdfs dfs -ls /input/wordcount
4. 执行MapReduce任务(以WordCount为例)
# 提交MapReduce示例作业进行词频统计
./bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.1.3.jar wordcount /input/wordcount /output/wordcount
# 输出计算结果
./bin/hdfs dfs -cat /output/wordcount/part-r-00000
[此处为图片2]
| 问题描述 | 选项 | 正确答案 | 解析说明 |
|---|---|---|---|
| JAVA_HOME应在哪个配置文件中设置? | A. hadoop-default.xml B. hadoop-env.sh C. hadoop-site.xml D. configuration.xsl |
B | hadoop-env.sh用于设定Hadoop运行所需的环境变量;hadoop-default.xml为默认配置不可修改;hadoop-site.xml曾用于覆盖默认值;configuration.xsl仅用于XML页面格式化展示。 |
| fs.default.name参数应配置在哪个文件? | A. mapred-site.xml B. core-site.xml C. hdfs-site.xml D. 以上均不是 |
B | core-site.xml是核心配置文件,负责定义HDFS访问地址和默认工作目录等关键属性;mapred-site.xml管理MapReduce框架参数;hdfs-site.xml则控制副本数量和块大小等HDFS行为。 |
| Hadoop 0.20版本中,hadoop-site.xml拆分后的文件不包括哪一个? | A. conf-site.xml B. mapred-site.xml C. core-site.xml D. hdfs-site.xml |
A | 从Hadoop 0.20开始,原hadoop-site.xml被拆分为三个独立文件:core-site.xml、hdfs-site.xml、mapred-site.xml,不再包含conf-site.xml。 |
| 完全分布式模式下需要修改的主要配置文件有哪些? | core-site.xml、hdfs-site.xml、yarn-site.xml、mapred-site.xml | ||
JAVA_HOME。1. 大数据(Big Data)定义:指在一定时间范围内无法通过传统软件工具进行有效捕捉、管理与处理的数据集合。这类数据需借助新型处理模式,以实现更强的决策支持、深度洞察和流程优化能力,具有海量性、高增长速率及多样化的特征,属于一种重要的信息资产。
2. 大数据的5V特征:
3. Hadoop 相关知识:
4. Hadoop 生态系统组成:
1. HDFS 集群角色(基于 Master/Slave 架构):
[此处为图片1]
2. YARN 核心组件(Hadoop 2.x 及以上版本):
3. 其他重要角色(Hadoop 2.x+ 支持的高可用配置):
4. Hadoop 的三种运行模式:
[此处为图片2]
5. 模式相关考题:
| 题目 | 选项 | 答案 | 解析 |
|---|
在Hadoop的不同运行模式中,单机模式与伪分布式模式存在明显区别。单机模式不启动任何守护进程,主要用于调试和测试MapReduce程序,且不使用HDFS文件系统;而伪分布式模式则会在同一台机器上模拟完整的Hadoop集群环境,包括NameNode、DataNode、ResourceManager、NodeManager等守护进程,并启用HDFS进行数据存储与读写操作。
因此,以下说法中:
Hadoop共有三种标准运行模式:
因此,“互联网模式”并非Hadoop的运行模式之一,属于干扰项。
以下是Hadoop集群初始化及日常管理中的基本命令集合:
说明:hadoop fs 与 hdfs dfs 命令功能一致,可互换使用。
HDFS是Google GFS的开源实现,采用Master/Slave架构设计,专为大规模数据集的分布式存储而构建,为MapReduce计算框架提供底层数据支撑。与其类似的系统还包括GFS本身,在考试中可能作为参考答案出现。
HDFS将大文件分割成固定大小的数据块进行存储:
HDFS通过多副本机制保障数据可靠性:
1. 第一个副本存储位置的选择逻辑:若客户端位于集群内部,则优先选择其所在机架中的节点作为第一个副本存放点;若客户端不在集群内,则从集群中随机选取一个节点,但会避开负载过高或资源紧张的节点。
2. 第二个副本的放置策略:选择与第一个副本所在机架不同的另一个机架上的任意节点,实现跨机架冗余。
3. 第三个副本的位置确定:在第二个副本所在的机架中,选择一个不同于第二个副本的节点进行存储。
- 设计目的:通过跨机架分布副本,减少机架之间的数据传输频率,提升写入效率;同时保障系统容错能力——当某个机架发生故障时,仍可通过其他机架获取数据副本,确保服务可用性。
[此处为图片1]core-site.xml 配置文件中设置参数 net.topology.script.file.name,指定一个脚本路径。该脚本接收 DataNode 的网络地址作为输入,输出对应的机架 ID(RackID)。/default-rack,副本选择完全随机。dfs.safemode.threshold.pct,位于 hdfs-default.xml 文件中),NameNode 将自动退出安全模式。hadoop dfsadmin -safemode enterhadoop dfsadmin -safemode leavehadoop dfsadmin -safemode gethadoop dfsadmin -safemode wait| 题目 | 选项 | 答案 | 解析 |
|---|---|---|---|
| NameNode启动时进入安全模式,说法错误的是? | A. 检查DataNode数据块有效性 B. 必要时复制/删除数据块 C. 满足最小副本比率条件时自动退出 D. 文件系统允许修改 |
D | 安全模式下禁止对文件系统进行任何修改操作,包括创建、删除或重命名文件等。 |
HADOOP_HOME/bin/start-balancer.sh -t 10%,其中 -t 参数表示磁盘使用率偏差阈值,当各节点间使用率差异低于该值时,认为集群已达到平衡状态。heartbeat.recheck.interval 参数调整)。HDFS中的检查点操作由core-site.xml配置文件中的两个参数控制:fs.checkpoint.period(默认值为3600秒)和fs.checkpoint.size(默认大小为67108864字节)。当满足任一条件时,Secondary NameNode将协助NameNode执行元数据的合并与持久化。
DataNode作为HDFS的数据存储节点,主要承担以下职责:
常见考题示例:在HDFS架构中,负责具体数据存储的是哪个组件?答案为:DataNode。[此处为图片1]
远程过程调用(RPC)是Hadoop分布式系统中实现进程间通信的核心协议,基于TCP/IP或UDP进行数据传输。Hadoop自研的RPC框架包含以下几个关键层次:
文件写入过程涉及客户端、NameNode与多个DataNode之间的协同工作,具体步骤如下:
另一种角度描述该流程:
写入过程示例:
典型问题:HDFS中是谁负责将文件分割成多个Block?答案:Client。[此处为图片2]
读取操作同样依赖NameNode与DataNode的协作,具体流程如下:
定义:指文件在读写过程中数据可见性的规则,保证客户端能正确感知文件内容的变化。
存在的问题:
解决方案:调用sync()方法强制刷新缓冲区,该方法返回后,所有已写入的数据对新的读者均可见;此外,关闭文件流时会隐式执行sync()操作。
代码示例:
Path p = new Path("home/temp/a.txt");
FSDataOutputStream out = fs.create(p);
out.write("content".getBytes("UTF-8"));
out.hsync();
注:hsync()确保数据被刷写到操作系统缓冲区,提供更强的持久性保障。[此处为图片3]
HDFS高可用性(HA)机制通过配置“活动-备用”模式的NameNode来实现系统容错。当Active NameNode发生故障时,Standby NameNode可自动接管服务,确保集群持续运行。
核心组件包括:
优势特点:
存在的局限性:
可通过以下两种命令前缀操作HDFS:
hadoop fs ...hdfs dfs ...注:hadoop dfs ...为旧版语法,仍保留兼容性支持。
常用操作示例:
hadoop fs -copyFromLocal input/docs/quangle.txt hdfs://localhost/user/tom/quangle.txt可省略完整URL写法:
hadoop fs -copyFromLocal input/docs/quangle.txt /user/tom/quangle.txt
hadoop fs -copyToLocal quangle.txt quangle.copy.txt
md5sum input/docs/quangle.txt quangle.copy.txt
hadoop fs -mkdir /gl hadoop fs -put sample.txt / hadoop fs -ls /
核心命令功能汇总表:
| 命令 | 功能说明 | 典型应用场景示例 |
|---|---|---|
| hadoop dfs -ls | 列出指定路径下的文件或目录内容 | 查看HDFS根目录内容: hadoop dfs -ls / |
| hadoop dfs -lsr | 递归列出目录及其子目录中的所有内容 | - |
| hadoop dfs -df | 显示目录磁盘使用情况 | - |
| hadoop dfs -du | 展示目录内各文件与子目录的大小 | - |
| hadoop dfs -count [-q] | 统计目录下文件数量与子目录数;添加-q参数可查看配额信息 | - |
| hadoop dfs -mv | 在HDFS内部移动文件或目录 | - |
| hadoop dfs -rm [-skipTrash] | 将文件移至回收站;使用-skipTrash则直接删除 | - |
| hadoop dfs -rmr [-skipTrash] | 递归删除目录及其内容(默认进入回收站) | 清空考试目录: hadoop dfs -rmr /exam |
| hadoop dfs -expunge | 彻底清空回收站中已删除的文件 | - |
| hadoop dfs -put | 将本地文件上传至HDFS指定路径 | 上传测试文件: hadoop dfs -put /home/test.txt /input |
| hadoop dfs -get [-ignoreCrc] [-crc] | 从HDFS下载文件至本地;可选是否校验CRC | 下载结果文件: hadoop dfs -get /output/result.txt /home |
| hadoop dfs -copyToLocal [-ignoreCrc] [-crc] | 功能与get类似,用于将HDFS文件复制到本地 | - |
| hadoop dfs -moveToLocal [-crc] | 将HDFS文件移动到本地(原文件被删除);支持CRC信息迁移 | - |
| hadoop dfs -mkdir | 在HDFS上创建新目录 | 创建考试专用目录: hadoop dfs -mkdir /exam |
| hadoop dfs -touchz | 在HDFS上生成一个0字节的空文件 | 生成测试空文件: hadoop dfs -touchz /exam/test.txt |
| hadoop dfs -text | 输出HDFS中文本文件的内容(自动解压缩) | - |
hadoop dfs -cat 用于查看HDFS中文件的内容。例如,可通过命令查看存储在HDFS上的配置文件内容:
hadoop dfs -cat /config/hadoop-site.xml
hadoop dfs -setrep [-R][-w] 可设置指定文件或目录的副本数量,其中-R表示递归应用到所有子文件。例如,将/test目录下所有文件的副本数设为2:
hadoop dfs -setrep -R 2 /test
hadoop dfs -test -[ezd] 用于对文件进行条件判断:-e检测文件是否存在,-z判断文件是否为空(0字节),-d判断是否为目录。例如,检查/exam路径是否为目录:
hadoop dfs -test -d /exam
hadoop dfs -stat [format] 用于输出文件或目录的统计信息,支持格式化参数,如%b表示文件大小,%n表示文件名等。
hadoop dfs -chmod [-R] 用于修改文件或目录的权限,使用-R可递归更改。例如,将/test.txt文件权限修改为755:
hadoop dfs -chmod 755 /test.txt
hadoop dfs -chown [-R] [OWNER][:[GROUP]] 用于更改文件或目录的所有者(及所属组),-R表示递归操作。例如,将/test目录及其内容的所有者更改为user:
hadoop dfs -chown -R user /test
hadoop dfs -chgrp [-R] GROUP 用于修改文件或目录的所属组,-R为递归执行。例如,将/test.txt文件的所属组更改为group1:
hadoop dfs -chgrp group1 /test.txt
hadoop dfs -help 显示所有可用的HDFS命令帮助信息。
hadoop dfs -copyFromLocal 功能与put命令类似,用于将本地文件复制到HDFS中。
hadoop dfs -moveFromLocal 将本地文件移动至HDFS指定路径,移动后本地源文件将被删除。
[此处为图片1]
2. Java API 访问方式:
要通过Java程序访问HDFS,客户端必须具备以下条件:
- 包含 hdfs-site.xml 配置文件,以便获取NameNode的相关连接信息;
- 引用 $HADOOP_HOME/lib 目录下的必要JAR包以支持Hadoop运行时环境。
Hadoop提供了一个抽象类 org.apache.hadoop.fs.FileSystem,作为不同文件系统的统一接口。以下是常见的文件系统实现及其对应URL方案和说明:
| 文件系统 | URL方案 | Java实现类 | 说明 |
|----------|--------|------------|------|
| Local file | file | fs.LocalFileSystem | 带校验功能的本地磁盘文件系统 |
| HDFS | hdfs | hdfs.DistributedFileSystem | Hadoop分布式文件系统核心实现 |
| Hftp | hftp | hdfs.HftpFileSystem | 支持通过HTTP协议对HDFS进行只读访问 |
| HSFTP | hsftp | hdfs.HsftpFileSystem | 基于HTTPS协议的HDFS只读访问 |
| WebHDFS | webhdfs | hdfs.web.WebHdfsFileSystem | 提供基于HTTP的安全读写访问能力 |
| HAR | har | fs.HarFileSystem | 构建于其他文件系统之上,用于归档文件 |
| kfs | kfs | fs.kfs.KosmosFileSystem | CloudStore文件系统(类似GFS),由C++编写 |
| FTP | ftp | fs.ftp.FTPFileSystem | 由远程FTP服务器支撑的文件系统 |
| S3(原生) | s3n | fs.s3native.NativeS3FileSystem | 由Amazon S3对象存储支持的文件系统 |
[此处为图片2]
API 使用示例:
1. 使用URL方式从HDFS读取数据:
该方法需注册自定义的流处理器工厂FsUrlStreamHandlerFactory,从而支持hdfs://等协议。
java
import org.apache.hadoop.fs.FsUrlStreamHandlerFactory;
import org.apache.hadoop.io.IOUtils;
import java.io.InputStream;
import java.net.URL;
public class URLCat {
static {
URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
}
public static void main(String[] args) throws Exception {
InputStream in = null;
try {
in = new URL(args[0]).openStream();
IOUtils.copyBytes(in, System.out, 4096, false);
} finally {
IOUtils.closeStream(in);
}
}
}
2. 利用FileSystem API读取HDFS文件:
通过Configuration和FileSystem类直接构建连接,实现更灵活的操作控制。
java
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.conf.Configuration;
以下代码展示了如何在HDFS上进行基础的目录创建操作:
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.net.URI;
public class CreateDirectory {
public static void main(String[] args) throws Exception {
String uri = "hdfs://master:9000/output/newdir";
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(URI.create(uri), conf);
Path mkdirPath = new Path(uri);
boolean isCreated = fs.mkdirs(mkdirPath);
System.out.println(isCreated ? "目录创建成功" : "目录创建失败");
}
}
[此处为图片1]
接下来是将本地文件上传至HDFS的实现方式。该程序通过输入流读取本地文件,并将其写入分布式文件系统中,同时在传输过程中显示进度提示符“.”。
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.Progressable;
import org.apache.hadoop.io.IOUtils;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.URI;
public class FileCopyFromLocal {
public static void main(String[] args) throws Exception {
String localSrc = "/home/hadoop/files/sample.txt";
String dst = "hdfs://master:9000/input/hadoop/sample.txt";
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(URI.create(dst), conf);
InputStream in = null;
OutputStream out = null;
try {
in = new BufferedInputStream(new FileInputStream(localSrc));
out = fs.create(new Path(dst), new Progressable() {
@Override
public void progress() {
System.out.print(".");
}
});
IOUtils.copyBytes(in, out, 4096, false);
} finally {
IOUtils.closeStream(in);
IOUtils.closeStream(out);
}
}
}
[此处为图片2]
从HDFS中删除指定文件的操作也十分常见。下面的代码示例演示了如何删除一个已存在的HDFS文件,并输出操作结果状态。
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.net.URI;
public class DeleteFile {
public static void main(String[] args) throws Exception {
String uri = "hdfs://master:9000/input/hadoop/sample.txt";
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(URI.create(uri), conf);
Path deletePath = new Path(uri);
boolean isDeleted = fs.delete(deletePath, false);
System.out.println(isDeleted ? "删除成功" : "删除失败");
}
}
[此处为图片3]
最后是一个读取HDFS文件内容并输出到控制台的Java程序。它利用FileSystem的open方法获取文件输入流,并通过IOUtils工具类将数据复制到标准输出。
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import java.io.InputStream;
import java.net.URI;
public class FileSystemCat {
public static void main(String[] args) throws Exception {
String uri = "hdfs://master:9000/input/sample.txt";
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(URI.create(uri), conf);
InputStream in = null;
try {
in = fs.open(new Path(uri));
IOUtils.copyBytes(in, System.out, 4096, false);
} finally {
IOUtils.closeStream(in);
}
}
}
[此处为图片4]
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.net.URI;
public class CreateDir {
public static void main(String[] args) throws Exception {
String uri = "hdfs://master:9000/input/hadoop/tmp";
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(URI.create(uri), conf);
Path dirPath = new Path(uri);
boolean isCreated = fs.mkdirs(dirPath);
System.out.println(isCreated ? "目录创建成功" : "目录创建失败");
}
}
上述代码用于在HDFS中创建指定路径的目录。通过调用fs.mkdirs()方法实现目录的递归创建,并输出操作结果状态。
[此处为图片1]
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.net.URI;
public class CheckFileIsExist {
public static void main(String[] args) throws Exception {
String uri = "hdfs://master:9000/input/hadoop/sample.txt";
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(URI.create(uri), conf);
Path path = new Path(uri);
boolean isExists = fs.exists(path);
System.out.println(isExists ? "文件存在" : "文件不存在");
}
}
该程序段的功能是判断HDFS中某个指定路径的文件是否存在。利用FileSystem对象的exists()方法返回布尔值,进而打印出“文件存在”或“文件不存在”的提示信息。
[此处为图片2]
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.net.URI;
public class ListFiles {
public static void main(String[] args) throws Exception {
String uri = "hdfs://master:9000/input";
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(URI.create(uri), conf);
Path path = new Path(uri);
FileStatus[] status = fs.listStatus(path);
for (FileStatus s : status) {
System.out.println(s.getPath().toString());
}
fs.close();
}
}
此代码示例展示了如何列出HDFS中某一目录下的所有子文件和子目录。通过调用listStatus()方法获取文件状态数组,遍历并输出每个条目的完整路径。最后关闭文件系统连接以释放资源。
[此处为图片3]
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.BlockLocation;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.net.URI;
public class LocationFile {
public static void main(String[] args) throws Exception {
String uri = "hdfs://master:9000/input/sample.txt";
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(URI.create(uri), conf);
Path path = new Path(uri);
该部分代码用于后续获取HDFS文件的数据块存储位置信息。初始化了文件系统的连接以及目标文件的路径对象,为下一步读取块信息做准备。
[此处为图片4]
FileStatus status = fs.getFileStatus(path);
BlockLocation[] blocks = fs.getFileBlockLocations(status, 0, status.getLen());
for (int i = 0; i < blocks.length; i++) {
String[] hosts = blocks[i].getHosts();
System.out.println("block_" + i + "_location: " + hosts[0]);
}
fs.close();
| 题目 | 选项 | 答案 | 解析 |
|---|---|---|---|
| 下列关于Hadoop API的说法错误的是? | A. Hadoop的文件API不是通用的,只用于HDFS文件系统 B. Configuration类的默认实例化方法是以HDFS系统的资源配置为基础的 C. FileStatus对象存储文件和目录的元数据 D. FSDataInputStream是java.io.DataInputStream的子类 |
A | A错误:Hadoop文件API具有通用性,不仅支持HDFS,还支持本地文件系统、S3等多种存储系统;B正确:Configuration类默认加载HDFS相关的配置文件进行初始化;C正确:FileStatus用于封装文件或目录的元信息,如路径、长度、权限等;D正确:FSDataInputStream继承自java.io.DataInputStream,扩展了对HDFS随机读取的支持 |
Hadoop通过校验和机制确保数据在传输和存储过程中的完整性。
校验方式:采用循环冗余校验(CRC),每个文件对应生成一个以.crc为后缀的校验文件,例如.passwd.crc。
检测机制:
ChecksumException异常。DataBlockScanner进程,定期扫描并验证其管理的所有数据块,主动发现潜在损坏。ChecksumException。合理使用压缩技术可有效降低存储开销,并加快数据在磁盘和网络间的传输效率。
优势:| 压缩格式 | 压缩率 | 压缩速度 | Split支持 | 应用场景 |
|---|---|---|---|---|
| gzip | 中 | 中 | 否 | 适用于压缩后小于130MB的文件(单HDFS块内),如小时级或天级日志归档;Hive、MapReduce、Streaming程序无需代码调整即可支持 |
| lzo | 低 | 快 | 是 | 适合大于200MB的大文件压缩,文件越大优势越明显;支持分片处理,可用于直接作为MapReduce输入 |
| snappy | 低 | 快 | 否 | 常用于MapReduce作业中map阶段输出的中间结果压缩;也可作为某一作业输出供下一作业输入,兼顾性能与效率 |
| bzip2 | 高 | 慢 | 是 | 适用于对压缩率要求高而对速度无严格限制的场景;可用于长期存档类MapReduce输出;支持Split特性,兼容部分遗留应用中的大文本处理需求 |
序列化是分布式系统中实现数据跨节点传递的核心技术之一。
定义:将内存中的结构化对象转换为字节流的过程称为序列化;反之,从字节流重建对象的过程称为反序列化。 目的:支持高效的远程过程调用(RPC),确保数据传输的安全性、高效性和紧凑性。 设计要求:Writable:用于值类型的序列化,提供基本的读写功能WritableComparable<T>:扩展自Writable,同时实现Comparable接口,主要用于键类型,支持排序操作BooleanWritableByteWritable、ShortWritable、IntWritable、VIntWritable、LongWritable、VLongWritableFloatWritable、DoubleWritableText(UTF-8编码,替代Java原生String)MapReduce采用“分而治之”的编程思想,将大规模数据处理任务分解为多个可并行执行的子任务,最终汇总结果。整个过程以键值对(Key-Value)作为基本的数据表示形式。
其核心流程如下:
(k1, v1) → Map → list(k2, v2) → Shuffle(分组与合并) → (k2, list(v2)) → Reduce → list(k3, v3)
其中,Combine函数是可选组件,形式上与Reduce函数一致,作用是在Map端进行局部聚合,减少网络传输的数据量,提升整体性能。
Map阶段:接收输入的键值对(k1, v1),经过处理后输出中间结果(k2, v2)。
Shuffle阶段:
Map端操作流程:
Reduce端操作流程:
排序机制说明:
| 题目 | 选项 | 答案 | 解析 |
|---|---|---|---|
| Hadoop集群的主要瓶颈是? | A. CPU B. 磁盘IO C. 网络 D. 内存 | B | MapReduce属于IO密集型作业,大量中间结果需读写磁盘并经网络传输,因此磁盘IO成为主要性能瓶颈。 |
| 下列关于MapReduce说法不正确的是? | A. MapReduce是一种计算框架 B. MapReduce来源于google的学术论文 C. MapReduce程序只能用java语言编写 D. MapReduce隐藏了并行计算的细节,方便使用 | C | MapReduce支持多语言开发,例如可通过Hadoop Streaming使用Python、Shell等脚本语言编写Mapper和Reducer。 |
| MapReduce框架中,支持序列化的类充当键或值,以下说法错误的是? | A. 实现Writable接口的类是值 B. 实现WritableComparable接口的类可以是值或键 C. Hadoop的基本类型Text并不实现WritableComparable接口 D. 键和值的数据类型可以超出Hadoop自身支持的基本类型 | C | Text类实际上实现了WritableComparable接口,因此既可以作为值也可以作为键使用。 |
| 在MapReduce编程模型中,键必须实现下列哪个接口? | A. WritableComparable B. Comparable C. Writable D. LongWritable | A | 由于键需要参与排序,因此必须实现WritableComparable接口;而值仅需实现Writable接口即可。 |
| Hadoop Streaming未设定Reducer时,运行会出现问题吗? | A. 会 B. 不会 | B | 若未显式指定Reducer,默认会启用IdentityReducer,直接输出接收到的键值对,不会导致运行失败。 |
| YARN的基本思想是将Hadoop中哪个进程拆分为ResourceManager和ApplicationMaster? | A. JobTracker B. TaskTracker C. NameNode D. DataNode | A | YARN将原Hadoop 1.x中的JobTracker职责拆分为两部分:资源管理由ResourceManager负责,任务调度由ApplicationMaster承担。 |
此外,在实际应用中还涉及多种支持序列化的集合类,包括但不限于:
ArrayWritable、ArrayPrimitiveWritable、TwoDArrayWritable、MapWritable、SortedMapWritable、EnumMapWritable。
这些类用于封装复杂结构的数据,便于在MapReduce各阶段之间高效传输。
执行命令如下:
bin/hadoop jar contrib/streaming/hadoop-0.20-streaming.jar -input input/filename -output output -mapper 'dosth.py 5' -file dosth.py -D mapred.reduce.tasks=1
说明:
YARN 的诞生背景:为满足对 HDFS 上数据进行大规模交互式处理的需求而设计,旨在提升集群资源利用率与作业调度效率。
核心设计理念:将原 JobTracker 的双重职责——资源管理与任务调度/监控——进行解耦。资源管理交由全局的 ResourceManager 负责,而每个应用程序的调度与协调则由其专属的 ApplicationMaster 承担。
主要组件构成:
典型工作流程:
1. Reduce Side Join(Reduce 端连接)
基本原理:
产生原因:由于 Map 阶段无法获取完整的 join 字段信息,且同 key 的数据可能分布在不同的 Map 任务中,因此必须推迟到 Reduce 阶段进行合并处理。
特点分析:实现逻辑简单,适用于任意大小的表连接;但缺点在于 Shuffle 阶段传输数据量大,网络 IO 开销高,整体性能较低。
2. Map Side Join(Map 端连接)
核心思想:将较小的数据表复制多份,分发至各节点并在每个 Map 任务的内存中构建哈希表(如 HashMap)。随后在扫描大表的过程中,以记录的 key 查询哈希表,若匹配成功则直接输出连接结果。
适用场景:适用于“一大一小”两张表之间的连接操作。
优势:连接操作在 Map 阶段即完成,避免了中间数据写入 Shuffle 过程,显著减少网络传输开销,执行效率较高。
局限性:不适用于两个均为大表的情况,受限于单个 Map 任务的内存容量。
3. SemiJoin(半连接)
实现思路:首先提取小表中的 join 键集合,通过 DistributedCache 将其广播到各个计算节点,并加载进内存(如 HashSet 结构)。在 Map 阶段处理大表时,先判断当前记录的 join 键是否存在于本地缓存中,若不存在则过滤掉,仅保留可参与连接的有效记录。
这些筛选后的记录仍需经过 Shuffle 传输至 Reduce 端,后续连接流程与 Reduce Side Join 相同。
优化目的:有效减少 Shuffle 阶段的数据传输量,缓解网络 IO 瓶颈,是对传统 Reduce Side Join 的重要改进手段。
扫码加好友,拉您进群



收藏
