Hive tables in object storage
A Hive catalog can create databases and tables whose files live in
Amazon S3, Azure Data Lake Storage (ADLS), or Google Cloud Storage (GCS) instead of HDFS. Gravitino
passes the location of a schema or table to the Hive metastore, and the metastore creates the
directory there, so the metastore itself must be able to reach the object store. Configure that once
on the metastore, then give schemas and tables an s3a://, abfss://, or gs:// location.
Quick start
The example assumes the metastore already reaches S3, as set up in
Hive metastore configuration, and that the metastore is connected as
the catalog hive_catalog; see Hive catalog. It creates the
schema sales_s3 at an S3 location and a Parquet table in it, whose files land under that location.
-
Create the schema at an S3 location. For ADLS use an
abfss://location, and for GCS ags://location.Create a schema with an S3 locationcurl -sS -X POST "https://{gravitino_host}/api/metalakes/{metalake}/catalogs/hive_catalog/schemas" \
-H "Accept: application/vnd.gravitino.v1+json" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"name": "sales_s3",
"properties": {"location": "s3a://{bucket}/sales_s3"}
}' -
Create a table in it. With no
locationof its own, the table is placed under the schema's.Create a Parquet tablecurl -sS -X POST "https://{gravitino_host}/api/metalakes/{metalake}/catalogs/hive_catalog/schemas/sales_s3/tables" \
-H "Accept: application/vnd.gravitino.v1+json" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"name": "orders",
"columns": [
{"name": "id", "type": "long", "nullable": true},
{"name": "amount", "type": "decimal(10,2)", "nullable": true}
],
"properties": {"format": "PARQUET"}
}' -
Check the location. The
locationproperty of the loaded table iss3a://{bucket}/sales_s3/orders.Load the tablecurl -sS "https://{gravitino_host}/api/metalakes/{metalake}/catalogs/hive_catalog/schemas/sales_s3/tables/orders" \
-H "Accept: application/vnd.gravitino.v1+json" \
-H "Authorization: Bearer $TOKEN"
Configure the metastore
The settings go in the metastore's hive-site.xml. Add the ones for your object store and restart
the metastore.
- S3
- ADLS
- GCS
<property>
<name>fs.s3a.access.key</name>
<value>{access_key_id}</value>
</property>
<property>
<name>fs.s3a.secret.key</name>
<value>{secret_access_key}</value>
</property>
<property>
<name>fs.s3a.endpoint</name>
<value>{s3_endpoint}</value>
</property>
<property>
<name>fs.abfss.impl</name>
<value>org.apache.hadoop.fs.azurebfs.SecureAzureBlobFileSystem</value>
</property>
<property>
<name>fs.azure.account.key.{storage_account}.dfs.core.windows.net</name>
<value>{storage_account_key}</value>
</property>
<property>
<name>fs.gs.auth.service.account.enable</name>
<value>true</value>
</property>
<property>
<name>fs.gs.auth.service.account.json.keyfile</name>
<value>{service_account_key_file}</value>
</property>
The key file path is a path on the metastore host.
To place every new database in the object store without giving each a location, also set
hive.metastore.warehouse.dir to a path there, such as s3a://{bucket}/warehouse.
The metastore also needs the Hadoop file system jars for the store on its classpath:
# S3
cp ${HADOOP_HOME}/share/hadoop/tools/lib/*aws* ${HIVE_HOME}/lib
# ADLS
cp ${HADOOP_HOME}/share/hadoop/tools/lib/*azure* ${HIVE_HOME}/lib
# GCS, with the connector release that matches your Hadoop version
cp gcs-connector-hadoop3-2.2.22-shaded.jar ${HIVE_HOME}/lib
The GCS connector is published on the Hadoop connectors releases page. Restart the metastore after adding the settings and jars.
Create a schema in object storage
Give the schema a location in the store. Tables created in it without their own location are
placed under it.
- REST
- Java
curl -sS -X POST "https://{gravitino_host}/api/metalakes/{metalake}/catalogs/hive_catalog/schemas" \
-H "Accept: application/vnd.gravitino.v1+json" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"name": "hive_schema",
"comment": "Schema in object storage",
"properties": {"location": "s3a://{bucket}/hive_schema"}
}'
GravitinoClient gravitinoClient = GravitinoClient
.builder("https://{gravitino_host}")
.withMetalake("{metalake}")
.withBasicAuth("{user}", "{password}")
.build();
SupportsSchemas schemas = gravitinoClient.loadCatalog("hive_catalog").asSchemas();
schemas.createSchema(
"hive_schema",
"Schema in object storage",
ImmutableMap.of("location", "s3a://{bucket}/hive_schema"));
For ADLS use a location such as abfss://{container}@{storage_account}.dfs.core.windows.net/hive_schema,
and for GCS one such as gs://{bucket}/hive_schema. Tables are covered in
Tables and views.
Read the tables from Hive
Hive sees the database and its tables in the metastore with their object storage locations, and reads and writes them directly once it has the same file system settings and jars as the metastore.
SHOW CREATE DATABASE hive_schema;
USE hive_schema;
SHOW CREATE TABLE hive_table;
INSERT INTO hive_table VALUES (1, '2022-11-12', 'hello');
SELECT * FROM hive_table;
SHOW CREATE DATABASE shows the LOCATION in the object store, and the table's LOCATION is under
it.
Read the tables from Spark
With the Spark connector, pass the file system settings for
the store to the Hive catalog in Spark as spark.sql.catalog.{hive_catalog}.* settings:
SparkSession spark = SparkSession.builder()
.config("spark.plugins", "org.apache.gravitino.spark.connector.plugin.GravitinoSparkPlugin")
.config("spark.sql.gravitino.uri", "https://{gravitino_host}")
.config("spark.sql.gravitino.metalake", "{metalake}")
.config("spark.sql.gravitino.authType", "basic")
.config("spark.sql.gravitino.basic.username", "{user}")
.config("spark.sql.gravitino.basic.password", "{password}")
.config("spark.sql.catalog.hive_catalog.fs.s3a.access.key", "{access_key_id}")
.config("spark.sql.catalog.hive_catalog.fs.s3a.secret.key", "{secret_access_key}")
.config("spark.sql.catalog.hive_catalog.fs.s3a.endpoint", "{s3_endpoint}")
.config("spark.sql.catalog.hive_catalog.fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem")
.enableHiveSupport()
.getOrCreate();
spark.sql("SELECT * FROM hive_catalog.hive_schema.hive_table").show();
For ADLS, set fs.abfss.impl and fs.azure.account.key.{storage_account}.dfs.core.windows.net the
same way; for GCS, fs.gs.auth.service.account.enable and fs.gs.auth.service.account.json.keyfile.
For S3-compatible stores that need it, add fs.s3a.path.style.access set to true.
Spark also needs the file system jars on its classpath: the Hadoop AWS jar and the AWS SDK bundle for S3, the Hadoop Azure jar and the Azure Storage Blob SDK for ADLS, and the GCS connector for GCS.