文章目录

  • 01 引言
  • 02 JuiceFS Hadoop Java API
    • 2.1 如何使用?
    • 2.2 入口
      • 2.2.1 getFileSystem方法
      • 2.2.2 小结
    • 2.3 JuiceFS源码
      • 2.3.1 从hadoop-api到juicefs-api
      • 2.3.2 JuiceFS底层库
  • 03 总结
  • 04 文末

01 引言

在前面的博客《JuiceFS-开源分布式文件系统入门(一篇就够了)》,我们大致了解了JuiceFS的一些基本概念,它的架构图大致如下:

本文主要针对HadoopJava API来分析下它的源码。

02 JuiceFS Hadoop Java API

官方使用教程:《在 Hadoop 生态使用 JuiceFS 存储》

2.1 如何使用?

使用Hadoop Java API去调用JuiceFS是很简单的,一般分为如下几个步骤。

STEP1:引入依赖

<dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-common</artifactId><version>版本号</version>
</dependency><dependency><groupId>io.juicefs</groupId><artifactId>juicefs-hadoop</artifactId><version>版本号</version>
</dependency>

STEP2:代码使用,只需要修改下Configuration就可以了

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;public class JuiceFSDemo {public static void main(String[] args) throws Exception {Configuration conf = new Configuration();conf.set("fs.jfs.impl", "io.juicefs.JuiceFileSystem");conf.set("juicefs.meta", "redis://127.0.0.1:6379/0");  // JuiceFS 元数据引擎地址Path p = new Path("jfs://{JFS_NAME}/");  // 请替换 {JFS_NAME} 为正确的值FileSystem jfs = p.getFileSystem(conf);FileStatus[] fileStatuses = jfs.listStatus(p);// 遍历 JuiceFS 文件系统并打印文件路径for (FileStatus status : fileStatuses) {System.out.println(status.getPath());}}
}

STEP3:接下来,直接使用hadoop-common的java api即可使用JuiceFS系统了。

可以看得出,操作是十分简单的,只要引入了hadoop-common以及juicefs-hadoop的依赖,修改一下配置,即可使用。那么其底层的代码又是怎么走的呢?接下来讲讲。

2.2 入口

从上面的代码,我们可以知道,仅仅是配置了两项,然后指定了地址,即可使用JuiceFS文件系统了,如下代码:

Configuration conf = new Configuration();
conf.set("fs.jfs.impl", "io.juicefs.JuiceFileSystem");
conf.set("juicefs.meta", "redis://127.0.0.1:6379/0");  // JuiceFS 元数据引擎地址
Path p = new Path("jfs://{JFS_NAME}/");  // 请替换 {JFS_NAME} 为正确的值
FileSystem jfs = p.getFileSystem(conf);

其中主要核心是 p.getFileSystem(conf) 这一段代码。

2.2.1 getFileSystem方法

跟着断点走,会进入到org.apache.hadoop.fs.FileSystem.Cache#getInternal方法:

其中较为核心的是createFileSystem方法,进去看看:

可以看到,createFileSystem方法主要做了获取类的元数据对象以及初始化操作,我们主要看卡getFileSystemClass方法:

该方法会加载所有的文件系统,对应的方法为loadFileSystems,继续断点:

当然到这里,并没有我们需要的JuiceFS系统,继续走下一步:

可以看到红框的那一行,原来是通过拼接scheme来去动态加载JuiceFileSystem的对象,也就是对应前面设置的:

conf.set("fs.jfs.impl", "io.juicefs.JuiceFileSystem");

2.2.2 小结

hadoop-common初始化JuiceFS文件系统的流程:

  • 首先会解析地址获取scheme,如:(jfs://{JFS_NAME}/,它的schemejfs);
  • 接着hadoop-common里面的org.apache.hadoop.fs.FileSystem#getFileSystemClass方法通过拼接"fs." + scheme + ".impl"作为key值去获取config的内容,即:
//conf.set("fs.jfs.impl", "io.juicefs.JuiceFileSystem");
conf.get("fs.jfs.impl", null);
  • 最后即可实例化JuiceFS文件系统了。

2.3 JuiceFS源码

到这里我们知道了hadoop-common api对接JuiceFS的方式了,那么JuiceFS里的代码是如何的呢?

2.3.1 从hadoop-api到juicefs-api

我们可以从实际的业务入手,如下示例:

 private void initHdfsPath() {Path path = new Path(RESOURCE_UPLOAD_PATH);try {if (!fs.exists(path)) {fs.mkdirs(path);}} catch (Exception e) {LOGGER.error(e.getMessage(), e);}}

断点看看fs.exists方法:

从断点可以看到,当前的文件系统为JuiceFileSystem了,继续断点进去:

会发下,这里会进入org.apache.hadoop.fs.FileSystem#exists方法,其中里面有一个getFileStatus方法,点击查看:

原来它是一个抽象方法,由子类实现:

它有多个子类实现,当然也包括我们目前的JuiceFileSystemImpl,进入看看:

终于进来了,接着继续看io.juicefs.JuiceFileSystemImpl#getFileStatusInternal方法:

可以看到,原来查询是否存在,JuiceFS是使用了lib去查,这个lib其实是调用到了底层的库了(JNI技术)。

2.3.2 JuiceFS底层库

我们通过搜索io.juicefs.JuiceFileSystemImpl#lib变量:

可以看到它是在io.juicefs.JuiceFileSystemImpl#loadLibrary方法初始化了,看看里面的代码:

可以看到它是通过识别当前操作系统来去加载JuiceFS的底层so库的,那么底层库的接口支持哪些呢?看看:

其实就是支持文件系统的CURD这些,也没啥好看的了。

简单的说,它的核心并不在java代码,而是通过JNI来调用底层的库来实现的

03 总结

通过阅读本文,我们可以知道,JucieFS对接hadoop-common api的流程如下:

  1. hadoop-common里面的FileSystem类首先会解析地址获取scheme,如:(jfs://{JFS_NAME}/,它的schemejfs);
  • 接着hadoop-common里面的getFileSystemClass方法通过拼接"fs." + scheme + ".impl"作为key值去获取config的内容并实例化JuiceFS文件系统了;
  • JuiceFS文件系统对象是继承FileSystem对象实现的,所以使用FileSystem的接口去调用,最终由JuiceFS文件系统来实现;
  • JuiceFS文件系统的java代码最终是调用了底层的so库去实现。

其实关键的核心还是在JuiceFS的底层库,不知道有无开源呢?感兴趣的小伙伴可以去参考它的源码:https://github.com/juicedata/juicefs

04 文末

本文主要讲解了hadoop-common java api层面JuiceFS的实现流程,希望能帮助到大家,谢谢大家的阅读,本文完!

JuiceFS分布式文件系统源码分析(Java层)相关推荐

  1. Handler源码分析 - Java层

    Handler最常见的使用场景就是下载回调,为了不影响用户体验Android不支持在主线程中进行耗时时操作,长时间的耗时操作会产生ANR异常,而下载无疑是耗时操作,所以我们会在子线程中进行下载.但,下 ...

  2. 深入源码分析Java线程池的实现原理

    转载自   深入源码分析Java线程池的实现原理 程序的运行,其本质上,是对系统资源(CPU.内存.磁盘.网络等等)的使用.如何高效的使用这些资源是我们编程优化演进的一个方向.今天说的线程池就是一种对 ...

  3. 视频教程-Spring底层源码分析-Java

    Spring底层源码分析 鲁班学院-子路老师曾就职于谷歌.天猫电商等多家互联网公司,历任java架构师.研发经理等职位,参与并主导千万级并发电商网站与后端供应链研发体系搭建,多次参与电商大促活动技术保 ...

  4. 视频教程-RPC服务框架(Dubbo)源码分析-Java

    RPC服务框架(Dubbo)源码分析 鲁班学院-子路老师曾就职于谷歌.天猫电商等多家互联网公司,历任java架构师.研发经理等职位,参与并主导千万级并发电商网站与后端供应链研发体系搭建,多次参与电商大 ...

  5. Kafka#4:存储设计 分布式设计 源码分析

    https://sites.google.com/a/mammatustech.com/mammatusmain/kafka-architecture/4-kafka-detailed-archite ...

  6. Android源码分析 - Framework层的Binder(客户端篇)

    开篇 本篇以aosp分支android-11.0.0_r25作为基础解析 我们在之前的文章中,从驱动层面分析了Binder是怎样工作的,但Binder驱动只涉及传输部分,待传输对象是怎么产生的呢,这就 ...

  7. JDK源码分析——Java的SPI机制分析与实战

    重点提示:在我博客中的所有的源码分析的实例,我都将会放到github上,感兴趣的朋友可以下载下来调试运行,我相信还是可以有所收获的.我的目的是让所有读到我博客的朋友都可以了解到有价值的东西,学习到ja ...

  8. java类加载机制为什么双亲委派_[五]类加载机制双亲委派机制 底层代码实现原理 源码分析 java类加载双亲委派机制是如何实现的...

    Launcher启动类 本文是双亲委派机制的源码分析部分,类加载机制中的双亲委派模型对于jvm的稳定运行是非常重要的不过源码其实比较简单,接下来简单介绍一下我们先从启动类说起有一个Launcher类 ...

  9. [转]php与memcached服务器交互的分布式实现源码分析[memcache版]

    原文链接:http://www.cnblogs.com/luckcs/articles/2619846.html 前段时间,因为一个项目的关系,研究了php通过调用memcache和memcached ...

最新文章

  1. LiveVideoStackCon 2020北京站-售票通道关闭倒计时1天
  2. 分析ip流量的python脚本
  3. C89,C99: C数组结构体联合体快速初始化
  4. java 蓝桥杯算法提高 成绩排序2
  5. 毛绒材质渲染_零基础如何用OCtane做一只毛绒绒的皮卡丘?
  6. linux下mysql 8.0忘记密码后重置密码
  7. 雷军:程序员如何成功创业?
  8. 29.TCP/IP 详解卷1 --- 网络文件系统
  9. Spring入门之IOC
  10. win7 ASP.NET 2.0 部署
  11. 分享一个奇葩SM2258XT板子(100-H00112581-590)没有CE跳线,只有CE飞线,顺便量产开卡
  12. linux setlocale函数,linux setlocale用法
  13. RuntimeError: The size of tensor a (4) must match the size of tensor b (3)
  14. php制作国旗头像图片,不要再@微信官方了,自己动手一秒制作国旗头像
  15. 发布jar包至maven本地库及私服
  16. Wox主题样式基础的自定义
  17. 推荐系统的PMF - 概率矩阵分解和协同过滤
  18. 怎么在图片中添加表格?
  19. 阿里旺旺登陆提示超时
  20. 阿里云Ubuton开MCJava服务器_每小时不到1元,弹性计算服务按流量缴费

热门文章

  1. 揭明星工作室待遇:助理3000经纪人30万
  2. Ping和traceroute的原理
  3. ubuntu中文输入法输入不了中文
  4. Windows留后门--教程(二)——Windows计划任务后门
  5. Symantec Ghost Solution Suite简介
  6. RH850从0搭建Autosar开发环境【1】- 如何创建Davinci Configurator配置工程
  7. 蓝牙BLEBLEcc2540开启广播的过程
  8. 我对ML和DL的看法
  9. 30岁转行程序员晚了吗?分享30岁转行的经历
  10. .net and oracle