Cache

Cache#

Rotas /v1/cloudcache/* · owner/admin · gated por CLOUDCACHE_DEDICATED_ENABLED (off → 404 CLOUDCACHE_DEDICATED_UNAVAILABLE)

O que é#

Redis gerenciado, dedicated-only: cada cliente que quer cache provisiona a própria instância Redis numa VM dedicada (core/RAM/eviction/falha isolados, não compartilha com ninguém). Igual ao Database (decisão D1), é control-plane only — o seu app conecta direto no DSN via qualquer cliente Redis (redis.UniversalClient, ioredis, etc.); a Catcher não faz proxy de comando, então não há latência extra no caminho quente.

O modelo shared anterior (namespaces ACL sobre tiers ephemeral/retained compartilhados) foi aposentado em 2026-06-25. As rotas …/cloudcache/namespaces* não existem mais — hoje é só dedicated.

O que dá pra fazer#

  • Estimar o custo mensal antes de provisionar (dry-run, não cria nada).
  • Provisionar uma VM Redis dedicada (assíncrono) — a senha aparece uma vez.
  • Listar / detalhar suas instâncias (status + dsn_host quando ready).
  • Redimensionar (muda máquina/RAM), pausar/religar (corta o custo de compute), reconciliar o status com a VM real, destruir.
  • Ver métricas da VM (CPU/memória/etc.).

Como funciona por dentro (na prática)#

  • Control-plane + VM real. A API guarda a control-row no tenant DB; o Redis roda numa VM Debian dedicada (startup-script instala + configura o Redis por modo + hardening), sem service account (zero credencial na VM), servindo Redis TLS (rediss://) na porta 6380 com um cert Let's Encrypt para o host brandado da VM (DNS próprio, ou <ip>.sslip.io como fallback).
  • Dois modos:
    • mem_fastnoeviction, dimensionado por RAM, sub-ms, mais caro. Para cache que não pode perder chave sob pressão.
    • economicoallkeys-lru, RAM menor, mais barato — um miss cai no banco. É eviction, não swap.
  • Provisionamento assíncrono. POST …/dedicated responde com a instância pending/provisioning + a senha (uma única vez); você faz poll de GET …/dedicated/{id} até ready, quando o dsn_host aparece.
  • Conexão direta, por TLS. A resposta traz dsn_host + tls. O endpoint é um rediss:// TLS roteável (porta 6380, cert Let's Encrypt, host brandado), então o DSN é rediss://default:<senha>@<dsn_host> e o app conecta de qualquer lugar por TLS. (Um host interno plaintext usaria o esquema redis://.)

Fluxo típico (end-to-end)#

bash
KEY="X-API-Key: ctc_…" ; B=https://data-api.catcher.one ; JS='Content-Type: application/json'

# 1. Veja o custo ANTES de criar (dry-run, não provisiona)
curl -sX POST $B/v1/cloudcache/dedicated/estimate -H "$KEY" -H "$JS" \
  -d '{"mode":"mem_fast","machine":"e2-medium","ram_mb":4096,"disk_gb":20,"region":"southamerica-east1"}'
# → { "total_usd": 31.80, ... }

# 2. Provisiona (assíncrono) — a senha vem UMA vez, guarde já
curl -sX POST $B/v1/cloudcache/dedicated -H "$KEY" -H "$JS" \
  -d '{"name":"prod","mode":"economico","machine":"e2-micro","ram_mb":1024,"disk_gb":20,"region":"southamerica-east1"}'
# → { "instance": { "id":"…","status":"provisioning",… }, "password":"…" }

# 3. Poll até ready (o dsn_host aparece quando pronto)
curl -s $B/v1/cloudcache/dedicated/<id> -H "$KEY" | jq '.status, .dsn_host'

# 4. No seu app: conecta direto por TLS (DSN = rediss://default:<senha>@<dsn_host>)
#    e prefixe as chaves por tenant — ver a seção abaixo.

Referência de endpoints#

Método Rota O que faz
POST /v1/cloudcache/dedicated/estimate Custo $/mês ({mode,machine,ram_mb,disk_gb,region}) — dry-run, não cria
POST /v1/cloudcache/dedicated Provisiona (async) → {instance, password} (senha uma vez)
GET /v1/cloudcache/dedicated Lista as instâncias
GET /v1/cloudcache/dedicated/{id} Detalhe (status + dsn_host quando ready)
GET /v1/cloudcache/dedicated/{id}/metrics Métricas da VM (CPU/memória/…)
POST /v1/cloudcache/dedicated/{id}/resize Muda máquina/modo ({machine,ram_mb}; stop→resize→start)
POST /v1/cloudcache/dedicated/{id}/stop · /start Pausa (corta custo de compute) / religa
POST /v1/cloudcache/dedicated/{id}/reconcile Re-sincroniza o status com a VM real (não-disruptivo)
DELETE /v1/cloudcache/dedicated/{id} Destrói a VM + a control-row

O custo aparece na ativação ANTES de confirmar (ex.: e2-micro econômico ~US$ 10,20/mês · e2-medium mem-fast ~US$ 31,80/mês).

Isolamento por tenant (end-customers)#

Como o Cache é control-plane only (você conecta direto no DSN; não há proxy de comando), o isolamento por cliente final é por convenção, aplicada no SEU código:

  1. Prefixe toda chave de um tenant com t:<tenant_id>: — ex. t:acme:sessao:123.
  2. (Recomendado) crie um usuário ACL do Redis por tenant, restrito ao padrão ~t:<tenant_id>:*, de modo que aquele tenant não leia/escreva fora do próprio prefixo.

É o mesmo tenant_id que você usa no Database, Vector e Storage — o eixo transversal. Modelo completo + recomendações: Tenants.

Códigos de erro do módulo#

CLOUDCACHE_DEDICATED_UNAVAILABLE (404 — feature desligada no ambiente, ou o wiring de GCP Compute não pôde ser construído).

Gotchas#

  • A senha aparece uma única vez (na criação) — guarde no seu secret manager. Para trocar, redimensione/recrie conforme a necessidade.
  • Provisionar é assíncrono — não trate a criação como pronta; faça poll de GET …/dedicated/{id} até ready (o dsn_host só aparece então).
  • Endpoint TLS público (rediss:// :6380) — host brandado com cert Let's Encrypt; a conexão é criptografada. O esquema vem indicado pelo campo tls na resposta (rediss:// quando público-TLS, redis:// se host interno plaintext).
  • economico é eviction, não swap — sob pressão, chaves são descartadas (allkeys-lru) e o miss cai no banco. Use mem_fast quando não pode perder chave.
  • stop corta o custo de compute mas mantém a instância — útil para ambientes que não rodam 24/7. reconcile conserta uma control-row presa em failed após timeout de uma operação de control-plane, sem reiniciar a VM.