尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Apache Atlas实战:大数据元数据治理与数据血缘全攻略

Apache Atlas实战:大数据元数据治理与数据血缘全攻略 “Atlas”这个词在我脑子里会同时弹出好几个画面小时候书架上那本砖头一样的世界地图册希腊神话里用肩膀扛起天空的泰坦巨神甚至学解剖那会儿背过的第一颈椎。但在大数据这个圈子里泡了十多年之后再看到“Atlas”我第一反应已经变成了一个非常具体的开源项目——Apache Atlas。我一度跟团队里的年轻人说如果你的公司正在被数据湖里的元数据搅得焦头烂额那Apache Atlas就是你最值得花时间研究的工具之一。Apache Atlas是Apache软件基金会旗下的顶级项目定位很明确开源的大数据元数据管理与数据治理平台。它要解决的问题是国内不少中大型互联网公司数据平台团队都会遇到的硬骨头——表越建越多、字段含义靠猜、数据从哪来到哪去完全说不清、敏感数据散落在各个业务集群里没人管。Atlas的做法是用一套统一的元数据模型把Hive、HBase、Kafka、Sqoop这些组件里的元数据全部串起来自动捕获数据血缘、支持自定义分类标签、提供全链路审计还能跟Apache Ranger配合做基于标签的访问控制。这篇文章我把从部署到实际使用中积累的经验完整过一遍适合正在选型元数据治理方案的数据平台工程师、数据架构师以及对数据资产管理感兴趣的技术负责人参考。1. 项目思路拆解为什么大数据平台最后都绕不开Apache Atlas1.1 当数据量上来之后团队最先崩掉的一定是“元数据认知”我先聊一个几乎所有数据团队都会经历的阶段。最开始上线数仓也就几十张Hive表每个人对自己负责的链路都门儿清。但业务发展起来之后数仓表数量轻松破千随手一个需求可能就要跨三个部门的数据。这时候最先暴露的问题不是计算资源不够而是你根本不知道该信哪张表。举个例子我们之前遇到过两个不同部门都维护着一张叫user_info的表字段、口径、更新频率全不一样。下游做报表的人不知道听谁的最后报表数据出来对不上业务方来质问数据团队花了两天梳理口径才发现源头就是元数据没人管。这种“找数难、理解难、追溯难”的困境几乎是所有数据平台规模化的必经之路。Apache Atlas的思路是把整个平台变成一张巨大的“数据地图”让表、字段、分区、处理过程都变成地图上的“地标”和“道路”。地标有明确的经纬度类型定义和属性道路有方向输入输出关系你在图上随便点一个节点就能看出它的上游是谁、下游影响了谁、是什么时候被改的、加了哪些安全标签。1.2 核心架构图存储加索引先天就是为“关系”而生的Atlas在底层存储上选型很讲究这也是很多初次接触它的人容易忽略的一个点。它没有用传统的关系型数据库存元数据而是把整个元数据空间建模成一张有向图。实体是节点关系是边血缘就是边里最典型的一种有向关系。这个设计跟元数据本身的特点是匹配的——元数据实体之间的关联关系远比单个实体本身复杂用图来表达查询“一条链路的所有上下游”这种场景会非常自然。我简单梳理一下Atlas核心组件之间的关系组件作用类比Atlas Core类型系统、图引擎、REST API整个平台的中枢神经Graph ProviderJanusGraph图数据存储与事务管理记录“谁连谁”的账本IndexSolr全文检索与属性过滤数据地图的“搜索引擎”KafkaHook与Atlas之间的异步消息通道快递员把增量元数据送进系统HookHive Hook等嵌入各组件捕获元数据变化安装在各个仓库门口的“传感器”Kafka的存在挺关键。Hive Hook捕获到一条建表语句不会直接同步写入Atlas而是先扔到Kafka的ATLAS_HOOK主题里Atlas异步消费再入库。这套异步解耦的机制好处很明显元数据采集不影响业务集群的查询性能而且Kafka本身具备削峰能力业务高峰期钩子产生的消息不会直接把Atlas打挂。1.3 比起研发新存储复用生态才是核心优势在我看来Atlas最聪明的设计不是自己造了一套存储而是把开源的图数据库、搜索引擎、消息队列这些成熟组件组合起来自己专注于最核心的“元数据模型和血缘处理逻辑”。这个选择带来的实际好处是团队里只要有接触过HBase、Solr的人上手运维Atlas的成本就很低。而且JanusGraph本身支持水平扩展Solr集群也可以横向扩容Atlas的存储瓶颈基本可以靠加机器扛过去不用改业务代码。2. 部署与集成实操一套能跑起来的Atlas环境是怎么搭出来的2.1 版本选型与环境规划我们用的是Atlas 2.x系列具体版本是2.2.0。你如果自己搭测试环境我建议直接上2.2.0之后的版本因为1.x版本太老了很多坑后来虽然修复了但网上搜到的中文资料普遍比较旧照着一套1.x的教程折腾半天最后往往卡在一些早已变化的配置上心态容易崩。部署之前先想清楚跑在什么组件组合上。Atlas官方支持三种组合HBase Solr、JanusGraph内嵌 Solr、仅内嵌存储。我只建议一种组合HBase Solr。JanusGraph内嵌模式虽然省事但生产环境下数据量大到一定程度单机内嵌的存储和事务能力根本扛不住到时候想迁移再迁移成本更高。如果你是个人学习只想起个环境看看界面那内嵌模式也可以接受但不要拿它当生产参考。至少准备这些基础组件JDK 1.8Atlas 2.x对JDK版本敏感不要贪新上JDK 11编译和运行会有兼容问题HBase 2.0并为Atlas单独创建命名空间Solr 7.x官方推荐的版本号段不要盲目上8.x或9.xKafka单节点即可用于测试生产建议至少3节点ZooKeeperHBase和Solr都依赖它协调2.2 一步步把Atlas跑起来以我们内部实践为例Atlas是部署在一台独立服务器上的没有跟Hadoop的NameNode或ResourceManager混部署。原因很简单Atlas的Solr索引和JanusGraph事务都相当吃内存跟大数据集群的主节点抢资源两边都不讨好。先下载Atlas 2.2.0的二进制包解压到/opt/atlas。然后编辑conf/atlas-application.properties这是整个部署过程中最核心的配置文件。我挑几个重点配置说明一下# 存储和索引后端选择 atlas.graph.storage.backendhbase atlas.graph.index.search.backendsolr atlas.graph.index.search.solr.zookeeper-urlzk1:2181,zk2:2181,zk3:2181 atlas.kafka.bootstrap.serverskafka1:9092,kafka2:9092,kafka3:9092 atlas.kafka.zookeeper.connectzk1:2181,zk2:2181,zk3:2181这里有一个非常容易被坑的地方atlas.graph.index.search.solr.zookeeper-url和atlas.graph.index.search.solr.zookeeper-connect-timeout这些参数必须确保Atlas能访问到Solr所在的ZooKeeper。如果你的Solr和HBase用的是两套ZooKeeper千万别搞混。我们第一次部署的时候就因为在配置文件里把HBase的ZK地址写到了Solr那一行结果Solr集合一直创建不起来日志里全是连接超时。配置完成后需要在Solr里提前创建Atlas用到的索引集合。这一步官方文档写得很简单实际上执行时对环境的要求不少。官方提供了脚本/opt/atlas/bin/atlas-solr-init.sh脚本会连接配置好的Solr ZK地址自动创建比如vertex_index、edge_index、fulltext_index这些集合。如果脚本执行时报找不到集合的错多半是Solr的SOLR_HOME或者是ZooKeeper的chroot路径没配对。接下来是初始化Atlas数据表。Atlas会在HBase里创建自己的表空间和表/opt/atlas/bin/atlas-start.py建议不要直接启动服务而是先在前台跑一下确认日志没有报错/opt/atlas/bin/atlas_start.py -console看到类似Application started或者Started AtlasServer的日志后再按CtrlC停掉改用后台方式启动。这样做的好处是如果初始化阶段就有问题你能第一时间从控制台日志里看到具体异常而不是启动后去翻几百行的log文件。启动完成后访问http://atlas-server:21000能看到登录页面默认账号密码是admin/admin。到这步Atlas核心已经就绪。2.3 接入Hive让血缘真正“自动”跑起来Atlas单机跑起来没什么实际价值必须接入至少一个数据源。最经典的是接Hive因为数仓体系里Hive是元数据量最大、血缘关系最复杂、治理需求最迫切的部分。Hive接入Atlas的原理是往Hive中塞一个Hook。Hive执行DDL/DML语句时Hook会捕获这些操作并提取元数据再序列化成Atlas的实体消息发给Atlas的Kafka。因此Hive服务端必须能同时访问到Atlas和Kafka。配置方式是在每台HiveServer2和运行Hive任务的节点上找到Hive的配置文件目录修改hive-site.xmlproperty namehive.exec.pre.hooks/name valueorg.apache.atlas.hive.hook.HiveHook/value /property property namehive.exec.post.hooks/name valueorg.apache.atlas.hive.hook.HiveHook/value /property property namehive.exec.failure.hooks/name valueorg.apache.atlas.hive.hook.HiveHook/value /property同时需要把Atlas自带的Hive Hook依赖包放到Hive的classpath里官方在/opt/atlas/hook/hive目录下提供了打包好的目录里面包含atlas-plugin-classloader-2.2.0.jar等。最简单的做法是把这个目录整体拷贝到每台Hive节点的/opt下面然后在hive-env.sh里加一行export HIVE_AUX_JARS_PATH/opt/atlas-hive-hook修改完毕后需要重启HiveServer2。这一步经常有人图省事不重启然后怎么测血缘都出不来折腾半天最后发现Hook压根没有加载进去。2.4 与Kafka的连通性验证Hive Hook不直接访问Atlas的REST接口而是通过Kafka把消息发出去。所以Hive节点到Kafka的网络连通性是血缘能正常捕获的关键前置条件。验证方法很简单在Hive节点上用Kafka自带命令消费一下Atlas的Kafka主题kafka-console-consumer.sh --bootstrap-server kafka1:9092 --topic ATLAS_HOOK --from-beginning然后在Hive里执行一条建表语句CREATE TABLE test_atlas (id INT, name STRING);如果Kafka终端里能看到一条JSON格式的消息里面包含typeName: hive_table之类的关键词说明Hook已经生效消息链路是通的。如果等了几分钟什么都看不到优先检查Hive的日志里有没有Hook相关的报错尤其要注意是不是Hive的classpath里其他jar包跟Atlas插件产生了冲突。3. 核心功能使用从类型体系到血缘分析3.1 理解Atlas的类型系统实体、属性、关系Atlas里的“类型”是一套自己定义的元模型。比如一张Hive表在Atlas里会对应一个类型为hive_table的实体这个实体会有name、owner、createTime、db等属性其中db是引用类型指向一个类型为hive_db的另一个实体。类型、实体、属性这三者的关系可以类比成面向对象里的“类、对象、成员变量”。类型定义了元数据的骨架实体是这些骨架在运行时的具体实例。你可以在Atlas UI的Admin页面里查看到系统内置的所有类型。除了hive_table、hive_column、hive_db、hive_process之外还有hdfs_path、kafka_topic、sqoop_process这些预设好的类型。这意味着一套基础的数据资产模型已经帮你搭好了。但真实业务中光靠内置类型远远不够。比如你希望给表打一个“数据域”例如交易域、用户增长域的属性内置类型就没这个概念。这时候就需要自定义类型。自定义类型可以通过Atlas自带的一个脚本工具它本质上会调用REST API把类型定义以JSON格式提交上去。下面是一个自定义类型的示例{ enumDefs: [], structDefs: [], classificationDefs: [], entityDefs: [ { name: business_domain, superTypes: [DataSet], typeVersion: 1.0, attributeDefs: [ { name: qualifiedName, typeName: string, isOptional: false, cardinality: SINGLE, isUnique: true, isIndexable: true }, { name: domain_owner, typeName: string, isOptional: true, cardinality: SINGLE } ] } ] }把这段JSON保存为business_domain.json然后执行curl -u admin:admin -X POST \ -H Content-Type: application/json \ -d business_domain.json \ http://atlas-server:21000/api/atlas/v2/types/typedefs之后就可以创建business_domain类型的实体并把现有的Hive表关联到这个domain上。这些后续扩展场景非常灵活有的团队甚至基于Atlas的类型系统搭建出了自己的数据资产目录前端展示层完全对接Atlas的REST API。3.2 血缘到底是怎么生成的血缘是Atlas最有价值的功能也是很多人第一次用Atlas时觉得“好神奇”的地方。在Hive里执行一条SQLINSERT INTO table target SELECT id, name FROM source;Atlas的Hive Hook会解析这条SQL的语义识别出输入表source和输出表target然后生成一个类型为hive_process的实体实体的属性inputs引用hive_table类型的source实体outputs引用hive_table类型的target实体。这样一条“从source流向target”的血缘边就通过hive_process实体记录了下来。在Atlas UI里打开任意一张表切换到血缘图就能看到它从根到叶的完整链条。血缘图支持按层数展开从当前表往上游看3层、往下游看3层是日常排查问题最常用的方式。这里要提醒一句血缘信息越积累越多之后图会变得非常复杂。我们线上有张核心事实表上下游节点加起来上百个UI渲染会有明显的卡顿。这时候别怪Atlas性能差合理做法是利用血缘查询API把数据拉出来然后集成到自研的数据平台上做可视化。Atlas提供了一系列查询血缘的REST接口例如通过Gremlin查询语句从一个指定的guid出发遍历所有上下游节点。每次新的血缘分析需求我都会先在Atlas的Debug页面里用Gremlin试跑确认查询结果正确后再封装成接口交给前端。3.3 分类与标签敏感数据的安全防线Atlas里分类Classification是一套非常灵活的机制可以给实体打标签比如“PII”个人身份信息、“PHI”医疗健康信息、“财务敏感数据”等。分类的基础用法是给单个实体打标签。在表详情的Classifications区域选择已有的分类类型比如PII直接应用上去。但实际工作中表成百上千全靠人工一张张表去点既不现实也容易漏。这时候就需要用到Atlas的分类传播Classification Propagation特性。默认情况下分类是会从上游表传播到下游表的。例如给source表打上PII标签source表的数据经过ETL流入target表那么target表也会被自动打上PII标签。这正是血缘的价值在安全领域的一个重要体现。不过默认传播策略有时候也会让你意外——某些场景下下游表只是读了上游表一个非敏感字段但还是继承了PII这就会造成“误伤”。这时候可以在Atlas里调整实体的分类传播行为比如把某个实体的分类传播设置成仅明确指定的分类或不传播。标签还有一个极其重要的下游应用就是跟Apache Ranger集成实现基于标签的访问控制Tag Based Policies。简单来说你可以在Ranger里配置一条策略凡是带PII标签的表只有数据安全组可以查询其他用户一律拒绝。这样即便ETL跑出了几十张衍生表只要血缘关系正确敏感数据的保护就自动覆盖到所有衍生表上而不用手工去额外配置。这个能力解决了很多安全合规团队的痛点因为在实际业务里敏感数据最怕的不是原始表泄露而是衍生表在不知不觉中把敏感字段带了出去。3.4 通过REST API快速定位元数据Atlas的操作几乎所有功能都支持REST API这为自动化元数据管理提供了基础。我平时用的比较多的两个API是搜索和查询详情。搜索接口curl -u admin:admin \ http://atlas-server:21000/api/atlas/v2/search/attribute?typeNamehive_tableattrNamenameattrValuePrefixfact_limit20这个接口可以快速返回所有名称以fact_开头的Hive表列表。类似的接口还有很多比如按分类搜索、按标签搜索、DSL搜索等。查询一个实体完整详情curl -u admin:admin \ http://atlas-server:21000/api/atlas/v2/entity/guid/这里填实体的guid返回值里会包含这个实体的所有属性、分类、关系信息是写自动化巡检脚本的好帮手。我们曾经基于这个接口做了一套“元数据健康度巡检”每周扫描一遍所有Hive表找出那些超过30天没有更新、没有归属人、没有业务注释的表自动生成一个清单推送到数据团队群里。别看这个功能简单它帮我们逼着各业务线的数据owner去认领和清理自己的表资产效果出乎意料地好。4. 常见问题与排查技巧4.1 Solr集合初始化失败这是部署阶段我遇到过最多的坑。atlas-solr-init.sh执行时会连接ZooKeeper尝试创建或更新Solr集合。如果日志里出现类似org.apache.solr.common.SolrException: No such collection或者Collection not found的错误大体上可以从几个方向排查Solr的集群和Atlas配置的ZooKeeper地址是否一致Solr是否开启了Cloud模式单机模式是跑不起来的ZooKeeper里是否存在Solr的chroot路径例如/solr配置里必须对应写上解法通常是在Solr集群上手动创建集合然后再跑脚本。创建集合的命令curl -X POST \ http://solr-server:8983/solr/admin/collections?actionCREATEnamevertex_indexnumShards1replicationFactor1但这里更推荐直接参考官方文档因为Atlas脚本创建集合时还会上传schema、配置分词器等手动创建容易缺东西。稳妥做法是先检查ZooKeeper连通性再检查环境变量SOLR_ZK是否设置正确。4.2 Hive Hook不生效Kafka收不到消息如果Hook没生效Kafka的ATLAS_HOOK主题里始终看不到消息可以按顺序排查确认hive-site.xml里的Hook配置真的生效了hive.exec.pre.hooks不能只写在本地文件里要确认HiveServer2读的是这个配置文件。确认Atlas的Hook jar包已经加载到Hive的aux路径中。一个很笨但有效的验证方法是在Hive CLI里执行SET hive.exec.pre.hooks;输出里如果能看到org.apache.atlas.hive.hook.HiveHook说明配置是生效的。检查Hive日志。很多时候Hook已经加载了但在初始化时因为某些依赖包找不到而报错日志里会有类似ClassNotFoundException: org.apache.atlas.hive.hook.HiveHook。这是因为Atlas插件的classloader跟Hive本身的classpath有冲突解决办法是把Hive里跟Atlas冲突的旧版依赖排除掉比如某些老版本的jackson包。有个经验可以分享集群里如果有多套Hive环境比如CDH发行版和Apache社区版混用Atlas的Hook包必须跟Hive版本匹配。CDH的Hive用官方原版的Hook包经常会出怪问题这种情况下要重新编译适配CDH的Hook或者用CDH内置的Atlas插件。4.3 UI登录后搜索无结果Atlas UI能正常打开但搜索任何表都返回空。这种情况八成是Solr索引有问题。如果指定名字查询Table完全不返回在atlas-application.properties里确认索引后端配置然后去Solr的管理页面看一下vertex_index等集合的状态有没有处于READONLY或DOWN状态。另一个常见原因是Solr集合的副本分片分配不均匀某个节点挂掉导致索引分片全部落在不可用的节点上。可以用Solr的/admin/collections?actionREBALANCELEADERS或者actionADDREPLICA命令手动均衡分片。4.4 血缘图缺失部分实体有时候能搜索到表但打开血缘图上下游就有很多节点不显示。我的经验是这通常是消息延迟或者消费失败导致的。Atlas消费Kafka消息是异步的如果某个消费线程卡住或者消费失败后没有重试血缘关系就会出现缺失。排查流程看Atlas的日志文件/opt/atlas/logs/application.log里有没有消费异常记录。重点搜索关键词kafka和offset。如果发现一直重复消费某条消息可以到Kafka里手动查看主题的最新offset再用Atlas的REST API手动重建血缘实体。这种办法属于“兜底方案”不能作为常规操作依赖。要想从根上避免就得保证Kafka集群本身稳定同时给Atlas的消费端配置合理的并发和重试参数。4.5 关于性能调优的一点心得Atlas跑了一段时间之后最明显的性能瓶颈通常在图查询和全文检索。基础调优思路是给Atlas分配足够多的JVM堆内存。我们线上是64GB内存的机器给Atlas分配的堆内存是30GB左右。Solr本身要独立部署不要跟Atlas进程混在一台机器上。定期清理不需要的元数据历史版本。Atlas会保留实体的历史快照时间久了存储膨胀很快。curl -u admin:admin -X DELETE \ http://atlas-server:21000/api/atlas/v2/entity/guid/实体guid?deleteSubGraphfalse注意删除实体要非常谨慎特别是带血缘的实体删错了可能会影响下游。建议先备份Atlas的元数据再执行删除操作。Atlas官方提供了export/import功能可以把元数据以JSON格式导出恢复时重新导入。5. 从实际项目中总结的经验与建议部署和使用Apache Atlas一年多我最大的感受是这个工具的价值上限取决于你如何定义“元数据”的边界。不少人把Atlas当成一个“自动画血缘的工具”装完之后看一眼血缘图就放那儿了然后过几个月说这玩意儿没什么用。但实际上当你把自定义业务标签、数据域、负责人机制、质量校验规则都接进去之后Atlas慢慢会变成整个数据平台的一个“活字典”所有人都愿意上来查一查。围绕Atlas的项目规划我有几点很实在的建议先做小范围试点从Hive这一个组件开始把完整链路跑通建立一套元数据规范和操作流程再考虑覆盖Kafka、HBase等其他组件。元数据补充是个持久战要产品化地看待它。给表加注释、打标签、填负责人这些工作不能让平台团队全包必须推动业务数据owner参与进来。血缘数据的准确性需要定期校准。Hive Hook也不是万能的某些复杂的动态SQL、跨集群的远程表血缘可能捕获不到或者捕获错误需要有专门的巡检机制去发现和修正。我个人在实际操作中还养成了一个习惯每次新上线一张重要表建表的同时就去Atlas里确认一下血缘是否生成正确顺手把表的负责人和业务标签补上。这五分钟的额外操作会给后面排查问题时省下好几个小时。数据治理说白了就是一个持续积累的过程工具只是帮你把积累的东西沉淀下来真正让这套体系活起来的是团队里每一个人对“数据资产”这五个字的认真程度。
返回列表