hadoop基础(二)

JAVA客户端

环境搭建

创建Maven项目,添加Hadoop依赖.

<dependencies>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!-- 添加hadoop的依赖  -->
        <!--添加hdfs的客户端依赖-->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-core</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-common</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-mapreduce-client-jobclient</artifactId>
            <version>3.1.1</version>
        </dependency>
    </dependencies>

FileSystem使用

核心类 org.apache.hadoop.fs.FileSystem 文件系统类 抽象类

//静态方法创建对象
public static FileSystem newInstance(URI uri,Configuration conf,String user)
/*
     	  参数一  URI  分布式文件系统 HDFS的资源地址 NN地址 hdfs://linux01:8020
          参数二  Configuration  用户自定义参数设置   副本数 3   物理切块的大小 128M
          		 
          参数三  user  客户端用户名      
 */                        
/*
      org.apache.hadoop.fs.FileSystem  文件系统类  抽象类
         静态方法获取对象(子类对象)
              public static FileSystem newInstance(URI uri,Configuration conf,String user)
                    URI uri: 统一资源标识符   协议://
                                url统一资源定位符   www.baidu.com
                                只要是网络相关的 都是uri包括url
                                迅雷下载 百度网盘 邮件发送 mailto:  jdbc连接
                             分布式文件系统 HDFS的资源地址 NN地址
                             hdfs://linux01:8020
                             构造方法
                                  public URI uri
                   Configuration conf:用户自定义参数设置   副本数 3   物理切块的大小 128M
                                      如果不设置 使用默认设置
                   String user: 用户名  root
 */
public class Demo01_FileSystem {
    public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException {
        //文件系统的客户端连接对象
        URI  uri = new URI("hdfs://linux01:8020");
        //配置对象 没有进行配置 使用默认配置
        Configuration  con = new Configuration();
        //用户名
        String user = "root";
        //通过静态方法 获取 分布式文件系统对象
        FileSystem fs = FileSystem.newInstance(uri, con, user);
        System.out.println(fs);
    }
}

常用方法

public void copyFromLocalFile(Path src, Path dst)  将本地文件上传到文件系统
public void copyFromLocalFile(boolean delSrc, Path src, Path dst)
public void copyToLocalFile(Path src, Path dst)    将文件系统上的文件下载到本地
public void copyToLocalFile(boolean delSrc, Path src, Path dst)
public FileStatus[] listStatus(Path f) 列出目录下所有的内容 包括文件  文件夹
public RemoteIterator<LocatedFileStatus> listFiles(Path f, boolean recursive)列出目录下所有的文件
public FSDataOutputStream create(Path f, boolean overwrite)  获取字节输出流 向文件中写数据
public FSDataOutputStream append(Path path) 向指定的文件路径中追加写入数据
public FSDataInputStream open(Path f) 获取字节输入流 读取文件中数据

获取文件系统对象工具类

public class HDFSUtils {
    private HDFSUtils(){}

    public static FileSystem  getFileSystem() throws  Exception {
        //文件系统的客户端连接对象
        URI uri = new URI("hdfs://linux01:8020");
        //配置对象 没有进行配置 使用默认配置
        Configuration con = new Configuration();
        //用户名
        String user = "root";
        //通过静态方法 获取 分布式文件系统对象
        FileSystem fs = FileSystem.newInstance(uri, con, user);
        return fs;
    }
}

上传文件

/*
     public void copyFromLocalFile(Path src, Path dst)  将本地文件上传到文件系统
     public void copyFromLocalFile(boolean delSrc, Path src, Path dst)
            boolean delSrc:是否删除源文件  true删除 false则不删除
            Path src:数据源  本地系统上的文件
            Path dst:数据目的 文件系统

     1.创建FileSystem对象
     2.调用方法上传文件到分布式文件系统
     3.关闭资源
 */
