Skip to main content

Gravitino server configuration

Introduction​

The Apache Gravitino server reads conf/gravitino.conf at startup. Almost every property has a default, so the server starts with an empty file, and most deployments change only a handful of them. The exception is gravitino.authorization.serviceAdmins, which you must set once you turn authorization on.

This page covers the server itself. Catalog properties, which configure an individual catalog rather than the server, are covered further down. Properties for the auxiliary services live with those services: see Iceberg REST Catalog Service and Security.

Quick start​

Configure with Helm​

Datastrato Enterprise runs on Kubernetes and is configured through its Helm chart. Server configuration goes in your values file, my-values.yaml, and is applied by running the helm upgrade --install command from Install with Helm again with the same values file. The chart deploys PostgreSQL for the entity store by default, so an evaluation install needs no entity store configuration. For the settings the chart exposes, see Configure.

Production​

A production deployment uses the same my-values.yaml as an evaluation, with the changes in Prepare for Production, applied by running the helm upgrade --install command from Install with Helm again. Keep the license on the command line each time. The changes are:

  • Entity store: a database you operate and back up, with gravitino.postgresql.enabled: false. See Relational Backend Storage.
  • Sign-in: your identity provider, with gravitino.authenticators: "oauth,basic" and gravitino.authenticator.oauth.*, so the local admin account remains for recovery. See How to Authenticate.
  • Authorization: gravitino.authorization.enable and gravitino.authorization.serviceAdmins, as in the values file from Install with Helm. gravitino.authorization.serviceAdmins has no default, and enabling authorization without it fails at startup. What those admins and everyone else may then do is the subject of Privileges.
  • Users and groups: provisioned from your directory with gravitino.scim.enabled and gravitino.scim.ingress. See SCIM provisioning.
  • Admin password: held in a Secret you create, named in gravitino.admin.existingSecret, so the values file carries no credential.
  • Memory: gravitino.resources with requests.memory equal to limits.memory. The JVM heap is set by the GRAVITINO_MEM entry in gravitino.env.
  • Entity cache: turn on cache statistics.
  • Audit log: already on. The chart sets gravitino.audit.enabled to true by default.

The entity cache settings:

my-values.yaml
gravitino:
cache:
enableStats: true
additionalConfigItems:
gravitino.cache.lockSegments: "16"

Only gravitino.cache.enableStats changes behavior here; it logs hit count, miss count, and load failures every five minutes, which is what makes a cache problem visible in production. The chart already sets gravitino.cache.enabled to true and gravitino.cache.implementation to caffeine. gravitino.cache.lockSegments has no dedicated chart value, so it goes under gravitino.additionalConfigItems (see Set Other Server Properties); 16 restates the default and is spelled out so the cache configuration is reviewable in one place. Raise lockSegments above the default if the server runs hot enough for cache lock contention to show up in profiles.

Server configuration​

Set a property in this section through its dedicated chart value when one exists, and otherwise under gravitino.additionalConfigItems in my-values.yaml; see Set Other Server Properties. The server reads gravitino.conf once, at startup, so a change takes effect when the Helm upgrade restarts the server pod. A Default Value of (empty) means the property exists with an empty string or list; (none) means it has no default at all.

Serving requests​

HTTP server​

Configuration ItemDescriptionDefault Value
gravitino.server.webserver.hostThe address the server binds to.0.0.0.0
gravitino.server.webserver.httpPortThe port the server listens on.8090
gravitino.server.webserver.minThreadsMinimum threads in the Jetty thread pool. Values below 8 are raised to 8.Twice the processor count, 8 to 100
gravitino.server.webserver.maxThreadsMaximum threads in the Jetty thread pool. Values below 8 are raised to 8, and the value must be at least minThreads.Four times the processor count, min 400
gravitino.server.webserver.threadPoolWorkQueueSizeSize of the Jetty thread pool work queue.100
gravitino.server.webserver.idleTimeoutTimeout in milliseconds for idle connections.30000
gravitino.server.webserver.stopTimeoutTime in milliseconds Jetty waits for a graceful shutdown. See org.eclipse.jetty.server.Server#setStopTimeout.30000
gravitino.server.shutdown.timeoutTime in milliseconds for the Gravitino server itself to shut down gracefully.3000
gravitino.server.webserver.requestHeaderSizeMaximum size in bytes of an HTTP request header.131072
gravitino.server.webserver.responseHeaderSizeMaximum size in bytes of an HTTP response header.131072
gravitino.server.webserver.customFiltersComma-separated list of servlet filter class names to apply to the API.(empty)
gravitino.server.rest.extensionPackagesComma-separated list of packages to scan for additional REST resources.(empty)
gravitino.server.visibleConfigsComma-separated list of extra properties to expose on the unauthenticated GET /configs endpoint, on top of the fixed set it always returns. Additive, so each entry widens what is public.(empty)

