Ubuntu 22.04 安装 Apache Fluo 2.0.0 指南

在 Ubuntu 22.04.5 上从官方二进制包安装 Apache Fluo 2.0.0,完整覆盖 Hadoop 3.3.6 HDFS、ZooKeeper 3.8.4、Accumulo 2.1.0 依赖栈搭建、lib/fetch.sh 依赖补齐、fluo init 应用初始化、systemd 托管与 Java 客户端读写验证,含 JVM 堆内存限制与 10 个常见问题实测排障

Apache FluoFluoApache大数据分布式HadoopZooKeeperAccumuloJava安装部署Ubuntu 22.042026/10/14

Ubuntu 22.04 安装 Apache Fluo 2.0.0 指南

目标:在单台 Ubuntu 22.04.5 服务器上从官方二进制包安装 Apache Fluo 2.0.0,并搭建其完整依赖栈(Hadoop 3.3.6 HDFS + ZooKeeper 3.8.4 + Accumulo 2.1.0),完成 Fluo 应用初始化、systemd 托管、Java 客户端事务写入与扫描读取验证。Fluo 发行包本身仅约 900KB,Accumulo/Hadoop/ZooKeeper 依赖需通过 lib/fetch.sh 补齐——这是 Fluo 安装与其他大数据组件最大的不同,本文将完整展示全过程。全文命令均在 Ubuntu 22.04.5(x86_64)环境实测通过。

一、环境信息

项目值
操作系统Ubuntu 22.04.5 LTS(x86_64)
主机名node1.fluo.example(/etc/hosts 已做 IP 映射)
Fluo 版本2.0.0(fluo-2.0.0-bin.tar.gz,约 900KB)
Accumulo 版本2.1.0(accumulo-2.1.0-bin.tar.gz,约 38MB)
Hadoop 版本3.3.6(hadoop-3.3.6.tar.gz,约 697MB)
ZooKeeper 版本3.8.4(apache-zookeeper-3.8.4-bin.tar.gz,约 14MB)
JDK 版本OpenJDK 11.0.32.1
安装目录/opt/fluo-2.0.0、/opt/accumulo-2.1.0、/opt/hadoop-3.3.6、/opt/apache-zookeeper-3.8.4-bin
数据目录/opt/hadoop-data(HDFS NameNode/DataNode)、/opt/zookeeper-data(ZK)
HDFS 逻辑路径/accumulo(Accumulo 数据)、/fluo(Fluo 应用数据)
端口HDFS RPC 9000、NameNode UI 9870、ZooKeeper 2181、Accumulo Monitor 9995、Fluo Oracle 6850
服务管理Fluo 用 systemd(fluo-oracle.service、fluo-worker.service);HDFS/ZK/Accumulo 用自带脚本

二、前置条件

本节安装 Fluo 运行所需的 JDK、SSH 与基础工具。Fluo 2.0.0 是 Java 11 编写的分布式应用:客户端与 Oracle/Worker 进程需要 JDK;Hadoop 的启停脚本通过 SSH 连接本机拉起进程,因此需要 SSH 免密;Fluo 依赖补齐脚本需要 Maven。

2.1 安装 JDK 11 与基础工具

# 安装 OpenJDK 11 与基础工具(wget/tar/ssh 用于下载解压与 Hadoop 启停)
apt-get update
apt-get install -y openjdk-11-jdk wget tar openssh-client openssh-server maven

⚠️ 注意:maven 是第九章 lib/fetch.sh ahz 补齐 Accumulo/Hadoop/ZooKeeper 依赖的必需工具,务必在此一并安装。

验证 JDK 版本:

java -version

实测输出:

openjdk version "11.0.32.1" 2026-08-18
OpenJDK Runtime Environment (build 11.0.32.1+1-post-1ubuntu1-22.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 11.0.32.1+1-post-1ubuntu1-22.04-Ubuntu, mixed mode, sharing)

2.2 设置主机名与 /etc/hosts

Accumulo 与 Fluo 的进程发现依赖主机名,将本机主机名设为可解析的 FQDN:

# 设置主机名(按实际规划修改)
hostnamectl set-hostname node1.fluo.example

编辑 /etc/hosts,把本机 IP 与主机名映射(IP 按服务器实际地址填写):

127.0.0.1       localhost
::1             localhost ip6-localhost ip6-loopback
172.17.0.4      node1.fluo.example node1

验证主机名解析:

hostname

实测输出:

node1.fluo.example

2.3 配置 SSH 免密登录

Hadoop 的 start-dfs.sh/stop-dfs.sh 默认通过 SSH 连接节点执行命令,即使单机也需要本机 SSH 免密:

# 生成密钥对(无口令)
ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa
# 将公钥写入本机 authorized_keys
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
# 首次连接记录本机 host key(避免脚本交互卡住)
ssh -o StrictHostKeyChecking=accept-new localhost true

验证免密(不提示输密码即成功):

ssh localhost hostname

实测输出:

node1.fluo.example

💡 说明:Hadoop 集群脚本底层用 pdsh 并行执行远程命令,单机场景若遇到 pdsh: connect: Connection refused,见「十三、常见问题」Q2。

三、版本选型说明

Fluo 是构建在 Accumulo 之上的分布式事务键值存储,其版本与依赖栈强绑定。选型对照如下:

组件本文版本选择理由
Apache Fluo2.0.0Apache 官方归档当前稳定版,要求 Accumulo 2.1.x
Apache Accumulo2.1.0Fluo 2.0.0 官方适配的 Accumulo 2.x 系列
Apache Hadoop3.3.6Hadoop 3.x 稳定版,提供 Fluo 所需的 HDFS 存储
Apache ZooKeeper3.8.43.8 稳定版,为 Fluo/Accumulo 提供协调服务
JDKOpenJDK 11Fluo 2.0.0 与 Accumulo 2.1.0 均以 Java 11 为基准编译

💡 说明:Fluo 2.0.0 的二进制发行包不含 Accumulo、Hadoop、ZooKeeper 的 jar(这就是它只有 900KB 的原因)。运行时依赖有两种补齐方式,决定了第九章两种安装方案的差异:

方式命令原理适用场景
A 在线补依赖lib/fetch.sh ahz用 Maven 从中央仓库下载指定版本的 Accumulo/Hadoop/ZK jar 到 lib/ahz/服务器可访问 Maven 中央仓库
B 复用本机安装fluo-env.sh 扫描系统安装目录直接引用已安装的 Accumulo/Hadoop/ZK 的 jar三者均已在本机安装且版本匹配

本文实际采用「方式 A(fetch.sh ahz)」:依赖版本在命令行显式指定,与本机安装版本解耦,行为最可控。

四、下载安装包与校验