public class Demo02_FileSystem {
    public static void main(String[] args) throws Exception {
        //通过工具类获取对象
        FileSystem fileSystem = HDFSUtils.getFileSystem();

        /*
            public void copyFromLocalFile(Path src, Path dst)  将本地文件上传到文件系统
            数据源:本地文件  d:\\mm.jpg
            数据目的:分布式文件系统  /
         */
      //上传并改名
        Path  src = new Path("d:\\mm.jpg");
        Path  dest = new Path("/java/meimei.jpg");

        fileSystem.copyFromLocalFile(true,src,dest);

        fileSystem.close();    
    }
}

下载文件

/*
    将文件系统上的文件下载到本地
    public void copyToLocalFile(Path src, Path dst)
    public void copyToLocalFile(boolean delSrc, Path src, Path dst)

                boolean delSrc: 是否删除数据源  true删除 false不删除
                Path src:数据源 文件系统
                Path dst:数据目的 本地

    注意:由于win和HDFS分布式兼容不好 需要安装Hadoop环境 不安装不能下载文件
        解压 hadoop3.1.1 配置环境变量HADOOP_HOME 加入Path
        需要重启idea  可能需要重启电脑
 */
public class Demo03_FileSystem {
    public static void main(String[] args) throws Exception {
        //通过工具类获取对象
        FileSystem fs = HDFSUtils.getFileSystem();


//        Path  src = new Path("/mm.jpg");
//        Path  dest = new Path("d:\\");
        //将文件系统中的文件 下载到本地  自动生成.crc的检验文件
//        fs.copyToLocalFile(src,dest);

        Path  src = new Path("/mm.jpg");
        Path  dest = new Path("d:\\meimei.jpg");
        下载并改名
      //  fs.copyToLocalFile(src,dest);

        /*
            public void copyToLocalFile(boolean delSrc, Path src, Path dst, boolean useRawLocalFileSystem)
            参数1:是否删除源文件
            参数2:数据源
            参数3:数据目的
            参数4:是否使用本地文件系统 true则不生成.crc文件
         */
        fs.copyToLocalFile(false,src,dest,true);
        fs.close();
    }
}

遍历文件

/*
    public FileStatus[] listStatus(Path f) 列出指定目录下所有的内容 包括文件  文件夹
 */
public class Demo04_FileSystem {
    public static void main(String[] args) throws Exception {
        //获取对象
        FileSystem fs = HDFSUtils.getFileSystem();
        //获取根目录下所有内容 文件 文件夹
        FileStatus[] fileStatusArr = fs.listStatus(new Path("/"));
        //增强for循环遍历
        for(FileStatus file : fileStatusArr){
//            System.out.println(file);
            //判断是否是文件夹
            boolean b = file.isDirectory();
            //判断是否是文件
            boolean b2 = file.isFile();
            //获取文件路径
            Path path = file.getPath();
            if(b){
                System.out.println("文件夹:"+path);
            }else{
                System.out.println("文件:"+path);
            }
        }
    }
}

/*
    public RemoteIterator<LocatedFileStatus> listFiles(Path f, boolean recursive)列出目录下所有的文件 只获取文件
                方法参数
                    Path f:路径
                    boolean recursive:是否递归遍历  true false

                方法返回值
                    RemoteIterator 迭代器
                          hasNext()  判断是否有元素
                          next()  获取元素

              
                    LocatedFileStatus  分布式文件系统上的文件对象 可以获取文件的信息
                                       获取文件大小  副本个数  block块个数 大小等等

                                 Path getPath() 获取路径
                                 long getLen()  获取文件的字节数
                                 short getReplication()获取副本个数
                                 long  getBlockSize() 获取block块的大小
                                 BlockLocation[] getBlockLocations() 获取block块数组

                    BlockLocation  物理切块对象
                           String[]   getHosts()  获取block块在主机的位置
                           String[]   getNames()  获取block块在主机的名称端口
                           long   getLenth()  获取每个切块的大小
                           long   getOffset() 获取偏移量
 */