Filters named in customFilters must be standard javax.servlet filters. Pass parameters to a filter with properties of the form gravitino.server.webserver.{filter_class_name}.param.{param_name} = {value}.

GET /configs backs the Web UI, so it answers without authentication and always returns gravitino.authenticators, gravitino.authorization.enable, and gravitino.schema.separator. It adds gravitino.authorization.serviceAdmins when authorization is on, and the OAuth client settings when oauth is among the authenticators. Treat anything you add through visibleConfigs as public.

Two further groups of gravitino.server.webserver.* properties are documented elsewhere, because they belong to features rather than to the web server itself. TLS, key stores, trust stores, and client certificate authentication are in HTTPS. The CORS filter and its allowed origins, methods, and headers, needed when a browser client runs on a different origin than the server, are in CORS.

Schema names​

Catalogs that support hierarchical schemas expose the hierarchy as a single delimited name at the API boundary. Internally the levels are stored with ASCII-1 as the physical separator, so the configured separator is an external representation only, and it may be neither blank, nor ., nor ASCII-1.

Configuration ItemDescriptionDefault Value
gravitino.schema.separatorSeparator representing a multi-level schema name at the API boundary, as in A:B:C. See Hierarchical schema.:

Health check endpoints​

Gravitino exposes three health endpoints following MicroProfile Health semantics. All of them are exempt from authentication, so Kubernetes probes, load balancers, and traffic managers reach them without credentials.

EndpointRoot AliasDescriptionHTTP Status
GET /api/health/liveGET /health/liveLiveness. Returns 200 as long as an HTTP server thread can respond. Use it to decide whether to restart a pod.200
GET /api/health/readyGET /health/readyReadiness. Returns 200 when the entity store answers within the probe timeout, 503 when it is unavailable or slow. Use it to route traffic.200 or 503
GET /api/healthGET /healthAggregate. Returns 200 when both of the above pass. Also aliased as GET /health.html.200 or 503
Configuration ItemDescriptionDefault Value
gravitino.server.health.entityStore.probeTimeoutMsTimeout in milliseconds for the entity store probe behind /ready.2000

Every endpoint returns the same JSON shape, but not the same checks. code is always 0, status is UP or DOWN, and checks carries one entry per component probed. /live reports httpServer alone, /ready reports entityStore alone, and the aggregate endpoint reports both:

Example health response
{
"code": 0,
"status": "DOWN",
"checks": [
{ "name": "httpServer", "status": "UP", "details": {} },
{ "name": "entityStore", "status": "DOWN", "details": { "reason": "timeout" } }
]
}

A failing entityStore check reports timeout, interrupted, probe-rejected, entity store not initialized, or the simple class name of an unexpected exception.

JVM memory​

GRAVITINO_MEM sets the heap and metaspace flags. The launch scripts append it to JAVA_OPTS, and the Iceberg REST server and Lance REST server launchers read the same variable. Set it in conf/gravitino-env.sh or in the environment before starting the server.

The default, from bin/common.sh, is -Xms1024m -Xmx1024m -XX:MaxMetaspaceSize=512m. Raise it in line with catalog count, plugin count, and query concurrency: -Xms4g -Xmx4g -XX:MaxMetaspaceSize=1g suits a moderate production server, and larger deployments go beyond that.

Metrics​

Configuration ItemDescriptionDefault Value
gravitino.metrics.timeSlidingWindowSecsWidth in seconds of the metrics time sliding window.60

Storing metadata​

Storage backend​

Gravitino stores metadata over JDBC. H2 is the default because it is embedded and needs nothing external, which makes it right for local development and wrong for anything else: Gravitino makes no consistency or durability guarantee for metadata held in H2. Production deployments use MySQL or PostgreSQL, and the setup procedure for both is in Relational Backend Storage.

