- 内容提要
- 序
- 前言
- 第一部分 背景知识
- 第 1 章 Spring Data 项目
- 第 2 章 Repository:便利的数据访问层
- 第 3 章 使用 Querydsl 实现类型安全的查询
- 第二部分 关系型数据库
- 第 4 章 JPA Repository
- 第 5 章 借助 Querydsl SQL 实现类型安全的 JDBC 编程
- 第三部分 NoSQL
- 第 6 章 MongoDB: 文档存储
- 第 7 章 Neo4j:图数据库
- 第 8 章 Redis:键/值存储
- 第四部分 快速应用开发
- 第 9 章 使用 Spring Roo 实现持久层
- 第 10 章 REST Repository 导出器
- 第五部分 大数据
- 第 11 章 Spring for Apache Hadoop
- 第 12 章 使用 Hadoop 分析数据
- 第 13 章 使用 Spring Batch 和 Spring Integration 创建大数据管道
- 第六部分 数据网格
- 第 14 章 分布式数据网格:GemFire
- 关于封面
11.5 在 JVM 中编写 HDFS 脚本
在开发 Hadoop 应用程序时,需要经常与 HDFS 交互。作为开始,最常见的方法是使用 HDFS 命令行 Shell。例如下面的命令可获取目录内的文件清单:
这在初始阶段足以满足需求,但是在编写 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 脚本
<script/>元素用于创建一个 FsShell 实例,它会通过变量名 fsh 隐式地传入 Groovy 脚本之中。Groovy 脚本如示例 11-24 所示。
示例 11-24 在 HDFS 中使用的 Groovy 脚本
还有其他的选项可以用来控制脚本何时执行以及求值的方式。如果不想在启动时执行脚本,需在 script 标签的元素中设置 run-at-startup = "false"。如果想要脚本在文件系统中被更改时重新执行,需在 script 标签的元素中设置 evaluate = "IF_MODIFIED"。
也可以将要执行脚本参数化,传入由 Spring 的属性占位符功能所定义的参数,如示例 11-25 所示。
示例 11-25 配置参数化的 Groovy 脚本来使用 HDFS
属性文件 hadoop.properties 以及 copy-files.groovy 分别如示例 11-26 与示例 11-27 所示。
示例 11-26 包含 HDFS 脚本变量的属性文件
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
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
在这个例子中,Groovy 脚本内嵌于 XML 之中,而不是引用一个外部的文件。值得注意的是,可以使用 Spring 的属性占位符功能在脚本中引用如${src}和${dst}这样的变量,从而实现脚本参数化。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论