Blog

23 de março de 2022

Banco de Dados Colunar com o MariaDB

O MariaDB surgiu a alguns anos como um fork do banco de dados MySQL. Podemos dizer que ambos são muito parecidos implementando inclusive as mesmas engines de armazenamento como o InnoDB e o MyISAM. Mas com a necessidade de se ter uma maneira mais eficiente de processar grandes volumes de dados em relatórios analíticos foi incorporado o ColumnStore.

O MariaDB ColumnStore foi criado a partir do porte de uma outra solução chamada InfiniDB e ele nada mais é do que uma engine assim como o InnoDB e o MyISAM, mas que ao invés de armazenar os dados “linha a linha” os armazena “coluna a coluna”.

Antes o MariaDB ColumnStore era um produto implementado e instalado completamente separado do banco de dados principal. Mas a partir da versão 10.5.4 o MariaDB incorporou o ColumnStore como uma engine de armazenamento própria.

Neste artigo iremos conhecer um pouquinho mais sobre este mecanismo e como ele pode beneficiar nossas aplicações.

Tipos de Armazenamento de Dados

Em termos de armazenamento podemos dividir os bancos de dados em dois grupos principais:

Armazenamento Orientado a Linhas

Este modelo de armazenamento favorece muito a velocidade de escrita de dados e o controle de transações e adotado pela grande maioria dos bancos, como o PostgreSQL, MySQL, Microsoft SQL Server, Oracle e até mesmo o MariaDB. Para acelerar as consultas devemos criar índices nas colunas de forma que o banco saiba exatamente em qual ponto da memória ou do disco uma determinada informação pode ser encontrada. Caso uma consulta SQL busque dados em uma coluna que não esteja indexada, o banco de dados é forçado a executar uma operação chamada Scan na qual ele percorre as linhas do início ao fim da tabela até que a informação seja encontrada.

Imagine um caso em que uma consulta precise encontrar uma informação em uma tabela que possua gigabytes de dados armazenados ou até mesmo terabytes. Imagine também que uma das colunas consultadas não possui índice. O tempo necessário para se executar uma operação de Scan nessa tabela pode ser enorme podendo levar horas para ser concluída.

Esse tipo de problema acontece bastante quando escrevemos novas consultas SQL para geração de relatórios em uma aplicação. Com o passar do tempo surgem novas perguntas que o sistema precisa responder, novas informações precisam ser extraídas e assim caímos no problema de precisar acessar dados de uma coluna que ainda não está indexada. Começam então as reclamações de relatórios que demoram uma eternidade para serem gerados ou que derrubam o banco de dados no exato momento em que começam a ser executados.

Na maioria das vezes para resolver o problema o desenvolvedor recorre à criação de mais índices nas nas colunas que estão envolvidas na consulta trazendo com isso mais alguns problemas. Além do espaço em disco a mais que é necessário para cada índice criado, o banco passa a ter um trabalho adicional no momento da gravação ou atualização de novos registros, pois precisará também escrever dados em um arquivo a mais no momento de efetivar a transação tornando as operações de inserção, atualização e remoção de dados cada vez mais lenta.

Armazenamento Orientado a Colunas

Para tentar solucionar o problema de consulta em tabelas que possuem muitos registros surgiu uma nova idéia de armazenamento que organiza os dados em uma tabela não por linhas, mas sim por colunas. Chamamos este tipo de abordagem de Column Oriented Storage ou Armazenamento Orientado a Colunas. Neste modelo, o banco de dados procura as informações desejadas carregando do disco ou acessando na memória apenas as colunas mencionadas na consulta. Assim, ao invés de fazer a leitura carregando linhas inteiras para comparar apenas um ou dois atributos, o banco carrega os dados apenas das colunas que fazem sentido para a operação. Isso traz um ganho de performance enorme do ponto de vista de I/O.

Além do ganho de velocidade na leitura de dados podemos ter ganho também no processamento dos dados da consulta, pois os bancos que utilizam o armazenamento colunar geralmente permitem a paralelização do processamento da consulta em mais de um servidor. Uma consulta SQL que possua várias instruções JOIN pode executar cada uma delas em um servidor do cluster de forma paralela diminuindo mais ainda o tempo de resposta da consulta. Até mesmo a leitura dos dados das colunas pode acontecer em servidores diferentes e depois agregadas pelo servidor principal do cluster.

Vários bancos de dados implementam o armazenamento colunar. Entre eles temos:

Amazon RedShift

Google BigQuery

MariaDB ColumnStore

Destes bancos citados apenas o MariaDB permite que criemos tabelas com armazenamento colunar sem a necessidade de pagamento de licenças.

Na imagem acima temos uma tabela que organiza os dados dos clientes de uma empresa. No modelo de armazenamento orientado a linhas os dados seriam agrupados por registro, isto é, por linhas. Assim, no momento em que a consulta SELECT nome FROM Cliente WHERE cpf = 34567890123 fosse executada, o banco leria do disco o bloco de dados que contém todas as colunas das linhas acessadas para trabalhar apenas com o CPF e o nome do cliente.

