官方文档:
https://hadoop.apache.org/docs/r2.10.0/hadoop-project-dist/hadoop-common/ClusterSetup.html
一些软件的官网提供了 source 和 binary 两个版本
source
是源码,需要手动编译成可执行文件
binary
是可执行版,是已经编译好的
以hadoop2.7来说,官网的可执行版不支持snappy和bzip2两种压缩算法,且没有提供带C程序访问的接口。所以这里对source
版本重新编译。
编译所需准备:
版本:Hadoop 2.7.5
Linux环境
jdk1.7
maven3.x
findbugs
依赖包
protobuf
snappy
可以通过以下命令检查本地库
# 检查本地库
bin/hadoop checknative
通过ssh
命令生成公私密钥对,公钥加密,私钥解密,实现免密登录。
# 解压安装包
tar -zxvf hadoop-2.7.5.tar.gz -C /export/soft
# 创建软连接,方便使用
ln -s hadoop-2.7.5 hadoop
配置文件位于hadoop/etc/hadoop
中。
方便起见,可以通过editplus、notepad++或者其他Windows宿主机的软件,通过ftp的方式远程修改这些配置文件。
注意,utf-8编码。
<configuration>
<!-- 指定集群的文件系统类型:分布式文件系统 -->
<property>
<name>fs.default.name</name>
<value>hdfs://node01:8020</value>
</property>
<!-- 指定临时文件存储目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/export/soft/hadoop-2.7.5/hadoopDatas/tempDatas</value>
</property>
<!-- 缓冲区大小,实际工作中根据服务器性能动态调整 -->
<property>
<name>io.file.buffer.size</name>
<value>4096</value>
</property>
<!-- 开启hdfs的垃圾桶机制,删除掉的数据可以从垃圾桶中回收,单位分钟 -->
<property>
<name>fs.trash.interval</name>
<value>10080</value>
</property>
</configuration>
<configuration>
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>node01:50090</value>
</property>
<!-- 指定namenode的访问地址和端口 -->
<property>
<name>dfs.namenode.http-address</name>
<value>node01:50070</value>
</property>
<!-- 指定namenode元数据的存放位置 -->
<property>
<name>dfs.namenode.name.dir</name>
<value>file:///export/soft/hadoop-2.7.5/hadoopDatas/namenodeDatas,file:///export/soft/hadoop-2.7.5/hadoopDatas/namenodeDatas2</value>
</property>
<!-- 定义dataNode数据存储的节点位置,实际工作中,一般先确定磁盘的挂载目录,然后多个目录用,进行分割 -->
<property>
<name>dfs.datanode.data.dir</name>
<value>file:///export/soft/hadoop-2.7.5/hadoopDatas/datanodeDatas,file:///export/soft/hadoop-2.7.5/hadoopDatas/datanodeDatas2</value>
</property>
<!-- 指定namenode日志文件的存放目录 -->
<property>
<name>dfs.namenode.edits.dir</name>
<value>file:///export/soft/hadoop-2.7.5/hadoopDatas/nn/edits</value>
</property>
<property>
<name>dfs.namenode.checkpoint.dir</name>
<value>file:///export/soft/hadoop-2.7.5/hadoopDatas/snn/name</value>
</property>
<property>
<name>dfs.namenode.checkpoint.edits.dir</name>
<value>file:///export/soft/hadoop-2.7.5/hadoopDatas/dfs/snn/edits</value>
</property>
<!-- 文件切片的副本个数-->
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<!-- 设置HDFS的文件权限-->
<property>
<name>dfs.permissions</name>
<value>false</value>
</property>
<!-- 设置一个文件切片的大小:128M-->
<property>
<name>dfs.blocksize</name>
<value>134217728</value>
</property>
</configuration>
hadoop2.7.5版本是第25行
export JAVA_HOME=/export/soft/jdk
这一文件目录中没有,有一个mapred-site.xml.template
,将它复制改名即可
<configuration>
<!-- 开启MapReduce小任务模式 -->
<property>
<name>mapreduce.job.ubertask.enable</name>
<value>true</value>
</property>
<!-- 设置历史任务的主机和端口 -->
<property>
<name>mapreduce.jobhistory.address</name>
<value>node01:10020</value>
</property>
<!-- 设置网页访问历史任务的主机和端口 -->
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>node01:19888</value>
</property>
</configuration>
<configuration>
<!-- 配置yarn主节点的位置 -->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>node01</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 开启日志聚合功能 -->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<!-- 设置聚合日志在hdfs上的保存时间 -->
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>604800</value>
</property>
<!-- 设置yarn集群的内存分配方案 -->
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>20480</value>
</property>
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>2048</value>
</property>
<property>
<name>yarn.nodemanager.vmem-pmem-ratio</name>
<value>2.1</value>
</property>
</configuration>
hadoop2.7.5版本是第16行
export JAVA_HOME=/export/soft/jdk
2.2.7 slaves
这个文件是节点的名单
官方的英文说明是:
List all slave hostnames or IP addresses in your etc/hadoop/slaves
file, one per line. Helper scripts (described below) will use the
etc/hadoop/slaves file to run commands on many hosts at once. It is
not used for any of the Java-based Hadoop configuration. In order to
use this functionality, ssh trusts (via either passphraseless ssh or
some other means, such as Kerberos) must be established for the
accounts used to run Hadoop.
翻译一下:
列出etc/hadoop/slaves文件中的所有从属主机名或IP地址,每行一个。Helper脚本(如下所述)将使用etc/hadoop/slaves文件一次在许多主机上运行命令。它不用于任何基于Java的Hadoop配置。为了使用此功能,必须为用于运行Hadoop的帐户建立ssh信任(通过无密码ssh或其他一些方法,如Kerberos)。
由于已经在三台机器上设置了免密登录,且在/etc/hosts
文件中设置了主机与ip地址之间的映射关系。
所以,slaves
文件如下:
node01
node02
node03
需要创建以下目录:
mkdir -p /export/soft/hadoop-2.7.5/hadoopDatas/tempDatas
mkdir -p /export/soft/hadoop-2.7.5/hadoopDatas/namenodeDatas
mkdir -p /export/soft/hadoop-2.7.5/hadoopDatas/namenodeDatas2
mkdir -p /export/soft/hadoop-2.7.5/hadoopDatas/datanodeDatas
mkdir -p /export/soft/hadoop-2.7.5/hadoopDatas/datanodeDatas2
mkdir -p /export/soft/hadoop-2.7.5/hadoopDatas/nn/edits
mkdir -p /export/soft/hadoop-2.7.5/hadoopDatas/snn/name
mkdir -p /export/soft/hadoop-2.7.5/hadoopDatas/dfs/snn/edits
注:这些目录都是前面配置文件时声明的,这里需要手动创建
在第一台机器上做好以上操作后,就可以把整个hadoop文件分发到另外两台机器上了。
cd /export/soft/
scp -r hadoop-2.7.5 node02:$PWD
scp -r hadoop-2.7.5 node03:$PWD
配置环境变量的操作需要在所有的节点上都执行这样的操作
1.路径是:
vim /etc/profile
2.加上前面配置的命令行显示绝对路径、jdk环境变量等,该文件配置了以下内容:
# Command prompt shows absolute path
export PS1='[\u@\h `pwd`]\$'
# jdk
export JAVA_HOME=/export/soft/jdk
export PATH=$PATH:$JAVA_HOME/bin
# mysql
export MySQL_HOME=/export/soft/mysql
export PATH=$PATH:$MySQL_HOME/bin
# hadoop
export HADOOP_HOME=/export/soft/hadoop
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
3.通过source
命令使修改后的环境变量生效:
source /etc/profile
4.接着,可以验证hadoop是否成功:
hadoop version
# 或
hdfs version
首次启动 HDFS 时,必须对其进行格式化操作。 本质上是一些清理和准备工作,因为此时的 HDFS 在物理上还是不存在的。
1.进入路径:
cd /export/soft/hadoop-2.7.5/
2.格式化操作:
bin/hdfs namenode -format
3.分别启动hdfs
和yarn
两个模块:
# 启动hdfs
sbin/start-dfs.sh
# 启动yarn
sbin/start-yarn.sh
# 启动历史记录
sbin/mr-jobhistory-daemon.sh start historyserver
HDFS(Hadoop Distributed File System):分布式文件系统
适合的应用场景:
主/从(Mater/Slave)体系
结构。文件副本机制
所有的文件都是以 block 块的方式存放在 HDFS 文件系统当中,作用如下:
hdfs-site.xml
当中的配置文件进行指定:<property>
<name>dfs.block.size</name>
<value>块大小 以字节为单位</value>
</property>
机架感知
HDFS分布式文件系统的内部有一个副本存放策略:以默认的副本数=3为例:
格式:hdfs dfs -ls URI
作用:类似于Linux的ls命令,显示文件列表
hdfs dfs -ls /
格式 : hdfs dfs -lsr URI
作用 : 在整个目录下递归执行ls, 与UNIX中的ls-R类似
hdfs dfs -lsr /
格式 :hdfs dfs [-p] -mkdir <paths>
作用 : 以<paths>中的URI作为参数,创建目录。使用-p参数可以递归创建目录
格式 :hdfs dfs -put <localsrc> ... <dst>
作用 :将单个的源文件src或者多个源文件srcs从本地文件系统拷贝到目标文件系统中(<dst>对应的路径)。也可以从标准输入中读取输入,写入目标文件系统中
hdfs dfs -put /root/a.txt /dir1
格式:hdfs dfs -moveFromLocal <localsrc> <dst>
作用: 和put命令类似,但是源文件localsrc拷贝之后自身被删除
格式:hdfs dfs -get [-ignorecrc] [-crc] <src> <localdst>
作用:将文件拷贝到本地文件系统。CRC校验失败的文件通过-ignorecrc选项拷贝。文件和CRC校验和可以通过-CRC选项拷贝。
hdfs dfs -mv /dir1/a.txt /dir2
格式:hdfs dfs -mv URI <dest>
作用:将hdfs上的文件从原路径移动到目标路径(移动之后文件删除),该命令不能跨文件系统
hdfs dfs -mv /dir1/a.txt /dir2
格式:hdfs dfs -rm [-r] [-skipTrash] URI [URI 。。。]
作用:删除参数指定的文件,参数可以有多个。此命令只删除文件和非空目录。
如果指定-skipTrash选项,那么在回收站可用的情况下,该选项将跳过回收站而直接删除文件;
否则,在回收站可用时,在HDFS Shell 中执行此命令,会将文件暂时放到回收站中。
hdfs dfs -rm -r /dir1
格式:hdfs dfs -cp URI [URI ...] <dest>
作用:将文件拷贝到目标路径中。如果<dest>为目录的话,可以将多个文件拷贝到该目录下。
-f
选项将覆盖目标,如果它已经存在。
-p
选项将保留文件属性(时间戳、所有权、许可、ACL、XAttr)。
hdfs dfs -cp /dir1/a.txt /dir2/b.txt
格式:hdfs dfs -cat URI [uri ...]
作用:将参数所指示的文件内容输出到stdout
hdfs dfs -cat /install.log
格式:hdfs dfs -chmod [-R] URI[URI ...]
作用:改变文件权限。如果使用-R选项,则对整个目录有效递归执行。使用这一命令的用户必须是文件的所属用户,或者超级用户。
hdfs dfs -chmod -R 777 /install.log
格式:hdfs dfs -chmod [-R] URI[URI ...]
作用:改变文件的所属用户和用户组。如果使用 -R选项,则对整个目录有效递归执行。用这一命令的用户必须是文件的所属用户,或者超级用户。
hdfs dfs -chown -R hadoop:hadoop /install.log
格式:hdfs dfs -appendToFile <localsrc> ... <dst>
作用:追加一个或者多个文件到hdfs指定文件中。也可以从命令行读取输入。
hdfs dfs -appendToFile a.xml b.xml /big.xml
在多人共用HDFS的环境下,配置设置非常重要。特别是在Hadoop处理大量资料的环境,如果没有配额管理,很容易把所有的空间用完造成别人无法存取。Hdfs的配额设定是针对目录而不是针对账号,可以 让每个账号仅操作某一个目录,然后对目录设置配置。
hdfs文件的限额配置允许我们以文件个数,或者文件大小来限制我们在某个目录下上传的文件数量或者文件内容总量,以便达到我们类似百度网盘网盘等限制每个用户允许上传的最大的文件的量。
首先可以查看配额信息:
hdfs dfs -count -q -h /user/root/dir1
-q
表示显示配额信息
-h
以人类可读的格式显示大小
# 首先,创建hdfs文件夹
hdfs dfs -mkdir -p /user/root/dir
# 给该文件夹下面设置最多上传两个文件,只能上传一个文件,因为它把文件夹本身算做了一个文件
hdfs dfsadmin -setQuota 2 dir
# 清除文件数量限制
hdfs dfsadmin -clrQuota /user/root/dir
# 限制空间大小384M
hdfs dfsadmin -setSpaceQuota 384m /user/root/dir
# 生成任意大小文件的命令
# 生成2M的文件
dd if=/dev/zero of=1.txt bs=1M count=2
# 清除空间配额限制
hdfs dfsadmin -clrSpaceQuota /user/root/dir
安全模式是hadoop的一种保护机制,用于保证集群中的数据块的安全性。当集群启动的时候,会首先进入安全模式。当系统处于安全模式时会检查数据块的完整性。
假设我们设置的副本数(即参数dfs.replication)是3
,那么在datanode上就应该有3个副本存在,假设只存在2个副本,那么比例就是2/3=0.666。hdfs默认的副本率0.999
。我们的副本率0.666明显小于0.999,因此系统会自动的复制副本到其他dataNode,使得副本率不小于0.999。如果系统中有5个副本,超过我们设定的3个副本,那么系统也会删除多于的2个副本。
在安全模式状态下,文件系统只接受读数据请求,而不接受删除、修改等变更请求。当整个系统达到安全标准时,HDFS自动离开安全模式。
安全模式操作命令:
# 查看安全模式状态
hdfs dfsadmin -safemode get
# 进入安全模式
hdfs dfsadmin -safemode enter
# 离开安全模式
hdfs dfsadmin -safemode leave
实际生产环境当中,hadoop的环境搭建完成之后,第一件事情就是进行压力测试,测试我们的集群的读取和写入速度,测试我们的网络带宽是否足够等一些基准测试。
# 向HDFS文件系统中写入数据,10个文件,每个文件10MB,文件存放到/benchmarks/TestDFSIO中
hadoop jar /export/soft/hadoop-2.7.5/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.7.5.jar TestDFSIO -write -nrFiles 10 -fileSize 10MB
查看写入速度结果
hdfs dfs -text /benchmarks/TestDFSIO/io_write/part-00000
-text
获取源文件并以文本格式输出该文件
也可以通过vim
的方式查看生成的log文件,该文件会生成在当前目录下
# 在HDFS文件系统中读入10个文件,每个文件10M
hadoop jar /export/soft/hadoop-2.7.5/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.7.5.jar TestDFSIO -read -nrFiles 10 -fileSize 10MB
查看读取速度结果
hdfs dfs -text /benchmarks/TestDFSIO/io_read/part-00000
hadoop jar /export/soft/hadoop-2.7.5/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-2.7.5.jar TestDFSIO -clean
在 Hadoop 的集群中,NameNode的所有元数据信息都保存在了 FsImage 与 Edits 文件中。
这两个文件就记录了所有的数据的元数据信息,元数据信息的保存目录配置在了hdfs-site.xml
中。
<property>
<name>dfs.namenode.name.dir</name>
<value>file:///export/soft/hadoop-2.7.5/hadoopDatas/namenodeDatas,file:///export/soft/hadoop-2.7.5/hadoopDatas/namenodeDatas2</value>
</property>
<property>
<name>dfs.namenode.edits.dir</name>
<value>file:///export/soft/hadoop-2.7.5/hadoopDatas/nn/edits</value>
</property>
fsimage
存放了一份比较完整的元数据信息。首先要进入目录
cd /export/soft/hadoop2.7.5/hadoopDatas/namenodeDatas
再通过oiv进行查看
hdfs oiv -i fsimage_0000000000000000864 -p XML -o hello.xml
注,如果不知道具体命令,可以查看系统中的帮助:
hdfs oiv
同样,首先要进入目录
再通过oev查看
hdfs oev -i edits_0000000000000000865-0000000000000000866 -p XML -o myedit.xml
SecondaryNameNode 定期合并 fsimage 和 edits,把 edits 控制在一个范围内。
配置 SecondaryNameNode
{
SecondaryNameNode运行在另外一台机器上:
conf/masters
中指定hdfs-site.xml
:<property>
<name>dfs.http.address</name>
<value>host:50070</value>
</property>
}
<!-- 多久记录一次 HDFS 镜像, 默认1小时 -->
<property>
<name>fs.checkpoint.period</name>
<value>3600</value>
</property>
<!-- 一次记录多大, 默认64M -->
<property>
<name>fs.checkpoint.size</name>
<value>67108864</value>
</property>
过程:
edits.new
。以Hadoop2.7.5为例,主要是Hadoop的bin目录,除此之外,还要添加一些文件,winutils等等:
这些文件是在Windows下编译得到的
参考地址:https://github.com/cdarlint/winutils
将hadoop2.7.5文件夹拷贝到一个没有中文没有空格的路径
配置环境变量
把hadoop2.7.5文件夹中bin目录下的hadoop.dll文件放到系统盘:C:\Windows\System32
目录
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>2.7.5</version>
</dependency>
<!--日志-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>2.0.0-alpha1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<!-- <verbal>true</verbal>-->
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
注:
为了不显示日志的警告,可以在resources
中加入log4j.properties
文件:
# Configure logging for testing: optionally with log file
#log4j.rootLogger=debug,appender
log4j.rootLogger=info,appender
#log4j.rootLogger=error,appender
#\u8F93\u51FA\u5230\u63A7\u5236\u53F0
log4j.appender.appender=org.apache.log4j.ConsoleAppender
#\u6837\u5F0F\u4E3ATTCCLayout
log4j.appender.appender.layout=org.apache.log4j.TTCCLayout
@Test
public void urlHdfs() throws IOException {
//1.注册url
URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
//2.获取hdfs文件输入流
InputStream inputStream = new URL("hdfs://node01:8020/a.txt").openStream();
//3.获取本地文件输出流
FileOutputStream fileOutputStream = new FileOutputStream(new File("D:/java2/hello.txt"));
//4.文件拷贝
IOUtils.copy(inputStream, fileOutputStream);
//5.关闭
IOUtils.closeQuietly(inputStream);
IOUtils.closeQuietly(fileOutputStream);
}
set
方法设置文件系统类型FileSystem
的静态方法get
获得该对象
@Test
public void getFileSystem1() throws IOException {
//1.创建Configuration对象
Configuration configuration = new Configuration();
//2.设置文件系统类型
configuration.set("fs.defaultFS", "hdfs://node01:8020");
//3.获取指定的文件系统
FileSystem fileSystem = FileSystem.get(configuration);
//4.输出
System.out.println(fileSystem);
}
@Test
public void getFileSystem2() throws IOException, URISyntaxException {
FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:8020"), new Configuration());
System.out.println(fileSystem);
}
@Test
public void getFileSystem3() throws IOException {
//1.创建Configuration对象
Configuration configuration = new Configuration();
//2.设置文件系统类型
configuration.set("fs.defaultFS", "hdfs://node01:8020");
//3.获取指定的文件系统
FileSystem fileSystem = FileSystem.newInstance(configuration);
//4.输出
System.out.println(fileSystem);
}
@Test
public void getFileSystem4() throws IOException, URISyntaxException {
FileSystem fileSystem = FileSystem.newInstance(new URI("hdfs://node01:8020"), new Configuration());
System.out.println(fileSystem);
}
@Test
public void listFiles() throws URISyntaxException, IOException {
//1.获取FileSystem实例
FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:8020"), new Configuration());
//2.调用listFiles获取/目录下所有的文件信息
RemoteIterator<LocatedFileStatus> iterator = fileSystem.listFiles(new Path("/"), true);
//3.遍历迭代器
while (iterator.hasNext()) {
LocatedFileStatus fileStatus = iterator.next();
//获取文件的绝对路径 hdfs://node01:8020/xxx
System.out.println(fileStatus.getPath() + "----" + fileStatus.getPath().getName());
//获取文件的block信息
BlockLocation[] blockLocations = fileStatus.getBlockLocations();
System.out.println("block数:" + blockLocations.length);
}
}
可以创建文件夹、文件
创建文件时,如果目录不存在,则会创建目录
@Test
public void mkdirsTest() throws IOException, URISyntaxException {
//1.
FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:8020"), new Configuration());
//2.创建文件夹
/*boolean bl = fileSystem.mkdirs(new Path("/aaa/bbb/ccc"));
System.out.println(bl);*/
fileSystem.create(new Path("/aaa/bbb/ccc/a.txt"));
//3.关闭fs
fileSystem.close();
}
@Test
public void getFileToLocal() throws URISyntaxException, IOException {
//1.
FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:8020"), new Configuration());
//2.获取hfds输入流
FSDataInputStream fsDataInputStream = fileSystem.open(new Path("/a.txt"));
//3.获取本地路径的输入流
FileOutputStream fileOutputStream = new FileOutputStream("D:/java2/a.txt");
//4.文件的拷贝
IOUtils.copy(fsDataInputStream, fileOutputStream);
//5.关闭流
IOUtils.closeQuietly(fsDataInputStream);
IOUtils.closeQuietly(fileOutputStream);
}
@Test
public void getFileToLocal2() throws IOException, URISyntaxException {
//1.
FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:8020"), new Configuration());
//2.调用方法,实现文件下载
fileSystem.copyToLocalFile(new Path("/a.txt"), new Path("D:/java2/a.txt"));
//3.关闭fs
fileSystem.close();
}
@Test
public void putFileFromLocal() throws URISyntaxException, IOException {
//1.
FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:8020"), new Configuration());
//2.调用方法,实现文件上传
fileSystem.copyFromLocalFile(new Path("D:/java2/123.txt"), new Path("/"));
//3.关闭fs
fileSystem.close();
}
hdfs访问权限控制由hdfs-site.xml
和chmod
设置的权限决定
hdfs-site.xml:
如果“真”,则在HDFS中启用权限检查。如果“false”,则关闭权限检查,但所有其他行为不变。从一个参数值切换到另一个参数值不会更改模式、所有者或文件或目录组。
<property>
<name>dfs.permissions.enabled</name>
<value>true</value>
</property>
伪装用户
get
或newInstance
的三参数的方法,第三个参数是String user
,这个user
可以是任意的
@Test
public void getFileToLocal3() throws IOException, URISyntaxException, InterruptedException {
//1.
FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:8020"), new Configuration(), "root");
//2.调用方法,实现文件下载
fileSystem.copyToLocalFile(new Path("/a.txt"), new Path("D:/java2/a.txt"));
//3.关闭fs
fileSystem.close();
}
# 将很多的 hdfs 文件合并成一个大文件下载到本地
hdfs dfs -getmerge /config/*.xml ./hello.xml
上传时将小文件合并为一个大文件:
@Test
public void mergeFiles() throws URISyntaxException, IOException, InterruptedException {
//1.(伪造了一个root用户)
FileSystem fileSystem = FileSystem.get(new URI("hdfs://node01:8020"), new Configuration(), "root");
//2.获取hdfs大文件的输出流
FSDataOutputStream fsDataOutputStream = fileSystem.create(new Path("/bigText.txt"));
//3.获取一个本地文件系统
LocalFileSystem localFileSystem = FileSystem.getLocal(new Configuration());
//4.获取本地文件夹下所有文件的详情
FileStatus[] fileStatuses = localFileSystem.listStatus(new Path("D:/java2/d0"));
//5.遍历每个文件,获取每个文件的输入流
for (FileStatus fileStatus : fileStatuses) {
FSDataInputStream fsDataInputStream = localFileSystem.open(fileStatus.getPath());
//6.将小文件的数据复制到大文件
IOUtils.copy(fsDataInputStream, fsDataOutputStream);
IOUtils.closeQuietly(fsDataInputStream);
}
//7.关闭流
IOUtils.closeQuietly(fsDataOutputStream);
localFileSystem.close();
fileSystem.close();
}
在典型的HA集群中,两台独立的机器被配置为NameNode。在工作集群中,NameNode机器中的一个处于Active状态,另一个处于Standby状态。Active NameNode负责群集中的所有客户端操作,而Standby充当从服务器。Standby机器保持足够的状态以提供快速故障切换(如果需要)。