
# 初始化HDFS
#### 功能简介
在使用HDFS提供的API之前，需要先进行HDFS初始化操作。过程为：
1. 加载HDFS服务配置文件，并进行kerberos安全认证。
2. 认证通过后，实例化Filesystem。
3. 使用HDFS的API。
![](https://support.huaweicloud.com/devg-mrs/public_sys-resources/note_3.0-zh-cn.png)
此处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配置信息。      | 如果是安全模式集群，您可以联系管理员获取相应账号对应权限的keytab文件和krb5文件。          |
   
![](https://support.huaweicloud.com/devg-mrs/public_sys-resources/note_3.0-zh-cn.png)
- 不同集群的"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(PRINCIPAL_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!!!!!!!!!!!!!!");
  }
```