本章下载全部 4 个发行包。Hadoop 3.3.6 体量大,优先使用国内镜像;其余三个包从 Apache 官方归档下载。

4.1 创建下载目录并下载

mkdir -p /opt/dl && cd /opt/dl
# Hadoop 3.3.6(华为云镜像,直连速度快)
wget https://mirrors.huaweicloud.com/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz
# ZooKeeper 3.8.4(Apache 官方归档)
wget https://archive.apache.org/dist/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz
# Accumulo 2.1.0(Apache 官方归档)
wget https://archive.apache.org/dist/accumulo/2.1.0/accumulo-2.1.0-bin.tar.gz
# Fluo 2.0.0(Apache 官方归档)
wget https://archive.apache.org/dist/fluo/fluo/2.0.0/fluo-2.0.0-bin.tar.gz

下载完成后核对文件大小:

ls -lh /opt/dl/*.tar.gz

实测输出:

-rw-r--r-- 1 root root  38M Nov  1  2022 accumulo-2.1.0-bin.tar.gz
-rw-r--r-- 1 root root  14M Feb 12  2024 apache-zookeeper-3.8.4-bin.tar.gz
-rw-r--r-- 1 root root 900K Apr 18  2023 fluo-2.0.0-bin.tar.gz
-rw-r--r-- 1 root root 697M Jun 25  2023 hadoop-3.3.6.tar.gz

4.2 SHA-512 校验

sha512sum hadoop-3.3.6.tar.gz apache-zookeeper-3.8.4-bin.tar.gz accumulo-2.1.0-bin.tar.gz fluo-2.0.0-bin.tar.gz

实测输出(哈希应与 Apache 官方公布的 .sha512 文件一致):

de3eaca2e0517e4b569a88b63c89fae19cb8ac6c01ff990f1ff8f0cc0f3128c8e8a23db01577ca562a0e0bb1b4a3889f8c74384e609cd55e537aada3dcaa9f8a  hadoop-3.3.6.tar.gz
4d85d6f7644d5f36d9c4d65e78bd662ab35ebe1380d762c24c12b98af029027eee453437c9245dbdf2b9beb77cd6b690b69e26f91cf9d11b0a183a979c73fa43  apache-zookeeper-3.8.4-bin.tar.gz
9bbc4defc114013f145e9e9fdd08683c842a29faaa01ea6e80555549a6aecef86ee6657cce23183b411a64c31123db682a6944e2825eef83c76fb5a91620235f  accumulo-2.1.0-bin.tar.gz
79c4706ca18cbbbf2883f7371a36529de8182be7afd5f3cbf70c4bd9d6c577d63db90d1f17cfdb5a3108dbe25b5bc5423a5936f1505d6b1dba7ff96a0fbcaf7e  fluo-2.0.0-bin.tar.gz

五、安装 Hadoop HDFS(单节点)

Fluo 的应用数据(快照文件、jar 等)存放在 HDFS 上,因此先搭建一个单节点 HDFS。本章按「解压 → 配置 → 格式化 → 启动 → 验证」完成。

5.1 解压安装

cd /opt
tar -xzf /opt/dl/hadoop-3.3.6.tar.gz -C /opt/
ls -ld /opt/hadoop-3.3.6

实测输出:

drwxr-xr-x 9 root root 4096 Jun 25  2023 /opt/hadoop-3.3.6

5.2 配置环境变量

统一写入 /etc/profile.d/bigdata.sh,后续各组件的环境变量也集中在此:

cat > /etc/profile.d/bigdata.sh <<'EOF'
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
export HADOOP_HOME=/opt/hadoop-3.3.6
export ZOOKEEPER_HOME=/opt/apache-zookeeper-3.8.4-bin
export ACCUMULO_HOME=/opt/accumulo-2.1.0
export PATH=$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$ZOOKEEPER_HOME/bin:$ACCUMULO_HOME/bin:$PATH
EOF
source /etc/profile.d/bigdata.sh

5.3 配置 hadoop-env.sh

Hadoop 启动脚本不加载 /etc/profile.d,且默认不允许以 root 运行 HDFS 进程,必须在 hadoop-env.sh 中显式声明:

cat >> /opt/hadoop-3.3.6/etc/hadoop/hadoop-env.sh <<'EOF'
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
export HDFS_NAMENODE_OPTS="-Xms256m -Xmx512m"
export HDFS_DATANODE_OPTS="-Xms256m -Xmx512m"
export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root
export PDSH_RCMD_TYPE=ssh
EOF

逐项说明:

  • JAVA_HOME:Hadoop 通过 SSH 启动进程时是非登录 shell,读不到 profile 里的环境变量,必须在此显式指定;
  • HDFS_NAMENODE_OPTS/HDFS_DATANODE_OPTS:NameNode 与 DataNode 堆内存限制在 256–512MB(演示/小型环境推荐值);
  • HDFS_NAMENODE_USER/HDFS_DATANODE_USER/HDFS_SECONDARYNAMENODE_USER:以 root 运行 HDFS 进程时必需,否则 start-dfs.sh 报 ERROR: but there is no HDFS_NAMENODE_USER defined;
  • PDSH_RCMD_TYPE=ssh:指定 pdsh 使用 ssh 作为远程执行方式。

5.4 配置 core-site.xml 与 hdfs-site.xml

cat > /opt/hadoop-3.3.6/etc/hadoop/core-site.xml <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://localhost:9000</value>
  </property>
  <property>
    <name>hadoop.tmp.dir</name>
    <value>/opt/hadoop-data/tmp</value>
  </property>
</configuration>
EOF
cat > /opt/hadoop-3.3.6/etc/hadoop/hdfs-site.xml <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <property>
    <name>dfs.replication</name>
    <value>1</value>
  </property>
  <property>
    <name>dfs.namenode.name.dir</name>
    <value>file:///opt/hadoop-data/namenode</value>
  </property>
  <property>
    <name>dfs.datanode.data.dir</name>
    <value>file:///opt/hadoop-data/datanode</value>
  </property>
</configuration>
EOF
mkdir -p /opt/hadoop-data/tmp /opt/hadoop-data/namenode /opt/hadoop-data/datanode

逐项说明:

  • fs.defaultFS:HDFS 入口地址,Accumulo 与 Fluo 的配置里都会引用这个地址;
  • dfs.replication=1:单机没有第二台 DataNode,副本数必须是 1,否则写入报 Replication 1 is less than required min 之外的异常(多余副本无法放置);
  • dfs.namenode.name.dir/dfs.datanode.data.dir:数据落盘目录,显式指定到 /opt/hadoop-data 而不用默认的 /tmp(避免系统清理导致元数据丢失)。

💡 技术拓展:HDFS 单副本之外,生产通常采用「多副本」或「纠删码(Erasure Coding, EC)」保障数据可靠性,对比——

策略原理空间开销恢复速度适用场景
3 副本同一数据写 3 份到不同节点3 倍快(直接拷副本)通用默认、小文件多
纠删码 RS(6,3)数据分 6 条带+3 校验块1.5 倍慢(需计算重建)冷数据、大文件归档
单副本仅 1 份1 倍无自愈能力单机测试

本文是单机安装,实际采用 dfs.replication=1;生产集群建议 3 副本。

5.5 格式化 NameNode

首次启动前必须格式化(只做一次;重复格式化会清空 HDFS 全部数据):

hdfs namenode -format

实测输出节选(末段;存储目录路径为你的 dfs.namenode.name.dir 配置值):

2026-10-14 12:40:03,842 INFO common.Storage: Storage directory /opt/hadoop-data/namenode has been successfully formatted.
2026-10-14 12:40:03,984 INFO namenode.FSImageFormatProtobuf: Image file /opt/hadoop-data/namenode/current/fsimage.ckpt_0000000000000000000 of size 399 bytes saved in 0 seconds .
2026-10-14 12:40:04,015 INFO namenode.FSNamesystem: Stopping services started for active state
2026-10-14 12:40:04,020 INFO namenode.NameNode: SHUTDOWN_MSG:
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at node1.fluo.example/172.17.0.4
************************************************************/

