更新时间:2024-12-10 GMT+08:00

初始化HDFS

功能简介

在使用HDFS提供的API之前,需要先进行HDFS初始化操作。过程为:

  1. 加载HDFS服务配置文件,并进行kerberos安全认证。
  2. 认证通过后,实例化Filesystem。
  3. 使用HDFS的API。

此处kerberos安全认证需要使用到的keytab文件,请提前准备。

配置文件介绍

登录HDFS时会使用到如表1所示的配置文件。这些文件均已导入到“hdfs-example”工程的“conf”目录。
表1 配置文件

文件名称

作用

获取地址

core-site.xml

配置HDFS详细参数。

MRS_Services_ClientConfig\HDFS\config\core-site.xml

hdfs-site.xml

配置HDFS详细参数。

MRS_Services_ClientConfig\HDFS\config\hdfs-site.xml

user.keytab

对于Kerberos安全认证提供HDFS用户信息。

如果是安全模式集群,您可以联系管理员获取相应账号对应权限的keytab文件和krb5文件。

krb5.conf

Kerberos server配置信息。

  • 不同集群的“user.keytab”“krb5.conf”不能共用。
  • “conf”目录下的“log4j.properties”文件可根据自己的需要进行配置。

代码样例

如下是代码片段,详细代码请参考com.huawei.bigdata.hdfs.examples中的HdfsMain类。

在Linux客户端运行应用的初始化代码,代码样例如下所示。
 /**
   * 初始化,获取一个FileSystem实例
   *
   * @throws IOException
   */
  private void init() throws IOException {
    confLoad();
    authentication();
    instanceBuild();
  }
  
  /**
   * 
   * 如果程序运行在Linux上,则需要core-site.xml、hdfs-site.xml的路径,
   * 修改为在Linux下客户端文件的绝对路径。
   * 
   */
  private void confLoad() throws IOException {
    conf = new Configuration();
    // conf file
    conf.addResource(new Path(PATH_TO_HDFS_SITE_XML));
    conf.addResource(new Path(PATH_TO_CORE_SITE_XML));
   }
  
  /**
   * kerberos security authentication 
   * 如果程序运行在Linux上,则需要krb5.conf和keytab文件的路径,
   * 修改为在Linux下客户端文件的绝对路径。并且需要将样例代码中的keytab文件和principal文件
   * 分别修改为当前用户的keytab文件名和用户名。
   * 
   */
  private void authentication() throws IOException {
    // 安全模式
    if ("kerberos".equalsIgnoreCase(conf.get("hadoop.security.authentication"))) {
      System.setProperty("java.security.krb5.conf", PATH_TO_KRB5_CONF);
      LoginUtil.login(PRNCIPAL_NAME, PATH_TO_KEYTAB, PATH_TO_KRB5_CONF, conf);
    }
  }
  
  
  /**
   * build HDFS instance
   */
  private void instanceBuild() throws IOException {
    // get filesystem
    fSystem = FileSystem.get(conf);
  }
在Linux环境下需要运行login的代码样例,用于第一次登录使用,详细代码请参考com.huawei.bigdata.security中的LoginUtil类。
public synchronized static void login(String userPrincipal,
      String userKeytabPath, String krb5ConfPath, Configuration conf)
      throws IOException {
    // 1.检查放入的参数
    if ((userPrincipal == null) || (userPrincipal.length() <= 0)) {
      LOG.error("input userPrincipal is invalid.");
      throw new IOException("input userPrincipal is invalid.");
    }

    if ((userKeytabPath == null) || (userKeytabPath.length() <= 0)) {
      LOG.error("input userKeytabPath is invalid.");
      throw new IOException("input userKeytabPath is invalid.");
    }

    if ((krb5ConfPath == null) || (krb5ConfPath.length() <= 0)) {
      LOG.error("input krb5ConfPath is invalid.");
      throw new IOException("input krb5ConfPath is invalid.");
    }

    if ((conf == null)) {
      LOG.error("input conf is invalid.");
      throw new IOException("input conf is invalid.");
    }

    // 2.检查文件是否存在
    File userKeytabFile = new File(userKeytabPath);
    if (!userKeytabFile.exists()) {
      LOG.error("userKeytabFile(" + userKeytabFile.getAbsolutePath()
          + ") does not exist.");
      throw new IOException("userKeytabFile("
          + userKeytabFile.getAbsolutePath() + ") does not exist.");
    }
    if (!userKeytabFile.isFile()) {
      LOG.error("userKeytabFile(" + userKeytabFile.getAbsolutePath()
          + ") is not a file.");
      throw new IOException("userKeytabFile("
          + userKeytabFile.getAbsolutePath() + ") is not a file.");
    }

    File krb5ConfFile = new File(krb5ConfPath);
    if (!krb5ConfFile.exists()) {
      LOG.error("krb5ConfFile(" + krb5ConfFile.getAbsolutePath()
          + ") does not exist.");
      throw new IOException("krb5ConfFile(" + krb5ConfFile.getAbsolutePath()
          + ") does not exist.");
    }
    if (!krb5ConfFile.isFile()) {
      LOG.error("krb5ConfFile(" + krb5ConfFile.getAbsolutePath()
          + ") is not a file.");
      throw new IOException("krb5ConfFile(" + krb5ConfFile.getAbsolutePath()
          + ") is not a file.");
    }

    // 3.设置并检查krb5config
    setKrb5Config(krb5ConfFile.getAbsolutePath());
    setConfiguration(conf);

    // 4.检查是否需要登录
    if (checkNeedLogin(userPrincipal)) {

    // 5.登录hadoop并检查
      loginHadoop(userPrincipal, userKeytabFile.getAbsolutePath());
    }

    // 6.检查重新登录
    checkAuthenticateOverKrb();
    System.out.println("Login success!!!!!!!!!!!!!!");
  }