返回介绍

11.5 在 JVM 中编写 HDFS 脚本

发布于 2025-04-22 19:57:21 字数 3071 浏览 0 评论 0 收藏

在开发 Hadoop 应用程序时,需要经常与 HDFS 交互。作为开始,最常见的方法是使用 HDFS 命令行 Shell。例如下面的命令可获取目录内的文件清单:

P170

这在初始阶段足以满足需求,但是在编写 Hadoop 应用程序时,通常需要执行一连串更复杂的文件系统操作命令。例如,测试目录是否存在,如果存在则将它删除并将一些新的文件复制进去。作为一个 Java 开发者,你可能会觉得将这个功能加到 bash 脚本中去是一种落后的方法。或许可以使用程序来做这件事,是吗?好消息是:是的,可使用 HDFS 文件系统 API 来完成,坏消息是 Hadoop 文件系统 API 并不是很易用,它会抛出已检查异常并要求我们为它的诸多方法构建 Path 实例作为参数,这会让调用结构变得冗长和笨拙。此外,Hadoop 文件系统 API 并没有提供太多在命令行中可以使用的高级方法,如 test 与 chmod。

Spring for Apache Hadoop 在这中间提供了辅助功能,它对 Hadoop 的 FileSystem 类进行了封装,从而可以接受 String 类型的参数,而不是 Path 类型的参数。更重要的是,它提供了一个 FsShell 类用以模仿命令行 Shell 的功能,这就意味着可用编程的方式来使用它。FsShell 方法所返回的对象或集合可以进行查看也能够以编码的方式来使用,而不是直接将信息输出到控制台上。FsShell 类也可以跟 JVM 脚本语言结合,这样就可以继续使用脚本风格的交互模型,但增加了 JRuby、Jython 或 Groovy 的功能以取代 bash。示例 11-23 在 Groovy 脚本中使用 FsShell。

示例 11-23 定义一个可执行的 Groovy 脚本

P188a

<script/>元素用于创建一个 FsShell 实例,它会通过变量名 fsh 隐式地传入 Groovy 脚本之中。Groovy 脚本如示例 11-24 所示。

示例 11-24 在 HDFS 中使用的 Groovy 脚本

P188b

还有其他的选项可以用来控制脚本何时执行以及求值的方式。如果不想在启动时执行脚本,需在 script 标签的元素中设置 run-at-startup = "false"。如果想要脚本在文件系统中被更改时重新执行,需在 script 标签的元素中设置 evaluate = "IF_MODIFIED"。

也可以将要执行脚本参数化,传入由 Spring 的属性占位符功能所定义的参数,如示例 11-25 所示。

示例 11-25 配置参数化的 Groovy 脚本来使用 HDFS

P188c

属性文件 hadoop.properties 以及 copy-files.groovy 分别如示例 11-26 与示例 11-27 所示。

示例 11-26 包含 HDFS 脚本变量的属性文件

P189a

Spring for Apache Hadoop 还提供了一个 PathUtils 类,在创建基于时间命名的目录路径时它非常有用。调用静态的 format 方法之后,会生成一个以时间命名的路径,它会基于目前的日期,并使用 java.util.Formatter 的约定来对时间进行格式化。可以在 Java 中使用这个类,同时也可以在配置属性中通过 Spring 的表达式语言即 SpEL( http://docs.spring.io/spring/docs/current/spring-framework-reference/html/expressions.html )来引用它。SpEL 的语法类似 Java,它的表达式通常只是一行要求值的代码。在这里它不是使用语法${...}来引用变量,而是以语法#{...}的形式来执行表达式。在 SpEL 中,特殊的“T”运算符用来指定一个 java.lang.Class 实例,我们可以用“T”运算符调用静态方法。

示例 11-27 以参数化的 Groovy 脚本使用 HDFS

P189b

FsShell 可以很容易地在 Java 或 JVM 脚本语言中使用 HDFS Shell 操作,与之类似,org.springframework.data.hadoop.fs.DistCp 也可以让我们很容易地使用 Hadoop 命令行的 distcp 操作。distcp 工具类的用途是在单一的 Hadoop 集群或集群之间复制大量的文件,并且利用 Hadoop 本身以分布式的方式执行复制。distcp 变量会隐式地暴露到脚本之中,如示例 11-28 所示,在这个示例中,脚本内嵌于<hdp:script/>元素之中,而不是位于独立的文件中。

示例 11-28 在 Groovy 脚本内使用 distcp

P189c

在这个例子中,Groovy 脚本内嵌于 XML 之中,而不是引用一个外部的文件。值得注意的是,可以使用 Spring 的属性占位符功能在脚本中引用如${src}和${dst}这样的变量,从而实现脚本参数化。

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。