Introducción a Big Data (3) HDFS Shell y Java API

1. Carcasa HDFS

La mayoría de los comandos de HDFS Shell son similares a Unix Shell, la principal diferencia es que los comandos de HDFS Shell operan en archivos en el servidor Hadoop remoto, mientras que los comandos de Unix Shell operan en archivos locales.

Para ver los comandos completos de HDFS Shell, consulte el sitio web oficial: FileSystemShell  and  HDFS Commands Guide , o use el comando hadoop fs --help para verlo. A continuación se muestran varios comandos de uso común.

Orden ilustrar
hadoop FS se relaciona con un sistema de archivos genérico que puede apuntar a cualquier sistema de archivos como local, HDFS, etc. Por lo tanto, esto se puede usar cuando se trata de diferentes sistemas de archivos como Local FS, HFTP FS, S3 FS y otros (el más utilizado, puede operar cualquier sistema de archivos).
hadoop Obsoleto específicamente para el sistema de archivos distribuido hdfs
hdfs dfs Igual que hadoop dfs, y convertido internamente al comando hdfs dfs cuando se usa hadoop dfs
  • mkdir crea un directorio:

Cómo usar: hadoop fs -mkdir [-p] <ruta>...

Descripción: el parámetro -p creará directorios recursivamente, incluso si el directorio principal no existe, creará directorios automáticamente de acuerdo con el nivel del directorio

  • poner y copeFromLocal para cargar archivos:

Cómo usar put: hadoop fs -put <localsrc> ... <dst>

Descripción: copie rutas/archivos de origen únicos o múltiples desde el sistema de archivos local al sistema de archivos de destino, y también admita la lectura de entradas desde la entrada estándar y la escritura en el sistema de archivos de destino.

copyFromLocal: Igual que poner. La única diferencia es que -put es más relajado y puede copiar archivos locales o HDFS a HDFS, mientras que -copyFromLocal solo puede copiar archivos locales a HDFS.

  • ls enumera los archivos:

Cómo usar: hadoop fs -ls <args>

Nota: El comando "-ls" sin parámetros en HDFS no tiene valor de retorno y devuelve el contenido del directorio "inicio" de HDFS de forma predeterminada. En HDFS, no existe el concepto de directorio actual ni el comando cd.

Comando lsr: la función es enumerar recursivamente los archivos y la información del directorio en el subdirectorio. Se ha DESAPROBADO y se puede reemplazar por hadoop fs -ls -R <args>

  • cat: muestra el contenido del archivo en la ruta especificada a stdout

  • get y copeToLocal Descargar archivos: copia archivos en el sistema de archivos local. hadoop fs -get [-f] [-p] [-ignoreCrc] [-crc] <src> ... <localdst>

-p: Preservar tiempos de acceso y modificación, propiedad y permisos. (suponiendo que los permisos se puedan propagar a través de los sistemas de archivos)

-f: sobrescribir el destino si el destino ya existe

-ignorecrc: omite las comprobaciones de CRC para los archivos descargados

-crc: escribe la suma de comprobación CRC para los archivos descargados

Lectura adicional: archivo de verificación de datos CRC en HADOOP

copeToLocal: Igual que get. La única diferencia es que copeToLocal limita la ruta de destino solo a los archivos locales.

  • rm: elimina los archivos en la ruta especificada . hadoop fs -rm [-f] [-r|-R] [-skipTrash] [-safely] URI [URI...]

HDFS tiene un mecanismo de contenedor de recolección de basura (basura), que está deshabilitado de forma predeterminada y se puede habilitar configurando un valor mayor que cero (en minutos) a través de fs.trash.interval (en core-site.xml). Cuando la papelera está habilitada, HDFS moverá los archivos eliminados a un directorio de papelera (/usuario/nombre de usuario/.Papelera/). Si desea eliminar un archivo directamente sin ponerlo en la papelera de reciclaje, puede usar el comando -skipTrash.

El período de recuperación establecido aquí es de un día (60*24).

