本文还有配套的精品资源,点击获取
简介:本指南详细介绍了在Windows环境下如何使用
hadoop-common-2.2.0-bin-master.zip
文件开发HDFS客户端,涵盖了从下载、解压、环境配置到客户端开发的全过程。特别指出,在Windows系统中使用Hadoop需要对环境变量进行配置,并且要对Hadoop的配置文件进行适当修改以适配本地环境。提供了HDFS客户端的开发步骤和实例代码,并概述了解决Windows特有的挑战。
1. Hadoop Common 组件简介
1.1 Hadoop Common组件的功能与作用
1.1.1 Hadoop Common组件的定义
Hadoop Common,顾名思义,是Hadoop生态系统中的基础组件,它包含了运行Hadoop所必需的库和工具,以及构建其他Hadoop模块的基石。作为Hadoop的基础设施,它为其他组件,如HDFS、YARN和MapReduce等提供了核心支持。
1.1.2 Hadoop Common组件的主要功能
该组件提供了如输入输出、网络通信、数据序列化、文件系统操作等基本服务和工具。它确保了Hadoop不同模块之间的兼容性,并为开发者提供了一套统一的接口,以便在分布式环境中执行任务和数据处理。
1.1.3 Hadoop Common组件在Hadoop生态系统中的地位
Hadoop Common位于整个Hadoop架构的最底层,其它所有组件都是建立在它之上的。没有Hadoop Common,Hadoop的其他组件将无法运行,因此它对于整个生态系统来说是至关重要的。
1.2 Hadoop Common组件的架构与设计
1.2.1 Hadoop Common组件的架构概述
Hadoop Common遵循模块化设计原则,它包括一系列独立的库,这些库之间通过定义良好的接口相互作用。组件之间实现解耦合,便于维护和升级。
1.2.2 Hadoop Common组件的设计理念
设计上的核心理念是提供一套统一的、可扩展的接口,使得开发者能够在分布式环境中编写和运行应用程序,而无需担心底层细节。
1.2.3 Hadoop Common组件的架构优势
由于其高度模块化的设计,Hadoop Common组件能够被不同的应用程序和组件复用,减少了代码重复,提高了开发效率,并且也易于进行性能优化和错误修正。
1.3 Hadoop Common组件的使用场景与案例
1.3.1 Hadoop Common组件的典型使用场景
Hadoop Common的使用场景包括但不限于:在分布式文件系统中读写数据、通过网络传输数据、实现数据的序列化和反序列化以及处理多种文件格式等。
1.3.2 Hadoop Common组件的成功案例分享
许多大型互联网公司如Yahoo、Facebook等在构建大数据处理平台时都采用了Hadoop Common。例如,通过Hadoop Common提供的基础服务,它们能够处理PB级别的数据,并支持各种复杂的数据分析和处理任务。
本文介绍了Hadoop Common组件的基础知识,从它的定义、主要功能到在生态系统中的地位,以及它的架构设计和理念,最后探索了它的应用案例。Hadoop Common作为Hadoop生态的基石,对于理解整个分布式处理框架至关重要。接下来的文章将继续深入探讨如何在Windows环境下搭建开发环境。
2. Hadoop Common 在 Windows 下的开发环境搭建
2.1 Hadoop Common组件在Windows平台下的安装
2.1.1 下载与安装Hadoop Common组件的步骤
在Windows平台上安装Hadoop Common组件,您需要遵循以下步骤:
- ** 下载Hadoop ** :首先,从官方网站或镜像站点下载Hadoop的稳定版压缩包。
- ** 解压Hadoop文件 ** :解压下载的压缩包到您希望的目录中。
- ** 设置环境变量 ** :添加Hadoop的bin目录到系统的PATH环境变量中,以便能够在命令行中直接运行Hadoop命令。
- ** 验证安装 ** :通过运行
hadoop version
命令来验证安装是否成功。
2.1.2 安装过程中可能遇到的问题及解决方法
安装过程中可能会遇到以下问题:
- ** 环境变量配置错误 ** :确认添加的路径是正确的,并且没有拼写错误。路径应包括Hadoop安装目录下的
bin
和sbin
子目录。 - ** 版本兼容性问题 ** :确保下载的Hadoop版本与您的Windows操作系统兼容。您可能需要下载适用于Windows的预编译二进制版本。
- ** 权限问题 ** :以管理员权限运行命令提示符来安装Hadoop,以避免权限不足的问题。
2.2 Hadoop Common在Windows下的开发环境配置
2.2.1 配置Hadoop Common的环境变量
- ** 配置HADOOP_HOME ** :将Hadoop的安装目录设置为
HADOOP_HOME
环境变量。 - ** 更新PATH环境变量 ** :确保
%HADOOP_HOME%\bin
和%HADOOP_HOME%\sbin
被添加到PATH环境变量中。
2.2.2 配置Java环境
- ** 安装Java ** :确保您的系统中安装了Java JDK,并且
JAVA_HOME
环境变量指向JDK的安装目录。 - ** 设置PATH ** :在PATH环境变量中添加Java的
bin
目录。
2.2.3 配置Hadoop的环境变量
除了
HADOOP_HOME
和
JAVA_HOME
,还需要配置其他相关环境变量,如
HADOOP_CONF_DIR
,指向Hadoop配置文件所在的目录。
2.2.4 验证开发环境的配置是否成功
在命令行中运行以下命令来验证安装:
java -version
:检查Java是否安装正确。hadoop version
:检查Hadoop是否配置正确。
如果一切设置正确,您应该能够看到Java和Hadoop的版本信息。
2.3 Hadoop Common组件在Windows平台下的特殊配置
在Windows平台下使用Hadoop时,有一些特殊的配置步骤需要了解:
- ** 启用Hadoop的Windows子系统支持 ** :对于某些版本的Hadoop,需要使用Windows子系统来提供类Unix环境。这通常在较新版本的Windows中支持。
- ** 权限问题 ** :在Windows上,您可能需要以管理员权限运行Hadoop的某些命令,例如使用
start-dfs.cmd
和start-yarn.cmd
脚本。 - ** 兼容性问题 ** :需要确保Hadoop版本与您的Windows系统兼容。如果不兼容,您可能需要查找补丁或者使用旧版本的Hadoop。
- ** 网络配置 ** :Windows防火墙可能阻止Hadoop组件之间的通信。您可能需要配置防火墙允许相应的端口。
通过遵循上述步骤和注意事项,您应该能够在Windows环境下成功配置和使用Hadoop Common组件。这对于希望在Windows上进行Hadoop开发或测试的用户尤其重要。
3. 环境变量配置
3.1 环境变量配置的理论知识
3.1.1 环境变量的定义与作用
环境变量是操作系统中的一个重要概念,它们是操作系统用来指定系统运行环境的一些参数。环境变量一般以键值对的形式存在,存储了诸如系统路径、临时文件目录、系统设置等信息。这些变量可以被操作系统以及在操作系统上运行的程序读取和使用,来判断或设置系统的运行状态和行为。
3.1.2 环境变量的配置方法
在不同的操作系统中,环境变量的配置方法也有所不同。在Windows系统中,环境变量可以在系统的“环境变量”对话框中进行设置。而在类Unix系统中,通常通过命令行工具(如export命令)或者在用户的shell配置文件中(如.bashrc、.bash_profile等)进行设置。环境变量的配置通常需要管理员权限。
3.2 Hadoop Common环境变量配置的实践
3.2.1 Hadoop Common环境变量的配置步骤
在配置Hadoop Common环境变量之前,假设你已经成功安装了Java,并且Hadoop Common的安装包也已经下载并解压到指定目录。
- 打开系统的环境变量设置界面。
- 创建一个新的系统环境变量名为
HADOOP_HOME
,其值为Hadoop安装目录的完整路径,例如C:\hadoop\hadoop-3.2.1
。 - 在
Path
环境变量中添加Hadoop的bin目录和sbin目录的路径,以确保可以在命令行中直接运行Hadoop相关命令。例如,%HADOOP_HOME%\bin
和%HADOOP_HOME%\sbin
。
3.2.2 配置成功后的验证方法
配置完环境变量后,为了验证是否配置成功,可以在命令行窗口执行以下命令:
hadoop version
如果配置正确,该命令将输出Hadoop的版本信息。如果没有输出,或者命令无法识别,那么可能是环境变量配置有误,需要重新检查。
3.2.3 配置失败的常见问题与解决方法
如果遇到配置失败的情况,常见问题可能有:
- 环境变量值的路径错误,例如路径中存在多余的空格,或者路径指向了错误的安装目录。
- 权限问题,某些目录或文件需要管理员权限才能访问。
- 环境变量没有更新,需要重新启动命令行窗口或者计算机。
遇到这些问题时,首先检查环境变量的值是否正确,然后尝试以管理员权限重新启动命令行窗口进行配置。如果问题依旧,可尝试重启计算机。
在本章节中,我们详细地介绍了环境变量的理论知识,并进一步深入探讨了Hadoop Common环境变量的配置实践,包括配置步骤、验证方法及遇到问题时的解决策略。通过本章内容的学习,读者可以对环境变量有一个全面的认识,并能够熟练地配置Hadoop Common环境变量,为接下来的学习和开发工作打下坚实的基础。
4. Hadoop 配置文件设置
4.1 Hadoop配置文件的理论知识
4.1.1 Hadoop配置文件的类型与作用
Hadoop的配置是通过一系列配置文件来完成的,这些文件定义了Hadoop运行所需的各种参数和设置。最核心的配置文件包括
core-site.xml
、
hdfs-site.xml
、
mapred-site.xml
和
yarn-site.xml
,每个文件扮演着不同的角色:
core-site.xml
:这是核心设置文件,用于配置Hadoop运行的基本环境,例如文件系统的默认类型(HDFS)、IO设置(如缓冲区大小)以及安全性设置(如Kerberos)。hdfs-site.xml
:这个文件专门用于配置HDFS的参数,比如副本的数量、存储空间的配额以及名称节点和数据节点的相关设置。mapred-site.xml
:用于配置MapReduce作业的运行环境,包括作业调度器、资源管理器以及任务执行相关的参数。yarn-site.xml
:YARN(Yet Another Resource Negotiator)的配置文件,负责资源管理和作业调度,控制着NodeManager和ResourceManager的行为。
这些配置文件将被Hadoop框架在启动时读取,确保整个集群的配置一致性。正确的配置可以优化Hadoop集群的性能,提高数据处理效率,并确保集群的安全稳定运行。
4.1.2 Hadoop配置文件的设置方法
Hadoop配置文件遵循XML格式,每个文件内部都包含
<configuration>
标签,在这个标签内可以定义多个
<property>
元素,每个
<property>
元素代表一个配置项。配置项由
<name>
和
<value>
两个子元素组成,分别代表配置项的名称和值。
下面是一个简单的
core-site.xml
配置示例:
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>
</property>
<property>
<name>io.file.bufffer.size</name>
<value>131072</value>
</property>
<!-- 其他配置项 -->
</configuration>
设置配置文件的方法分为几个步骤:
- 创建或编辑相应的配置文件。
- 在文件中添加或修改所需的配置项。
- 确保配置项的
<name>
和<value>
正确无误。 - 保存配置文件并关闭编辑器。
完成配置文件的设置之后,通常需要重启相关服务,以便配置生效。在某些情况下,Hadoop提供动态加载配置文件的功能,可以无需重启服务而使更改立即生效。
4.2 Hadoop配置文件的实践操作
4.2.1 Hadoop配置文件的基本设置
对于初学者或者在搭建Hadoop集群时,首先需要完成基本的Hadoop配置。下面将介绍在单节点Hadoop集群上设置核心配置文件
core-site.xml
的基本步骤:
- 打开
core-site.xml
文件(如果不存在,则需要创建一个)。 - 添加以下基本配置项:
<configuration>
<!-- 配置默认的文件系统 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>
</property>
<!-- 配置Hadoop临时目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>file:/path/to/tmp</value>
</property>
<!-- 配置HDFS NameNode的http端口 -->
<property>
<name>dfs.namenode.http-address</name>
<value>localhost:50070</value>
</property>
<!-- 其他基本设置 -->
</configuration>
确保替换了示例中的
/path/to/tmp
为实际的本地路径。
- 保存文件并关闭编辑器。
- 重启Hadoop集群的所有相关服务。
4.2.2 Hadoop配置文件的高级设置
在实际部署和使用Hadoop集群时,通常需要进行一些高级配置以优化性能和稳定性。高级设置可能包括:
- ** HDFS副本因子的配置 ** :通过
hdfs-site.xml
文件可以设置HDFS文件的副本数量,以满足数据的可靠性要求。
<configuration>
<!-- 配置HDFS的副本因子 -->
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<!-- 其他高级设置 -->
</configuration>
- ** YARN资源管理的配置 ** :在
yarn-site.xml
中配置资源管理相关的参数,比如内存和CPU的核心数量。
<configuration>
<!-- 配置YARN NodeManager可用资源 -->
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>8192</value>
</property>
<!-- 其他高级设置 -->
</configuration>
- ** MapReduce作业调度器配置 ** :通过
mapred-site.xml
指定使用的作业调度器类型和相关参数。
<configuration>
<!-- 配置MapReduce作业调度器 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!-- 其他高级设置 -->
</configuration>
4.2.3 Hadoop配置文件设置后的验证方法
配置文件设置完成后,需要验证配置是否正确并生效。通常有以下几种方法进行验证:
- ** 查看日志文件 ** :检查Hadoop服务启动的日志文件,查看是否有配置文件相关错误信息。
- ** 使用Web界面 ** :访问Hadoop集群管理界面,如NameNode和ResourceManager的Web界面,查看集群状态信息,确认设置生效。
- ** 运行测试程序 ** :执行一些基本的Hadoop命令或运行测试MapReduce作业,如
hadoop fs -ls /
来查看HDFS根目录信息,确保配置成功。 - ** 检查配置文件中的值 ** :使用Hadoop的shell命令
hadoop getconf
来检查配置项的值,例如hadoop getconf -conf core-site.xml -namenode
,可以查看NameNode的相关配置。
通过上述验证方法,可以确保配置文件中的每个设置都已经正确地应用到Hadoop集群中。
下面是一个使用Hadoop shell命令
hadoop getconf
检查
fs.defaultFS
配置项的例子:
hadoop@localhost:~$ hadoop getconf -conf core-site.xml -namenode
hdfs://localhost:9000
该命令输出了
fs.defaultFS
的值,这里显示的是我们之前在
core-site.xml
中配置的HDFS默认文件系统路径,表示配置已经成功应用。
5. HDFS 客户端开发步骤
5.1 HDFS客户端开发的理论知识
5.1.1 HDFS客户端的概念与作用
HDFS客户端是用于与Hadoop分布式文件系统(HDFS)进行交互的接口,它允许开发者和应用程序通过编程方式访问存储在HDFS上的数据。HDFS客户端将底层网络通信、数据节点管理等复杂操作封装起来,为用户提供简单的API接口。
在分布式系统中,数据通常需要进行高效的读写、存储和管理。HDFS客户端提供以下核心功能:
- ** 文件操作: ** 包括创建、删除、移动、重命名文件或目录。
- ** 数据读写: ** 支持从文件中读取数据和向文件中写入数据。
- ** 文件状态管理: ** 能够查询文件的属性,例如文件大小、块大小、复制因子等。
- ** 权限管理: ** 对文件和目录进行权限控制,支持安全模式下的访问。
- ** 命名空间管理: ** 管理文件系统的命名空间,支持目录结构的创建和删除。
5.1.2 HDFS客户端的开发步骤
HDFS客户端的开发主要分为以下几个步骤:
- ** 环境搭建: ** 设置Hadoop环境变量,确认Hadoop客户端库已经加入到项目的依赖中。
- ** 代码开发: ** 使用Hadoop提供的API编写客户端程序,实现所需功能。
- ** 功能测试: ** 对开发的客户端程序进行测试,确保它能够正确地与HDFS交互。
- ** 异常处理: ** 对可能出现的异常进行处理,确保程序的健壮性和稳定性。
- ** 性能优化: ** 根据需要对客户端程序进行性能调优。
HDFS客户端开发过程中,开发者需要对Hadoop API有一定了解,特别是文件操作、目录管理等相关的API。此外,了解HDFS的基本架构和工作原理对于开发高效稳定的HDFS客户端至关重要。
5.2 HDFS客户端开发的实践操作
5.2.1 HDFS客户端开发的基本步骤
在开发HDFS客户端程序之前,开发者需要确保Hadoop开发环境已经搭建完成,并且相关的依赖库已经正确地添加到项目中。
- ** 初始化FileSystem对象: ** 首先需要创建一个
FileSystem
对象,这是HDFS客户端编程中最重要的一步。通常使用get
静态方法来获取一个与HDFS集群通信的FileSystem
实例。
java Configuration conf = new Configuration(); conf.set("fs.defaultFS", "hdfs://master:9000"); // 指定HDFS的NameNode地址 FileSystem fs = FileSystem.get(conf);
在上述代码中,
fs.defaultFS
配置项指向了HDFS的NameNode,其格式为
hdfs://主机名:端口号
。这个步骤是连接HDFS集群的关键。
- ** 读取文件: ** 读取HDFS文件的操作类似于标准Java IO操作。首先获取文件的输入流,然后读取数据。
java Path file = new Path("/user/hadoop/input.txt"); // 指定HDFS上的文件路径 FSDataInputStream fis = fs.open(file); // 读取数据逻辑... fis.close();
- ** 写入文件: ** 向HDFS写入文件时,首先需要创建一个
FSDataOutputStream
对象,然后通过这个输出流写入数据。
java Path file = new Path("/user/hadoop/output.txt"); // 指定HDFS上的文件路径 FSDataOutputStream fos = fs.create(file); // 写入数据逻辑... fos.close();
- ** 关闭FileSystem对象: ** 完成文件操作后,必须关闭
FileSystem
对象以释放资源。
java fs.close();
在实际开发过程中,开发者还需要考虑文件的分块读写、错误处理、日志记录等多个方面,以确保HDFS客户端程序的稳定运行。
5.2.2 HDFS客户端开发的高级操作
在基本的文件操作之外,HDFS客户端开发还涉及一些高级特性,比如:
- ** 文件系统元数据操作: ** 读取文件的元数据信息,如权限、修改时间、块大小等。
- ** 文件系统状态检查: ** 检查HDFS的健康状态,例如NameNode是否正常工作。
- ** 文件管理: ** 重命名、移动、复制文件或目录,设置文件权限。
- ** 读写高级配置: ** 动态修改HDFS客户端的配置,比如设置缓冲区大小等。
对于高级操作,Hadoop API同样提供了丰富的接口。例如,获取文件的详细信息可以通过
FileSystem
对象的
getFileStatus()
方法实现。
FileStatus fileStatus = fs.getFileStatus(new Path("/user/hadoop/file.txt"));
long blockSize = fileStatus.getBlockSize();
short replication = fileStatus.getReplication();
5.2.3 HDFS客户端开发的常见问题与解决方法
在HDFS客户端开发过程中,开发者可能会遇到各种问题。常见问题及解决方法包括:
- ** 连接问题: ** 确保Hadoop集群的NameNode地址和端口号正确无误。
- ** 权限问题: ** HDFS上的操作需要相应的权限,检查用户是否有权限执行相关操作。
- ** 网络问题: ** HDFS客户端与集群之间可能因为网络问题导致通信失败,需要检查网络配置和防火墙设置。
- ** 数据一致性问题: ** HDFS写入数据后可能存在短暂的数据不一致问题,可以使用
fsync()
方法确保数据落盘。
开发者在开发时应该根据不同的需求选择合适的API,并对可能出现的异常进行合理处理。对于API的使用,应该查阅官方文档,了解每个方法的参数意义和返回值。
HDFS客户端开发是深入理解和使用Hadoop生态系统的重要一步。掌握客户端开发不仅能够帮助开发者更好地利用HDFS,还能进一步提升对整个大数据处理流程的理解。
6. HDFS 客户端操作示例代码及Windows系统中使用 Hadoop 的特殊处理
6.1 HDFS客户端操作示例代码
在Hadoop分布式文件系统(HDFS)中,客户端操作是常见的任务,包括读取、写入和删除文件。以下是一些示例代码,这些示例代码使用Java编写,并且适用于大多数开发环境。
6.1.1 读取文件的示例代码
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 ReadFileExample {
public static void main(String[] args) throws Exception {
String uri = "hdfs://namenode:8020/path/to/file.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);
fs.close();
}
}
}
上述代码段创建了一个与指定URI(统一资源标识符)中的文件连接,打开文件,并将内容复制到标准输出流中。
6.1.2 写入文件的示例代码
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.OutputStream;
import java.net.URI;
public class WriteFileExample {
public static void main(String[] args) throws Exception {
String uri = "hdfs://namenode:8020/path/to/output.txt";
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(URI.create(uri), conf);
OutputStream out = null;
try {
out = fs.create(new Path(uri));
out.write("Example text to write".getBytes("UTF-8"));
} finally {
IOUtils.closeStream(out);
fs.close();
}
}
}
该代码段示例创建了一个新文件(如果该文件不存在),然后将字符串数据写入该文件。
6.1.3 删除文件的示例代码
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public class DeleteFileExample {
public static void main(String[] args) throws Exception {
String uri = "hdfs://namenode:8020/path/to/file.txt";
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(URI.create(uri), conf);
boolean result = fs.delete(new Path(uri), true);
if (result) {
System.out.println("File deleted successfully.");
} else {
System.out.println("Failed to delete file.");
}
fs.close();
}
}
这段代码尝试删除指定的文件。参数
true
指示要删除文件,如果该文件是目录,则会递归地删除该目录下的所有文件和子目录。
6.2 Windows系统中使用 Hadoop 的特殊处理
在Windows系统中使用Hadoop可能需要一些特殊配置和处理方法,因为Hadoop最初是为Linux环境设计的。
6.2.1 Windows系统中使用 Hadoop 的常见问题
在Windows系统中运行Hadoop时,一个常见的问题是文件路径格式不兼容。在Windows中,路径使用反斜杠(
\
),而在Hadoop配置中通常使用正斜杠(
/
)。此外,Hadoop在Windows上的性能可能不如在Linux上,因为磁盘I/O操作的不同。
6.2.2 Windows系统中使用 Hadoop 的特殊处理方法
为了在Windows上运行Hadoop,需要安装适用于Windows的Hadoop版本,或者配置Hadoop使用Windows子系统Linux(WSL)。在安装和配置时,需要更新Hadoop配置文件(如
core-site.xml
),将文件系统的URI方案更改为
file://
,并将路径格式转换为Windows格式。
6.2.3 Windows系统中使用 Hadoop 的最佳实践
一个最佳实践是在WSL环境下安装和使用Hadoop,这可以提供更接近Linux的体验,减少与文件系统兼容性相关的问题。另一个实践是使用专门的Hadoop Windows工具,比如Hortonworks或Cloudera提供的版本,它们通常带有针对Windows环境的改进和兼容性调整。此外,可以通过适当的测试和调整确保Hadoop配置的最佳性能。
本文还有配套的精品资源,点击获取
简介:本指南详细介绍了在Windows环境下如何使用
hadoop-common-2.2.0-bin-master.zip
文件开发HDFS客户端,涵盖了从下载、解压、环境配置到客户端开发的全过程。特别指出,在Windows系统中使用Hadoop需要对环境变量进行配置,并且要对Hadoop的配置文件进行适当修改以适配本地环境。提供了HDFS客户端的开发步骤和实例代码,并概述了解决Windows特有的挑战。
本文还有配套的精品资源,点击获取
版权归原作者 柯里丁丁 所有, 如有侵权,请联系我们删除。