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 个常见问题实测排障
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 Fluo | 2.0.0 | Apache 官方归档当前稳定版,要求 Accumulo 2.1.x |
| Apache Accumulo | 2.1.0 | Fluo 2.0.0 官方适配的 Accumulo 2.x 系列 |
| Apache Hadoop | 3.3.6 | Hadoop 3.x 稳定版,提供 Fluo 所需的 HDFS 存储 |
| Apache ZooKeeper | 3.8.4 | 3.8 稳定版,为 Fluo/Accumulo 提供协调服务 |
| JDK | OpenJDK 11 | Fluo 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 协议,它与另两种常见共识协议的对比——
协议 代表系统 原理特点 适用场景 ZAB ZooKeeper 崩溃可恢复的主备广播+全量/增量同步 协调服务、配置元数据 Raft etcd、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
⚠️ 注意:
--password是非交互执行的关键;不带该参数时 init 会交互式提示输入 root 密码,脚本化场景读不到输入会报NullPointerException。- 若 HDFS 的
instance.volumes目录已被其他实例初始化过,会报Filesystem is already initialized错误(实测报错全文见「十三、常见问题」Q10)。- 上面回显中的 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.sh | Hadoop | JAVA_HOME、HDFS 进程用户、NameNode/DataNode 堆内存 |
/opt/hadoop-3.3.6/etc/hadoop/core-site.xml | Hadoop | fs.defaultFS=hdfs://localhost:9000 |
/opt/hadoop-3.3.6/etc/hadoop/hdfs-site.xml | Hadoop | 副本数、NameNode/DataNode 数据目录 |
/opt/apache-zookeeper-3.8.4-bin/conf/zoo.cfg | ZooKeeper | 端口 2181、数据目录、四字命令白名单 |
/opt/apache-zookeeper-3.8.4-bin/conf/zookeeper-env.sh | ZooKeeper | ZK_SERVER_HEAP=256 |
/opt/accumulo-2.1.0/conf/accumulo.properties | Accumulo | instance.volumes、ZK 地址、instance.secret、native 开关 |
/opt/accumulo-2.1.0/conf/accumulo-env.sh | Accumulo | HADOOP_HOME/ZOOKEEPER_HOME、各服务 JVM 堆 |
/opt/accumulo-2.1.0/conf/accumulo-client.properties | Accumulo | 实例名与 root 凭据 |
/opt/fluo-2.0.0/conf/fluo-conn.properties | Fluo | fluo.connection.zookeepers=localhost:2181/fluo |
/opt/fluo-2.0.0/conf/myapp.properties | Fluo | dfs.root、Accumulo 实例/凭据/表名 |
/opt/fluo-2.0.0/conf/fluo-env.sh | Fluo | HADOOP_HOME、FLUO_JAVA_OPTS、classpath 装配 |
/etc/systemd/system/fluo-oracle.service | Fluo | Oracle 进程托管 |
/etc/systemd/system/fluo-worker.service | Fluo | Worker 进程托管 |
💡 说明:各参数的完整清单、默认值与调优建议见《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 可选删除。
十五、参考链接
- Apache Fluo 官方文档:https://fluo.apache.org/docs/
- Fluo 2.0.0 发布页与下载:https://fluo.apache.org/download/
- Apache Accumulo 2.x 文档:https://accumulo.apache.org/docs/2.x/
- Accumulo 属性参考(2.x):https://accumulo.apache.org/docs/2.x/configuration/server-properties
- Apache Hadoop 3.3.6 文档:https://hadoop.apache.org/docs/r3.3.6/
- Apache ZooKeeper 3.8.4 文档:https://zookeeper.apache.org/doc/r3.8.4/
- Apache Fluo GitHub 仓库:https://github.com/apache/fluo