Postgresql e ZFS
Por que eu preciso do ZFS em vez do TOAST embutido?
Para o tghub, eu uso um VPS bastante barato com apenas 1tb de armazenamento. Então eu preciso comprimir meus dados. Apesar do fato de que o Postgresql possui a funcionalidade TOAST (The Oversized-Attribute Storage Technique), ela não serve para mim. Por padrão, o TOAST é acionado para dados de texto com tamanho de 2 kB. A tabela de mensagens do meu projeto tghub tem quase 3 bilhões de linhas e continua crescendo, mas elas geralmente são pequenas, portanto, TOAST não funcionará para mim. Decidi tentar armazenar os dados das mensagens em um tablespace separado e movê-los para o sistema de arquivos ZFS.
Esquema de alto nível
Performance atual
Consegui alcançar um bom equilíbrio entre os drives.
- sda -- Tablespace Padrão
- sdb -- Tablespace ZFS
- sdc -- Tablespace de Índices
Durante a carga de trabalho normal, o disco de índices é o mais ocupado, o que é esperado. O disco possui 2 índices que estão sendo alterados por inserções aleatórias (~800 linhas por segundo). É melhor não sobrecarregar o drive com o tablespace padrão, porque ele possui índices para busca. Quando muitos usuários decidem buscar algo ao mesmo tempo, esse disco deve ter capacidade.
Ajustando Postgresql e ZFS
Fiz algumas configurações adicionais para o zfs e postgresql:
- Desativar TOAST, para não comprimir os dados duas vezes:
ALTER TABLE channel_message
ALTER COLUMN text SET STORAGE EXTERNAL;
- Seguir recomendações do zfs para bancos de dados e definir o tamanho do setor para 32K. O tamanho padrão é 128K. É muito e causa leituras indesejadas. Podemos até definir o tamanho do setor para 8K, mas isso diminui a taxa de compressão. É importante encontrar um equilíbrio entre velocidade de leitura (setor menor) e taxa de compressão (setor maior)
sudo zfs set recordsize=32K datapool
- Desativar tempo de atualização, realmente não faz sentido:
sudo zfs set atime=off datapool
- Definir compressão para zstd, é mais lento que lz4, mas tem uma melhor taxa de compressão (pode ser x2 para dados de texto):
sudo zfs set atime=off datapool
Atualmente, minha tabela channel_message com quase 3 bilhões de linhas ocupa 1061Gb descompactados versus 291Gb compactados no disco ZFS. É uma proporção de mais de 3x!