所谓Catalog即数据目录,简单讲,Catalog是企业用于管理数据资产的方式,Catalog借助元数据来管理数据,包括数据收集、组织、访问、发现和治理。可见,Catalog在数据资产管理中处于核心位置。元数据本身内容非常丰富,包括技术元数据、业务元数据和操作元数据,本文仅仅研究大数据计算存储框架本身的技术元数据,比如数据库、数据表、分区、视图、函数等。限于篇幅,参与比较的计算存储框架为Flink、Iceberg和Hive,比较维度为Catalog的定义、Catalog的实现和生态拓展几个方面。

Catalog接口定义

1 Flink Catalog

在这里插入图片描述

在这里插入图片描述

从Flink Catalog的接口定义来看,Flink Catalog提供了基本的数据库、数据表、函数、视图、分区的增删改查基本操作。

2 Iceberg Catalog

在这里插入图片描述

从Iceberg Catalog的接口定义来看,Iceberg Catalog提供了基本的表创建、表替换、表删除、表改名和表加载、查询等操作。在对外接口参数中,Iceberg使用TableIdentifier来标识一个表,TableIdentifier内部又包含一个Namespace。在Iceberg中,一个表的完整标识组成为: TableIdentifier=Namespace+table,其中Namespace是一个字符串数组,支持多层级的表修饰,第0层为table,第1层为database。

3 Hive Catalog

Hive Catalog在3.x版本以前没有Catalog 的概念,此后的版本中才勉强在Metastore中加上了一张表,专门存储Catalog,从Hive Catalog的类定义中可见,声明是相当简单的:

private String name; // required private

String description; // optional private

String locationUri; // required

其中locationUri指定了Catalog所属的数据存储路径,该属性必填。

小结

通过Catalog定义来看,Flink Catalog功能相对完善,Iceberg Catalog跟Flink Catalog相比,没有明确的对数据库相关的操作,而且也没有像Flink Catalog那样明确的表的全名称(如用database.table来标识一个表)修饰概念,而是将表的标识概念泛化。相比Flink、Iceberg的 Catalog,Hive Catalog显得”后知后觉“,因为Hive早期设计是基于database和table两级命名来实现,也没有考虑到当前蓬勃发展的联邦查询场景。

Catalog实现

1 Flink Catalog

在这里插入图片描述

Flink Catalog的实现有两种:Hive Catalog和Memory Catalog。两者都继承抽象的AbstractCatalog,区别是前者借助HMS来管理元数据,后者基于内存管理,Flink Job停止之后,这些数据会丢失,需要重建。

2 Iceberg Catalog

在这里插入图片描述

Iceberg Catalog的实现类有4种,Hive Catalog、Hadoop Catalog、CacheCatalog和JDBC Catalog。它们都继承抽象类BaseMetastoreCatalog。Hive Catalog将表的元数据信息存储在Hive Metastore,为了兼容HMS,Namespace必须包含table和database。

Hadoop Catalog将表的元数据信息存储在Hadoop之上,因为Hadoop支持存算分离,因此底层的数据文件可以是HDFS或者是S3这样的对象系统,对Hadoop Catalog来讲,定位一个表的位置,只需要提供表的路径即可,因为表的元信息都存储在文件中,比如TableIdentifier为["test_table","test_db","test_nm1","test_nm2"]的表全路径为:

对Hadoop Catalog来讲,Namespace可以只有一层,即table 名称即可,它并不关心数据库的概念,只关心表的位置,但在实际应用中,为了规范管理表,建议使用规范的组织方式,具体如何组织,要看企业的行为习惯,目前没有最佳实践。

需要提醒一点的是,Hadoop Catalog构建在文件系统之上,一些文件系统不支持的操作,Catalog也无法实现,比如对表名的更改,涉及到更改路径,对象存储系统无法支持,有代码为证:

public class HadoopCatalog{

​    @Override  

​    public void renameTable(TableIdentifier from, TableIdentifier to) {      

​            throw new UnsupportedOperationException("Cannot rename Hadoop tables");    

​    }

 }

同Flink Catalog一样,Iceberg也提供了JDBC Catalog,JDBC Catalog将表的元信息存储在支持JDBC协议的数据库中。但是两者还是有区别的:Flink的JDBC Catalog能够查询注册和查询外部JDBC数据源,而Iceberg的JDBC Catalog只是将本身的元数据存储在JDBC数据库中,Iceberg目前支持的数据来源也仅仅是Hadoop。除了以上三类Catalog,Iceberg也提供了自定义Catalog实现,这类的典型实现是AWS Glue。CacheCatalog类似Flink的MemoryCatalog。

