agentsclimarketplace

Trino lakehouse platform architect

Skill ivanshamaev/de-agent-skills/group_skills/trino_group_skills/trino_lakehouse_platform_architect

Trino-based Modern Data Platform architecture design — decoupled storage/compute, Iceberg as open table format, Hive Metastore/Glue catalog, MinIO/S3 object storage, Kafka ingestion layer, dbt transformation, Airflow orchestration, Superset BI — coordinator/worker topology, catalog design, metadata-driven architecture, multi-layer lakehouse (Bronze/Silver/Gold), federated query across heterogeneous sourcesFrom its SKILL.md

Install
npx -y skills add ivanshamaev/de-agent-skills --skill trino_lakehouse_platform_architect

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 15 stars15 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

10.4 KB, ~2.3k tokens by cl100k_base, as published. Nobody here has run it

Trino Lakehouse Platform Architecture

When to Use

  • Designing a new Trino-based data platform from scratch
  • Migrating from legacy Hadoop/Hive stack to a Modern Data Stack
  • Architecting decoupled storage/compute to eliminate vendor lock-in
  • Building a multi-tenant analytical platform with federated query across databases, object storage, and streaming sources
  • Choosing between Trino, Spark, ClickHouse for the query layer

Core Architecture: Compute vs Storage Separation

┌──────────────────────────────────────────────────────────────────┐
│                        BI Layer                                   │
│         Superset / Metabase / Grafana / Tableau                  │
└────────────────────────────┬─────────────────────────────────────┘
                             │ SQL
┌────────────────────────────▼─────────────────────────────────────┐
│                     Query Layer: Trino                            │
│   Coordinator (1 per cluster) + Workers (auto-scale)            │
│   Catalogs: iceberg, postgresql, kafka, mysql, ...              │
└──────┬────────────┬──────────────┬──────────────────────────────┘
       │            │              │
┌──────▼──┐  ┌──────▼──────┐  ┌───▼────────────────────────┐
│ Iceberg  │  │  PostgreSQL  │  │  Kafka (read via connector) │
│ (S3/GCS) │  │  (OLTP)     │  │  (streaming data preview)  │
└──────┬──┘  └─────────────┘  └────────────────────────────┘
       │
┌──────▼──────────────────────────────────────────────────────────┐
│           Object Storage: MinIO / AWS S3 / GCS                   │
│   bronze/  silver/  gold/  (Parquet + Iceberg metadata)         │
└──────────────────────────────────────────────────────────────────┘
       │
┌──────▼──────────────────────────────────────────────────────────┐
│           Catalog / Metastore Layer                              │
│   Hive Metastore (HMS) / AWS Glue / REST catalog / Nessie       │
└──────────────────────────────────────────────────────────────────┘

Design principle: Trino is the query engine only — it stores nothing. All data lives in object storage (S3/GCS/MinIO) as open-format Iceberg/Parquet files.


Cluster Topology

Coordinator

# etc/config.properties — coordinator
coordinator=true
node-scheduler.include-coordinator=false   # never schedule work on coordinator
http-server.http.port=8080
discovery.uri=http://trino-coordinator:8080
query.max-memory=50GB
query.max-memory-per-node=10GB
query.max-total-memory=60GB
query.max-history=1000
query.min-expire-age=30m

Workers

# etc/config.properties — worker
coordinator=false
http-server.http.port=8080
discovery.uri=http://trino-coordinator:8080

JVM (per node, scale Xmx to ~80% of RAM)

# etc/jvm.config
-server
-Xmx54G
-XX:InitialRAMPercentage=80
-XX:MaxRAMPercentage=80
-XX:G1HeapRegionSize=32M
-XX:+ExplicitGCInvokesConcurrent
-XX:+ExitOnOutOfMemoryError
-XX:+HeapDumpOnOutOfMemoryError
-XX:ReservedCodeCacheSize=512M
-Djdk.attach.allowAttachSelf=true
-Djdk.nio.maxCachedBufferSize=2000000

OS Prerequisites

# /etc/security/limits.conf
* soft nofile 131072
* hard nofile 131072
* soft nproc  128000
* hard nproc  128000

Catalog Design

Each catalog maps Trino to one data source via a properties file in etc/catalog/.

Iceberg on S3 + HMS

# etc/catalog/iceberg.properties
connector.name=iceberg
iceberg.catalog.type=hive_metastore
hive.metastore.uri=thrift://hive-metastore:9083
hive.s3.path-style-access=true
hive.s3.endpoint=http://minio:9000
hive.s3.aws-access-key=minio_access
hive.s3.aws-secret-key=minio_secret
iceberg.file-format=PARQUET
iceberg.compression-codec=ZSTD
iceberg.max-partitions-per-writer=100
iceberg.table-statistics-enabled=true
iceberg.target-max-file-size=512MB

Iceberg on S3 + Glue (AWS)

connector.name=iceberg
iceberg.catalog.type=glue
hive.metastore.glue.region=us-east-1
hive.s3.region=us-east-1
iceberg.file-format=PARQUET
iceberg.compression-codec=ZSTD