看到 has been successfully formatted. 即格式化成功。

5.6 启动 HDFS 并验证

start-dfs.sh

实测输出节选(省略了行间的旧变量告警行):

Starting namenodes on [localhost]
Starting datanodes
Starting secondary namenodes [node1.fluo.example]

💡 说明:若设置过旧变量 HADOOP_PREFIX,上述每行前还会出现 WARNING: HADOOP_PREFIX has been replaced by HADOOP_HOME. 提示,属于无害告警,删除该变量即可消除(5.2 的环境变量配置未包含该旧变量,正常情况下不会出现)。

用 jps 确认三个 HDFS 进程:

jps

实测输出节选(此时仅 HDFS 相关进程):

26697 NameNode
26826 DataNode
27077 SecondaryNameNode
27957 Jps

通过 Web UI 二次确认(HTTP 200):

wget -q -O /dev/null http://localhost:9870 && echo "hdfs-9870 HTTP OK"

实测输出:

hdfs-9870 HTTP OK

再看 DataNode 是否存活:

hdfs dfsadmin -report | grep -A3 "Live datanodes"

实测输出:

Live datanodes (1):

Name: 127.0.0.1:9866 (localhost)
Hostname: node1.fluo.example

Live datanodes (1) 说明 NameNode 与 DataNode 已正常握手,HDFS 就绪。

六、安装与启动 ZooKeeper

Fluo 用 ZooKeeper 保存应用配置、Oracle 选主与 Worker 注册信息;Accumulo 也依赖它。单机部署一个 standalone 实例。

6.1 解压安装

tar -xzf /opt/dl/apache-zookeeper-3.8.4-bin.tar.gz -C /opt/
ls -ld /opt/apache-zookeeper-3.8.4-bin

实测输出:

drwxr-xr-x 8 root root 4096 Feb 12  2024 /opt/apache-zookeeper-3.8.4-bin

6.2 配置 zoo.cfg 与堆内存

cat > /opt/apache-zookeeper-3.8.4-bin/conf/zoo.cfg <<'EOF'
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/opt/zookeeper-data
clientPort=2181
maxClientCnxns=60
admin.enableServer=false
4lw.commands.whitelist=ruok,srvr,stat,mntr,conf
EOF
mkdir -p /opt/zookeeper-data
cat > /opt/apache-zookeeper-3.8.4-bin/conf/zookeeper-env.sh <<'EOF'
export ZK_SERVER_HEAP=256
EOF

逐项说明:

  • dataDir:事务日志与快照目录,指定到 /opt/zookeeper-data;
  • clientPort=2181:客户端端口,Accumulo/Fluo 都连这个端口;
  • admin.enableServer=false:关闭 8080 管理端口(单机无需);
  • 4lw.commands.whitelist:放行四字命令(ruok/srvr 等)便于探活;
  • ZK_SERVER_HEAP=256:ZooKeeper JVM 堆固定 256MB。

💡 技术拓展:ZooKeeper 保证一致性的核心是 ZAB 协议,它与另两种常见共识协议的对比——

协议代表系统原理特点适用场景
ZABZooKeeper崩溃可恢复的主备广播+全量/增量同步协调服务、配置元数据
Raftetcd、Consul领导者选举+日志复制,状态机模型清晰通用共识、服务发现
Paxos早期 Chubby/Google 系两阶段提交的纯共识协议,工程实现复杂理论基础、对一致性要求极高的场景

Fluo/Accumulo 直接使用现成的 ZooKeeper(ZAB),无需自行实现共识。

6.3 启动并验证

zkServer.sh start

实测输出:

ZooKeeper JMX enabled by default
Using config: /opt/apache-zookeeper-3.8.4-bin/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
zkServer.sh status

实测输出:

ZooKeeper JMX enabled by default
Using config: /opt/apache-zookeeper-3.8.4-bin/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: standalone

Mode: standalone 与 Client port found: 2181 说明 ZK 服务正常。

七、安装与初始化 Accumulo

Fluo 的数据最终落在 Accumulo 表中,Worker/Oracle 运行在 Accumulo tablet server 之内。本章完成 Accumulo 安装、初始化与启动。

7.1 解压安装

tar -xzf /opt/dl/accumulo-2.1.0-bin.tar.gz -C /opt/
ls -ld /opt/accumulo-2.1.0

实测输出:

drwxr-xr-x 9 root root 4096 Nov  1  2022 /opt/accumulo-2.1.0

7.2 配置 accumulo.properties

cat > /opt/accumulo-2.1.0/conf/accumulo.properties <<'EOF'
## Sets location in HDFS where Accumulo will store data
instance.volumes=hdfs://localhost:9000/accumulo

## Sets location of Zookeepers
instance.zookeeper.host=localhost:2181

## Change secret before initialization. All Accumulo servers must have same secret
instance.secret=q1w2e3r4

## Set to false if 'accumulo-util build-native' fails
tserver.memory.maps.native.enabled=false
EOF

逐项说明:

  • instance.volumes:Accumulo 数据在 HDFS 的根目录,必须与 fs.defaultFS 同一个 HDFS;
  • instance.zookeeper.host:ZooKeeper 地址;
  • instance.secret:所有 Accumulo 服务端共享的实例密钥,生产环境务必修改;
  • tserver.memory.maps.native.enabled=false:关闭原生内存映射库。该开关默认为 true,需要编译 native 库(依赖 gcc),无编译环境时会启动失败(见「十三、常见问题」Q3)。