public class Demo05_FileSystem {
    public static void main(String[] args) throws Exception {
        FileSystem fs = HDFSUtils.getFileSystem();

        //调用方法获取根目录下的所有内容
        RemoteIterator<LocatedFileStatus> it = fs.listFiles(new Path("/"), true);
        while (it.hasNext()) {
            LocatedFileStatus file = it.next();
//            System.out.println(file.getPath());

            //获取路径
            Path path = file.getPath();
            //获取文件的字节数
            long len = file.getLen();
            System.out.println("文件大小:" + len * 1.0 / 1024 / 1024 + "M");
            //获取文件的副本
            short s = file.getReplication();
            System.out.println("副本个数:" + s);
            //获取block大小
            long blockSize = file.getBlockSize();
            System.out.println("block块大小:" + blockSize * 1.0 / 1024 / 1024 + "M");

            //获取block的数组
            BlockLocation[] blockLocations = file.getBlockLocations();
            System.out.println("block块个数:" + blockLocations.length);


            //遍历物理切块数组
            for (BlockLocation b : blockLocations) {
                //获取物理切块的主机地址
                String[] hosts = b.getHosts();
                System.out.println(Arrays.toString(hosts));
                String[] names = b.getNames();
                System.out.println(Arrays.toString(names));
                long length = b.getLength();
                System.out.println("block大小:" + length * 1.0 / 1024 / 1024 + "M");
                long offset = b.getOffset();
                System.out.println("偏移量:" + offset);

            }
            System.out.println("------------------------------");
        }

    }
}

写数据

/*
    public FSDataOutputStream create(Path f, boolean overwrite)  获取字节输出流 向文件中写数据
                boolean overwrite:如果文件存在 是否覆盖  true 覆盖 false不覆盖
 */
public class Demo06_FileSystem {
    public static void main(String[] args) throws Exception {
        FileSystem fs = HDFSUtils.getFileSystem();

        //获取写数据的字节输出流
        FSDataOutputStream out = fs.create(new Path("/1.txt"), true);

        out.write("hello world\r\n".getBytes());

        out.write("hello boys  ".getBytes());
        out.write("hello girls  ".getBytes());

        out.close();
        fs.close();
    }
}

/*
    追加写入数据
      FSDataOutputStream append(Path path) 向指定的文件路径中追加写入数据
 */
public class Demo07_FileSystem {
    public static void main(String[] args) throws Exception {
        FileSystem fs = HDFSUtils.getFileSystem();

        //向文件中追加写入数据
        FSDataOutputStream out = fs.append(new Path("/1.txt"));
        out.write("hello  aaa\r\n".getBytes());
        out.write("hello  bbb\r\n".getBytes());
        out.write("hello  ccc\r\n".getBytes());

        out.close();
        fs.close();

    }
}

读数据

/*
    public FSDataInputStream open(Path f) 获取字节输入流 读取文件中数据
 */
public class Demo08_FileSystem {
    public static void main(String[] args) throws Exception {
        FileSystem fs = HDFSUtils.getFileSystem();

        //获取字节输入流 读取文件中数据
        FSDataInputStream in = fs.open(new Path("/1.txt"));

//        byte[] bytes = new byte[1024];
//        int len =0;
//        while((len = in.read(bytes))!=-1){
//            System.out.println(new String(bytes,0,len));
//
//        }
        //一行一行读取数据
        InputStreamReader isr = new InputStreamReader(in);
        //创建缓冲流
        BufferedReader br = new BufferedReader(isr);
//        String s = br.readLine();
        String line = null;
        while((line = br.readLine())!=null){
            System.out.println(line);
        }
        br.close();
        fs.close();

    }
}
/*
	seek和skip方法补充
 */
public class Demo09_FileSystem {
    public static void main(String[] args) throws Exception {
        FileSystem fs = HDFSUtils.getFileSystem();

        //获取字节输入流 读取文件中数据
        FSDataInputStream in = fs.open(new Path("/1.txt"));

        //跳过几个字节
       // in.skip(1);
	    //指定指针标记读取
        in.seek(0);

        int read = in.read();
        System.out.println(read);

        in.close();

        fs.close();
    }
}

其他方法