The driver, user, and password properties are required whenever the URL is not jdbc:h2.

Configuration ItemDescriptionDefault Value
gravitino.entity.storeEntity storage implementation. relational is the only supported value.relational
gravitino.entity.store.relationalRelational storage implementation. JDBCBackend is the only supported value, and it covers H2, MySQL, and PostgreSQL.JDBCBackend
gravitino.entity.store.relational.jdbcUrlDatabase URL the backend connects to.jdbc:h2
gravitino.entity.store.relational.jdbcDriverDriver class name. Place the driver jar in ${GRAVITINO_HOME}/libs/.org.h2.Driver
gravitino.entity.store.relational.jdbcUserDatabase username.gravitino
gravitino.entity.store.relational.jdbcPasswordDatabase password.gravitino
gravitino.entity.store.relational.storagePathWhere embedded H2 keeps its files. A relative value resolves against ${GRAVITINO_HOME}. The default sits inside the deployment directory, so an upgrade that replaces that directory discards the data. Change it.${GRAVITINO_HOME}/data/jdbc
gravitino.entity.store.relational.maxConnectionsMaximum size of the JDBC connection pool.100
gravitino.entity.store.relational.maxWaitMillisMaximum wait in milliseconds for a connection from the pool.1000
gravitino.entity.store.maxTransactionSkewTimeMsMaximum transaction skew in milliseconds.2000
gravitino.entity.store.deleteAfterTimeMsHow long in milliseconds deleted and superseded rows are kept. Accepts 10 minutes to 30 days.604800000 (7 days)
gravitino.entity.store.versionRetentionCountNumber of entity versions kept, including the current one. Accepts 1 to 10.1

Caching​

The server caches entities in memory to avoid reading the backend on every request. Caching is on by default, and the properties below tune what it holds and how it evicts.

Configuration ItemDescriptionDefault Value
gravitino.cache.enabledWhether to cache entities at all.true
gravitino.cache.implementationCache implementation. Use the short name, not a fully qualified class name.caffeine
gravitino.cache.maxEntriesMaximum number of cached entries. Ignored when enableWeigher is true.10000
gravitino.cache.expireTimeInMsTime to live in milliseconds, measured from entry creation.3600000 (1 hour)
gravitino.cache.enableWeigherWhether to evict by weight rather than by entry count.true
gravitino.cache.enableStatsWhether to log hit count, miss count, and load failures every five minutes at INFO.false
gravitino.cache.lockSegmentsNumber of lock segments used to reduce contention.16

Two eviction limits apply at once. Time to live always applies: an entry older than expireTimeInMs expires and is cleaned up asynchronously. Alongside it, the cache bounds its size either by count or by weight. With enableWeigher disabled, Caffeine's W-TinyLFU policy evicts the least-used entries once maxEntries is reached. With enableWeigher enabled, each entity type carries a weight, larger for entities higher in the hierarchy, and eviction targets a total weight budget instead; maxEntries is ignored, and a single entry heavier than the whole budget is never cached.

Change log propagation​

Caches are local to each server, so a metalake modified on one server would otherwise stay stale on its neighbors. Every server writes its changes to an entity change log table and polls that table to invalidate what other servers have touched. A separate cleaner trims old rows.

Configuration ItemDescriptionDefault Value
gravitino.entityChangeLog.pollIntervalSecsInterval in seconds between polls. Must be positive.3
gravitino.entityChangeLog.listenerMaxRetriesTimes a batch is retried for a failing listener before listenerFailureAction applies. Must be non-negative.10
gravitino.entityChangeLog.listenerFailureActionWhat happens when a listener exhausts its retries. EXIT stops the server, on the grounds that its caches are known stale; SKIP drops the batch and keeps serving.EXIT
gravitino.entityChangeLog.retentionSecsHow long in seconds change log rows are kept, measured by database time. 0 disables cleanup; otherwise use at least ten times pollIntervalSecs.2592000 (30 days)
gravitino.entityChangeLog.cleanupIntervalSecsInterval in seconds between cleaner runs. Must be positive.86400 (1 day)

Tree lock​

Gravitino serializes conflicting metadata operations with an in-memory tree lock. It is the only lock implementation available, and it is per-server.

