Apache Atlas 1.1.0 生产环境安装部署实战:依赖版本对齐与故障排查
1. 为什么1.1.0这个版本值得单独写一份安装方案Apache Atlas 的版本迭代节奏不算快但 1.1.0 这个版本在不少存量生产集群里依然是主力。原因很现实很多公司的数据治理平台是在 2019 到 2021 年间搭建的当时选型就落在 1.1.0 上后面因为 HBase、Solr、Kafka 这些依赖组件的版本锁定一直没敢往上升。所以直到现在仍然有人需要在新机器上把 1.1.0 重新装一遍——可能是扩容、可能是迁移、也可能是灾备环境重建。问题在于Atlas 1.1.0 的官方文档写得比较理想化它假设你的环境是干净的、依赖版本是匹配的、网络是通畅的。而真实的生产环境里你面对的往往是一台已经装了 JDK 8 但环境变量乱七八糟的机器、一个已经跑着其他服务的 HBase 集群、一套需要手动建 schema 的关系型数据库。这份方案就是把这些不理想的情况全部考虑进去给出一套能落地、能复现、能排错的安装路径。这篇文章适合三类人第一类是从零开始搭 Atlas 的运维或大数据工程师第二类是从别人手里接手了一套 Atlas、需要重新部署或迁移的开发者第三类是正在做数据治理选型、想先在本机或测试环境跑通 Atlas 看看效果的技术负责人。不管你属于哪一类下面的内容都会覆盖到——从依赖组件的版本选择到配置文件里每一个容易踩坑的参数再到启动失败时怎么一步步定位。需要先说明一点Atlas 1.1.0 对依赖版本相当敏感尤其是 HBase 和 Solr。版本差一个小号就可能出现元数据写不进去、索引查不出来的问题。所以整篇方案里我会反复强调版本对齐这件事这不是啰嗦而是血泪教训。2. 装之前必须想清楚的依赖矩阵与版本锁定2.1 Atlas 1.1.0 到底依赖哪些外部组件Atlas 本身不是一个单机就能跑的工具它的架构决定了它必须依赖外部存储和索引。核心依赖有四块元数据存储默认用 HBase也可以用 Cassandra但生产环境绝大多数选 HBase。Atlas 把实体定义、血缘关系、分类标签这些元数据都写进 HBase。全文索引用 Solr。Atlas 的搜索功能、按名称模糊查询、按分类过滤全靠 Solr 的索引。没有 SolrAtlas 的 UI 基本就是个摆设。消息队列用 Kafka。Atlas 通过 Kafka 接收来自 Hive、HBase、Storm 等组件的 Hook 消息异步写入元数据。没有 KafkaHook 就发不出消息。关系型数据库用 MySQL 或 PostgreSQL。Atlas 自己需要一张关系库来存用户、权限、审计日志等管理类数据。这四块缺一不可。很多人第一次装的时候只关注 Atlas 本身结果启动到一半报错才发现是 Kafka 没起或者 Solr 的 collection 没建。2.2 版本对齐为什么 HBase 1.1.x 和 Solr 5.5.x 是相对安全的选择Atlas 1.1.0 官方推荐的组合是 HBase 1.1.x Solr 5.5.x Kafka 0.10.x JDK 8。这个组合不是随便定的而是因为 Atlas 1.1.0 内部用的 HBase client 和 Solr client 就是按这些版本编译的。如果你用 HBase 2.x会遇到NoSuchMethodError或者ClassNotFoundException因为 HBase 2.x 的 API 有变动。如果你用 Solr 7.x 或 8.xAtlas 的 Solr 索引创建脚本会直接失败因为 Solr 的 collection API 在 6.0 之后改了。Kafka 同理0.10.x 和 2.x 的 producer API 不兼容。所以我的建议是不要试图用新版本去兼容 Atlas 1.1.0而是老老实实按它的版本要求来。如果生产环境已经有更高版本的 HBase 或 Solr 在跑其他业务那就给 Atlas 单独部署一套低版本的依赖或者用容器隔离。混用是灾难的开始。下面这张表是我实际验证过的版本组合可以直接参考组件推荐版本可接受范围风险说明JDK1.8.0_1811.8.0_151 以上低于 151 可能有 SSL 问题HBase1.1.131.1.x1.2.x 以上 API 有变动Solr5.5.55.5.x6.x 以上 collection API 不兼容Kafka0.10.2.20.10.x0.11.x 以上 producer 不兼容MySQL5.75.6 以上5.5 以下字符集有问题Atlas1.1.0固定本文只讨论这个版本2.3 内存和磁盘别让 JVM 成为第一个瓶颈Atlas 本身是个 Java 应用默认的 JVM 堆是 512MB这在生产环境肯定不够。Atlas 的元数据量一大堆内存很快就会被占满然后就是频繁 Full GC最后 OOM。我的经验是Atlas 服务端至少给 4GB 堆内存Solr 至少给 2GBHBase 的 RegionServer 至少给 4GB。如果元数据量特别大比如超过百万级实体Atlas 堆内存要加到 8GB。磁盘方面HBase 和 Solr 都是写密集型建议用 SSD。如果只有机械盘那至少要做 RAID 0 或者 RAID 10别用单盘。Atlas 本身的日志目录也要留够空间因为调试阶段日志会刷得很快。3. 从零开始的安装流程每一步都解释清楚为什么3.1 基础环境准备JDK、主机名、防火墙第一步永远是 JDK。Atlas 1.1.0 只支持 JDK 8不支持 JDK 11。安装完 JDK 后JAVA_HOME必须正确设置而且要注意Atlas 的启动脚本会读取JAVA_HOME如果这个变量指向了 JRE 而不是 JDK启动会失败。因为 Atlas 需要用到 JDK 里的tools.jar来做一些动态编译。主机名和 hosts 文件也容易被忽略。Atlas 在启动时会用主机名去注册服务如果主机名解析不了会卡在启动阶段。所以要在/etc/hosts里把本机主机名和 IP 对应上。防火墙方面Atlas 默认用 21000 端口HTTP和 21443 端口HTTPS。如果开了防火墙这两个端口要放行。另外 Atlas 还要连 HBase 的 2181ZooKeeper、Solr 的 8983、Kafka 的 9092这些端口也要通。提示如果是在云主机上部署除了系统防火墙还要检查安全组规则。我遇到过好几次系统防火墙关了但安全组没放行排查了半天。3.2 HBase 的安装与 Atlas 专用表空间HBase 的安装这里不展开讲假设你已经有一套可用的 HBase 1.1.x。重点讲 Atlas 对 HBase 的特殊要求。Atlas 在 HBase 里会创建两张表ATLAS_ENTITY和ATLAS_JANUS如果用了 JanusGraph 作为图存储。这两张表的列族和 TTL 都有讲究。Atlas 的安装包里带了atlas-hbase-schema脚本但很多人不知道这个脚本在哪、怎么用。脚本位置在atlas/conf/hbase/下面有一个create-hbase-schema.sh。执行之前要确保 HBase 的hbase-site.xml在 classpath 里或者通过HBASE_CONF_DIR环境变量指定。执行完脚本后可以用list命令在 HBase shell 里确认表是否创建成功。还有一个坑Atlas 默认用的 HBase 表是ATLAS_ENTITY但如果你之前装过其他版本的 Atlas表名可能不一样。1.1.0 用的是ATLAS_ENTITY而 0.8 版本用的是ATLAS_TABLE。如果表名对不上Atlas 启动时会报TableNotFoundException。3.3 Solr 的 collection 创建为什么不能自动建Atlas 1.1.0 不会自动创建 Solr collection必须手动建。这是很多人第一次装 Atlas 时最容易卡住的地方——Atlas 启动了UI 也能打开但搜索任何东西都报错因为 Solr 里根本没有 collection。创建 collection 的命令在atlas/conf/solr/下面有一个create-solr-collection.sh。执行前要确保 Solr 已经启动并且SOLR_HOME环境变量指向 Solr 的安装目录。collection 的名字默认是vertex_index和edge_index。这两个名字对应 Atlas 的图存储模型顶点索引和边索引。如果只建了一个Atlas 启动时会报CollectionNotFoundException。创建命令大概长这样# 假设 Solr 在 localhost:8983 curl http://localhost:8983/solr/admin/collections?actionCREATEnamevertex_indexnumShards1replicationFactor1maxShardsPerNode1collection.configNamevertex_index注意collection.configName要和 Atlas 提供的配置集名字一致。Atlas 的安装包里带了vertex_index和edge_index两个配置集需要先上传到 Solr 的 ZooKeeper 里。上传命令在atlas/conf/solr/下也有脚本。注意如果 Solr 是单机模式而不是 Cloud 模式collection 的创建方式不一样。Atlas 1.1.0 推荐用 Solr Cloud 模式因为需要 ZooKeeper 来管理配置集。单机模式虽然也能跑但配置集上传比较麻烦。3.4 Kafka 的 topic 准备与 Hook 消息格式Kafka 这边相对简单只需要确保 Kafka 集群可用并且 Atlas 能连上。Atlas 默认用的 topic 是ATLAS_HOOK和ATLAS_ENTITIES。ATLAS_HOOK用来接收 Hook 发来的消息ATLAS_ENTITIES用来接收 Atlas 自己产生的实体变更消息。这两个 topic 不需要手动创建Atlas 启动时会自动创建如果 Kafka 允许自动创建 topic。但如果 Kafka 关闭了自动创建就要手动建并且分区数建议至少 3 个副本数根据 Kafka 集群规模定。消息格式方面Atlas 1.1.0 用的是 JSON 序列化。Hook 端发消息时消息体是一个 JSON 数组每个元素是一个实体变更事件。如果消息格式不对Atlas 的消费者会报DeserializationException然后消息就被丢弃了。调试的时候可以在 Kafka 消费者端手动消费一下ATLAS_HOOK看看消息体长什么样。3.5 Atlas 本体的配置atlas-application.properties 逐项拆解Atlas 的核心配置文件是atlas-application.properties在atlas/conf/目录下。这个文件里的参数非常多但真正影响启动和运行的就这么几类存储配置atlas.graph.storage.backend默认是hbase如果要用 Cassandra 就改成cassandra。atlas.graph.storage.hostname填 ZooKeeper 地址多个用逗号分隔。索引配置atlas.graph.index.search.backend默认是solr。atlas.graph.index.search.solr.zookeeper-url填 Solr 的 ZooKeeper 地址。这里要注意如果 Solr 和 HBase 共用同一个 ZooKeeper要确保 chroot 路径不一样否则会冲突。Kafka 配置atlas.kafka.bootstrap.servers填 Kafka 地址。atlas.kafka.zookeeper.connect填 Kafka 的 ZooKeeper 地址。这两个别搞混了Kafka 的 bootstrap 地址是 broker 地址不是 ZooKeeper 地址。服务端口atlas.server.http.port默认 21000。如果这个端口被占了改成别的。管理员配置atlas.admin.user和atlas.admin.password是 Atlas 的管理员账号默认是admin/admin。生产环境一定要改。配置改完后不要急着启动先用atlas/conf/下的check-config.sh脚本检查一下配置是否有语法错误。这个脚本会读取atlas-application.properties并尝试解析如果有拼写错误或者格式问题会提前报出来。4. 启动之后才是真正的战场常见故障与排查链路4.1 Atlas 启动卡在 Starting Atlas Server 不动这是最常见的现象。Atlas 启动脚本会打印 Starting Atlas Server然后就没下文了。这时候不要干等直接去看日志。日志在atlas/logs/下面主要是atlas.log和application.log。如果atlas.log里最后一行是Connecting to ZooKeeper那说明卡在连 ZooKeeper 了。检查 ZooKeeper 地址是否正确、网络是否通、ZooKeeper 是否真的在跑。如果最后一行是Initializing graph那可能是 HBase 连不上或者 HBase 表没建。这时候要去application.log里找更详细的堆栈。如果日志里出现了java.lang.OutOfMemoryError那就是堆内存不够去atlas-env.sh里把ATLAS_SERVER_HEAP调大。4.2 Solr 索引查不到数据从 collection 状态查起Atlas 启动成功了UI 也能打开但搜索框里输入任何关键词都返回空。这种情况八成是 Solr 索引的问题。第一步去 Solr 的管理界面http://solr-host:8983/solr看vertex_index和edge_index两个 collection 的状态。如果状态是red或者down说明 collection 有问题。第二步如果 collection 状态是green但文档数是 0说明 Atlas 没有把数据写进 Solr。这时候要去 Atlas 日志里搜Solr相关的报错。常见的是SolrServerException原因可能是 Solr 的 ZooKeeper 地址配错了或者 Solr 的配置集没上传。第三步如果文档数不为 0 但搜索还是空那可能是查询语句的问题。Atlas 的搜索用的是 Solr 的edismax查询解析器如果字段名对不上就查不出来。这时候可以用 Solr 的admin界面手动执行一个*:*查询看看能不能查出文档。如果能查出说明索引里有数据问题在 Atlas 的查询逻辑上。4.3 Hook 消息发不出去Kafka 生产者端的排查Hive 或 HBase 的 Hook 配置好了但 Atlas 里就是看不到元数据。这时候要分两步排查先确认 Hook 有没有发消息再确认 Atlas 有没有收到消息。确认 Hook 发消息在 Hive 的日志里搜AtlasHook如果看到Sending message to Kafka说明 Hook 在尝试发消息。如果看到Failed to send message那就是 Kafka 连不上检查atlas-application.properties里的 Kafka 地址。确认 Atlas 收消息用 Kafka 的命令行消费者消费ATLAS_HOOKtopic看看有没有消息。如果有消息但 Atlas 没处理那就是 Atlas 的消费者有问题去 Atlas 日志里搜KafkaConsumer。还有一个隐蔽的坑Hook 端和 Atlas 端的 Kafka 版本不一致。Hook 端用的是 Hive 自带的 Kafka clientAtlas 端用的是 Atlas 自带的 Kafka client。如果两边版本差太多消息序列化格式可能不兼容。解决办法是统一 Kafka client 版本或者用 Atlas 提供的 Hook 库替换 Hive 自带的。4.4 元数据写入 HBase 失败RegionServer 的负载问题Atlas 运行一段时间后突然写不进元数据了日志里报RegionServer is busy或者TimeoutException。这通常是 HBase 的 RegionServer 负载太高或者 Region 分裂导致的。先看 HBase 的 RegionServer 日志确认有没有Too many open files或者GC pause过长的记录。如果有说明 RegionServer 的资源不够需要加内存或者加 RegionServer 节点。如果 RegionServer 本身没问题那可能是 Atlas 的写入批量太大。Atlas 默认的批量写入大小是 1000如果单次写入的实体太多会撑爆 RegionServer 的写缓冲。可以在atlas-application.properties里把atlas.graph.storage.hbase.batch.size调小比如改成 500。还有一个容易被忽略的点HBase 的hbase-site.xml里zookeeper.znode.parent配置。如果 HBase 的 ZooKeeper 根路径不是默认的/hbaseAtlas 也要相应配置atlas.graph.storage.hbase.zookeeper.znode.parent。这个配置对不上Atlas 就连不上 HBase。5. 生产环境特有的加固与调优经验5.1 把管理员密码和敏感配置从明文里挪出去Atlas 1.1.0 默认把数据库密码、Kafka 密码这些敏感信息明文写在atlas-application.properties里。这在生产环境是不可接受的。Atlas 支持通过atlas-application.properties里的atlas.jaas配置来集成 Kerberos但配置起来比较繁琐。一个折中方案是用环境变量替换明文密码。Atlas 的启动脚本支持读取环境变量可以在atlas-env.sh里定义ATLAS_DB_PASSWORD然后在atlas-application.properties里用${ATLAS_DB_PASSWORD}引用。这样密码就不在配置文件里了。另一个方案是用配置管理工具比如 Ansible Vault 或者 HashiCorp Vault来管理配置文件部署时动态生成。这个方案更彻底但需要额外的运维投入。5.2 JVM 调优别让 Full GC 拖垮 AtlasAtlas 的 JVM 调优主要是堆内存和 GC 策略。堆内存前面说了至少 4GB。GC 策略建议用 G1因为 Atlas 的元数据对象生命周期比较长G1 对大堆的支持更好。在atlas-env.sh里加上export ATLAS_SERVER_OPTS-XX:UseG1GC -XX:MaxGCPauseMillis200 -XX:InitiatingHeapOccupancyPercent45MaxGCPauseMillis设成 200 毫秒是权衡吞吐量和延迟的结果。如果设得太小GC 会太频繁设得太大单次 GC 停顿会很长。InitiatingHeapOccupancyPercent设成 45是让 G1 在堆用到 45% 的时候就开始并发标记避免到最后才触发 Full GC。还要加上 GC 日志方便出问题时排查export ATLAS_SERVER_OPTS$ATLAS_SERVER_OPTS -Xloggc:/var/log/atlas/gc.log -XX:PrintGCDetails -XX:PrintGCDateStamps5.3 备份策略元数据丢了就全完了Atlas 的元数据都在 HBase 和 Solr 里。HBase 有自带的快照功能可以定期对ATLAS_ENTITY表做快照。Solr 的 collection 也可以做备份但 Solr 的备份不如 HBase 成熟建议以 HBase 为准Solr 索引丢了可以重建。重建 Solr 索引的方法是停掉 Atlas清空 Solr 的vertex_index和edge_index然后重启 Atlas。Atlas 启动时会从 HBase 里读取所有元数据重新写入 Solr。这个过程可能比较慢取决于元数据量但至少数据不会丢。HBase 快照的命令hbase shell snapshot ATLAS_ENTITY, atlas_entity_backup_20250101恢复的时候用clone_snapshot或者restore_snapshot。注意restore_snapshot会覆盖当前表操作前要确认。5.4 监控指标哪些指标必须盯Atlas 本身暴露了一些 JMX 指标可以通过 JMX 客户端或者 Prometheus 的 JMX exporter 采集。必须盯的指标有JVM 堆使用率超过 80% 就要警惕超过 90% 就要考虑扩容。GC 停顿时间单次超过 1 秒就要查原因。Kafka 消费延迟ATLAS_HOOKtopic 的消费 lag 如果持续增长说明 Atlas 处理不过来。HBase 写入延迟Atlas 写 HBase 的 P99 延迟超过 100 毫秒就要关注。Solr 查询延迟Atlas 搜索的 P99 延迟超过 500 毫秒用户体验就会明显下降。这些指标可以用 Grafana 做面板配上告警规则。告警阈值根据实际业务量调整不要照搬网上的默认值。6. 迁移与扩容时容易忽略的细节6.1 迁移 Atlas 时 HBase 表怎么搬迁移 Atlas 最麻烦的是 HBase 表。如果只是换机器但 HBase 集群不变那简单改一下 Atlas 的配置指向新的 HBase 就行。但如果 HBase 集群也要换那就要搬表。搬表的方法有两种一是用 HBase 的Export/Import工具二是用快照。Export/Import适合小表快照适合大表。快照的步骤是在原集群做快照把快照文件复制到新集群在新集群恢复快照。注意Atlas 的 HBase 表在迁移过程中必须停止写入否则会丢数据。所以迁移前要停掉 Atlas 和所有 Hook迁移完再启动。6.2 扩容 Atlas 节点时 Solr 的 shard 怎么分Atlas 支持多节点部署多个 Atlas 实例共享同一个 HBase 和 Solr。扩容的时候新节点加入集群Solr 的 collection 可能需要重新分片。Solr 的 collection 在创建时指定了numShards这个值一旦确定就不能改了。如果要增加分片只能重建 collection。重建的步骤是停掉 Atlas删除旧的 collection用新的numShards创建新 collection然后重启 Atlas 让数据重新索引。所以扩容前要规划好分片数。如果预计元数据量会增长很快一开始就把numShards设大一点比如 4 或 8。分片多了查询会慢一点但扩容方便。6.3 版本升级的路径1.1.0 能直接升到 2.x 吗不能直接升。Atlas 1.1.0 到 2.x 的跨度太大HBase 表结构和 Solr 索引结构都变了。官方推荐的升级路径是 1.1.0 → 1.2.0 → 2.0.0 → 2.1.0每一步都要做数据迁移。如果只是想升到 1.2.0那相对简单因为 1.2.0 和 1.1.0 的存储结构基本兼容。升级步骤是停掉 1.1.0替换成 1.2.0 的二进制包启动 1.2.0它会自动做 schema 升级。但升级前一定要备份 HBase 表因为 schema 升级是不可逆的。我在实际迁移中遇到过一个问题1.1.0 的 HBase 表里有一些废弃的列族1.2.0 启动时会尝试删除这些列族但如果 HBase 的权限不够删除会失败然后 Atlas 启动就卡住了。解决办法是手动在 HBase shell 里删除这些列族或者给 Atlas 的 HBase 用户足够的权限。7. 一些零散但重要的实操心得装 Atlas 这件事说难不难说简单也不简单。难点不在步骤多而在细节多。下面这几条是我踩过坑之后总结出来的每条都对应一个真实的问题。第一条配置文件里的空格和换行。atlas-application.properties是 Java Properties 格式对空格和换行很敏感。如果某个参数的值后面多了一个空格Atlas 可能解析成不同的值。比如atlas.server.http.port21000后面多一个空格端口就变成21000启动时会报端口非法。所以改完配置后用cat -A看一下有没有多余的空格。第二条ZooKeeper 的 chroot。如果 HBase、Solr、Kafka 共用同一个 ZooKeeper 集群一定要用 chroot 隔离。HBase 默认的 chroot 是/hbaseSolr 是/solrKafka 是/kafka。Atlas 连 HBase 的时候ZooKeeper 地址要写成zk-host:2181/hbase连 Solr 的时候写成zk-host:2181/solr。如果漏了 chrootAtlas 会连到 ZooKeeper 的根路径然后找不到对应的节点。第三条Hook 的类路径冲突。Hive 的 Hook 和 Atlas 的 Hook 可能依赖不同版本的同一个库。比如 Hive 自带的commons-lang是 2.6Atlas 需要 3.x。如果类路径里先加载了 Hive 的版本Atlas 的 Hook 就会报NoSuchMethodError。解决办法是把 Atlas 的 Hook 库放在类路径的最前面或者用-Djava.class.path显式指定。第四条Solr 的autoSoftCommit配置。Atlas 写入 Solr 后默认不是立即能搜到的因为 Solr 有 commit 延迟。如果希望写入后马上能搜到要在 Solr 的solrconfig.xml里把autoSoftCommit的maxTime调小比如改成 1000 毫秒。但调太小会影响性能所以要在实时性和吞吐量之间权衡。第五条日志级别别开 DEBUG。Atlas 的 DEBUG 日志量非常大开一天就能把磁盘写满。调试的时候可以临时开 DEBUG调完马上改回 INFO。改日志级别在atlas-log4j.xml里找到对应的 logger把 level 从INFO改成DEBUG。第六条时间同步。Atlas、HBase、Solr、Kafka 这些组件之间的时间必须同步否则会出现各种诡异的问题比如 Kerberos 认证失败、消息时间戳乱序。生产环境一定要配 NTP确保所有节点的时间差在 1 秒以内。第七条别在 Atlas 机器上跑其他重负载服务。Atlas 本身对 CPU 和内存的占用就不低如果再跑一个 Spark 或者 Elasticsearch资源竞争会很严重。Atlas 的机器最好专用或者至少保证有足够的资源余量。这些心得看起来琐碎但每一条都是实际部署中会遇到的。Atlas 1.1.0 虽然是个老版本但它的稳定性在存量生产环境里已经得到了验证。只要把依赖版本对齐、配置项填对、启动顺序搞对它就能稳定运行。真正麻烦的是那些看起来没问题的细节而上面这些内容就是帮你把这些细节提前想到。