Cloud Bigtable é o banco de dados NoSQL wide-column do GCP. Projetado para cargas com alto throughput de escrita e latência sub-milissegundo em escala massiva: séries temporais, telemetria, IoT e analytics de eventos.
É a implementação gerenciada do paper “Bigtable: A Distributed Storage System for Structured Data” (Google, 2006) e a tecnologia por trás do Google Search, Google Analytics e Gmail.
Quando usar Bigtable
| Use Bigtable | Não use |
|---|---|
| > 1 TB de dados, > 100k ops/s | Dados analíticos ad-hoc (use gcp-bigquery) |
| Séries temporais, telemetria, IoT | Transações ACID (use gcp-spanner ou gcp-cloud-sql) |
| Latência P99 < 10ms em leitura/escrita | Documentos hierárquicos (use gcp-firestore) |
| Compatibilidade com HBase API | Dataset < 1 TB (custo não justificado) |
Modelo de dados
Bigtable é uma tabela ordenada por row key. Não há colunas fixas: cada linha pode ter células em qualquer coluna dentro de uma família:
Row Key | familia:coluna_a | familia:coluna_b | metricas:temp
-------------------|------------------|------------------|-------------
device#001#ts_inv | 23.5 @ ts3 | OK @ ts3 |
| 22.1 @ ts2 | |
device#002#ts_inv | 19.8 @ ts1 | OK @ ts1 | 19.8 @ ts1
- Row Key: string arbitrária, único índice disponível, determina ordem e distribuição
- Column Family: grupo de colunas com política de garbage collection compartilhada (ex:
cf,metrics) - Cell: interseção de linha + coluna, pode ter múltiplas versões por timestamp
- Timestamp: versão da célula (tempo real ou lógico), usada para versionamento e GC
Design de row key (crítico)
O row key é o único índice disponível. Queries ineficientes surgem de row keys mal projetados. Hotspots surgem quando muitas escritas vão para o mesmo nó (tablet).
Padrões recomendados
import time, hashlib
# Série temporal: device + timestamp invertido (mais recente vem primeiro no scan)
ts_invertido = str(2**63 - int(time.time() * 1000))
row_key = f"device#001#{ts_invertido}".encode()
# Hash prefix para distribuir IDs sequenciais ou UUIDs
prefix = hashlib.md5(user_id.encode()).hexdigest()[:4]
row_key = f"{prefix}#{user_id}#{event_type}".encode()
# Domínio invertido (distribui melhor do que domínio direto)
# "google.com/path" → "com.google#path"
row_key = f"com.google#/path/to/page".encode()Antipadrões de row key
# Ruim: timestamp crescente como prefixo → hotspot no split mais recente
"2026-05-05T10:00:00#evento-id"
# Ruim: domínio popular como prefixo → hotspot em "google.com"
"google.com/..."
# Ruim: ID sequencial sem hash → hotspot crescente
"0001", "0002", "0003", ...
Instância e clusters
# Instância de produção (SSD, 3 nodes)
gcloud bigtable instances create minha-instancia \
--display-name="Produção" \
--cluster=cluster-br \
--cluster-zone=southamerica-east1-a \
--cluster-num-nodes=3 \
--cluster-storage-type=SSD
# Cluster adicional para replicação cross-region
gcloud bigtable clusters create cluster-us \
--instance=minha-instancia \
--zone=us-central1-a \
--num-nodes=3
# Autoscaling de nodes
gcloud bigtable clusters update cluster-br \
--instance=minha-instancia \
--autoscaling-min-nodes=1 \
--autoscaling-max-nodes=10 \
--autoscaling-cpu-target=60Operações com Python SDK
from google.cloud import bigtable
from google.cloud.bigtable import row_filters
import time
client = bigtable.Client(project="meu-projeto", admin=True)
instance = client.instance("minha-instancia")
table = instance.table("eventos")
# Escrita de uma célula
row_key = b"device#001#9999850000000"
row = table.direct_row(row_key)
row.set_cell(
column_family_id="cf",
column="temperatura",
value=b"23.5",
timestamp_micros=int(time.time() * 1e6)
)
row.commit()
# Escrita em lote (mais eficiente)
rows = []
for device_id, temp in dados:
ts_inv = str(2**63 - int(time.time() * 1000))
row = table.direct_row(f"device#{device_id}#{ts_inv}".encode())
row.set_cell("cf", "temperatura", str(temp).encode())
rows.append(row)
errors = table.mutate_rows(rows)
# Leitura por row key exato
row = table.read_row(b"device#001#9999850000000")
if row:
cell = row.cells["cf"][b"temperatura"][0]
print(cell.value.decode())
# Scan com prefix (range query eficiente)
rows = table.read_rows(
start_key=b"device#001#",
end_key=b"device#001$", # "$" vem depois de "#" em ASCII
filter_=row_filters.CellsColumnLimitFilter(1) # apenas versão mais recente
)
for row in rows:
print(row.row_key, row.cells)Filtros
Bigtable tem filtros compostos aplicados no servidor, reduzindo dados transferidos:
from google.cloud.bigtable import row_filters
from datetime import datetime, timezone
# Filtro de timestamp (range)
time_filter = row_filters.TimestampRangeFilter(
start=datetime(2026, 5, 1, tzinfo=timezone.utc),
end=datetime(2026, 5, 5, tzinfo=timezone.utc)
)
# Filtro de valor com regex
value_filter = row_filters.ValueRegexFilter(b"^error.*")
# Limitar versões retornadas
version_filter = row_filters.CellsColumnLimitFilter(1)
# Composição: AND (chain)
chain = row_filters.RowFilterChain(filters=[time_filter, version_filter])
# Composição: OR (union)
union = row_filters.RowFilterUnion(filters=[filter_a, filter_b])
rows = table.read_rows(filter_=chain)Column families e garbage collection
from google.cloud.bigtable import column_family
import datetime
# Criar tabela com políticas de GC por família
cf_versoes = column_family.MaxVersionsGCRule(3) # manter 3 versões
cf_tempo = column_family.MaxAgeGCRule(datetime.timedelta(days=30)) # manter 30 dias
cf_uniao = column_family.GCRuleUnion([cf_versoes, cf_tempo]) # OR: apaga se qualquer regra for satisfeita
table.create(column_families={
"cf": cf_versoes,
"metricas": cf_tempo,
"raw": cf_uniao
})App Profiles
Controlam o roteamento de requisições para clusters (útil com replicação):
# Routing distribuído (eventually consistent, maior disponibilidade)
gcloud bigtable app-profiles create perfil-leitura \
--instance=minha-instancia \
--route-any
# Routing para cluster específico (consistência forte)
gcloud bigtable app-profiles create perfil-escrita \
--instance=minha-instancia \
--route-to=cluster-brIntegração com Dataflow
from apache_beam.io.gcp.bigtableio import ReadFromBigtable, WriteToBigtable
# Leitura
with beam.Pipeline() as p:
rows = p | ReadFromBigtable(
project_id="meu-projeto",
instance_id="minha-instancia",
table_id="eventos"
)
rows | beam.Map(processar_linha)Key Visualizer
Ferramenta no console GCP que exibe mapa de calor de acesso por row key ao longo do tempo. Ferramenta principal para diagnosticar hotspots.
# Ativar Key Visualizer na instância
gcloud bigtable instances update minha-instancia \
--enable-key-visualizerMonitoramento
- Cloud Monitoring:
bigtable.googleapis.com/cluster/cpu_load,bigtable.googleapis.com/server/latencies - Key Visualizer: identifica hotspots e distribuição de carga por row key
- Métricas por tabela e cluster no console GCP
Ver também: gcp | gcp-bigquery | gcp-dataflow | gcp-firestore | gcp-boas-praticas | db-tipos-de-bancos-de-dados | db-nosql