HDFS day2

                                                              

                                      HDFS Architecture

 

1.为什么说HDFS不擅长存储小文件?

      因为Namenode是使用单机存储元数据,因此导致namenode内存紧张

HDFS使用于高吞吐量,不适合低时间的延迟访问,如果同时存储大量的小文件会花费大量的时间

namenode 访问小文件,从一个datanode跳转到另外一个datanode,这样大大降低了读取性能。

2.NameNode和Secondary Namenode的关系?

fsimage - 它是在NameNode启动时对整个文件系统的快照
edit logs - 它是在NameNode启动后,对文件系统的改动序列,相当与日志

只有在NameNode重启时,edit logs才会合并到fsimage文件中,从而得到一个文件系统的最新快照。但是在产品集群中NameNode是很少重启的,这也意味着当NameNode运行了很长时间后,edit logs文件会变得很大

如果NameNode挂掉了,那我们就丢失了很多改动因为此时的fsimage文件非常旧,因此为了克服这个问题,我们需要一个易于管理的机制来帮助我们减小edit logs文件的大小和得到一个最新的fsimage文件,这样也会减小在NameNode上的压力。这跟Windows的恢复点是非常像的,Windows的恢复点机制允许我们对OS进行快照,这样当系统发生问题时,我们能够回滚到最新的一次恢复点上。

SecondaryNameNode就是来帮助解决上述问题的,辅助NameNode整理Edits和Fsimage文件,加速NameNode启动过程.

Secondary NameNode的整个目的是在HDFS中提供一个检查点。它只是NameNode的一个助手节点。这也是它在社区内被认为是检查点节点的原因。

3.HDFS Shell*

[root@CentOS ~]# hdfs dfs -appendToFile /root/install.log /aa.log #追加

[root@CentOS ~]# hadoop fs -cat /aa.log  #查看指定文件输出的内容

[root@CentOS ~]# hdfs dfs -checksum /aa.log
/aa.log    MD5-of-0MD5-of-512CRC32C    000002000000000000000000fa622ce196be3efd11475d6b55af76d2

[root@CentOS ~]# hadoop fs -chmod -R u+x /# 改变文件的权限
[root@CentOS ~]# hadoop fs -ls -R  / #查看文件
-rwxr--r--   1 root supergroup      17630 2019-01-03 09:05 /aa.log
-rwxr--r--   1 root supergroup  175262413 2019-01-02 20:29 /jdk-8u171-linux-x64.rpm

[root@CentOS ~]# hdfs dfs -copyFromLocal|-put install.log /  # 上传
[root@CentOS ~]# hdfs dfs -copyToLocal|-get /install.log ~/  # 下载

[root@CentOS ~]# hdfs dfs -mkdir -p /demo/dir #将文件从源路径复制到目标路径
[root@CentOS ~]# hdfs dfs -cp /install.log /demo/dir

[root@CentOS ~]# hdfs dfs -moveFromLocal ~/install.log  /
[root@CentOS ~]# ls
anaconda-ks.cfg  hadoop-2.6.0_x64.tar.gz  install.log.syslog
[root@CentOS ~]# hdfs dfs -moveToLocal /install.log  ~/ # 目前还没有实现
moveToLocal: Option '-moveToLocal' is not implemented yet.

[root@CentOS ~]# hdfs dfs -rm -r -f /install.log #删除

[root@CentOS ~]# hdfs dfs -text /cc.log #将文件尾部1k字节内容输出

[root@CentOS ~]# hdfs dfs -touchz /cc.log #创建空文件

更多参考:http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/FileSystemShell.html#appendToFile

开启 HDFS 的回收站

`etc/hadoop/core-site.xml`

<property>
        <name>fs.trash.interval</name>
        <value>1</value>
</property>
[root@CentOS ~]# hdfs dfs -rm -r -f /bb.log
19/01/03 12:27:08 INFO fs.TrashPolicyDefault: Namenode trash configuration: Deletion interval = 1 minutes, Emptier interval = 0 minutes.
Moved: 'hdfs://CentOS:9000/bb.log' to trash at: hdfs://CentOS:9000/user/root/.Trash/Current

[root@CentOS ~]# hdfs dfs -rm -r -f -skipTrash /aa.log
Deleted /aa.log

                               5.JAVA API 操作 HDFS

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-hdfs</artifactId>
    <version>2.6.0</version>
</dependency>

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-common</artifactId>
    <version>2.6.0</version>
</dependency>

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