3 Hive Catalog

虽然Hive 没有跟Flink、Iceberg类似的Catalog相关接口定义,但是在IMetaStoreClient接口有相似的实现,而且更完善:

在这里插入图片描述

在这里插入图片描述

上面只是截取了部分接口定义,实际上还有很多,感兴趣的读者自己去翻阅IMetaStoreClient接口定义。

Catalog管理

从前面介绍可知,Flink和Iceberg分别实现了多种Catalog的实例,在实际使用当中,如何方便跟使用方交互呢?

1 Flink Catalog

Flink通过定义类CatalogManager来组织当前系统中可用的Catalog和设置、查询当前Catalog等的信息:

@Internal public final class CatalogManager {   

 // A map between names and catalogs.   

 private final Map<String, Catalog> catalogs;   

 // The name of the current catalog and database    

private String currentCatalogName;        

private String currentDatabaseName;

 }

在Catalogmanager的外围,通过StreamTableEnvironment暴露给用户常用的操作接口,比如查询当前系统所有的Catalog,当前Catalog 的所有表和数据库等:

在这里插入图片描述

其中registerCatalog方法将Catalog实现注册到Catalogmanager,默认是MemoryCatalog。何为StreamTableEnvironment?文档中这么描述:

A table environment is responsible for:

  • Connecting to external systems.
  • Registering and retrieving Tables and other meta objects from a catalog.
  • Executing SQL statements.
  • Offering further configuration options.

StreamTableEnvironment的基本用法如下:

tableEnv.registerCatalog(catalogName, hiveCatalog);

 tableEnv.useCatalog(catalogName); 

tableEnv.executeSql("CREATE TABLE...");

tableEnv.executeSql会在注册的Catalog下创建数据表,如果没有指定Catalog和数据库,会在类型为GenericInMemoryCatalog,默认名为default_catalog 的默认default_db下创建表。比如下面的示例,在外部数据源mysql上创建了一张映射表,可以在Flink中对其进行读写操作:

-- register a MySQL table 'users' in Flink SQL 

CREATE TABLE MyUserTable (  

​    id BIGINT,  

​    name STRING, 

​    age INT,  

​    status BOOLEAN,  

​    PRIMARY KEY (id) NOT ENFORCED ) 

​    WITH (   'connector' = 'jdbc',   'url' = 'jdbc:mysql://localhost:3306/mydatabase',   'table-name' = 'users' );

再比如下面,将Kafka指定的Topic user_behavior映射到Flink中的表KafkaTable,然后通过Flink对其进行读写:

CREATE TABLE KafkaTable (  

​    event_time TIMESTAMP(3) METADATA FROM 'value.source.timestamp' VIRTUAL,  -- from Debezium format  

​    origin_table STRING METADATA FROM 'value.source.table' VIRTUAL, -- from Debezium format  

​    partition_id BIGINT METADATA FROM 'partition' VIRTUAL,  -- from Kafka connector 

​     offset BIGINT METADATA VIRTUAL,  -- from Kafka connector 

​     user_id BIGINT, 

​     item_id BIGINT,

​     behavior STRING ) 

WITH (

  'connector' = 'kafka', 

 'topic' = 'user_behavior', 

 'properties.bootstrap.servers' = 'localhost:9092',  

'properties.group.id' = 'testGroup', 

 'scan.startup.mode' = 'earliest-offset', 

 'value.format' = 'debezium-json' 

);

Currently, PostgresCatalog is the only implementation of JDBC Catalog at the moment。如需使用,需要引入依赖:

<dependency>  

​    <groupId>org.apache.flink</groupId> 

​     <artifactId>flink-connector-jdbc_2.11</artifactId>

​      <version>1.14.0</version>

 </dependency>

使用方式示例:

JdbcCatalog catalog = new JdbcCatalog(name, defaultDatabase, username, password, baseUrl); 

tableEnv.registerCatalog("mypg", catalog); 

// set the JdbcCatalog as the current catalog of the session tableEnv.useCatalog("mypg");

2 Iceberg Catalog

Iceberg Catalog的CatalogLoader等价于Catalog Mamager,接口中实现了3种CatalogLoader:hadoop、Hive和custom,见下图:

在这里插入图片描述

在对外接口暴露中,通过TableLoader:

