CentOS 8 安装 Apache DataFu 指南
面向 CentOS 8 服务器的 Apache DataFu 集成使用指南,讲解安装 JDK 与 Maven、引入依赖、解析与版本验证、最小示例的编译运行回显,以及卸载与缓存清理的完整流程,并附常见问题排查。
CentOS 8 安装 Apache DataFu 指南
Apache DataFu 是 Apache 基金会旗下面向 Hadoop 生态的 Java 库集合,提供哈希、采样、集合运算、统计等一批可直接在 Pig / Spark / 普通 Java 工程中复用的工具类与 UDF。它属于「库」形态,没有独立守护进程,所谓「安装」实质是把依赖引入到自己的工程中并完成编译、运行验证。本文以 CentOS Linux 8 服务器为目标,给出从系统准备、依赖引入到最小示例运行、卸载清理的完整流程。
一、前置条件
1.1 系统与硬件要求
- 操作系统:CentOS Linux 8(本文实测环境为 CentOS Linux 8,内核 6.8.0)。
- CPU / 内存:单核 1 GB 内存即可完成本文全部步骤;编译与运行 DataFu 示例建议 JVM 堆内存限制在 256–512 MB(本文示例统一使用
-Xmx384m)。 - 磁盘:预留 1 GB 以上用于 JDK、Maven、Maven 本地仓库(
~/.m2)。 - 权限:需要以 root 或具备 sudo 权限的账号执行安装。
1.2 网络与仓库要求
- 能访问软件源(本文实测时 CentOS Linux 8 的 AppStream / BaseOS 源可正常
dnf makecache)。 - 能访问 Maven 中央仓库
https://repo1.maven.org/maven2/以下载 DataFu 依赖。 - 若内网无法直连公网,需配置可用的本地/代理仓库镜像,或提前把依赖放入私服。
1.3 版本对照
| 组件 | 本文实测版本 |
|---|---|
| 操作系统 | CentOS Linux 8 |
| JDK | JDK 8(1.8.0_312)/ JDK 11(11.0.13,均已安装) |
| Maven | 3.5.4(Red Hat 构建) |
| Apache DataFu | datafu-pig 1.6.1 |
说明:DataFu 兼容 JDK 8 与 JDK 11。本文在 CentOS 8 上以默认的 JDK 8 完成编译与运行验证,JDK 11 同样可用。
二、安装 JDK 与 Maven
2.1 刷新 DNF 源
dnf makecache
正常回显(截取):
CentOS Linux 8 - AppStream 209 B/s | 4.3 kB 00:21
CentOS Linux 8 - BaseOS 627 B/s | 3.9 kB 00:06
Metadata cache created.
若默认源不可用,可改用阿里云等 vault 源替换 /etc/yum.repos.d/ 下的 CentOS-*.repo 中 mirrorlist 为 baseurl,再重新执行 dnf makecache。
2.2 安装 JDK
dnf install -y java-11-openjdk-devel
如需 JDK 8:
dnf install -y java-1.8.0-openjdk-devel
2.3 安装 Maven
dnf install -y maven
2.4 版本验证
java -version
mvn -v
真实回显:
openjdk version "1.8.0_312"
OpenJDK Runtime Environment (build 1.8.0_312-b07)
OpenJDK 64-Bit Server VM (build 25.312-b07, mixed mode)
Apache Maven 3.5.4 (Red Hat 3.5.4-5)
Maven home: /usr/share/maven
Java version: 1.8.0_312, vendor: Red Hat, Inc., runtime: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.312.b07-2.el8_5.x86_64/jre
OS name: "linux", version: "6.8.0", arch: "amd64", family: "unix"
安装结果确认:
rpm -qa | grep -E '^java-11-openjdk-devel|^maven-'
java-11-openjdk-devel-11.0.13.0.8-4.el8_5.x86_64
maven-3.5.4-5.module_el8.0.0+39+6a9b6e22.noarch
三、引入 Apache DataFu 依赖
3.1 关于坐标(重要)
在 Maven 中央仓库 https://repo1.maven.org/maven2/org/apache/datafu/ 下,实际可用的构件为:
datafu-pig/ datafu-hourglass/
datafu-spark_2.11/ datafu-spark_2.12/
不存在 org.apache.datafu:datafu 这个「核心库」构件。DataFu 的核心工具类与 Pig UDF(datafu.pig.*:哈希、采样、集合、统计、工具等)全部打包在 datafu-pig 中,因此 datafu-pig 即是事实上的核心依赖。各构件最新发布版本(实测回显):
| 坐标 | latest / release |
|---|---|
org.apache.datafu:datafu-pig | 1.6.1 |
org.apache.datafu:datafu-hourglass | 1.6.1 |
org.apache.datafu:datafu-spark_2.12 | 2.1.0 |
3.2 创建 Maven 工程
mkdir -p /root/datafu-lab/src/main/java/demo
cd /root/datafu-lab
3.3 Maven 坐标引入(pom.xml)
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>demo</groupId>
<artifactId>datafu-lab</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.datafu</groupId>
<artifactId>datafu-pig</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.apache.pig</groupId>
<artifactId>pig</artifactId>
<version>0.17.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.7</version>
</dependency>
</dependencies>
</project>
关键点(实测):
datafu-pig声明 Pig / Hadoop 为 provided 作用域,不会传递引入。若要在普通 Java 工程中直接调用 UDF,必须自行补充pig与hadoop-common(UDF 依赖org.apache.pig.data.Tuple,而 Pig 的Tuple又继承org.apache.hadoop.io.WritableComparable,缺少 hadoop-common 会报cannot access org.apache.hadoop.io.WritableComparable)。若仅在 Hadoop 集群里运行、集群本身已提供 Pig/Hadoop,则应把这两项改为provided,避免与集群版本冲突。
3.4 Gradle 方式引入
等价的 Gradle 声明如下,适用于使用 Gradle 构建的工程:
dependencies {
implementation 'org.apache.datafu:datafu-pig:1.6.1'
// 在独立 Java 工程中直接调用 UDF 时按需补充:
implementation 'org.apache.pig:pig:0.17.0'
implementation 'org.apache.hadoop:hadoop-common:2.7.7'
}
只做 Pig 脚本运行、由集群提供运行时的工程,可写成:
dependencies {
compileOnly 'org.apache.datafu:datafu-pig:1.6.1'
}
3.5 依赖解析验证
mvn -q -B dependency:build-classpath -Dmdep.outputFile=cp.txt
回显中会包含 datafu-pig-1.6.1.jar、pig-0.17.0.jar 等条目,说明依赖已成功解析到本地仓库 ~/.m2/repository/org/apache/datafu/。
四、版本验证与最小示例
4.1 依赖树确认
mvn -B dependency:tree
关键回显:
[INFO] demo:datafu-lab:jar:1.0
[INFO] +- org.apache.datafu:datafu-pig:jar:1.6.1:compile
[INFO] +- org.apache.pig:pig:jar:0.17.0:compile
[INFO] | +- commons-cli:commons-cli:jar:1.2:compile
[INFO] | +- commons-codec:commons-codec:jar:1.4:compile
4.2 最小示例源码
文件 src/main/java/demo/DataFuDemo.java:
package demo;
import org.apache.pig.data.BagFactory;
import org.apache.pig.data.DataBag;
import org.apache.pig.data.Tuple;
import org.apache.pig.data.TupleFactory;
import datafu.pig.hash.MD5;
import datafu.pig.hash.SHA;
import datafu.pig.util.Base64Encode;
import datafu.pig.sampling.ReservoirSample;
public class DataFuDemo {
public static void main(String[] args) throws Exception {
TupleFactory tf = TupleFactory.getInstance();
BagFactory bf = BagFactory.getInstance();
MD5 md5 = new MD5();
System.out.println("MD5(apache-datafu) = " + md5.exec(tf.newTuple("apache-datafu")));
SHA sha = new SHA("256");
System.out.println("SHA-256(apache-datafu) = " + sha.exec(tf.newTuple("apache-datafu")));
Base64Encode b64 = new Base64Encode();
System.out.println("Base64Encode(datafu) = " + b64.exec(tf.newTuple("datafu")));
ReservoirSample rs = new ReservoirSample("2");
DataBag input = bf.newDefaultBag();
for (int i = 1; i <= 10; i++) {
Tuple row = tf.newTuple(1);
row.set(0, i);
input.add(row);
}
Tuple group = tf.newTuple(1);
group.set(0, input);
rs.accumulate(group);
DataBag sampled = rs.getValue();
StringBuilder sb = new StringBuilder();
for (Tuple t : sampled) {
if (sb.length() > 0) sb.append(",");
sb.append(t.get(0));
}
System.out.println("ReservoirSample(2 of 1..10) = [" + sb + "] size=" + sampled.size());
}
}
易错点:
ReservoirSample.accumulate(Tuple)内部会对传入元组的第 0 个字段做(DataBag)转换并逐个抽样;TupleFactory.newTuple(int)的语义是「创建指定字段数的空元组」,若写成newTuple(i)传入整数会得到 size=i 的全 null 元组,必须写newTuple(1)后set(0, 值)。
4.3 编译、运行与真实回显
cd /root/datafu-lab
mvn -B compile
java -Xmx384m -cp "target/classes:$(cat cp.txt)" demo.DataFuDemo
编译回显(截取):
[INFO] Compiling 1 source file to /root/datafu-lab/target/classes
[INFO] BUILD SUCCESS
运行回显:
MD5(apache-datafu) = f3faa986c556bc49f4131c987f22d04a
SHA-256(apache-datafu) = 07ee215182b6749bc26d1afa300da5f2bf1833d8f0c5396e56a2f36110dafc56
Base64Encode(datafu) = ZGF0YWZ1
ReservoirSample(2 of 1..10) = [6,10] size=2
MD5 / SHA-256 / Base64 输出确定且与 Ubuntu 22.04 机器一致;
ReservoirSample使用随机打分器,每次运行抽出的元素不同(样本数恒为 2),属正常随机抽样。
4.4 打包为可分发 jar
mvn -B package
ls -l target/*.jar
-rw-r--r-- 1 root root 3305 ... target/datafu-lab-1.0.jar
五、卸载与清理
5.1 移除工程依赖
删除工程中 pom.xml 里对应的 <dependency> 节点(datafu-pig / pig / hadoop-common)后执行:
mvn -B clean
即可清除 target/ 下的编译产物。
5.2 清理本地仓库缓存
rm -rf ~/.m2/repository/org/apache/datafu
如需彻底清理全部依赖缓存(会影响其它工程):
rm -rf ~/.m2/repository
5.3 卸载 JDK 与 Maven
dnf remove -y java-11-openjdk-devel maven
dnf autoremove -y
确认:
which java mvn || echo "已卸载"
java -version # 若仍有其它 JDK,则显示剩余版本
注意:
datafu-pig仅作为依赖被下载到~/.m2,不会向系统安装任何文件或服务;卸载系统软件包不影响业务工程源码。
六、常见问题排查
6.1 编译报 cannot access org.apache.hadoop.io.WritableComparable
Q1: 引入 datafu-pig 后编译示例为何提示找不到 org.apache.hadoop.io.WritableComparable?
A: 因为 DataFu 的 UDF 依赖 Pig 的 Tuple,而 Tuple 继承自 Hadoop 的 WritableComparable,且 datafu-pig 把 Pig/Hadoop 标为 provided 不传递。解决办法是在 pom 中显式加入 org.apache.hadoop:hadoop-common(本文实测使用 2.7.7)。
6.2 找不到 org.apache.datafu:datafu
Q2: 按 org.apache.datafu:datafu:<ver> 写依赖为何解析失败?
A: 中央仓库没有 datafu 这个核心构件(实测确认)。核心类在 datafu-pig 中,请使用 org.apache.datafu:datafu-pig:1.6.1。
6.3 采样结果每次不同
Q3: 运行示例时 ReservoirSample 输出元素每次都不一样,是异常吗?
A: 不是。ReservoirSample 默认使用随机打分器 PureRandomScoreGenerator,抽样具有随机性,样本数固定而元素随机,属预期行为。