Configuration ItemDescriptionDefault Value
gravitino.lock.maxNodesMaximum tree lock nodes held in memory.100000
gravitino.lock.minNodesMinimum tree lock nodes held in memory.1000
gravitino.lock.cleanIntervalInSecsInterval in seconds for reclaiming stale lock nodes.60

Loading catalogs​

These properties govern how the server loads and isolates catalogs. The properties that configure an individual catalog are covered under Catalog Properties.

credential.backfillToProperties below is the escape hatch for connectors that cannot consume vended credentials; the mechanism it opts out of is described in Credential Vending.

Configuration ItemDescriptionDefault Value
gravitino.catalog.cache.evictionIntervalMsInterval in milliseconds before an idle catalog is evicted from the catalog cache.3600000
gravitino.catalog.classloader.isolatedWhether to load each catalog's libraries and configuration in an isolated classloader rather than the application classloader.true
gravitino.catalog.classloader.sharing.enabledWhether catalogs whose isolation-relevant properties match may share one classloader. Sharing reduces Metaspace usage; disabling it gives every catalog its own.true
gravitino.catalog.credential.backfillToPropertiesWhether to return hidden catalog credentials such as jdbc-user and jdbc-password in the catalog properties response, for connectors that cannot consume vended credentials. Anyone who can read catalog properties can then read those credentials. Turn it off once your connectors are upgraded.false

Securing the server​

Authentication​

Authentication decides who a caller is. It is off by default: an unconfigured server trusts whatever username the client sends.

Configuration ItemDescriptionDefault Value
gravitino.authenticatorsComma-separated authenticators to enable. Valid values are simple, oauth, kerberos, basic, and none.simple

Datastrato Enterprise does not support simple. Set gravitino.authenticators to "basic" or "oauth,basic" in my-values.yaml; the chart refuses to render with simple.

Naming an authenticator is one line; configuring it is not. Each value reads its own family of gravitino.authenticator.* properties, covered in How to Authenticate. To hold users, password hashes, and group membership in Gravitino's own relational store rather than an external provider, see Local users and groups.

gravitino.authenticator, in the singular, is a deprecated spelling that still works.

Authorization​

Authorization decides what an authenticated caller may do. It is also off by default, and turning it on requires naming the service admins, since that property has no default of its own.

Configuration ItemDescriptionDefault Value
gravitino.authorization.enableWhether to enforce privileges on metadata operations.false
gravitino.authorization.serviceAdminsComma-separated users who administer the service. Metalake creation is restricted to them.(none)
gravitino.authorization.implAuthorizer implementation.org.apache.gravitino.server.authorization.jcasbin.JcasbinAuthorizer
gravitino.authorization.threadPoolSizeThreads serving authorization checks.100

The privilege model these properties switch on, roles, grants, ownership, and the gravitino.authorization.jcasbin.* tuning of the default authorizer, is described in Privileges. To push enforcement down into the underlying systems through Apache Ranger or a native permission model, see Authorization Pushdown.

Remote file fetching​

The server fetches files by URI in two situations: staging a job's files, and loading catalog files such as a Kerberos keytab. Both accept remote URIs, so both are a path by which a caller who can create a catalog or submit a job could make the server issue requests of its own.

Configuration ItemDescriptionDefault Value
gravitino.fetchFile.blockUnsafeRemoteUriWhether to refuse remote URIs that resolve to unsafe addresses. Disable only for trusted URIs that need them.true

Audit logging​

The audit log framework has two halves. A formatter turns an Event into an AuditLog, and a writer puts that AuditLog somewhere. Both are interfaces, so a deployment with its own log pipeline can replace either.

Configuration ItemDescriptionDefault Value
gravitino.audit.enabledWhether to write an audit log.false
gravitino.audit.formatter.classNameFormatter class name.org.apache.gravitino.audit.v2.SimpleFormatterV2
gravitino.audit.writer.classNameWriter class name.org.apache.gravitino.audit.FileAuditWriter

SimpleFormatterV2 is the default formatter. JsonAuditFormatter is available where structured output is wanted: it emits one JSON object per line, serializes customInfo, and writes timestamps as ISO 8601 with millisecond precision and a zone offset. Both formatters replace the value of a sensitive customInfo key with ***. The masked keys are authorization, cookie, x-amz-security-token, s3.access-key-id, and jdbc-password.