La implementación específica de la papelera de HDFS es en realidad abrir un subproceso de fondo Emptier (org.apache.Hadoop.fs.TrashPolicyDefault.Emptier, puede cambiar la clase TrashPolicy a través de fs.trash.classname) en NameNode. Este subproceso eliminará automáticamente los archivos y directorios de la papelera de reciclaje que hayan excedido el ciclo de vida de manera regular. Alternativamente, los usuarios pueden eliminar archivos manualmente en la papelera de reciclaje. La operación de eliminación de archivos en la papelera de reciclaje es la misma que la eliminación de otros directorios de archivos. La única diferencia es que HDFS detectará si el directorio de archivos es una papelera de reciclaje. Si es así, HDFS no los colocará en la papelera de reciclaje.

Comando rmr: la función es eliminar recursivamente todos los archivos en el directorio de archivos. Ha quedado DEPRECATADO y puede ser reemplazado por hadoop fs -rm [-R | -r] <URI>

  • borrar 命令: hadoop fs -borrar [-inmediato]

Al ejecutar hadoop fs -expurge por primera vez, HDFS creará un nuevo punto de control y moverá los archivos eliminados recientemente almacenados en la Papelera al punto de control; la próxima vez que se ejecute hadoop fs -expurge (tenga en cuenta que si configura la propiedad fs.trash.checkpoint.interval en el sitio central. (Nota: consulte Eliminación y recuperación de archivos para obtener más detalles )

Si se pasa la opción -immediate, se ignorará la configuración fs.trash.interval y todos los archivos basura del usuario actual se eliminarán inmediatamente.

  • du: hadoop fs [opciones genéricas] -du [-s] [-h] [-v] [-x] <ruta> ... Mostrar el tamaño de todos los archivos en el directorio

Nota: La primera columna indica el tamaño total de los archivos en este directorio, la segunda columna indica el tamaño de almacenamiento total de todos los archivos en este directorio en el clúster (igual al tamaño del archivo * coeficiente de copia) y la tercera columna es el directorio que está consultando.

  • setrep: hadoop fs -setrep [-R] [-w] <numReplicas> <ruta> Se utiliza para modificar el coeficiente de réplica del archivo. Si la ruta es un directorio, el comando cambiará recursivamente el factor de copia de todos los archivos en el árbol de directorios enraizados en la ruta.

El parámetro -w espera a que se complete el comando, lo que puede llevar mucho tiempo. Si bien el parámetro -R es para compatibilidad con versiones anteriores, no tiene ningún efecto.

  • mv: hadoop fs -mv URI [URI ...] <dest> Mover archivos desde el origen al destino. El comando también permite múltiples fuentes, en cuyo caso el destino debe ser un directorio. No se permite mover archivos entre sistemas de archivos.

Aquí todo el directorio dir2 se ha movido a dir1.

  • cp: hadoop fs -cp [-f] [-p | -p[topax]] URI [URI ...] <dest> Copie archivos de origen a destino. Este comando también permite múltiples fuentes, en cuyo caso el destino debe ser un directorio.

  • head: hadoop fs -head URI imprime el primer 1 KB del archivo en la salida estándar.
  • tail: hadoop fs -tail [-f] URI Muestra el contenido de 1 KB de la cola del archivo en la salida estándar. Al igual que Unix, puede usar el parámetro -f para generar continuamente el último 1 KB de contenido.

  • stat: Imprime estadísticas para archivos/directorios en el formato especificado. El formato acepta permisos en octal (%a) y símbolos (%a), tamaño de archivo en bytes (%b), tipo (%F), nombre de grupo del propietario (%g), nombre (%n), tamaño de bloque (%o), copia (%r), nombre de usuario del propietario (%u), fecha de acceso (%x, %x) y fecha de modificación (%y, %y). %x y %y muestran la fecha UTC como "yyyy-MM-dd HH:mm:ss", %x y %y muestran los milisegundos de la hora UTC del 1 de enero de 1970. Si no se especifica ningún formato, se utiliza %y de forma predeterminada.
hadoop fs -stat "type:%F perm:%a %u:%g size:%b mtime:%y atime:%x name:%n" /user/hadoop/dir1/testHDFS.txt

  • prueba: hadoop fs -prueba -[defswrz] URI 
  1. -d: Devuelve 0 si la ruta es un directorio.
  2. -e: Devuelve 0 si existe la ruta.
  3. -f: Devuelve 0 si la ruta es un archivo.
  4. -s: Devuelve 0 si la ruta no está vacía.
  5. -w: Devuelve 0 si la ruta existe y se otorga permiso de escritura.
  6. -r: Devuelve 0 si la ruta existe y tiene permiso de lectura.
  7. -z: Devuelve 0 si la longitud del archivo es 0.

Use $? en bash para obtener el valor de retorno de la última llamada.

  • texto: hadoop fs -text <src> toma un archivo de origen y genera el archivo en formato de texto. Los formatos permitidos son zip y TextRecordInputStream.

  • touchz: hadoop fs -touchz URI [URI ...] crea un archivo vacío con 0 bytes

  • Comando de modo seguro: el NameNode de HDFS entrará automáticamente en modo seguro cuando se inicie. Safemode es un estado de NameNode en el que no se permiten modificaciones en el sistema de archivos. El propósito del modo seguro es verificar la validez de los bloques de datos en cada Nodo de datos cuando se inicia el sistema, y ​​copiar o eliminar los bloques de datos según sea necesario de acuerdo con la política. Cuando el número de copias de los bloques de datos alcance el número mínimo de copias, se saldrá automáticamente del modo seguro. Cabe señalar que después de que HDFS ingrese al modo seguro, Hive y HBase se iniciarán de manera anormal. Extensión: Comprensión del modo de seguridad HDFS        Los comandos de operación del modo de seguridad son los siguientes:
# 进入安全模式
hadoop dfsadmin -safemode enter

# 退出安全模式
hadoop dfsadmin -safemode leave

# 查看集群是否处于安全模式
hadoop dfsadmin -safemode get

 

二、HDFS Java API

2.1 IDEA (Windows) se conecta al clúster Hadoop de la máquina virtual

La conexión al clúster de Hadoop en la máquina virtual bajo Windows requiere algunos preparativos preliminares, que son los siguientes:

  1. Primero, busque un directorio en Windows para descomprimir el hadoop-3.0.0.tar.gz descargado en la primera sección de Introducción a Big Data (1) Instalación pseudodistribuida de Hadoop
  2. Luego  descargue hadoop.dll y winutils.exe desde el espejo de winutils y cópielos en el directorio bin del directorio descomprimido hadoop-3.0.0.tar.gz
  3. Finalmente, configure la variable de entorno HADOOP_HOME, el valor es el directorio descomprimido hadoop-3.0.0.tar.gz, y luego agregue $HADOOP_HOME\bin a la ruta de la variable del sistema.

2.2 Prueba del proyecto IDEA

Cree un nuevo proyecto de primavera y las dependencias del archivo pom son las siguientes:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>hadoopdemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>hadoopdemo</name>
    <description>Demo project for Hadoop</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--引入hadoop-client Jar包  -->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>3.1.1</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>log4j-over-slf4j</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- 引入hadoop-common Jar包 -->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>3.1.1</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>log4j-over-slf4j</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- 引入hadoop-hdfs Jar包 -->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-hdfs</artifactId>
            <version>3.1.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Luego está la clase de configuración de HDFS

package com.example.hadoopdemo.config;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.springframework.context.annotation.Bean;

import java.net.URI;

@org.springframework.context.annotation.Configuration
public class HDFSConfig {
    private static String HDFS_URI = "hdfs://hadoop0:9000/";

    @Bean
    public FileSystem getFileSystem() throws Exception {
        Configuration configuration = new Configuration();
        FileSystem fs = FileSystem.get(new URI(HDFS_URI), configuration, "root");
        return fs;
    }
}

Después de configurar la información anterior, podemos usar HDFS. Las clases de operación de archivos en Hadoop están básicamente en el paquete "org.apache.hadoop.fs”. Las operaciones admitidas por estas API incluyen abrir archivos, leer y escribir archivos y eliminar archivos. El código de ejemplo es el siguiente:

package com.example.hadoopdemo.utils;

import org.apache.hadoop.fs.*;
import org.apache.hadoop.hdfs.DistributedFileSystem;
import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
import org.apache.hadoop.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.OutputStream;

@Component
public class HDFSUtils {
    @Autowired
    private FileSystem hdfs;

    // 判断文件、目录是否存在
    public boolean isExists(String pathString) throws IOException {
        Path path = new Path(pathString);
        return hdfs.exists(path);
    }

    // 上传文件
    public void upload(String src, String dst) throws IOException {
        Path scrPath = new Path(src);
        Path dstPath = new Path(dst);
        hdfs.copyFromLocalFile(scrPath, dstPath);
    }

    // 下载文件
    public void download(String src, String dst) throws IOException {
        Path scrPath = new Path(src);
        Path dstPath = new Path(dst);
        hdfs.copyToLocalFile(scrPath, dstPath);
    }

    // 创建文件并写入数据
    public void createFile(String dst, String context) throws IOException {
        Path dstPath = new Path(dst);
        FSDataOutputStream outputStream = hdfs.create(dstPath);
        outputStream.write(context.getBytes());
        outputStream.close();
    }

    // 创建目录
    public boolean createDir(String dir) throws IOException {
        return hdfs.mkdirs(new Path(dir));
    }

    // 文件重命名
    public boolean renameFile(String src, String dst) throws IOException {
        return hdfs.rename(new Path(src), new Path(dst));
    }

    // 删除文件或目录,recursive标志用来确定是否要递归删除
    public boolean delete(String src, boolean recursive) throws IOException {
        return hdfs.delete(new Path(src), recursive);
    }

    // 读取文件, 输出到outputStream
    public void readFile(String src, OutputStream outputStream) throws IOException {
        FSDataInputStream inputStream = hdfs.open(new Path(src));
        IOUtils.copyBytes(inputStream, outputStream, 1024, false);
        IOUtils.closeStream(inputStream);
    }

    // 查看指定目录下的文件信息
    public void list(String src) throws IOException {
        FileStatus[] fileStatusList = hdfs.listStatus(new Path(src));
        for (FileStatus fileStatus : fileStatusList) {
            // 文件路径
            System.out.println(fileStatus.getPath());
            // 文件的修改时间
            System.out.println(fileStatus.getModificationTime());
        }
    }

    // 获取DataNode信息
    public void getNodeMessage() throws IOException {
        DistributedFileSystem distributedFileSystem = (DistributedFileSystem) hdfs;
        DatanodeInfo[] datanodeInfos = distributedFileSystem.getDataNodeStats();
        for (int i = 0; i < datanodeInfos.length; i++) {
            System.out.println("DataNode_" + i + "_Name: " + datanodeInfos[i].getHostName());
        }
    }
}

El código de prueba es el siguiente:

package com.example.hadoopdemo;

import com.example.hadoopdemo.utils.HDFSUtils;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class HDFSTest {
    @Autowired
    private HDFSUtils hdfsUtils;

    @Test
    public void test() throws Exception {
        System.out.println("hdfs目录是否存在:" + hdfsUtils.isExists("/hdfs"));
        System.out.println("创建hdfs目录:" + hdfsUtils.createDir("/hdfs"));
        hdfsUtils.upload("C:\\Users\\Minghui.Ni\\Desktop\\test.txt", "/hdfs");
        System.out.println("test.txt文件是否上传成功:" + hdfsUtils.isExists("/hdfs/test.txt"));
        System.out.println("test.txt重命名为hdfsTest.txt:" + hdfsUtils.renameFile("/hdfs/test.txt", "/hdfs/hdfsTest.txt"));
        hdfsUtils.readFile("/hdfs/hdfsTest.txt", System.out);
        System.out.println("\n");
        hdfsUtils.createFile("/hdfs/test2.txt", "Hello HDFS\n");
        hdfsUtils.readFile("/hdfs/test2.txt", System.out);
        hdfsUtils.list("/hdfs");
        hdfsUtils.getNodeMessage();
        hdfsUtils.delete("/hdfs", true);
        System.out.println("hdfs目录是否删除成功:" + !hdfsUtils.isExists("/hdfs"));
    }
}

La captura de pantalla en ejecución es la siguiente:

 

3. Otros

Spring para Apache Hadoop - Documentación de referencia

 

Supongo que te gusta

Origin blog.csdn.net/qq_37771475/article/details/116596779
Recomendado
Clasificación