<img src="/Users/deepexi/Library/Application Support/typora-user-images/image-20220125141929760.png" alt="image-20220125141929760" style="zoom:80%;" />

一旦有了TableLoader,就可以通过去loadTable方法加载相应的表。上述接口可以通过API方便的调用,那如何通过SQL方式跟Iceberg交互呢?下面列举了Hive、Hadoop和Custom三种Catalog的用法:

CREATE CATALOG hive_catalog WITH (

  'type'='iceberg',  

'catalog-type'='hive', 

 'uri'='thrift://localhost:9083',

  'clients'='5',  'property-version'='1', 

 'warehouse'='hdfs://nn:8020/warehouse/path' ); 



CREATE CATALOG hadoop_catalog 

WITH (

  'type'='iceberg',

 'catalog-type'='hadoop',  

'warehouse'='hdfs://nn:8020/warehouse/path',

  'property-version'='1' ); 


CREATE CATALOG my_catalog WITH ( 

 'type'='iceberg', 

 'catalog-impl'='com.my.custom.CatalogImpl',  

'my-additional-catalog-config'='my-value' );

有了Catalog就可以进行通常的ddl了,比如创建一张表sample:


CREATE TABLE hive_catalog.default.sample (  

  id BIGINT COMMENT 'unique id',   

 data STRING );

3 Hive Catalog

<img src="/Users/deepexi/Library/Application Support/typora-user-images/image-20220125142155089.png" alt="image-20220125142155089" style="zoom:80%;" />

HiveMetaStoreClient、HiveMetaStoreClientPreCatalog、CacheableHiveMetaStoreClient和SessionHiveMetaStoreClient都是IMetaStoreClient接口类的实现,最常用的是HiveMetaStoreClient。在对外暴露接口方面,既可以使用HiveMetaStoreClient,也可以使用HCatalog。HCatalog是Hadoop的表存储管理工具,扩展了HiveMetaStoreClient的功能,它将Hive Metastore的表格数据公开给其他Hadoop应用程序,使得具有不同数据处理工具(Pig,MapReduce)的用户能够轻松将数据写入表格。它确保用户不必担心数据存储在何处或以何种格式存储。Hcatalog可以通过命令行及REST API来访问HiveMetaStore,允许你使用HiveQLDDL语法来定义表。

<img src="/Users/deepexi/Library/Application Support/typora-user-images/image-20220125142217773.png" alt="image-20220125142217773" style="zoom:80%;" />

以下是HCatalog的三个基本用途:

  • 工具间通信——大多数复杂的Hadoop应用程序都会使用多种工具来处理相同的数据。它们可能将Pig和MapReduce的组合用于抽取、转换、加载(ETL)的实现,MapReduce用于实际的数据处理,而Hive用于分析查询。中心化元数据存储库的使用简化了数据共享,并确保了某个工具的执行结果总是对其他工具可见。
  • 数据发现——对于大型Hadoop集群来说,常见的情形是应用程序和数据具有多样性。通常,一个应用程序的数据可以被其他应用程序使用,但试图发现这些情况需要大量跨应用程序的信息。在这种情况下,可以将HCatalog用作对任何应用程序可见的注册表。将数据在HCatalog中发布就可以让其他应用程序发现它们。
  • 系统集成——HCatalog所提供的REST服务,打开了Hadoop数据和处理的大门,使其可以应用在整体的企业级数据和处理基础设施中。Hadoop以简易API和类似SQL语言的形式提供了简单的接口。

小结

Flink和Iceberg都实现了相似的Catalog 管理功能,前者通过CatalogManager,后者通过CatalogLoader。两者相同点都支持HMS和JDBC,但是Iceberg也有额外对Hadoop的支持。Hive Catalog因为出现较早,没有专门的CatalogManager,但是它的 MetaStoreClient接口实现了同样的功能,而且更为完善。不仅如此,HCatalog的引入解决不同Hadoop应用之间,按照统一规范的方式访问HDFS文件数据。另外,HMS 底层存储支持derby、jdbc数据库等。相比而言,Flink和Iceberg是横向发展,而Hive是纵向发展。

生态扩展

在Catalog之上,Flinl、Iceberg和Hive通过不同的方式来拓展自己的生态。

1 Flink Catalog