FileAuditWriter is the default writer, and it manages no files itself. Rotation, compression, and retention are delegated to Log4j2 through a logger named gravitino.audit, configured by the audit_file appender group in conf/log4j2.properties. Out of the box it writes gravitino_audit.log under the log directory, rotates daily and at 256 MB, gzips what it rotates, and deletes anything older than 30 days. Change the path or the retention there:

conf/log4j2.properties
appender.audit_file.fileName    = /var/log/gravitino/my_audit.log
appender.audit_file.filePattern = /var/log/gravitino/my_audit_%d{yyyyMMdd}.%i.log.gz

appender.audit_file.strategy.delete.ifAll.ifLastModified.age = 90d

Earlier releases configured the writer directly through gravitino.audit.writer.file.*. Those properties now do nothing, and FileAuditWriter logs a warning at startup if it finds any of them.

Removed PropertyConfigure Instead In conf/log4j2.properties
gravitino.audit.writer.file.fileNameappender.audit_file.fileName
gravitino.audit.writer.file.appendappender.audit_file.append
gravitino.audit.writer.file.flushIntervalSecsimmediateFlush on the appender, or wrap it in an async appender

Extending the server​

Event listeners​

An event listener receives the events Gravitino emits around metadata operations, which is how external systems observe the catalog without polling it. To use one, implement EventListenerPlugin, put the jar on the server classpath, and name it in my-values.yaml under gravitino.additionalConfigItems.

Configuration ItemDescriptionDefault Value
gravitino.eventListener.namesComma-separated listener names, as in audit,sync.(empty)
gravitino.eventListener.{name}.classClass name of the listener registered under {name}.(none)
gravitino.eventListener.{name}.{key}Any other property under a listener's name is passed through to that plugin unchanged.(none)

Every name in names needs a matching {name}.class, or the server fails to build that listener.

Each operation emits up to three events: a pre-event before it runs, a post-event after it succeeds, and a failure event after it throws. The names follow the operation, so createTable produces CreateTablePreEvent, CreateTableEvent, and CreateTableFailureEvent. Operations served by the Gravitino IRC endpoint carry an Iceberg prefix, as in IcebergCreateTableEvent. Not every operation defines all three. The full set of classes lives in the org.apache.gravitino.listener.api.event package.

Throwing a ForbiddenException from a pre-event handler stops the operation before it runs, which makes pre-events a veto point rather than a notification.

A plugin declares how its events are dispatched:

ModeBehavior
SYNCProcessed inline, before the operation's result reaches the client. A slow listener slows the request.
ASYNC_SHAREDProcessed on a queue and dispatcher shared with other listeners. One slow listener degrades the rest, and events can be dropped.
ASYNC_ISOLATEDProcessed on a queue and dispatcher of its own. Better isolation, at the cost of a queue and thread per listener.

Auxiliary services​

An auxiliary service runs inside the Gravitino server process on its own port. The property has no default, but the Helm chart sets it to iceberg-rest,lance-rest through its gravitino.auxService.names value, so both start unless you change that value.

Configuration ItemDescriptionDefault Value
gravitino.auxService.namesComma-separated auxiliary services to start. iceberg-rest is the Gravitino IRC server, lance-rest the Lance REST server.(empty)

The rest of the IRC configuration, and the gravitino.lance-rest.* properties of the Lance REST server, are documented with those services. See Iceberg REST Catalog Service.

Jobs​

Configuration ItemDescriptionDefault Value
gravitino.job.executorExecutor that runs jobs. Implement your own and name it here to replace the built-in one.local
gravitino.job.stagingDirDirectory holding staging files for running jobs./tmp/gravitino/jobs/staging
gravitino.job.stagingDirKeepTimeInMsHow long in milliseconds a finished job's staging files are kept. Use at least 10 minutes outside testing.604800000 (7 days)
gravitino.job.statusPullIntervalInMsInterval in milliseconds between job status polls. Use at least 1 minute outside testing.300000 (5 minutes)

Catalog properties​

Catalog properties configure one catalog rather than the server. They come from two places: a catalog configuration file supplies defaults for every catalog of that provider, and the properties field on a create-catalog request supplies values for that catalog alone. The request wins. Neither affects schema or table properties.

