HDFS符号链接和硬链接

前言


初看这个标题,可能很多人会心生疑问:符号链接和硬链接是什么意思?这些概念不是在Linux操作系统下才有的嘛,HDFS目前也有?当然大家可能还会有其他疑问,没关系,在后面的内容讲述中答案会一一揭晓。归纳起来一句话:不管是符号链接还是硬链接,它们本质上都是一种快捷的链接方式。熟悉Linux系统的同学应该都知道在Linux文件系统下有硬链接和软链接的概念,而HDFS同样作为一套文件系统,它也能支持文件链接的形式。本文所讲述的主题正是HDFS下的文件链接操作。

相关背景:Linux软链接和硬链接


在讲述HDFS下的文件链接内容之前,有必要了解一下相关内容:Linux软链接和硬链接。因为HDFS文件链接的原理设计基本与此相似。Linux软链接和硬链接分别代表着2种截然不同的连接形式,它们在作用上也存在部分微妙的差异。

软链接


软链接又被称为符号链接,英文名称soft link或symbolic link(HDFS内采用的软链接名称就是symbolic link,简称symlink)。就个人感觉而言,软链接在实际工作中用得频率会略高于硬链接。一句话简单地概括软链接的作用:

软链接其实就是文件的一个快捷方式,软链接删除了,其指向的真实文件并不会受到影响。

所以在实际的工作中,我们一般会把依赖资源包的路径用软链接的方式引用,这样的话资源包的路径可以一直保持不变,而其所指向的真实资源包可以根据使用场景进行任意变化

硬链接


硬链接,英文名称为hard link。它的一个主要目的在于文件的共享。文件的硬链接创建出来之后,它具有如下的特点:

硬链接相当于文件的一个别名。它指向的是一个文件inode的引用地址,而非软链接中的文件路径指向。所以对于硬链接中的文件做修改会影响到其所指向的真实文件,当对硬链接做删除动作后,如果其所指向的文件inode当前没有被外部引用的话,则原文件会被删除,否则原文件不会被删除。

上面的意思通俗地解释就是说,当真实文件或此文件的硬链接有一个存在的情况下,对文件执行删除操作,文件不会被真正删除。当只剩下一个文件inode引用的情况下,删除操作才能生效。

HDFS符号链接(软链接)与硬链接概述


了解完Linux下的软链接与硬链接的概念后,我们将进入本文的主题:HDFS下的符号链接与硬链接。

Hadoop社区在HDFS-245(Create symbolic links in HDFS)中优先对符号链接功能进行了实现。符号链接另外一部分的工作在HADOOP-6421(Symbolic links)中,此部分是HADOOP-COMMON模块相关的底层代码改动。在硬链接方面,社区目前有相关的JIRA:HDFS-3370(HDFS hardlink),但是社区目前并没有在跟进,只有初始的设计文档。所以本文准备讲述的HDFS硬链接将会是一个设计模型,并未真正实现,这点需要注意

鉴于目前HDFS的硬链接功能并未真正实现,所以本文的主讲内容还是符号链接的功能,硬链接功能将给出大致设计模型。

HDFS符号链接(软链接)


HDFS符号链接,在HDFS中称之为symbolic link,在下文的讲述中此名称都将会简称为symlink。与Linux文件系统中的软链接概念一样,HDFS符号链接也是相当于给目标文件新建一个自定义路径,这个自定义路径实质指向目标文件。所以在这里HDFS符号链接中做的最重要的事情就是路径的解析。而且这个解析还有可能是嵌套的,符号链接中指向的是另外一个符号链接。下面来学习HDFS符号链接的主要原理实现。

HDFS符号链接原理


HDFS符号链接功能的实现主要分为2个部分:一个是对现有文件符号链接的添加,另外一个则是符号链接的解析过程。

对现有文件符号链接的添加在HDFS中的实现就是添加一个新的INode对象在NameNode中,只是这个INode对象是Symlink类型的,叫做INodeSymlink。此对象内部会包含一个实际指向的target地址。

而符号链接的解析过程则会略微复杂一些,HDFS并不是直接在NameNode最终处理方法的地方做解析的,而是在前面一层FileContext类上做解析的,然后将解析好后的路径再传到HDFS中做处理。换句话说,客户端需要通过FileContext上下文对象来操作符号链接相关的操作,如果直接用FileSystem的API来操作的话,会抛出解析异常的错误

HDFS符号链接核心代码实现


此部分我们将通过部分代码的跟踪来学习HDFS符号链接的实现过程。

同样首先是创建符号链接的过程,我们直接进入到最终的服务端处理方法,FSNamesystem的createSymlink方法。

   *// 为目标文件创建一个符号链接
  void createSymlink(String target, String link,
      PermissionStatus dirPerms, boolean createParent, boolean logRetryCache)
      throws IOException {
    if (!FileSystem.areSymlinksEnabled()) {
      throw new UnsupportedOperationException("Symlinks not supported");
    }
    HdfsFileStatus auditStat = null;
    writeLock();
    try {
      checkOperation(OperationCategory.WRITE);
      checkNameNodeSafeMode("Cannot create symlink " + link);
      // 此处进入创建软链接实际操作
      auditStat = FSDirSymlinkOp.createSymlinkInt(this, target, link, dirPerms,
                                                  createParent, logRetryCache);
      ...

我们继续进入FSDirSymlinkOp的createSymlinkInt方法,

  static HdfsFileStatus createSymlinkInt(
      FSNamesystem fsn, String target, final String linkArg,
      PermissionStatus dirPerms, boolean createParent, boolean logRetryCache)
      throws IOException {
    FSDirectory fsd = fsn.getFSDirectory();
    String link = linkArg;
    // 检验符号链接的名称
    if (!DFSUtil.isValidName(link)) {
      throw new InvalidPathException("Invalid link name: " + link);
    }
    if (FSDirectory.isReservedName(target) || target.isEmpty()
        || FSDirectory.isExactReservedName(target)) {
      throw new InvalidPathException("Invalid target name: " + target);
    }

    if (NameNode.stateChangeLog.isDebugEnabled()) {
      NameNode.stateChangeLog.debug("DIR* NameSystem.createSymlink: target="
          + target + " link=" + link);
    
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值