TigerBeetle — Banco de Dados Financeiro de Alta Performance em Zig
O TigerBeetle é um dos projetos mais ambiciosos e bem-sucedidos construídos com Zig. Trata-se de um banco de dados distribuído projetado especificamente para contabilidade financeira, capaz de processar milhões de transações por segundo com garantias ACID rigorosas. O TigerBeetle demonstra que Zig é capaz de competir com C e C++ em sistemas de missão crítica.
O Que É o TigerBeetle
O TigerBeetle é um banco de dados OLTP (Online Transaction Processing) otimizado para o caso de uso específico de ledgers financeiros — registros contábeis que rastreiam saldos, transferências e transações monetárias. Diferente de bancos de dados genéricos como PostgreSQL ou MySQL, o TigerBeetle é projetado do zero para garantir:
- Correção absoluta: Nunca perder dinheiro por bugs de software
- Performance extrema: Milhões de transações por segundo
- Durabilidade: Dados nunca são perdidos, mesmo em falhas de hardware
- Auditabilidade: Cada transação é rastreável e imutável
Por Que Zig
A equipe do TigerBeetle escolheu Zig por razões técnicas específicas:
- Controle de memória determinístico: Sem GC significa latência previsível
- Compilação cruzada: Deploy fácil em qualquer arquitetura
- Interoperabilidade C: Reutilização de código existente quando necessário
- Segurança de memória em tempo de compilação: Detecção de bugs antes da produção
- Performance comparável a C: Sem overhead de runtime
Joren Spit, CEO do TigerBeetle, descreveu a escolha: “Zig nos dá a performance de C com a segurança e produtividade que precisamos para construir infraestrutura financeira confiável.”
Arquitetura
Motor de Armazenamento
O TigerBeetle usa um motor de armazenamento customizado chamado LSM-Forest (Log-Structured Merge Forest), uma variação otimizada do LSM-Tree:
┌─────────────────────────────────┐
│ WAL (Write-Ahead Log) │
├─────────────────────────────────┤
│ Memtable (RAM) │
├─────────────────────────────────┤
│ Level 0 (Disco) │
├─────────────────────────────────┤
│ Level 1 (Disco) │
├─────────────────────────────────┤
│ Level N (Disco) │
└─────────────────────────────────┘
Esse design permite:
- Escritas sequenciais no disco (otimizado para SSDs)
- Compactação em background sem impactar latência
- Recuperação rápida após falhas
Consenso Distribuído
O TigerBeetle implementa o protocolo Viewstamped Replication (VSR) para consenso distribuído, garantindo que o cluster continue operando mesmo com falhas de nós:
┌──────────┐
│ Primary │
│ (Líder) │
└────┬─────┘
│
┌────────┼────────┐
│ │ │
┌───▼──┐ ┌──▼───┐ ┌──▼───┐
│Backup│ │Backup│ │Backup│
│ 1 │ │ 2 │ │ 3 │
└──────┘ └──────┘ └──────┘
O cluster tolera f falhas com 2f + 1 nós. Um cluster de 5 nós tolera 2 falhas simultâneas.
I/O Direto
O TigerBeetle utiliza Direct I/O (O_DIRECT no Linux) e io_uring para I/O assíncrono de alta performance, bypassando o cache do sistema operacional:
// Exemplo conceitual do I/O direto usado pelo TigerBeetle
const file = try std.fs.openFileAbsolute("/data/tigerbeetle.dat", .{
.mode = .read_write,
.intended_io_mode = .direct,
});
// Writes alinhados para I/O direto
const aligned_buffer = try std.heap.page_allocator.alignedAlloc(
u8,
std.mem.page_size,
block_size,
);
Modelo de Dados
O TigerBeetle trabalha com dois tipos fundamentais:
Accounts (Contas)
Account {
id: u128, // Identificador único
debits_pending: u128, // Débitos pendentes
debits_posted: u128, // Débitos confirmados
credits_pending: u128, // Créditos pendentes
credits_posted: u128, // Créditos confirmados
user_data_128: u128, // Dados customizados
user_data_64: u64,
user_data_32: u32,
ledger: u32, // Ledger ao qual pertence
code: u16, // Tipo da conta
flags: u16, // Flags de comportamento
timestamp: u64, // Timestamp de criação
}
Transfers (Transferências)
Transfer {
id: u128, // Identificador único
debit_account_id: u128, // Conta debitada
credit_account_id: u128, // Conta creditada
amount: u128, // Valor da transferência
pending_id: u128, // ID da transferência pendente
user_data_128: u128,
user_data_64: u64,
user_data_32: u32,
timeout: u32, // Timeout em segundos
ledger: u32,
code: u16,
flags: u16,
timestamp: u64,
}
Usando o TigerBeetle
Instalação
# Download do binário
curl -Lo tigerbeetle https://github.com/tigerbeetle/tigerbeetle/releases/latest/download/tigerbeetle-linux-x86_64
chmod +x tigerbeetle
# Criar arquivo de dados
./tigerbeetle format --cluster=0 --replica=0 --replica-count=1 0_0.tigerbeetle
# Iniciar o servidor
./tigerbeetle start --addresses=3001 0_0.tigerbeetle
Cliente em Zig
const tb = @import("tigerbeetle");
pub fn main() !void {
var client = try tb.Client.init(
std.heap.page_allocator,
0, // cluster_id
&.{std.net.Address.parseIp4("127.0.0.1", 3001) catch unreachable},
);
defer client.deinit();
// Criar contas
const accounts = [_]tb.Account{
.{
.id = 1,
.ledger = 700,
.code = 10,
.flags = .{},
},
.{
.id = 2,
.ledger = 700,
.code = 10,
.flags = .{},
},
};
_ = try client.createAccounts(&accounts);
// Criar transferência
const transfers = [_]tb.Transfer{
.{
.id = 1,
.debit_account_id = 1,
.credit_account_id = 2,
.amount = 1000, // R$ 10,00 em centavos
.ledger = 700,
.code = 1,
.flags = .{},
},
};
_ = try client.createTransfers(&transfers);
// Consultar saldos
const results = try client.lookupAccounts(&.{1, 2});
for (results) |account| {
std.debug.print("Conta {}: débitos={}, créditos={}\n", .{
account.id,
account.debits_posted,
account.credits_posted,
});
}
}
Clientes em Outras Linguagens
O TigerBeetle oferece clientes oficiais para diversas linguagens:
- Go:
go get github.com/tigerbeetle/tigerbeetle-go - Java: Via Maven Central
- C#/.NET: Via NuGet
- Node.js:
npm install tigerbeetle-node - Python:
pip install tigerbeetle
Performance
Os benchmarks do TigerBeetle são impressionantes:
- ~3.4 milhões de transações/segundo em um único nó
- Latência p99 < 1ms para operações de transferência
- Throughput linear com hardware adicional no cluster
- Zero downtime durante failover de líder
Casos de Uso
O TigerBeetle é usado em cenários como:
- Fintechs e neobancos: Processamento de pagamentos em tempo real
- Marketplaces: Split de pagamentos e escrow
- Exchanges de criptomoedas: Registro de ordens e saldos
- Sistemas de fidelidade: Pontos e recompensas
- Jogos online: Economias virtuais
Confira o case detalhado do TigerBeetle para mais informações sobre adoção em produção.
Boas Práticas
- Use transferências com dois passos (pending + posting) para operações complexas
- Projete seus ledgers cuidadosamente — cada ledger é um namespace isolado
- Use user_data para vincular transferências a entidades do seu sistema
- Configure cluster com pelo menos 3 réplicas para produção
- Monitore latência e throughput com as métricas exportadas pelo TigerBeetle
Próximos Passos
Explore outros drivers de banco de dados do ecossistema Zig, aprenda sobre as bibliotecas de rede que suportam comunicação eficiente, e veja como fintechs usam Zig em produção. Para aprender mais sobre Zig, visite nossos tutoriais.