Windows开发Hadoop应用环境配置

  • 解压hadoop安装包到C:/

  • winutils.exehadoop.dll拷贝到hadoop的bin目录下

  • 在windows配置HADOOP_HOME环境变量

  • 重启开发工具idea,否则开发工具无法识别HADOOP_HOME

  • 在Windows主机配置CentOS的主机名和IP的映射关系

C:\Windows\System32\drivers\etc\hosts

192.168.169.139 CentOS

core-site.xml和hdfs-site.xml放到resources下

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.util.Progressable;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import java.io.*;

public class TestHDFSDemo {
    private FileSystem fileSystem;
    private Configuration conf;
    @Before
    public void before() throws IOException {
        conf=new Configuration();
        conf.addResource("core-site.xml");
        conf.addResource("hdfs-site.xml");
        fileSystem=FileSystem.newInstance(conf);
    }

    @Test
    public void testConfig(){
        String value = conf.get("dfs.replication");
        System.out.println(value);
    }

    @Test
    public void testUpload01() throws IOException {
        String file="C:\\Users\\HIAPAD\\Desktop\\SpringBoot启动原理.pdf";
        Path dst=new Path("/demo/access/springBoot.pdf");
        InputStream is  = new FileInputStream(file);
        OutputStream os = fileSystem.create(dst, new Progressable() {
            public void progress() {
                System.out.print(".");
            }
        });
        IOUtils.copyBytes(is,os,1024,true);
    }
    @Test
    public void testUpload02() throws IOException {
        Path src=new Path("C:\\Users\\HIAPAD\\Desktop\\SpringBoot启动原理.pdf");
        Path dst=new Path("/springBoot1.pdf");
        fileSystem.copyFromLocalFile(src,dst);
    }

    @Test
    public void testDownload01() throws IOException {
        String file="C:\\Users\\HIAPAD\\Desktop\\SpringBoot启动原理1.pdf";
        Path dst=new Path("/springBoot.pdf");
        OutputStream os  = new FileOutputStream(file);
        InputStream is = fileSystem.open(dst);
        IOUtils.copyBytes(is,os,1024,true);
    }
    @Test
    public void testDownload02() throws IOException {
        Path dst=new Path("C:\\Users\\HIAPAD\\Desktop\\SpringBoot启动原理3.pdf");
        Path src=new Path("/springBoot1.pdf");
        //fileSystem.copyToLocalFile(src,dst);
        fileSystem.copyToLocalFile(false,src,dst,true);
    }
    @Test
    public void testDelete() throws IOException {
        Path src=new Path("/user");

        fileSystem.delete(src,true);//true 表示递归删除子文件夹
    }

    @Test
    public void testExists() throws IOException {
        Path src=new Path("/springBoot1.pdf");
        boolean exists = fileSystem.exists(src);
        assertTrue(exists);
    }
    @Test
    public void testMkdir() throws IOException {
        Path src=new Path("/demo/access");
        boolean exists = fileSystem.exists(src);
        if(!exists){
            fileSystem.mkdirs(src);
        }
    }
    @Test
    public void testListFiles() throws IOException {
        Path src=new Path("/");
        RemoteIterator<LocatedFileStatus> files = fileSystem.listFiles(src, true);

        while (files.hasNext()){
            LocatedFileStatus file = files.next();
            System.out.println(file.getPath()+" "+file.isFile()+" "+file.getLen());
            BlockLocation[] locations = file.getBlockLocations();
            for (BlockLocation location : locations) {
                System.out.println("offset:"+location.getOffset()+",length:"+location.getLength());
            }
        }

    }
    @Test
    public void testDeleteWithTrash() throws IOException {
        Trash trash=new Trash(fileSystem,conf);
        Path dst=new Path("/springBoot1.pdf");
        trash.moveToTrash(dst);
    }
    @After
    public void after() throws IOException {
        fileSystem.close();
    }

}

HDFS权限不足导致写失败?

org.apache.hadoop.security.AccessControlException: Permission denied: user=HIAPAD, access=WRITE, inode="/":root:supergroup:drwxr-xr-x
	at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.checkFsPermission(FSPermissionChecker.java:271)
	at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.check(FSPermissionChecker.java:257)

解决方案

方案1

etc/hadoop/hdfs-site.xml

<property>
        <name>dfs.permissions.enabled</name>
        <value>false</value>
</property>

关闭HDFS文件权限检查,修改完成后,重启HDFS服务

-DHADOOP_USER_NAME=root   就是设置JAVA虚拟机启动参数java XXX -Dxx=xxx

猜你喜欢

转载自blog.csdn.net/weixin_43989957/article/details/85713683