Flink主要通过Connector来连接不同类型的Source和Sink,Source比如Kafka、Kinesis、RabbitMQ、ActiveMQ等,Sink比如Kafka、Kinesis、RabbitMQ、ActiveMQ、HDFS、Redis、Elasticsearch、Cassandra等,使用这些Connector,需要引入相应的依赖包,对于系统自带的比如Socket、Files、Collections、Std Out等可以直接使用,除了上述类型之外,为满足自定义使用场景,Flink还提供了SourceFunction和SinkFunction。完整的系统生态支持类型列举如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O8bUwpPF-1646015245125)(/Users/deepexi/Library/Application Support/typora-user-images/image-20220125142250533.png)]

2 Iceberg Catalog

Iceberg实现了名叫FlinkCatalog的Catalog,该Catalog不同于Iceberg的Catalog,是Flink定义的类型。理论上,Fink Source支持的的数据源都可以写入Iceberg。因此Iceberg的生态拓展方式可以这样描述:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A8Xy2toj-1646015245127)(/Users/deepexi/Library/Application Support/typora-user-images/image-20220125142313174.png)]

3 Hive Catalog

Hive没有类似Connector的概念,Hive是通过HiveStorageHandler接口来提供对不同数据格式的访问,下面是Hive已经实现的StorageHandler:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fkp9kv85-1646015245127)(/Users/deepexi/Library/Application Support/typora-user-images/image-20220125142334591.png)]

其中比较常用的是DefaultStorageHandler、HBaseStorageHandler、DruidStorageHandler和JdbcStorageHandler。DefaultStorageHandler常用于基类,用于实现自定义StoargeHandler,JdbcStorageHandler较新。

引入Storage Handler,Hive用户使用SQL可读写外部数据源。ElasticSearch, Kafka,HBase等数据源的查询对非专业开发是有一定门槛的,借助Storage Handler,他们有了一种方便快捷的手段查询数据。另外,Hive作为数仓的核心组件,借助Storage Handler,数据导入导出可以统一以SQL实现,减少了大数据开发维护的技术栈。下图列举了常用的一些Storage Handler实现:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QcQus5iH-1646015245128)(/Users/deepexi/Library/Application Support/typora-user-images/image-20220125142438480.png)]

小结

在生态拓展方面,Flink主要通过Connector机制支持不同数据源和数据目的的读取和写入;Iceberg则借助Flink的Source Connector能力,向下支持基于Hadoop的数据入湖,间接方式来拓展生态边界;Hive通过HiveStorageHandler接口,外部通过实现HiveStorageHandler来接入对不同数据源的支持。在积极性方面,Flink处于积极进攻态势,Iceberg处于练内功阶段,Hive正在补短板,处于积极追赶态势。

总结

Catalog是大数据技术体系中至关重要的一环,本文从技术角度,从Catalog 的接口定义、Catalog的实现、Cataslog的管理和生态拓展几个方面比较了Flink、Iceberg和Hive在这方面的应用和发展,研究结果表明Flink、Iceberg和Hive都具备了一定的Catalog管理方面的能力,但是发展节奏不同:Flink在流计算方面发展较快,并且建立起了相对完善的生态,Iceberg处于后到一方,目前专注于湖上数据的组织管理,在数据获取方面通过拥抱Flink大腿来拓展生态边界,而Hive属于传统离线数据的元数据管理的绝对霸主,相对Flink等计算引擎,Hive向内发展,在纵向拓展方面发展很完善,在横向发展方面,目前处于查漏补缺,积极追赶阶段,比如实现了Streaming处理,在联邦查询方面,通过外部三方系统的支持,也拓展到了HBase、Kafka、Iceberg、JDBC等技术体系。而且Hive Metastore也被Flink、Iceberg深度依赖,看起来相当长时间都很难摆脱对HMS的依赖(也没有摆脱的必要),但是Hive还不具备对JDBC Catalog等自动元数据发现能力,因此如果需要开发新的Catalog Manager,较好的方式依然是像Flink、Iceberg做的那样,将HMS集成到系统之中,然后再横向拓展其他类型的Catalog。

参考链接

https://www.oracle.com/big-da...

https://iceberg.apache.org/#h...

https://nightlies.apache.org/...

https://trino.io/docs/current...

https://issues.apache.org/jir...

0505-使用Apache Hive3实现跨数据库的联邦查询

https://cwiki.apache.org/conf...

https://issues.apache.org/jir...


滴普科技DEEPEXI
46 声望11 粉丝

滴普科技成立于2018年,是专业的数据智能服务商。滴普科技基于数据智能技术,以客户价值为驱动,为企业提供基于流批一体、湖仓一体的实时数据存储与计算、数据处理与分析、数据资产管理等服务。