由于HDFS会在NameNode中存储元数据,而元数据是存在于内存中,所以HDFS是不适合用来存储小文件的。针对存在的问题,在HDFS可以进行小文件合并的操作

1、小文件合并

1.1、命令行操作

  • appendToFile命令,将本地文件上传到HDFS
hadoop fs -appendToFile 需要合并的文件(本地) HDFS文件系统路径
# 举例:将本地/root/a.txt,/root/b.txt,/root/c.txt合并并上传到/hello.txt
hadoop fs /root/a.txt /root/b.txt /root/c.txt /hello.txt

1.2、JavaAPI操作

利用JavaAPI操作,也可以将文件进行合并,示例代码如下

该操作将本地的D盘file文件夹中的文件进行合并并上传到HDFS成为hello.txt

public void appendToFile () {
	FileSystem fileSystem = FileSystem.get(new URI("hdfs://hd01:8020"), new Configuration(),"root");
	FSDataOutputStream outputStream = fileSystem.create(new Path("/hello.txt"));
	File file = new File("D:\\file");
	for (File file1 : files) {
		FileInputStream inputStream = new FileInputStream(file1);
		IOUtils.copy(inputStream,outputStream);
		inputStream.close();
	}
	outputStream.close();
}

1.3、Archive

上面两个点是从上传之前做一个合并,针对已经在hdfs中存在的文件,可以用Archive档案进行操作。
要注意的是:
1、Archive本质是一个MR任务,需要启动Yarn,生成archive后,文件拓展名是.har
2、创建Archive时,原来文件不会被更改或删除
3、Archive不支持压缩,只是看起来被压缩过了

  • 创建命令
Usage: hadoop archive -archiveName name -p <parent> <src>* <dest>
# 说明:-archiveName是指要创建的存档的名称,-p参数指定文件存档文件(src)的路径
# 示例:对一个在/test 目录下的所有文件进行存档,存到/test_archive,取名为test.har(.har为固定写法)
hadoop archive -archiveName -test.har -p /test /test_archive
# 此时会在hdfs文件系统下的/test_archive文件夹下生成test.har文件
  • 查看Archive
# 列出har文件下的文件列表
hadoop fs -ls /test_archive/test.har
# 查看合并后的文件内容
hadoop fs -cat /test_archive/test.har/part-0
# 推荐用以下命令查看
hadoop fs -ls har://hdfs-node1:8020/test_archive/test.har
  • 解压Archive
# 比如将刚刚的archive解压到unzip文件夹中
hadoop fs -cp har:///test_archive/test.har/* /unzip

2、hdfs高可用(HA)方案

Hadoop 拆分与合并 hadoop 合并文件命令_大数据

NameNode单节点的hdfs架构存在一些问题:当NameNode宕机了,会导致hdfs一整个挂掉,针对这个问题,我们可以利用zookeeper来辅助hdfs,达到hdfs高可用的目的。图中,是HDFS官方推荐的HDFS-HA方案之一,即QJM(Quorum Journal Manager)方案。使用zookeeper中ZKFC来实现主备切换;使用Journal Node(JN)集群实现edits log的共享以达到数据同步的目的。

  • zookeeper在HA方案中,有以下特性:
1、临时znode:生命周期与客户端session绑定
2、路径唯一
3、watch机制,监听znode发生的事件,返回给监听的客户端
  • FailoverController,即Zookeeper FailoverController(简称zkfc),有以下职责:
1、监听和管理NameNode
2、维持和zk的联系,如NN宕机,zk会通过选举机制选出新的NN并使其处于active状态(故障转移)

2.1、Fencing隔离

故障转移过程也就是主备切换的过程,切换过程中最怕的就是脑裂的发送。因此需要Fencing机制来避免,将先前的Active节点隔离,然后将本地NameNode转换为Active状态。

Hadoop公共库中对外提供了两种fenching实现,分别是sshfence和shellfence(缺省实现),其中sshfence是指通过ssh登陆目标节点上,使用命令fuser将进程杀死(通过tcp端口号定位进程pid,该方法比jps命令更准确),shellfence是指执行一个用户事先定义的shell命令(脚本)完成隔离。

2.2、Journal Node

在NameNode单节点的过程中,我们是通过SecondaryNameNode进行元数据辅助管理,但是在HA的情况下,我们可以借助Journal Node来替代SecondaryNameNode角色进行高速读写数据、存储数据。JN也遵循过半机制,即推荐部署的机器为奇数台。

在图中,JN的职责是:共享NN的状态,具体可以表现为:

当Active NN发生变化时,JN会记录对应的edits log,此时Standby NN会检测到JN中的数据变化,同步记录。
当Active NN挂掉时,Standby NN在成为Active NN之前会读取JN中所有的修改日志后进行同步,从而达到高可用的目的。