7.3 配置 accumulo-env.sh

需要显式指定 Hadoop 与 ZooKeeper 的安装路径,并把各服务 JVM 堆限制在 256–512MB。编辑 /opt/accumulo-2.1.0/conf/accumulo-env.sh,确认/修改以下关键行:

HADOOP_HOME="${HADOOP_HOME:-/opt/hadoop-3.3.6}"
HADOOP_CONF_DIR="${HADOOP_CONF_DIR:-${HADOOP_HOME}/etc/hadoop}"
ZOOKEEPER_HOME="${ZOOKEEPER_HOME:-/opt/apache-zookeeper-3.8.4-bin}"

文件末尾的按服务分配堆的 case 分支保持如下(默认值即在此范围):

case "$cmd" in
  manager | master) JAVA_OPTS=('-Xmx512m' '-Xms512m' "${JAVA_OPTS[@]}") ;;
  monitor) JAVA_OPTS=('-Xmx256m' '-Xms256m' "${JAVA_OPTS[@]}") ;;
  gc) JAVA_OPTS=('-Xmx256m' '-Xms256m' "${JAVA_OPTS[@]}") ;;
  tserver) JAVA_OPTS=('-Xmx512m' '-Xms256m' "${JAVA_OPTS[@]}") ;;
  compaction-coordinator) JAVA_OPTS=('-Xmx512m' '-Xms512m' "${JAVA_OPTS[@]}") ;;
  compactor) JAVA_OPTS=('-Xmx256m' '-Xms256m' "${JAVA_OPTS[@]}") ;;
  *) JAVA_OPTS=('-Xmx256m' '-Xms64m' "${JAVA_OPTS[@]}") ;;
esac

7.4 配置客户端连接文件

accumulo-client.properties 供命令行 shell 与后续客户端程序使用:

cat > /opt/accumulo-2.1.0/conf/accumulo-client.properties <<'EOF'
instance.name=accumulo1
instance.zookeepers=localhost:2181
auth.type=password
auth.principal=root
auth.token=q1w2e3r4
EOF

逐项说明:

  • instance.name:初始化时给实例起的名字(7.5 步使用 accumulo1);
  • auth.principal=root + auth.token=q1w2e3r4:以 root 用户、密码 q1w2e3r4 连接(该密码在 7.5 初始化时通过 --password 设置)。

7.5 初始化实例

accumulo init --instance-name accumulo1 --password q1w2e3r4

实测输出节选:

2026-10-14T12:41:08,255 [init.Initialize] INFO : Hadoop Filesystem is hdfs://localhost:9000
2026-10-14T12:41:08,257 [init.Initialize] INFO : Accumulo data dirs are [[hdfs://localhost:9000/accumulo]]
2026-10-14T12:41:08,257 [init.Initialize] INFO : Zookeeper server is localhost:2181
2026-10-14T12:41:08,257 [init.Initialize] INFO : Checking if Zookeeper is available. If this hangs, then you need to make sure zookeeper is running
2026-10-14T12:41:30,996 [init.Initialize] INFO : Created instanceId file hdfs://localhost:9000/accumulo/instance_id/b0ecea40-97d8-48f0-83da-1ec31fdbb562 in hdfs

⚠️ 注意:

  1. --password 是非交互执行的关键;不带该参数时 init 会交互式提示输入 root 密码,脚本化场景读不到输入会报 NullPointerException。
  2. 若 HDFS 的 instance.volumes 目录已被其他实例初始化过,会报 Filesystem is already initialized 错误(实测报错全文见「十三、常见问题」Q10)。
  3. 上面回显中的 UUID(b0ecea40-97d8-48f0-83da-1ec31fdbb562)每次初始化都会随机生成,以你环境的实际值为准。

7.6 启动 Accumulo 并验证

Accumulo 2.1 通过 accumulo-service 管理各服务进程,逐个启动:

accumulo-service manager start

实测输出:

Starting manager on node1.fluo.example
2026-10-14T12:44:50,425 [conf.SiteConfiguration] INFO : Found Accumulo configuration on classpath at /opt/accumulo-2.1.0/conf/accumulo.properties
2026-10-14T12:44:51,216 [fs.VolumeManagerImpl] WARN : dfs.datanode.synconclose set to false in hdfs-site.xml: data loss is possible on hard system reset or power loss
2026-10-14T12:44:51,724 [server.ServerContext] INFO : Attempting to talk to zookeeper
2026-10-14T12:44:51,726 [server.ServerContext] INFO : ZooKeeper connected and initialized, attempting to talk to HDFS
2026-10-14T12:44:51,744 [server.ServerContext] INFO : Connected to HDFS
accumulo-service tserver start

实测输出:

Starting tserver on node1.fluo.example
accumulo-service gc start

实测输出:

Starting gc on node1.fluo.example
accumulo-service monitor start

实测输出:

Starting monitor on node1.fluo.example

⚠️ 注意:Starting manager/tserver/gc/monitor on node1.fluo.example 这类输出只表示进程已提交拉起,服务完全就绪需要数秒到半分钟。若立刻执行后续验证失败,等待后重试。manager 的控制台输出停在 Connected to HDFS 属正常现象(后续日志写入 logs/ 目录)。

用 jps 确认四个 Accumulo 进程(Accumulo 各服务的主类都是 org.apache.accumulo.start.Main,jps 显示为 Main):

jps

实测输出节选:

12448 QuorumPeerMain
27604 Main
27671 Main
27739 Main
27547 Main
26697 NameNode
26826 DataNode
27077 SecondaryNameNode
29001 Jps

其中 4 个 Main 分别为 manager、tserver、gc、monitor。通过 shell 验证实例可用(-np 表示不分页):

accumulo shell -e "tables -np"

实测输出:

Loading configuration from /opt/accumulo-2.1.0/conf/accumulo-client.properties
accumulo.metadata
accumulo.replication
accumulo.root

能列出 accumulo.metadata/accumulo.root 等系统表即实例健康。再确认 Monitor Web UI:

wget -q -O /dev/null http://localhost:9995 && echo "accumulo-9995 HTTP OK"

实测输出:

accumulo-9995 HTTP OK

八、安装 Apache Fluo 2.0.0

前置栈就绪后,本章安装 Fluo 本体:解压 → 补依赖 → 配置 → 初始化应用。

8.1 解压安装

tar -xzf /opt/dl/fluo-2.0.0-bin.tar.gz -C /opt/
ls -ld /opt/fluo-2.0.0

实测输出:

drwxr-xr-x 10 root root 4096 Apr 18  2023 /opt/fluo-2.0.0

发行包关键目录结构:

/opt/fluo-2.0.0/
├── bin/fluo           # 全部 CLI 命令入口
├── conf/
│   ├── fluo-app.properties   # 应用属性模板(init 时用 -p 指向你的副本)
│   ├── fluo-conn.properties  # 实例连接配置
│   ├── fluo-env.sh           # 环境变量与 classpath 装配
│   └── log4j2.properties
├── lib/               # Fluo 自身 jar(fluo-api/fluo-core 等)
│   ├── fetch.sh       # 依赖下载脚本(extra / ahz)
│   └── ahz/           # fetch.sh ahz 下载的 Accumulo/Hadoop/ZK 依赖
└── logs/

8.2 补齐依赖(lib/fetch.sh)

分两步:extra 下载 Fluo 自身的日志等补充依赖;ahz 下载 Accumulo/Hadoop/ZooKeeper 客户端 jar(需要 Maven,见 2.1)。

/opt/fluo-2.0.0/lib/fetch.sh extra

实测输出:

SUCCESS: Dependency exists - /opt/fluo-2.0.0/lib/./log4j/log4j-core-2.19.0.jar
SUCCESS: Dependency exists - /opt/fluo-2.0.0/lib/./log4j/log4j-slf4j2-impl-2.19.0.jar
Done!

NOTE - The dependencies downloaded have been tested with some versions of Hadoop, Zookeeper, and Accumulo.
There is no guarantee they will work with all versions. Fluo chose to defer dependency resolution to as
late as possible in order to make it easier to resolve dependency conflicts.  If you run into a dependency
conflict in your environment, please consider bringing it up on the Fluo dev list.
/opt/fluo-2.0.0/lib/fetch.sh ahz -Daccumulo.version=2.1.0 -Dhadoop.version=3.3.6 -Dzookeeper.version=3.8.4

实测输出节选(Maven 下载过程较长,保留首尾):

[INFO] Scanning for projects...
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/accumulo/accumulo-core/2.1.0/accumulo-core-2.1.0.jar
[INFO] Copying hadoop-client-api-3.3.6.jar to /opt/fluo-2.0.0/lib/ahz/target/../hadoop-client-api-3.3.6.jar
[INFO] Copying netty-transport-native-epoll-4.1.105.Final.jar to /opt/fluo-2.0.0/lib/ahz/target/../netty-transport-native-epoll-4.1.105.Final.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.371 s

💡 说明:首次执行时 Maven 从中央仓库真实下载(耗时数分钟、输出大量 Downloading 行);依赖已在本地 Maven 缓存时则只显示 Copying 行,秒级完成。-Daccumulo.version 等三个参数显式指定依赖版本,与你安装的 Accumulo/Hadoop/ZooKeeper 保持一致。

核对依赖目录:

ls /opt/fluo-2.0.0/lib/ahz | wc -l

实测输出:

49

49 个 jar 即依赖补齐完成(含 accumulo-core-2.1.0.jar、hadoop-client-api-3.3.6.jar、zookeeper-3.8.4.jar 等)。

8.3 配置 fluo-env.sh

编辑 /opt/fluo-2.0.0/conf/fluo-env.sh,共三处改动。

改动一:Hadoop 安装路径(模板默认是占位路径):

export HADOOP_HOME="${HADOOP_HOME:-/opt/hadoop-3.3.6}"

改动二:在 JAVA_OPTS 装配处加上 Fluo 进程堆限制(模板默认无此行):

FLUO_JAVA_OPTS=("-Xms256m" "-Xmx256m")
JAVA_OPTS=("${FLUO_JAVA_OPTS[@]}")

改动三:文件末尾的 classpath 装配调用。模板默认调用 setupClasspathFromSystem(扫描本机 Accumulo/ZK/Hadoop 安装目录拼 classpath);本文采用 8.2 下载好的 lib/ahz 依赖,改为调用 setupClasspathFromLib:

# 模板末尾原为:setupClasspathFromSystem
# 修改为:
setupClasspathFromLib

该函数从模板中原样保留,其实现为:

setupClasspathFromLib(){
  CLASSPATH="$lib/*"
  CLASSPATH="$CLASSPATH:$lib/log4j/*"
  CLASSPATH="$CLASSPATH:$lib/ahz/*"
  export CLASSPATH
}

验证 classpath 装配结果:

fluo classpath | tr ":" "\n" | head -6

实测输出:

/opt/fluo-2.0.0/lib/*
/opt/fluo-2.0.0/lib/log4j/*
/opt/fluo-2.0.0/lib/ahz/*

三行目录与预期一致(fluo classpath 完整输出为分号连接的上述目录串)。

8.4 配置 fluo-conn.properties(实例连接)

编辑 /opt/fluo-2.0.0/conf/fluo-conn.properties,设置 ZooKeeper 连接串:

fluo.connection.zookeepers=localhost:2181/fluo

逐项说明:

  • localhost:2181 指向第六章的 ZooKeeper;
  • chroot 后缀 /fluo 必须带上:Fluo 的全部实例数据存在该 ZK 子目录下,模板注释明确要求「A chroot directory suffix must be specified」,缺省时应用无法初始化;
  • 其余项(fluo.connection.zookeeper.timeout=30000、fluo.connection.retry.timeout.ms=-1 等)保持模板默认即可。

8.5 配置应用属性 myapp.properties

从模板 conf/fluo-app.properties 复制一份应用配置,填写必填项:

cat > /opt/fluo-2.0.0/conf/myapp.properties <<'EOF'
fluo.dfs.root=hdfs://localhost:9000/fluo
fluo.accumulo.instance=accumulo1
fluo.accumulo.user=root
fluo.accumulo.password=q1w2e3r4
fluo.accumulo.table=myapp2
EOF

逐项说明:

  • fluo.dfs.root:Fluo 应用数据在 HDFS 的根目录(第五章 fs.defaultFS 配置的 HDFS + /fluo);
  • fluo.accumulo.instance:第七章初始化的实例名 accumulo1;
  • fluo.accumulo.user/fluo.accumulo.password:与 7.4 客户端配置一致;
  • fluo.accumulo.table:Fluo 数据落地的 Accumulo 表名,必填。模板中该行用花括号变量引用的方式指向应用名,而 Java Properties 不做变量插值,直接沿用模板会导致取值为空、init 报缺少必填属性(见「十三、常见问题」Q4),必须手工落实际值。

8.6 初始化应用

fluo init -a myapp2 -p /opt/fluo-2.0.0/conf/myapp.properties

实测输出:

Initializing Fluo 'myapp2' application using /opt/fluo-2.0.0/conf/myapp.properties
Initialization is complete.

该命令在 HDFS 创建 /fluo/myapp2 目录、在 Accumulo 创建 myapp2 表、在 ZooKeeper 写入应用配置。验证三处产物:

hdfs dfs -ls /

实测输出:

Found 2 items
drwx------   - root supergroup          0 2026-10-14 11:40 /accumulo
drwxr-xr-x   - root supergroup          0 2026-10-14 12:14 /fluo
accumulo shell -e "tables -np"

实测输出:

Loading configuration from /opt/accumulo-2.1.0/conf/accumulo-client.properties
accumulo.metadata
accumulo.replication
accumulo.root
myapp2

/fluo 目录与 myapp2 表均已出现,初始化成功。

九、systemd 托管 Fluo 服务

Fluo 应用由两类进程组成:Oracle(管理时间戳分配与事务回滚)与 Worker(执行观察者逻辑)。本章把两者交给 systemd 托管,实现开机自启与故障自动拉起。

9.1 创建 fluo-oracle.service

cat > /etc/systemd/system/fluo-oracle.service <<'EOF'
[Unit]
Description=Fluo Oracle for application myapp2
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=root
Environment=JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
Environment=PATH=/usr/lib/jvm/java-11-openjdk-amd64/bin:/opt/hadoop-3.3.6/bin:/opt/hadoop-3.3.6/sbin:/opt/apache-zookeeper-3.8.4-bin/bin:/opt/accumulo-2.1.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=/opt/fluo-2.0.0/bin/fluo oracle -a myapp2
SuccessExitStatus=143
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

逐项说明:

  • 两个 Environment= 行注入 JAVA_HOME 与 PATH:systemd 不加载 shell 配置,需要显式指定(Fluo 脚本要找 java 及 Hadoop/ZK/Accumulo 的可执行文件);
  • ExecStart:前台方式启动 Oracle(fluo oracle -a myapp2),由 systemd 直接托管该进程;
  • SuccessExitStatus=143:systemctl stop 时 JVM 收到 SIGTERM 退出码为 143,若不声明会把服务标成 failed(见「十三、常见问题」Q8);
  • Restart=on-failure + RestartSec=5:异常退出 5 秒后自动拉起。

💡 技术拓展:systemd 的自动重启策略对比——

策略行为适用场景
no从不重启(默认)调试、手动管理
on-failure非零退出/信号杀死时重启常规服务(本文采用)
on-success仅正常退出时重启特殊兜底场景
always任何退出都重启必须常驻、允许被手动 stop 后仍拉起的场景需慎用
on-abnormal信号/超时等异常时重启对正常退出码有业务含义的服务

本文采用 on-failure:手动 systemctl stop 不会被强制拉起,异常崩溃又能自愈。

9.2 创建 fluo-worker.service

cat > /etc/systemd/system/fluo-worker.service <<'EOF'
[Unit]
Description=Fluo Worker for application myapp2
After=network-online.target fluo-oracle.service
Wants=network-online.target

[Service]
Type=simple
User=root
Environment=JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
Environment=PATH=/usr/lib/jvm/java-11-openjdk-amd64/bin:/opt/hadoop-3.3.6/bin:/opt/hadoop-3.3.6/sbin:/opt/apache-zookeeper-3.8.4-bin/bin:/opt/accumulo-2.1.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=/opt/fluo-2.0.0/bin/fluo worker -a myapp2
SuccessExitStatus=143
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

说明:After=network-online.target fluo-oracle.service 让 worker 在 oracle 之后启动;其余项与 oracle 单元一致。

9.3 启用并启动服务

systemctl daemon-reload
systemctl enable fluo-oracle

实测输出:

Created symlink /etc/systemd/system/multi-user.target.wants/fluo-oracle.service → /etc/systemd/system/fluo-oracle.service.
systemctl enable fluo-worker

实测输出:

Created symlink /etc/systemd/system/multi-user.target.wants/fluo-worker.service → /etc/systemd/system/fluo-worker.service.
systemctl start fluo-oracle
systemctl start fluo-worker

💡 说明:systemctl start 成功时无任何输出;daemon-reload 与已存在符号链接时重复执行的 enable 同样无输出,均为正常现象。

验证服务状态:

systemctl is-active fluo-oracle

实测输出:

active
systemctl is-active fluo-worker

实测输出:

active
systemctl is-enabled fluo-oracle

实测输出:

enabled
systemctl is-enabled fluo-worker

实测输出:

enabled

查看 Oracle 启动日志确认监听端口:

journalctl -u fluo-oracle --no-pager -o cat | head -6

实测输出:

2026-10-14T12:20:00,712 [oracle.OracleServer] INFO : Leader ID = node1.fluo.example:6850
2026-10-14T12:20:00,721 [oracle.OracleServer] INFO : Listening 0.0.0.0/0.0.0.0:6850
2026-10-14T12:20:00,738 [oracle.OracleServer] INFO : Assumed leadership node1.fluo.example:6850
2026-10-14T12:20:00,739 [oracle.OracleServer] INFO : Current timestamp: 2

9.4 验证应用运行状态

fluo status -a myapp2

实测输出:

RUNNING
fluo list

实测输出:

Fluo instance (localhost:2181/fluo) contains 1 application(s)

Application     Status     # Workers     # Oracles
-----------     ------     ---------     ---------
myapp2          RUNNING        1             1

确认两个 JVM 进程的堆参数确实生效:

jps -lv | grep FluoProgram

实测输出:

28964 org.apache.fluo.command.FluoProgram -Xms256m -Xmx256m -Dfluo.conn.props=/opt/fluo-2.0.0/conf/fluo-conn.properties
28952 org.apache.fluo.command.FluoProgram -Xms256m -Xmx256m -Dfluo.conn.props=/opt/fluo-2.0.0/conf/fluo-conn.properties

-Xms256m -Xmx256m 来自 8.3 中 fluo-env.sh 的 FLUO_JAVA_OPTS,修改堆大小时改那一行并重启服务即可。

十、写入与读取数据验证(Java 客户端)

本章用 Fluo 官方客户端 API 编写一个最小演示程序:开启事务写入 3 行数据、提交,再用 fluo scan 读回,完成端到端验证。

💡 技术拓展:Fluo 提供的是「快照隔离(Snapshot Isolation)」事务,与常见隔离级别的对比——

隔离级别脏读不可重复读幻读说明
Read Uncommitted可能可能可能读到未提交数据
Read Committed不会可能可能只读已提交数据
Snapshot Isolation不会不会可能(写冲突检测兜底)读事务快照;提交时检测写写冲突
Serializable不会不会不会完全串行语义,开销最高

Fluo 事务读取发起时刻的一致性快照、提交时做写写冲突检测,实际采用快照隔离;这也是它区别于直接读写 Accumulo(无事务语义)的核心能力。

10.1 编写演示程序

创建 /opt/demo/FluoWriter.java:

mkdir -p /opt/demo
cat > /opt/demo/FluoWriter.java <<'EOF'
import org.apache.fluo.api.client.FluoClient;
import org.apache.fluo.api.client.FluoFactory;
import org.apache.fluo.api.client.Transaction;
import org.apache.fluo.api.config.FluoConfiguration;
import org.apache.fluo.api.data.Column;

public class FluoWriter {
  public static void main(String[] args) throws Exception {
    FluoConfiguration config = new FluoConfiguration();
    config.setApplicationName("myapp2");
    config.setInstanceZookeepers("localhost:2181/fluo");
    config.setAccumuloInstance("accumulo1");
    config.setAccumuloZookeepers("localhost:2181");
    config.setAccumuloUser("root");
    config.setAccumuloPassword("q1w2e3r4");
    config.setAccumuloTable("myapp2");
    try (FluoClient client = FluoFactory.newClient(config)) {
      try (Transaction tx = client.newTransaction()) {
        tx.set("user:0001", new Column("info","name"), "Alice");
        tx.set("user:0001", new Column("info","age"), "30");
        tx.set("user:0002", new Column("info","name"), "Bob");
        tx.commit();
      }
    }
    System.out.println("3 rows committed");
  }
}
EOF

关键点:

  • setInstanceZookeepers("localhost:2181/fluo") 必须带 chroot /fluo,与 8.4 的 fluo.connection.zookeepers 一致;
  • FluoConfiguration 的各项取值与 8.5 的 myapp.properties 一一对应;
  • 事务内的 tx.set() 在 tx.commit() 成功前对外不可见(快照隔离)。

10.2 编译与运行

编译(fluo-api jar 在发行包 lib/ 中):

cd /opt/demo
javac -cp "/opt/fluo-2.0.0/lib/*" FluoWriter.java
ls -la FluoWriter.class

实测输出:

-rw-r--r-- 1 root root 2095 Oct 14 12:38 FluoWriter.class

运行(classpath 用 fluo classpath 输出 + 演示类目录):

java -cp "$(/opt/fluo-2.0.0/bin/fluo classpath):/opt/demo" FluoWriter

实测输出:

3 rows committed

10.3 扫描验证数据

fluo scan -a myapp2

实测输出:

user:0001 info age      30
user:0001 info name     Alice
user:0002 info name     Bob

三行数据全部读回,行键、列族/列限定符与写入一致,端到端链路(Java 客户端 → Oracle → Worker → Accumulo → HDFS)验证完成。

⚠️ 注意:客户端程序也可以用 fluo exec myapp2 FluoWriter 方式运行,但该命令要求应用 jar 已上传到 HDFS(通过 fluo.accumulo.jars 配置)。本地类未上传时会报 fluo exec failed - Class FluoWriter not found(实测),此时用上面的 java -cp 方式即可。

十一、安装方案对比与选择建议

第八章 8.2 的依赖补齐方式决定了两种安装方案,对比如下:

维度方案 A:fetch.sh ahz(本文采用)方案 B:复用本机安装(setupClasspathFromSystem)
依赖来源Maven 中央仓库下载到 lib/ahz/(49 个 jar)引用 /opt/accumulo-2.1.0、/opt/hadoop-3.3.6、ZK 安装目录中的 jar
版本控制-D 参数显式指定,与机器安装版本解耦与本机安装版本强绑定
前置要求可访问 Maven 中央仓库 + Maven本机必须已装好三个组件且版本兼容
离线可用性可在联网机执行后整目录拷贝(见下)完全离线可用
classpath 内容lib/*:lib/log4j/*:lib/ahz/*扫描各安装目录(排除 log4j/asm/guava 冲突 jar)
适用场景标准在线安装、依赖版本可精确复现无外网且三组件已就绪的环境

选择建议:可联网服务器一律用方案 A(本文主流程);完全离线的环境先用方案 A 在联网机下载好 lib/ahz/ 与 lib/log4j/ 目录,随安装包一并拷贝到离线服务器后,仍按方案 A 的 classpath 装配(等效于离线安装);方案 B 仅在无外网且不想预置依赖目录时使用,且要确保本机组件版本与 Fluo 2.0.0 兼容。

十二、配置说明汇总

安装完成后,全部配置文件的分布与职责如下:

文件所属组件核心内容
/etc/profile.d/bigdata.sh全局JAVA_HOME/HADOOP_HOME/ZOOKEEPER_HOME/ACCUMULO_HOME 与 PATH
/opt/hadoop-3.3.6/etc/hadoop/hadoop-env.shHadoopJAVA_HOME、HDFS 进程用户、NameNode/DataNode 堆内存
/opt/hadoop-3.3.6/etc/hadoop/core-site.xmlHadoopfs.defaultFS=hdfs://localhost:9000
/opt/hadoop-3.3.6/etc/hadoop/hdfs-site.xmlHadoop副本数、NameNode/DataNode 数据目录
/opt/apache-zookeeper-3.8.4-bin/conf/zoo.cfgZooKeeper端口 2181、数据目录、四字命令白名单
/opt/apache-zookeeper-3.8.4-bin/conf/zookeeper-env.shZooKeeperZK_SERVER_HEAP=256
/opt/accumulo-2.1.0/conf/accumulo.propertiesAccumuloinstance.volumes、ZK 地址、instance.secret、native 开关
/opt/accumulo-2.1.0/conf/accumulo-env.shAccumuloHADOOP_HOME/ZOOKEEPER_HOME、各服务 JVM 堆
/opt/accumulo-2.1.0/conf/accumulo-client.propertiesAccumulo实例名与 root 凭据
/opt/fluo-2.0.0/conf/fluo-conn.propertiesFluofluo.connection.zookeepers=localhost:2181/fluo
/opt/fluo-2.0.0/conf/myapp.propertiesFluodfs.root、Accumulo 实例/凭据/表名
/opt/fluo-2.0.0/conf/fluo-env.shFluoHADOOP_HOME、FLUO_JAVA_OPTS、classpath 装配
/etc/systemd/system/fluo-oracle.serviceFluoOracle 进程托管
/etc/systemd/system/fluo-worker.serviceFluoWorker 进程托管

💡 说明:各参数的完整清单、默认值与调优建议见《Apache Fluo 2.0.0 配置参数详解》;命令行工具的完整用法见《Apache Fluo 2.0.0 常用 CLI 命令与工具详解》。

十三、常见问题(FAQ)

Q1:start-dfs.sh 后 jps 没有 NameNode/DataNode,日志报 JAVA_HOME is not set? Hadoop 启动经 SSH 非登录 shell,读不到 profile 环境变量。按 5.3 在 hadoop-env.sh 里显式 export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 后重新执行 start-dfs.sh。

Q2:start-dfs.sh 卡住或报 pdsh: connect: Connection refused? Hadoop 用 pdsh 批量执行远程命令,单机也需要 SSH 免密。按 2.3 配置密钥,并在 hadoop-env.sh 中设置 export PDSH_RCMD_TYPE=ssh(默认 rsh 会被拒绝)。

Q3:Accumulo tserver 启动即退出,日志报 native libraries 相关 FATAL? accumulo.properties 模板默认 tserver.memory.maps.native.enabled=true,需要 gcc 编译原生库。无编译环境时按 7.2 设为 false 即可(本文配置已含此项)。

Q4:fluo init 报缺少必填属性? Fluo 的应用配置模板 fluo-app.properties 中 fluo.accumulo.table 一行使用了变量引用写法,而 Java Properties 不做变量插值,导致取值为空。按 8.5 手工填写 fluo.accumulo.table=myapp2 等全部必填项后再执行 init。

Q5:运行 fluo 命令报 NoClassDefFoundError: org/apache/curator/CuratorFramework? 依赖没有补齐。按 8.2 依次执行 lib/fetch.sh extra 与 lib/fetch.sh ahz -Daccumulo.version=2.1.0 -Dhadoop.version=3.3.6 -Dzookeeper.version=3.8.4(ahz 需要 Maven),并用 ls /opt/fluo-2.0.0/lib/ahz | wc -l 确认有 49 个 jar。

Q6:fluo scan 报 NoClassDefFoundError: org/apache/log4j/Logger? classpath 里同时混入了多套日志实现。setupClasspathFromLib(ahz 方式)已内置 lib/log4j/* 统一日志 jar 并排除冲突;不要把方案 A 与方案 B 的 classpath 混用,fluo-env.sh 末尾只保留一个装配调用(本文为 setupClasspathFromLib)。

Q7:Accumulo manager 日志报 FATAL: ZooKeeper session expired? 多为 ZK 会话因 JVM 堆积或启动顺序问题超时。逐个启动服务(manager → tserver → gc → monitor),每步等待就绪;确认 7.3 的各服务堆配置生效(jps -lv 查看)。必要时全部停止后按顺序重新启动。

Q8:systemctl stop fluo-oracle 后 systemctl status 显示 failed? JVM 收到 SIGTERM 的退出码是 143,systemd 默认视为异常。按第九章 unit 模板加入 SuccessExitStatus=143 后 systemctl daemon-reload 即可。

Q9:停止服务后立刻 fluo remove 报应用已在运行? Fluo 在 ZooKeeper 中的应用状态有会话超时延迟,服务停止后约 30 秒 ZK 状态才更新为 STOPPED。等待约 30–40 秒再执行 remove,或先用 fluo status -a myapp2 确认状态不再是 RUNNING。

Q10:accumulo init 报 Filesystem is already initialized? 实测报错全文如下(原因:instance.volumes 指向的 HDFS 目录已被初始化过):

2026-10-14T12:40:20,036 [init.Initialize] ERROR: It appears the directories [hdfs://localhost:9000/accumulo] were previously initialized.
2026-10-14T12:40:20,036 [init.Initialize] ERROR: Change the property instance.volumes to use different volumes.
2026-10-14T12:40:20,036 [init.Initialize] ERROR: The current value of instance.volumes is |hdfs://localhost:9000/accumulo|
2026-10-14T12:40:20,036 [init.Initialize] ERROR: FATAL: Problem during initialize
java.io.IOException: Filesystem is already initialized

这是防止误覆盖数据的保护机制。重新初始化时把 instance.volumes 换成未用过的目录;若确认要重建实例,先清理该 HDFS 目录与对应 ZooKeeper 节点(见「十四、卸载与清理」)。

十四、卸载与清理

按「Fluo → Accumulo → ZooKeeper → HDFS」顺序停止并清理。若只想重置 Fluo 应用(保留依赖栈),只执行 14.1 与 14.2。

14.1 停止并注销 Fluo 服务

systemctl stop fluo-worker
systemctl stop fluo-oracle
systemctl is-active fluo-worker

实测输出:

inactive
systemctl is-active fluo-oracle

实测输出:

inactive
systemctl disable fluo-oracle

实测输出:

Removed /etc/systemd/system/multi-user.target.wants/fluo-oracle.service.
systemctl disable fluo-worker

实测输出:

Removed /etc/systemd/system/multi-user.target.wants/fluo-worker.service.

⚠️ 注意:若不执行 disable 而直接删除 unit 文件,开机自启的符号链接会悬空;建议先 disable 再删文件。

14.2 删除 Fluo 应用数据

应用停止后等待约 30–40 秒(ZK 状态延迟,见 Q9),执行 remove——它会自动清理 ZooKeeper 中的应用节点、Accumulo 表与 HDFS 应用目录:

fluo remove -a myapp2

实测输出:

Removing Fluo 'myapp2
Remove is complete.

删除 systemd 单元文件与 Fluo 安装目录:

rm /etc/systemd/system/fluo-oracle.service
rm /etc/systemd/system/fluo-worker.service
systemctl daemon-reload
rm -rf /opt/fluo-2.0.0

14.3 停止 Accumulo 并清理数据

accumulo-service gc stop

实测输出:

Stopping gc on node1.fluo.example
accumulo-service monitor stop

实测输出:

Stopping monitor on node1.fluo.example
accumulo-service tserver stop

实测输出:

Stopping tserver on node1.fluo.example
accumulo-service manager stop

实测输出:

Stopping manager on node1.fluo.example
jps

实测输出节选(Accumulo 进程已消失):

12448 QuorumPeerMain
27077 SecondaryNameNode
26697 NameNode
26826 DataNode
30054 Jps

清理 Accumulo 的 HDFS 数据与安装目录:

hdfs dfs -rm -r /accumulo
rm -rf /opt/accumulo-2.1.0

14.4 停止 ZooKeeper 并清理

zkServer.sh stop

实测输出:

ZooKeeper JMX enabled by default
Using config: /opt/apache-zookeeper-3.8.4-bin/bin/../conf/zoo.cfg
Stopping zookeeper ... STOPPED
rm -rf /opt/apache-zookeeper-3.8.4-bin /opt/zookeeper-data

14.5 停止 HDFS 并清理

stop-dfs.sh

实测输出节选(省略了行间的旧变量告警行):

Stopping namenodes on [localhost]
Stopping datanodes
Stopping secondary namenodes [node1.fluo.example]
rm -rf /opt/hadoop-3.3.6 /opt/hadoop-data
rm /etc/profile.d/bigdata.sh

至此全部组件与数据清理完毕。安装包 rm -rf /opt/dl 可选删除。

十五、参考链接