Hive 中 MetastoreListener 的分类
Metastore Listeners 是一种机制,用于在 Hive Metastore 发生元数据变更时(如表的创建、修改、删除等)触发自定义的逻辑,且无需重新编译Hive。MetaStoreListener 提供了扩展和集成外部组件的方式。根据不同的 MetaStoreListener 类型,可以在不同的阶段运行。在 Hive 中提供了如下三类:
- MetaStorePreEventListener:在元数据变更操作实际发生之前触发,适合用于预处理和验证。
- MetaStoreEventListener:在元数据变更操作实际发生后触发,适合用于后处理和记录。其中 Atlas 提供的 HiveMetastoreHook属于这一类型。
- MetaStoreEndFunctionListener:在 Metastore 函数调用结束时触发,适合用于记录函数调用的结果和性能监控。
Atlas-HiveMetastoreHook 的实现
从 Atlas 集成 Hive MetaStoreEventListener 的配置中得知两个信息
- hive.metastore.event.listeners:Atlas 实现的 MetastoreListener 类型为 MetaStoreEventListener。
- org.apache.atlas.hive.hook.HiveMetastoreHook:是 Atlas 实现 MetaStoreEventListener 的入口。
<property>
<name>hive.metastore.event.listeners</name>
<value>org.apache.atlas.hive.hook.HiveMetastoreHook</value>
</property>
一句话总结下上述配置的作用,Atlas 的 HiveMetastoreHook 继承了 Hive 提供的抽象类 MetaStoreEventListener 并重写了其关于元数据变更后的处理方法, HiveMetastoreHook 获取到元数据表变更事件并进行后续更新元数据操作。
HiveMetastoreHook 的入口
- Atlas 源码路径:atlas/addons/hive-bridge-shim
- 类全名:org.apache.atlas.hive.hook.HiveMetastoreHook
- 解释:下述源码笔者删减了非主流程的部分源码仅留下核心的代码。从源码可得知该类仅为用于 Atlas 实体注册的 MetaStoreEventListener,而并非实现处理逻辑的代码,具体处理逻辑为 atlas/addons/hive-bridge 路径下的 HiveMetastoreHookImpl。
/**
* Hive Metastore hook to capture DDL operations for atlas entity registration.
*/
public class HiveMetastoreHook extends MetaStoreEventListener {
// .....
private static final String ATLAS_HIVE_METASTORE_HOOK_IMPL_CLASSNAME = "org.apache.atlas.hive.hook.HiveMetastoreHookImpl"; // 实现类
private void initialize() {
Class.forName(ATLAS_HIVE_METASTORE_HOOK_IMPL_CLASSNAME, true, atlasPluginClassLoader);
atlasMetastoreHookImpl = cls.getDeclaredConstructor(Configuration.class).newInstance(config); // org.apache.atlas.hive.hook.HiveMetastoreHookImpl
}
@Override
public void onCreateTable(CreateTableEvent tableEvent) throws MetaException {
atlasMetastoreHookImpl.onCreateTable(tableEvent); // 所有变更事件都交由 HiveMetastoreHookImpl 处理
}
// .....
}
HiveMetastoreHook 的处理流程
- HiveMetastoreHookImpl:通过将所有表变更事件封装成 HiveOperationContext,然后调用内部类 HiveMetastoreHook.handleEvent() 进行处理。
- HiveMetastoreHook:继承 AtlasHook,handleEvent()方法 与 HiveHook 逻辑类似,通过 HiveOperationContext 获取 HiveOperation,并根据 oper 创建对应的事件,交由父类 (AtlasHook) notifyEntities 处理事件。
- 后续流程与 HiveHook 一致,参考 Apache Atlas-HiveHook源码分析。
public class HiveMetastoreHookImpl extends MetaStoreEventListener {
private static final Logger LOG = LoggerFactory.getLogger(HiveMetastoreHookImpl.class);
private final HiveHook hiveHook;
private final HiveMetastoreHook hook;
public HiveMetastoreHookImpl(Configuration config) {
super(config);
this.hiveHook = new HiveHook(this.getClass().getSimpleName());
this.hook = new HiveMetastoreHook();
}
// HiveMetastoreHookImpl 源码54行
// 将变更事件封装成 HiveOperationContext,并调用 hook.handleEvent() 处理
public void onCreateDatabase(CreateDatabaseEvent dbEvent) {
HiveOperationContext context = new HiveOperationContext(CREATEDATABASE, dbEvent);
hook.handleEvent(context);
}
// .....
public class HiveMetastoreHook extends AtlasHook {
public HiveMetastoreHook() {
}
@Override
public String getMessageSource() {
return HMS_SOURCE;
}
// HiveMetastoreHookImpl 源码115行
public void handleEvent(HiveOperationContext operContext) {
ListenerEvent listenerEvent = operContext.getEvent();
if (!listenerEvent.getStatus()) {
return;
}
try {
// 1、通过 operContext 获取到 HiveOperation
HiveOperation oper = operContext.getOperation();
// 2、将 hookContext 包装为 AtlasHiveHookContext
AtlasHiveHookContext context = new AtlasHiveHookContext(hiveHook, oper, hiveHook.getKnownObjects(), this, listenerEvent, hiveHook.isSkipTempTables());
BaseHiveEvent event = null;
// 3、基于 oper 创建相应的 event(org.apache.atlas.hive.hook.events.BaseHiveEvent 的实现类)
switch (oper) {
case CREATEDATABASE:
event = new CreateDatabase(context);
break;
// .....
}
if (event != null) {
final UserGroupInformation ugi = SecurityUtils.getUGI() == null ? Utils.getUGI() : SecurityUtils.getUGI();
// 4 、调用父类(AtlasHook) notifyEntities 处理 event
super.notifyEntities(event.getNotificationMessages(), ugi);
}
} catch (Throwable t) {
LOG.error("HiveMetastoreHook.handleEvent({}): failed to process operation {}", listenerEvent, t);
}
}
}
}
一句话总结下 HiveMetastoreHook 处理流程:HiveMetastoreHook 通过继承 Hive 开放的 MetaStoreEventListener 重写表元数据变更的方法,通过 HiveOperationContext 将相应的 HiveOperation 转变为对应的事件,并调用父类 Atlas 的 notifyEntities() 方法将事件消息发送至 Kafka,Topic 为 ATLAS_HOOK。
下面再补充下 HiveMetastoreHook 以及其他各类的关系图