在ECI中访问HDFS数据

使用Hadoop、Spark等运行批处理作业时,可以选择文件存储HDFS作为存储。本文以Spark为例,演示如何上传文件到在HDFS中,并在Spark中进行访问。

准备数据并上传到HDFS

  1. 开通HDFS。具体操作,请参见开通文件存储HDFS版服务

  2. 创建文件系统。具体操作,请参见创建文件系统

  3. (可选)创建权限组,并设置规则。具体操作,请参见管理权限组

  4. 创建挂载点。具体操作,请参见管理挂载点

  5. 安装Apache Hadoop。

    1. 下载Apache Hadoop。

      Apache Hadoop下载地址请参见Hadoop下载,建议选用的Apache Hadoop版本不低于2.7.2,本文档中使用的Apache Hadoop版本为Apache Hadoop 2.7.2。

    2. 解压Apache Hadoop压缩包到指定文件夹。

      tar -zxvf hadoop-2.7.2.tar.gz -C /usr/local/
    3. 修改core-site.xml配置文件。

      vim /usr/local/hadoop-2.7.2/etc/hadoop/core-site.xml

      修改core-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>fs.defaultFS</name>
              <value>dfs://f-4b1fcae5dv***.cn-hangzhou.dfs.aliyuncs.com:10290</value>
              <!-- 该地址填写您的HDFS挂载点地址 -->
          </property>
          <property>
              <name>fs.dfs.impl</name>
              <value>com.alibaba.dfs.DistributedFileSystem</value>
          </property>
          <property>
              <name>fs.AbstractFileSystem.dfs.impl</name>
              <value>com.alibaba.dfs.DFS</value>
          </property>
          <property>
              <name>io.file.buffer.size</name>
              <value>8388608</value>
          </property>
          <property>
              <name>alidfs.use.buffer.size.setting</name>
              <value>false</value>
              <!-- 建议不开启,开启后会降低iosize,进而影响数据吞吐 -->
          </property>
          <property>
              <name>dfs.usergroupservice.impl</name>
              <value>com.alibaba.dfs.security.LinuxUserGroupService.class</value>
          </property>
          <property>
              <name>dfs.connection.count</name>
              <value>256</value>
          </property>
      </configuration>	
      说明

      配置时,只需配置HDFS相关的几个配置项,修改后的core-site.xml文件在配置应用时将会用到。

    4. 修改/etc/profile配置文件,并使其生效。

      vim /etc/profile

      添加环境变量如下:

      export HADOOP_HOME=/usr/local/hadoop-2.7.2
      export HADOOP_CLASSPATH=/usr/local/hadoop-2.7.2/etc/hadoop:/usr/local/hadoop-2.7.2/share/hadoop/common/lib/*:/usr/local/hadoop-2.7.2/share/hadoop/common/*:/usr/local/hadoop-2.7.2/share/hadoop/hdfs:/usr/local/hadoop-2.7.2/share/hadoop/hdfs/lib/*:/usr/local/hadoop-2.7.2/share/hadoop/hdfs/*:/usr/local/hadoop-2.7.2/share/hadoop/yarn/lib/*:/usr/local/hadoop-2.7.2/share/hadoop/yarn/*:/usr/local/hadoop-2.7.2/share/hadoop/mapreduce/lib/*:/usr/local/hadoop-2.7.2/share/hadoop/mapreduce/*:/usr/local/hadoop-2.7.2/contrib/capacity-scheduler/*.jar
      export HADOOP_CONF_DIR=/usr/local/hadoop-2.7.2/etc/hadoop

      修改完成后,执行以下命令使其生效。

      source /etc/profile
  6. 添加阿里云HDFS依赖。

    cp aliyun-sdk-dfs-1.0.3.jar  /usr/local/hadoop-2.7.2/share/hadoop/hdfs

    HDFS SDK的下载地址为HDFS SDK。只需部署HDFS Client,无需部署HDFS集群。

  7. 上传数据到HDFS。

    1. 创建数据目录。

      $HADOOP_HOME/bin/hadoop fs -mkdir -p /pod/data
    2. 将本地文件上传到HDFS。

      以下命令使用本地准备的一本书作为示例,请根据实际替换。

      $HADOOP_HOME/bin/hadoop fs -put ./A-Game-of-Thrones.txt /pod/data/A-Game-of-Thrones.txt
    3. 确认文件信息。

      $HADOOP_HOME/bin/hadoop fs -ls /pod/data

在Spark应用中读取HDFS的数据

  1. 开发应用。

    SparkConf conf = new SparkConf().setAppName(WordCount.class.getSimpleName());
    JavaRDD<String> lines = sc.textFile("dfs://f-4b1fcae5dv***.cn-hangzhou.dfs.aliyuncs.com:10290/pod/data/A-Game-of-Thrones.txt", 250);
    ...
    wordsCountResult.saveAsTextFile("dfs://f-4b1fcae5dv***.cn-hangzhou.dfs.aliyuncs.com:10290/pod/data/A-Game-of-Thrones-Result");
    sc.close();   	
  2. 在应用中配置HDFS信息。

    • 方式一:使用静态配置文件

      将core-site.xml放入到应用项目的resources目录下。

    • 方式二:提交应用时进行动态设置

      以Spark为例,在提交应用时进行设置,示例如下:

      hadoopConf:
          # HDFS
          "fs.defaultFS": "dfs://f-4b1fcae5dv***.cn-hangzhou.dfs.aliyuncs.com:10290"
          "fs.dfs.impl": "com.alibaba.dfs.DistributedFileSystem"
          "fs.AbstractFileSystem.dfs.impl": "com.alibaba.dfs.DFS"
  3. 打包JAR文件。

    mvn assembly:assembly

    打包的JAR文件中需包含所有依赖。应用的pom.xml如下:

     1<?xml version="1.0" encoding="UTF-8"?>
     2<project xmlns="http://maven.apache.org/POM/4.0.0"
     3         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     5    <modelVersion>4.0.0</modelVersion>
     6
     7    <groupId>com.aliyun.liumi.spark</groupId>
     8    <artifactId>SparkExampleJava</artifactId>
     9    <version>1.0-SNAPSHOT</version>
    10
    11    <dependencies>
    12        <dependency>
    13            <groupId>org.apache.spark</groupId>
    14            <artifactId>spark-core_2.12</artifactId>
    15            <version>2.4.3</version>
    16        </dependency>
    17
    18        <dependency>
    19            <groupId>com.aliyun.dfs</groupId>
    20            <artifactId>aliyun-sdk-dfs</artifactId>
    21            <version>1.0.3</version>
    22        </dependency>
    23
    24    </dependencies>
    25
    26    <build>
    27    <plugins>
    28        <plugin>
    29            <groupId>org.apache.maven.plugins</groupId>
    30            <artifactId>maven-assembly-plugin</artifactId>
    31            <version>2.6</version>
    32            <configuration>
    33                <appendAssemblyId>false</appendAssemblyId>
    34                <descriptorRefs>
    35                    <descriptorRef>jar-with-dependencies</descriptorRef>
    36                </descriptorRefs>
    37                <archive>
    38                    <manifest>
    39                        <mainClass>com.aliyun.liumi.spark.example.WordCount</mainClass>
    40                    </manifest>
    41                </archive>
    42            </configuration>
    43            <executions>
    44                <execution>
    45                    <id>make-assembly</id>
    46                    <phase>package</phase>
    47                    <goals>
    48                        <goal>assembly</goal>
    49                    </goals>
    50                </execution>
    51            </executions>
    52        </plugin>
    53    </plugins>
    54    </build>
    55</project>
    			
  4. 编写Dockerfile。

    # spark base image
    FROM registry.cn-hangzhou.aliyuncs.com/eci_open/spark:2.4.4
    # 默认的kubernetes-client版本有问题,建议用最新的
    RUN rm $SPARK_HOME/jars/kubernetes-client-*.jar
    ADD https://repo1.maven.org/maven2/io/fabric8/kubernetes-client/4.4.2/kubernetes-client-4.4.2.jar $SPARK_HOME/jars
    # 拷贝本地的应用JAR
    RUN mkdir -p /opt/spark/jars
    COPY SparkExampleJava-1.0-SNAPSHOT.jar /opt/spark/jars
  5. 构建应用镜像。

    docker build -t registry.cn-beijing.aliyuncs.com/liumi/spark:2.4.4-example -f Dockerfile .	
  6. 将镜像推送到阿里云ACR。

    docker push registry.cn-beijing.aliyuncs.com/liumi/spark:2.4.4-example	

完成上述操作,即准备好Spark应用镜像后,可以使用该镜像在Kubernetes集群中部署Spark应用。