PostgreSQL (operational DB)

# etc/catalog/postgresql.properties
connector.name=postgresql
connection-url=jdbc:postgresql://postgres:5432/appdb
connection-user=trino_reader
connection-password=${ENV:POSTGRES_PASSWORD}
metadata.cache-ttl=5m
dynamic-filtering.enabled=true

Kafka (event preview)

# etc/catalog/kafka.properties
connector.name=kafka
kafka.nodes=kafka:9092
kafka.hide-internal-columns=false

Lakehouse Layer Design

LayerIceberg SchemaKey PropertiesUse Case
Bronzeiceberg.bronzeformat=PARQUET, no partitionRaw ingestion, append-only
Silvericeberg.silverformat=PARQUET, partitioning=ARRAY['day(event_time)']Cleaned, deduplicated
Goldiceberg.goldformat=PARQUET, partitioned + sortedAnalytical aggregates
-- Bronze: raw events, append only
CREATE SCHEMA iceberg.bronze WITH (location = 's3://data-lake/bronze/');

CREATE TABLE iceberg.bronze.orders_raw (
    raw_payload VARCHAR,
    kafka_topic  VARCHAR,
    kafka_offset BIGINT,
    ingested_at  TIMESTAMP(6)
)
WITH (
    format = 'PARQUET',
    compression_codec = 'ZSTD'
);

-- Silver: curated orders
CREATE SCHEMA iceberg.silver WITH (location = 's3://data-lake/silver/');

CREATE TABLE iceberg.silver.orders (
    order_id     BIGINT        NOT NULL,
    customer_id  BIGINT,
    order_date   DATE,
    amount       DECIMAL(18,2),
    status       VARCHAR,
    updated_at   TIMESTAMP(6)
)
WITH (
    format = 'PARQUET',
    partitioning = ARRAY['day(order_date)'],
    sorted_by    = ARRAY['customer_id'],
    compression_codec = 'ZSTD',
    format_version = 2
);

-- Gold: aggregated fact
CREATE SCHEMA iceberg.gold WITH (location = 's3://data-lake/gold/');

CREATE TABLE iceberg.gold.daily_revenue (
    order_date      DATE,
    region          VARCHAR,
    total_orders    BIGINT,
    gross_revenue   DECIMAL(18,2),
    net_revenue     DECIMAL(18,2)
)
WITH (
    format = 'PARQUET',
    partitioning = ARRAY['month(order_date)', 'region'],
    sorted_by    = ARRAY['order_date DESC'],
    compression_codec = 'ZSTD'
);

Technology Selection Matrix

NeedRecommendedWhy
Large analytical queries across data lakeTrinoDistributed SQL, federated, no data lock-in
Sub-second dashboard queries on pre-aggregated dataClickHouseColumnar, co-located compute+storage
ML feature engineering at scaleSparkUDFs, MLlib, Python ecosystem
Operational queries on fresh OLTP dataPostgreSQL/MySQL directLow latency, indexes
Mixed: federate OLTP + data lakeTrinoCross-catalog JOIN

Component Stack Reference

ComponentTechnologyVersion
Query engineTrino481+
Table formatApache Iceberg1.7+
MetastoreHive Metastore 3.x / AWS Glue3.1.3
Object storageMinIO (on-prem) / AWS S3 / GCS-
Transformationdbt-trino1.8+
OrchestrationApache Airflow2.9+
Streaming ingestApache Kafka + Flink/Debezium-
BIApache Superset4.x
MonitoringPrometheus + Grafana-

Anti-Patterns

  1. Running Trino coordinator on the same node that runs heavy workers — dedicate coordinator, set node-scheduler.include-coordinator=false in production.
  2. Using Hive-style static partitions (date=2024-01-01) instead of Iceberg hidden partitioning — Iceberg transforms (day(ts)) enable partition evolution and don't require client-side partition pruning.
  3. One giant catalog for all data — separate catalogs by domain or environment (bronze/silver/gold as schemas within iceberg, not as separate catalogs) for RBAC and resource isolation.
  4. Cross-catalog JOINs between connectors — Trino fetches data from each connector separately then joins in-memory; expensive for large tables. Pre-materialize into Iceberg when JOIN is frequent.
  5. JVM heap under 16GB per worker — Trino is memory-intensive; workers with less than 16GB heap will spill constantly; 32–64GB is typical production sizing.
  6. Omitting sorted_by on Gold tables — sorted files dramatically improve filter performance and compaction efficiency on large analytical tables.

References

  • Trino deployment: trino.io/docs/current/installation/deployment.html
  • Iceberg connector: trino.io/docs/current/connector/iceberg.html
  • Trino concepts: trino.io/docs/current/overview/concepts.html
  • Related skills: [[trino-iceberg-best-practices]], [[trino-query-optimization]], [[trino-docker-compose-stack]], [[trino-production-readiness-review]]

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.