//DistributedFileSystem
public class Demo10_FileSystem {
    public static void main(String[] args) throws Exception {
        FileSystem fileSystem = HDFSUtils.getFileSystem();

        fileSystem.delete(new Path("/1.txt"),true);  //删除
        fileSystem.mkdirs(new Path("/aaa/bbb") ); //创建文件夹
        fileSystem.exists(new Path("/aaa/1.txt")); //判断路径是否存在

        //...
      fileSystem.close();
    }
}

小文件合并

由于Hadoop擅长存储大文件,因为大文件的元数据信息比较少,如果Hadoop集群当中有大量的小文件,那么每个小文件都需要维护一份元数据信息,会大大的增加集群管理元数据的内存压力,所以在实际工作当中,如果有必要一定要将小文件合并成大文件进行一起处理在我们的HDFS的shell命令模式下,可以通过命令行将很多的hdfs文件合并成一个大文件下载到本地.

 hdfs dfs -getmerge /aaa/* ./abc.txt  

既然可以在下载的时候将这些小文件合并成一个大文件一起下载,那么肯定就可以在上传的时候将小文件合并到一个大文件里面去

     FileSystem fs = HDFSUtils.getFS();

        FSDataOutputStream out = fs.create(new Path("/aaa/big.txt"));

        LocalFileSystem local = FileSystem.getLocal(new Configuration());
        FileStatus[] fileStatuses = local.listStatus(new Path("file:///d:\\input"));

        for (FileStatus fileStatus : fileStatuses) {

            FSDataInputStream in = local.open(fileStatus.getPath());
            IOUtils.copy(in,out);

            IOUtils.closeQuietly(in);
        }

        IOUtils.closeQuietly(out);

参数配置

使用Configuration类进行配置

       Configuration conf = new Configuration();
        // 修改存储的副本个数  5  name  value
        conf.set( "dfs.replication", "5");
        // 修改物理切块的大小
        conf.set("dfs.blocksize", "64m");

使用配置文件进行配置

在resources下创建配置文件hdfs-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<!--
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License. See accompanying LICENSE file.
-->

<!-- Put site-specific property overrides in this file. -->
<configuration>
        <property>
             <name>dfs.replication</name>
                 <value>5</value>
        </property>
   		<property>
             <name>dfs.blocksize</name>
                 <value>64m</value>
        </property>
</configuration>

HDFS文件限额配置

在多人共用HDFS的环境下,配置设置非常重要。特别是在Hadoop处理大量资料的环境,如果没有配额管理,很容易把所有的空间用完造成别人无法存取。Hdfs的配额设定是针对目录而不是针对账号,可以让每个账号仅操作某一个目录,然后对目录设置配置。
hdfs文件的限额配置允许我们以文件个数,或者文件大小来限制我们在某个目录下上传的文件数量或者文件内容总量,以便达到我们类似百度网盘网盘等限制每个用户允许上传的最大的文件的量。

hdfs dfs -count -q -h /aaa    #查看配额信息

数量限额

hdfs dfs -mkdir -p /aaa
hdfs dfsadmin -setQuota 2 /aaa #给该文件夹下设置最多上传两个文件 ,发现只能上传一个
hdfs dfsadmin -clrQuota /aaa # 清除限额

空间大小限额

在设置空间配额时,设置空间至少是block_size*3大小

hdfs dfsadmin -setSpaceQuota 4k /aaa #限制空间大小4KB
hdfs dfs -put  a.txt /aaa  #上传失败

生成任意大小文件命令

dd if=/dev/zero of=1.txt bs=1M count=2 #生成任意大小文件  bs*count

清除空间配额限制

hdfs dfsadmin -clrSpaceQuota /aaa

hdfs的安全模式

安全模式是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自动离开安全模式。

dfs.namenode.safemode.threshold-pct  副本率 默认值 0.999f
dfs.namenode.safemode.extension 默认值30000   检查完成后 30秒后退出安全模式

安全模式操作命令

hdfs dfsadmin -safemode get  #查看安全模式状态
hdfs dfsadmin -safemode enter #进入安全模式
hdfs dfsadmin -safemode leave #离开安全模式

原理介绍

上传数据流程

网络拓扑及机架感知

 网络拓扑
	节点距离:两个节点到达共同父节点的距离和

机架感知 ( 副本节点的选择 )
	例如:500个节点,上传数据my.tar.gz,副本数为3, 
		  根据机架感知,副本数据存储节点的选择。
	
    
   BlockPlacementPolicyDefault 
   官方注释
   the 1st replica is placed on the local machine, 
   otherwise a random datanode. The 2nd replica is placed on a datanode
   that is on a different rack. The 3rd replica is placed on a datanode
   which is on a different node of the rack as the second replica.

上传流程

Block
HDFS中的文件在物理上是分块存储的,即分成Block;
block在Hadoop不同版本大小不同:
Hadoop1.x:64M
Hadoop2.x:128M


Pipeline,中文翻译为管道。这是HDFS在上传文件写数据过程中采用的一种数据传输方式。
客户端将数据块写入第一个数据节点,第一个数据节点保存数据之后再将块复制到第二个数据节点,后者保存后将其复制到第三个数据节点。

为什么datanode之间采用pipeline线性传输,而不是一次给三个datanode拓扑式传输呢?
因为数据以管道的方式,顺序的沿着一个方向传输,这样能够充分利用每个机器的带宽,避免网络瓶颈和高延迟时的连接,最小化推送所有数据的延时。

ACK (Acknowledge character )即是确认字符,在数据通信中,接收方发给发送方的一种传输类控制字符。表示发来的数据已确认接收无误。


Packet
Packet是Client端向Datanode,或者DataNode的PipLine之间传输数据的基本单位,默认64kB.
Chunk
Chunk是最小的Hadoop中最小的单位,是Client向DataNode或DataNode的PipLne之间进行数据校验的基本单位,默认512Byte,因为用作校验(自己校验自己),故每个chunk需要带有4Byte的校验位。
所以世纪每个chunk写入packet的大小为516Byte,真实数据与校验值数据的比值为128:1。

下载数据流程

 IO操作过程中难免会出现数据丢失或脏数据,数据传输得量越大出错得几率越高。校验错误最常用得办法就是传输前计算一个校验和,传输后计算一个校验和,两个校验和如果不相同就说明数据存在错误,比较常用得错误校验码是CRC32.
 hdfs写入的时候计算出校验和,然后每次读的时候再计算校验和。要注意的一点是,hdfs每固定长度就会计算一次校验和,这个值由io.bytes.per.checksum指定,默认是512字节。

DataNode节点如何保证数据的完整性

1.当datanode读取Block的时候,会计算CheckSum
2.如果计算后的CheckSum,与Block创建时值不一样,说明Block已经损坏
3.客户端读取其他DataNode上的Block
4.常见的校验算法crc,md5等 
5.DataNode在其文件创建后周期验证CheckSum(DataNode后台进程(DataBlockScanner))

如果客户端发现有block坏掉呢,会怎么恢复这个坏的块,主要分几步:

 1.客户端在抛出ChecksumException之前会把坏的block和block所在的datanode报告给namenode
 2.namenode把这个block标记为已损坏,这样namenode就不会把客户端指向这个block,也不会复制这个block到其他的datanode。
 3.namenode会把一个好的block复制到另外一个datanode
 4.namenode把坏的block删除掉

元数据信息管理

什么是元数据信息

元数据:描述数据的数据信息
HDFS中元数据分为两种 
	1.描述文件自身属性的元数据信息
	2.描述文件与block之间映射的元数据信息

如何管理元数据信息

​ 元数据信息就是虚拟目录的一个映射关系,如何保存这些信息.按存储形式分为内存元数据元数据文件两种,分别存在内存磁盘上。

内存元数据

为了保证用户操作元数据交互高效,延迟低,NameNode把所有的元数据都存储在内存中,我们叫做内存元数据。内存中的元数据是最完整的,包括文件自身属性信息文件块位置映射信息。但是内存的致命问题是,断点数据丢失,数据不会持久化。因此NameNode又辅佐了元数据文件来保证元数据的安全完整。

元数据文件

有两种:fsimage镜像文件,edit编辑日志

fsimage镜像文件:是内存元数据的一个持久化的检查点。但是fsimage中仅包含Hadoop文件系统中文件自身属性相关的元数据信息,但不包含文件块位置的信息。文件块位置信息只存储在内存中,是由datanode启动加入集群的时候,向namenode进行数据块的汇报得到的,并且后续间断指定时间进行数据块报告。

持久化的动作是数据从内存到磁盘的IO过程,并且fsimae文件会很大(GB级别的很常见)。如果所有的更新操作都往fsimage文件中添加,这样会导致系统运行的十分缓慢会.对namenode正常服务造成一定的影响,不能频繁的进行持久化。

edit编辑日志:为了避免两次持久化之间数据丢失的问题,又设计了Edits log编辑日志文件。文件中记录的是HDPS所有更改操作(文件创建,删除或修改)的日志,文件系统客户端执行的更改操作首先会被记录到edits文件中。

当HDFS集群运行一段时间后,就会出现下面一些问题:

1. edits logs因操作记录过多会变的很大,
2. fsimage因间隔时间长将会变得很旧;
3. namenode重启会花费很长时间,因为有很多改动要
   从edits log合并到fsimage文件上;
4. 如果频繁进行fsimage持久化,又会影响NN正常服
   务,毕竟I0操作是-种内存到磁盘的耗精力操作.

因此为了克服上述问题,需要一个易于管理的机制来帮助我们减小edit logs文件的大小和得到一个最新的fsimage文件,这样也会减小在NameNode,上的压力。

checkpoint机制

通过Secondary Namenode,每隔一段时间将Name Node的元数据更新并备份,然后返回fsimage给Name Node,供其下次启动时读取.

当集群启动时,NN和SNN都会启动,NN启动后会读取最新的fsimage文件,读到较新的元数据信息,同时还会读取最新的日志信息,根据日志信息的内容“回滚”上一次开机时的操作信息,这样即可保证当前的元数据信息是完整正确的

​ SNN会隔一段时间就去NN下载其fsimage文件和众多edits文件,下载到SNN的本机上,然后将fsimage反序列化到内存中,同时“回放”众多日志文件中的操作信息,更新补全元数据,元数据更新完毕后,SNN就会将该元数据对象序列化到本地磁盘中,然后再将该元数据对象发送给NN,供其下一次开机读取

checkpoint过程

checkpint相关参数设置(了解)

core-site.xml
dfs.namenode.checkpoint.period
--两次检查点创建之间的固定时间间隔,默认3600,即1小时。

dfs.namenode.checkpoint.txns
--未检查的事务数量。若没检查事务数达到这个值,也触发一次checkpoint,1,000,000。

dfs.namenode.checkpoint.check.period
--standby namenode检查是否满足建立checkpoint的条件的检查周期。默认60,即每1min检查一次。

dfs.namenode.num.checkpoints.retained
--在namenode上保存的fsimage的数目,超出的会被删除。默认保存2个。

dfs.namenode.num.checkpoints.retained
--最多能保存的edits文件个数,默认为1,000,000.

dfs.ha.tail-edits.period
--standby namenode每隔多长时间去检测新的Edits文件。只检测完成了的Edits, 不检测inprogress的文件。

查看FSImage和edit文件

cd /opt/hdpdata/name/current
hdfs oiv -p 文件类型  -i镜像文件  -o转换后的文件输出路径
hdfs oiv -p XML -i fsimage_0000000000000000434 -o /opt/fsimage.xml
hdfs oev -p XML -i edits_inprogress_0000000000000000695 -o /opt/edit.xml

HDFS缺点

1.不适合低延时数据访问,比如毫秒级的存储数据.
2.无法高效的对大量小文件进行存储
	  1.存储大量小文件的话,它会占用namenode大量内存来存储文件目录和块信息,而namenode的内存是有限的.
	  	一个block的需要存储的信息 150个字节
	  2.小文件存储的寻址时间会超过读取文件的时间,违反HDFS的设计目标
3.不支持并发写入,文件随机修改
	  1.一个文件只能有一个写,不允许多线程同时写
	  2.仅支持数据append,不支持文件的随机修改

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/29490.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CTFHub | php://input

0x00 前言 CTFHub 专注网络安全、信息安全、白帽子技术的在线学习&#xff0c;实训平台。提供优质的赛事及学习服务&#xff0c;拥有完善的题目环境及配套 writeup &#xff0c;降低 CTF 学习入门门槛&#xff0c;快速帮助选手成长&#xff0c;跟随主流比赛潮流。 0x01 题目描述…

selenium:元素定位之xpath、css

元素定位是在做UI自动化测试中最重要的一环&#xff0c;要牢牢掌握定位的方法&#xff0c;才能更有效率的进行UI自动化测试。 常见的元素定位方式&#xff1a; idnametag_nameclass_namelink_textpartial_link_textxpathcss 其中id&#xff0c;name是具有唯一性的&#xff0…

用HTML5制作精美战机游戏

每天要被大学老师催H5作业&#x1f44f;&#x1f3fb;&#x1f44f;&#x1f3fb;&#x1f44f;&#x1f3fb; 不如看看本文&#xff0c;代码齐全&#xff0c;直接用来做参考案例&#x1f44c;&#x1f3fb; 干货满满不看后悔&#x1f44d;&#x1f44d;&#x1f44d; 代码…

最终版:1分钟自动部署数字人平台并提供web服务:唇形合成(wav2lip) + 超分修复(codeformer),

Demo效果 本文实现步骤:数字人形象(AI绘画) -> 文字转语音(谷歌tts) -> 表情迁移 -> 唇形合成 -> 视频超分 上述步骤所有技术均已在此专栏发布,可点击上方专栏查看具体博文 所有技术依赖环境及api接口均封装打包完毕,使用docker一键部署,预计耗时10分钟 原图 …

【unity】URP的shader开发中支持多光源,_ADDITIONAL_LIGHTS_VERTEX 和 _ADDITIONAL_LIGHTS 区别

项目里有一个其他同事实现的shader&#xff0c;美术那边希望能支持多个光源&#xff0c; 我一看代码里面&#xff0c; frag 函数里已经实现了 #ifdef _ADDITIONAL_LIGHTSuint pixelLightCount GetAdditionalLightsCount();for (uint lightIndex 0u; lightIndex < pixelL…

开源软件介绍——开源基金会和开源许可证

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天我们来看一看世界范围内知名的开源基金会和开源许可证。 开源基金会 基金会是开源生态中的一个重要组成部分&#xff0c;用于资金的筹集与开源项目的前期资助与后期的发展。这里将介绍部分重要基金会&am…

阿里云备案服务码申请方法流程

阿里云备案服务码是什么&#xff1f;ICP备案服务码怎么获取&#xff1f;阿里云备案服务码分为免费和付费两种&#xff0c;申请备案服务码是有限制条件的&#xff0c;需要你的阿里云账号下有可用于申请备案服务码的云产品&#xff0c;如云服务器、建站产品、虚拟主机等&#xff…

Nginx+Tomcat负载均衡、动静分离群集

文章目录 NginxTomcat负载均衡、动静分离群集一.Nginx应用二.部署案例过程&#xff08;7层反向代理&#xff09;关闭防火墙与selinux 1.部署Nginx负载均衡器&#xff08;7-3&#xff09;2.部署Tomcat应用服务器&#xff08;7-2&#xff09;3.部署Tomcat多实例应用服务器&#x…

简单学生管理系统

简单学生管理系统(Java)_封奚泽优的博客-CSDN博客https://blog.csdn.net/weixin_64066303/article/details/130667107?spm1001.2014.3001.5501 转载请注明出处&#xff0c;尊重作者劳动成果。 目录 前期准备&#xff1a; 数据库的连接&#xff1a; 用户账号类&#xff1a;…

集权设施管理-AD域安全策略(二)

活动目录&#xff08;AD&#xff09;凭借其独特管理优势&#xff0c;从众多企业管理服务中脱颖而出&#xff0c;成为内网管理中的佼佼者。采用活动目录来管理的内网&#xff0c;称为AD域。 了解AD域&#xff0c;有助于企业员工更好地与其它部门协作&#xff0c;同时提高安全意…

【游戏编程扯淡精粹】工作第三年总结

工作第三年总结 文章目录 工作第三年总结#1 做了什么自研路线Lua 脚本系统ToolX #2 职业发展如何做事技术中台化内卷的职业市场个人成长 #3 心态建设Owner vs 打工人 今年仍然是个人成长视角更多一些&#xff0c;额外新学到的重点是&#xff0c;借助团队力量 先介绍两个词&…

python生成日报

目录 一&#xff1a;日报生成工具二&#xff1a;日报工具使用方式三&#xff1a;最终日报生成展示 一&#xff1a;日报生成工具 #!/usr/bin/python # coding:utf8class GetHtml(object):def __init__(self):self._html_head """<html><body style&qu…

线性神经网络

线性神经网络 我们应该从线性神经网络开始&#xff0c;去逐步了解深度神经网络&#xff08;深度学习&#xff09;的各种复杂结构和底层原理。 1. 线性回归 用一个线性的模型来拟合数据与它们的标签之间的映射&#xff0c;用于回归问题。 1.1 构造线性模型&#xff1a; y ω…

Hibernate框架【一】——HIbernate框架介绍

系列文章目录 Hibernate框架【三】——基本映射——一对一映射 Hibernate框架【四】——基本映射——多对一和一对多映射 Hibernate框架【五】——基本映射——多对多映射 Hibernate框架介绍 系列文章目录前言一、什么是HIbernate框架Hibernate架构图Hibernate提供的核心功能和…

MIT 6.S081 (BOOK-RISCV-REV1)教材第三章内容

MIT 6.S081 教材第三章内容 引言页表分页硬件内核地址空间物理内存分配代码&#xff08;物理内存分配&#xff09;kinit函数kfree函数kalloc函数 代码&#xff1a;创建一个地址空间kvminit 函数kvmmap函数walk函数kvminithart函数procinit函数 进程地址空间代码&#xff1a;sbr…

Java企业级开发学习笔记(4.4)Spring Boot加载自定义配置文件

一、使用PropertySource加载自定义配置文件 1.1 创建Spring Boot项目 创建Spring Boot项目 单击【创建】按钮 1.2 创建自定义配置文件 在resources里创建myconfig.properties文件 设置文件编码 设置学生的四个属性值 1.3 创建自定义配置类 在cn.kox.boot包里创建confi…

npm发布自己的包

按照上面流程操作

App 启动速度优化

前言​​​​​​​ APP打开的一瞬间速度快慢&#xff1b;就好比人的第一印象&#xff0c;快速的打开一个应用往往给人很舒服的体验。app经常性卡顿启动速度很慢&#xff0c;这无疑是对用户的流失。 启动方式介绍 APP启动的方式分为3种&#xff1a;冷启动、热启动、温启动。…

【服务器数据恢复】RAID5重建导致数据丢失的数据恢复案例

服务器数据恢复环境&#xff1a; HP某型号服务器&#xff0c;5块硬盘组建了一组raid5磁盘阵列。 服务器故障&分析&#xff1a; 服务器在工作过程中&#xff0c;raid5磁盘阵列中的一块磁盘掉线&#xff0c;由于raid5的容错特点&#xff0c;raid阵列未受影响&#xff0c;工作…

服务网格领域的百花齐放,是否存在一个更优解?

作者 lingsamuel&#xff0c;API7.ai 云原生技术专家&#xff0c;Apache APISIX Committer。作者 林志煌&#xff0c;API7.ai 技术工程师&#xff0c;Apache APISIX contributor。 服务网格是一种技术架构&#xff0c;它用于管理微服务系统中各个服务之间的通信&#xff0c;旨在…