A catalog property is one of three kinds. Gravitino defines some itself, as the settings a catalog needs to work. Anything prefixed gravitino.bypass. passes straight through to the underlying system untouched. Anything else Gravitino simply stores for you to use as you like.

Passing credentials, tokens, or access keys through gravitino.bypass. exposes them: bypassed properties are not managed by Gravitino and can come back in plaintext from the REST API. Where an underlying system leaves no alternative, restrict access to the catalog APIs accordingly.

These properties apply to every catalog:

Configuration ItemDescriptionDefault Value
packagePath to the catalog package, from which Gravitino loads the catalog's libraries and configuration. It holds a conf directory and a libs directory.(none)
cloud.nameCloud the catalog runs on. One of aws, azure, gcp, on_premise, or other.(none)
cloud.region-codeRegion code within that cloud.(none)

Everything else is per provider. The server adds each configuration directory below to the classpath automatically, which is also where provider-specific files such as hdfs-site.xml go.

Catalog ProviderCatalog PropertiesConfiguration File Path
hiveHive catalog propertiescatalogs/hive/conf/hive.conf
glueAWS Glue catalog propertiescatalogs/glue/conf/glue.conf
lakehouse-icebergLakehouse Iceberg catalog propertiescatalogs/lakehouse-iceberg/conf/lakehouse-iceberg.conf
lakehouse-paimonLakehouse Paimon catalog propertiescatalogs/lakehouse-paimon/conf/lakehouse-paimon.conf
lakehouse-hudiLakehouse Hudi catalog propertiescatalogs/lakehouse-hudi/conf/lakehouse-hudi.conf
lakehouse-genericLakehouse Generic catalog propertiescatalogs/lakehouse-generic/conf/lakehouse-generic.conf
jdbc-mysqlMySQL catalog propertiescatalogs/jdbc-mysql/conf/jdbc-mysql.conf
jdbc-postgresqlPostgreSQL catalog propertiescatalogs/jdbc-postgresql/conf/jdbc-postgresql.conf
jdbc-dorisDoris catalog propertiescatalogs/jdbc-doris/conf/jdbc-doris.conf
jdbc-starrocksStarRocks catalog propertiescatalogs/jdbc-starrocks/conf/jdbc-starrocks.conf
jdbc-clickhouse ‡ClickHouse catalog propertiescatalogs/jdbc-clickhouse/conf/jdbc-clickhouse.conf
jdbc-hologres ‡Hologres catalog propertiescatalogs/jdbc-hologres/conf/jdbc-hologres.conf
jdbc-oceanbase ‡OceanBase catalog propertiescatalogs/jdbc-oceanbase/conf/jdbc-oceanbase.conf
kafkaKafka catalog propertiescatalogs/kafka/conf/kafka.conf
filesetFileset catalog propertiescatalogs/fileset/conf/fileset.conf
modelModel catalog propertiescatalogs/model/conf/model.conf

‡ Contributed catalogs, shipped only in the -all distribution package. The standard package does not contain their directories.

Accessing Apache Hadoop​

Gravitino reaches Hadoop as a single operating system user, so that user needs the HDFS and YARN permissions for everything the server will touch. Without them, operations fail with Permission denied. Either grant the user that starts the server the permissions it needs, or set HADOOP_USER_NAME to a user that already has them before starting. For a local deployment, set it in conf/gravitino-env.sh.

  • Relational Backend Storage, for pointing the entity store at MySQL or PostgreSQL, including schema initialization and driver installation
  • Iceberg REST Catalog Service, for the gravitino.iceberg-rest.* properties of the auxiliary service named by gravitino.auxService.names
  • How to Authenticate, for the gravitino.authenticator.* properties behind each value of gravitino.authenticators
  • Local users and groups, for holding users, password hashes, and group membership in Gravitino's own relational store
  • Privileges, for the privilege model the authorizer enforces once gravitino.authorization.enable is set: roles, grants, ownership, and metalake administration
  • Authorization Pushdown, for propagating those privileges into the underlying systems through Apache Ranger or a native permission model
  • Credential Vending, for issuing temporary storage credentials to engines instead of distributing long-lived keys
  • HTTPS, for the gravitino.server.webserver.* key store, trust store, and client certificate properties
  • CORS, for letting browser clients served from another origin call the API
  • Security