Data Mesh Sem a Complexidade: Um Bucket Por Time
Data mesh soa ótimo na teoria: propriedade descentralizada, dados orientados a domínio, infraestrutura self-serve. Na prática, geralmente significa 18 meses de trabalho de “time de plataforma” construindo um portal self-serve que ninguém usa.
Aqui está o segredo sujo: você não precisa de uma plataforma para fazer data mesh. Você precisa de um bucket por time e um pip install.
A promessa do data mesh (e a falha usual)
A promessa:
- Cada time é dono dos seus dados
- Sem gargalo central
- Infraestrutura self-serve
- Design orientado a domínio
A implementação usual:
- 6 meses construindo uma “plataforma de dados” com Terraform, Kubernetes e Airflow
- Um “time de plataforma” de 5 pessoas mantendo
- Times ainda não conseguem se integrar sem abrir um ticket
- $200k/ano em infraestrutura antes de qualquer query
A implementação DataSpoc:
- Cada time roda
pip install dataspoc-pipe dataspoc-lens - Cada time cria seu próprio bucket S3
- Cada time gerencia seus próprios pipelines
- Custo total: $0 + armazenamento S3 (~$5/mês por time)
- Tempo de setup: 30 minutos por time
A arquitetura
┌─────────────────────────────────────────────────────────────────┐│ Company Cloud (AWS/GCS/Azure) ││ ││ ┌─────────────────┐ ┌─────────────────┐ ┌────────────────┐ ││ │ s3://finance │ │ s3://product │ │ s3://marketing │ ││ │ │ │ │ │ │ ││ │ Pipe → Parquet │ │ Pipe → Parquet │ │ Pipe → Parquet │ ││ │ Lens → SQL/AI │ │ Lens → SQL/AI │ │ Lens → SQL/AI │ ││ │ ML → predictions │ │ │ │ │ ││ │ │ │ │ │ │ ││ │ IAM: finance-team│ │ IAM: product-team│ │ IAM: mkt-team │ ││ └─────────────────┘ └─────────────────┘ └────────────────┘ ││ ││ Cross-domain analyst: registers all 3 buckets in Lens ││ AI agent: connects via MCP, scoped to team's bucket │└─────────────────────────────────────────────────────────────────┘Cada time é uma plataforma de dados autocontida:
- Seu próprio bucket (dados isolados)
- Sua própria configuração Pipe (suas fontes, seu agendamento)
- Sua própria configuração Lens (suas queries, seus transforms)
- Seu próprio agente de IA (MCP com escopo no seu bucket)
Sem infraestrutura compartilhada. Sem time central. Sem tickets.
Configurando o time de Finance (exemplo)
Passo 1: Criar o bucket e IAM
# AWS (or equivalent for GCS/Azure)aws s3 mb s3://company-financeaws iam create-policy --policy-name finance-data-access --policy-document '{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": ["s3:GetObject", "s3:PutObject", "s3:ListBucket"], "Resource": ["arn:aws:s3:::company-finance", "arn:aws:s3:::company-finance/*"] }]}'Passo 2: Instalar e configurar o Pipe
pip install dataspoc-pipe[s3]dataspoc-pipe initPipeline: Postgres (ERP) → bucket Finance
source: tap: tap-postgres config: ~/.dataspoc-pipe/sources/erp.json streams: - invoices - payments - accounts_receivable
destination: bucket: s3://company-finance path: raw compression: zstd
incremental: enabled: true
schedule: cron: "0 6 * * *" # daily at 6amPipeline: Stripe → bucket Finance
source: tap: tap-stripe config: ~/.dataspoc-pipe/sources/stripe.json streams: - charges - refunds - subscriptions
destination: bucket: s3://company-finance path: raw compression: zstd
incremental: enabled: true
schedule: cron: "0 7 * * *"dataspoc-pipe run _ --alldataspoc-pipe schedule installPasso 3: Instalar e configurar o Lens
pip install dataspoc-lens[s3,ai,mcp]dataspoc-lens initdataspoc-lens add-bucket s3://company-financePasso 4: Criar transforms de domínio
-- ~/.dataspoc-lens/transforms/001_monthly_revenue.sqlCREATE OR REPLACE TABLE monthly_revenue ASSELECT DATE_TRUNC('month', created_at) AS month, SUM(amount) AS revenue, COUNT(*) AS transactions, SUM(CASE WHEN type = 'refund' THEN amount ELSE 0 END) AS refundsFROM chargesGROUP BY 1ORDER BY 1;-- ~/.dataspoc-lens/transforms/002_accounts_aging.sqlCREATE OR REPLACE TABLE accounts_aging ASSELECT customer_id, SUM(CASE WHEN DATEDIFF('day', due_date, CURRENT_DATE) > 90 THEN amount ELSE 0 END) AS over_90, SUM(CASE WHEN DATEDIFF('day', due_date, CURRENT_DATE) BETWEEN 60 AND 90 THEN amount ELSE 0 END) AS days_60_90, SUM(CASE WHEN DATEDIFF('day', due_date, CURRENT_DATE) BETWEEN 30 AND 60 THEN amount ELSE 0 END) AS days_30_60, SUM(CASE WHEN DATEDIFF('day', due_date, CURRENT_DATE) < 30 THEN amount ELSE 0 END) AS current_amountFROM accounts_receivableWHERE status = 'open'GROUP BY 1;dataspoc-lens transform runPasso 5: Conectar o agente de IA do time
dataspoc-lens mcpConfiguração Claude Desktop para o time de finance:
{ "mcpServers": { "finance-data": { "command": "dataspoc-lens", "args": ["mcp"] } }}Agora o agente de IA do CFO pode perguntar:
"What's our monthly revenue trend?""Which customers have overdue payments over $10k?""What's our net retention rate this quarter?"Cada resposta vem de SQL real nos dados do time de finance. Sem acesso aos buckets de outros times.
Configurando o time de Product (mesmo padrão, dados diferentes)
pip install dataspoc-pipe[s3] dataspoc-lens[s3,ai]dataspoc-pipe init# Product team sources: Postgres (app DB) + Mixpanel eventssource: tap: tap-postgres config: ~/.dataspoc-pipe/sources/app-db.json streams: - users - subscriptions - feature_flags
destination: bucket: s3://company-product path: raw compression: zstd
incremental: enabled: truedataspoc-lens add-bucket s3://company-productdataspoc-lens ask "how many users signed up last week?"O time de product tem zero visibilidade nos dados de finance. Finance tem zero visibilidade nos dados de product. IAM reforça as fronteiras, não código de aplicação.
Analytics cross-domain
O head de analytics precisa ver entre times. Simples — registre múltiplos buckets:
dataspoc-lens add-bucket s3://company-financedataspoc-lens add-bucket s3://company-productdataspoc-lens add-bucket s3://company-marketingAgora podem fazer JOIN entre domínios:
SELECT p.user_id, p.plan, f.lifetime_value, m.acquisition_channelFROM product_users pJOIN finance_customer_360 f ON p.user_id = f.customer_idJOIN marketing_attribution m ON p.user_id = m.user_idWHERE p.plan = 'enterprise';Isso só funciona se o papel IAM do analista tem acesso de leitura aos três buckets. O modelo de acesso é:
| Papel | Buckets | Vê |
|---|---|---|
| Analista Finance | s3://company-finance | Apenas dados de finance |
| PM de Product | s3://company-product | Apenas dados de product |
| Head de Analytics | Todos os 3 | JOINs cross-domain |
| Agente IA do CEO | Todos os 3 | Tudo via MCP |
| Agente do time | Apenas bucket do time | Dados com escopo |
Princípios de data mesh mapeados para DataSpoc
| Princípio | Como o DataSpoc implementa |
|---|---|
| Propriedade de domínio | Cada time é dono do seu bucket, seus pipelines, seus transforms |
| Dados como produto | Manifest.json cataloga o que está disponível. Camadas clean/gold são o “produto” |
| Plataforma self-serve | pip install — sem tickets, sem time de plataforma |
| Governança federada | Cloud IAM no nível do bucket. Sem autenticação no nível da aplicação |
| Interoperabilidade | Mesmo formato (Parquet), mesma convenção (estrutura do bucket), mesmas ferramentas |
| Descobribilidade | dataspoc-lens catalog mostra todas as tabelas nos seus buckets registrados |
O contrato de dados: convenção de bucket
Times concordam em uma coisa — a estrutura do bucket:
s3://team-bucket/ .dataspoc/manifest.json # What tables exist (auto-generated) raw/<source>/<table>/*.parquet # Raw ingested data curated/<domain>/<table>/*.parquet # Cleaned data gold/<domain>/<table>/*.parquet # Business-ready aggregationsEste é o único contrato entre times. Se o time A quer compartilhar dados com o time B, eles concedem IAM de leitura no seu bucket. O time B registra com dataspoc-lens add-bucket. Pronto.
Sem API para construir. Sem catálogo de dados para manter. Sem reuniões de governança. O manifesto É o catálogo.
Escalando: de 1 time para 20
Team 1: pip install → bucket → pipe → lens → agent (30 min)Team 2: pip install → bucket → pipe → lens → agent (30 min)Team 3: pip install → bucket → pipe → lens → agent (30 min)...Team 20: pip install → bucket → pipe → lens → agent (30 min)Cada time é independente. Adicionar o time 20 não afeta os times 1-19. Sem Airflow compartilhado. Sem warehouse compartilhado. Sem compute compartilhado.
O que um “time de plataforma” faz neste modelo:
- Cria buckets e políticas IAM para novos times (5 min por time)
- Mantém o acesso do analista cross-domain
- Ajuda times com o primeiro setup de pipeline (oferta de serviço)
- Só isso. Sem Kubernetes. Sem Terraform. Sem time de 5 pessoas.
Custo por time
| Item | Custo |
|---|---|
| DataSpoc Pipe | $0 (open source) |
| DataSpoc Lens | $0 (open source) |
| Armazenamento S3 (50GB) | ~$1.15/mês |
| Requisições S3 | ~$2/mês |
| Total por time | ~$3-5/mês |
Para uma empresa de 10 times: $30-50/mês total. Compare com Databricks ($30k-100k/ano) ou Snowflake ($24k-120k/ano).
Quando isso não funciona
Sendo honesto:
- Escala de petabytes por time — DuckDB não aguenta. Precisa de Spark/Trino.
- Requisitos de real-time — DataSpoc é batch. Precisa de Kafka + Flink.
- Governança/compliance pesada — Precisa de um catálogo de dados real (DataHub, Atlan). Manifest.json é mínimo.
- 100+ fontes de dados por time — Gerenciar muitos taps Singer pode ficar complexo. Considere Meltano.
- Time sem habilidade técnica nenhuma — Precisa de conforto com CLI. Se não sabem
pip install, use Fivetran + Looker.
Experimente
Configure seu primeiro domínio em 10 minutos:
pip install dataspoc-pipe[s3] dataspoc-lens[s3,mcp]
# Create your domaindataspoc-pipe initdataspoc-pipe add my-sourcedataspoc-pipe run my-source
# Query your domaindataspoc-lens initdataspoc-lens add-bucket s3://my-team-datadataspoc-lens shell
# Connect your team's AI agentdataspoc-lens mcpData mesh não é um produto que você compra. É um padrão que você segue. O DataSpoc torna o padrão trivial: um bucket por time, pip install, pronto.