Já no modelo de armazenamento colunar, para a mesma consulta o banco irá carregar do disco apenas os dados das colunas cpf e nome, ou seja, apenas as colunas envolvidas na consulta. As demais seriam totalmente ignoradas mesmo que a tabela tivesse 100 colunas. Assim temos um ganho enorme de velocidade no acesso aos dados muito maior do que o modelo tradicional de armazenamento em linhas.

Instalando o MariaDB com Suporte a ColumnStore no Ubuntu Linux

Ao contrário de soluções de armazenamento colunar como o Amazon RedShift que podemos executar somente em ambiente cloud, o MariaDB ColumnStore nos permite fazer uma instalação local em ambiente de desenvolvimento ou até mesmo em ambiente de produção, em um servidor gerenciado pela própria equipe.

Neste passo-a-passo iremos realizar a instalação na versão LTS mais recente do Ubuntu, que no momento da escrita deste artigo é a 20.04.

Desabilite o AppArmor. Em seguida reinicie a máquina.

Após reiniciar o sistema, siga com a ativação do repositório APT oficial para instalação do MariaDB no Ubuntu. Para isso execute os seguintes comandos:

Instalar pacotes APT.

Configure o serviço MariaDB. Crie um arquivo no caminho /etc/mysql/mariadb.conf.d/50-custom.cnf com o seguinte conteúdo:

Configure os serviços para que iniciem junto com o Linux.

Reinicie os serviços. Finalmente chegou a hora de iniciar o serviço MariaDB na sua máquina e começar a criar tabelas com a engine ColumnStore. Para isso, execute os comandos abaixo:

Verifique se a engine ColumnStore está disponível.

Se tudo correu bem na instalação, o comando acima irá mostrar no console uma tabela onde uma das linhas terá o seguinte conteúdo:

Crie um usuário para acessar o banco de dados. Nunca é uma boa ideia usar o usuário root do banco dados para executar tarefas corriqueiras. Por isso vamos criar um novo usuário que possa estabelecer conexão tanto na própria máquina de instalação quanto de uma máquina remota com a instrução GRANT ALL PRIVILEGES ON *.* to ‘myuser’@’%’ IDENTIFIED BY ‘senha123’. Substitua a senha por qualquer outra que seja mais segura :-).

Teste a conexão com o novo usuário.

O prompt de comando irá solicitar a senha mas não irá exibi-la no console.

Criando sua Primeira Tabela ColumnStore

Agora com o banco de dados instalado e configurado chegou a hora de finalmente criar sua primeira tabela com armazenamento colunar. Para isso devemos primeiro criar um novo banco de dados e em seguida executar o comando CREATE TABLE para a geração da tabela. Sendo assim, execute estes comandos em sequência para criá-la:

Repare que precisamos apenas incluir a instrução engine=ColumnStore para que a tabela seja criada com o armazenamento orientado a colunas. Repare também que não foi necessário criar chaves primárias ou índices. Até mesmo se tivéssemos utilizado a instrução PRIMARY KEY na coluna id, o banco iria retornar uma mensagem de erro no momento da criação da tabela com a seguinte mensagem: “ERROR 1069 (42000): Too many keys specified; max 0 keys allowed”.

Bancos de dados de armazenamento colunar utilizam o conceito de Self-Indexing que indexa automaticamente os dados nas colunas. Isso favorece ainda mais a geração daquele relatório de última hora que acessa colunas que ninguém nunca havia pensado antes em criar índices para elas.

No momento da criação de um tabela ColumnStore no MariaDB, devemos também nos atentar aos seguintes pontos:

A documentação online do MariaDB ColumnStore possui mais informações sobre as diferenças de sintaxe e comportamento que podem haver entre a engine ColumnStore e as engines tradicionais de armazenamento no MariaDB como o InnoDB. Os endereços são:

https://mariadb.com/kb/en/columnstore-data-definition-statements/
https://mariadb.com/kb/en/columnstore-data-manipulation-statements/

Principais Vantagens do Armazenamento Colunar

Para resumir podemos citar os seguintes pontos como vantagens do armazenamento orientado a colunas para as nossas aplicações:

Desvantagens do Armazenamento Colunar

Nem tudo são flores quando usamos banco de dados colunares. Estes são alguns dos pontos que precisamos ter atenção no momento de adotar este tipo de solução:

No Próximo Artigo:

Em breve iremos abordar um pouco mais do funcionamento interno do MariaDB ColumnStore e como podemos carregar nele grandes bases de dados utilizando o comando cpimport. Também iremos comparar a performance de consultas SQL em tabelas com armazenamento orientado a linhas e orientado a colunas.

Texto: Patrick Gonçalves