Arquivo

Archive for the ‘Banco de Dados’ Category

Blocos de Dados: tamanho é documento?

A tecnologia da informação está cada vez mais ligada ao nosso cotidiano, seja em casa, no carro, ou no trabalho nós convivemos o tempo inteiro com dispositivos tecnológicos. Quanto maior é a nossa dependência de tecnologia, mais informação é gerada e mais espaço é utilizado para guardar as informações relevantes (ou não). No meio corporativo onde a demanda por espaço é bem maior e geralmente são informações que tem que estar disponíveis sempre que necessário, da maneira mais performática possível.

Com o crescimento acelerado de banco de dados e a adoção cada vez maior de sistemas virtualizados, os blobs (arquivos binários) gerados hoje em dia estão cada vez mais volumosos. Se antes uma imagem iso de pouco mais de 700MB era uma coisa enorme, hoje em dia em algumas empresas encontramos blobs de 1TB ou mais, geralmente blobs que ocupam uma LUN ou um Pool de LUNs inteiro apenas para sí, muitas vezes resultando em um desempenho sofrível principalmente no caso de bancos de dados quando precisam fazer algum tipo de “data scan” ou de arquivos que são tratados de forma sequencial e precisam serem lidos do inicio até o fim. O mesmo senário se repete para o contrário: arquivos pequenos demais que resultam em uma grande quantidade de informação, talvez esse senário seja pior, pois por gerar um maior número de IOPS, fazem uso do hardware muitas vezes de forma extrema, porém nada otimizada. Se você está sofrendo com algo parecido com isso, esse artigo é pra você!

De forma alguma venho através deste artigo dizer que X é certo e Y é errado, mesmo porque cada ambiente  tem suas regras de negócios, particularidades, limitações e etc. Venho aqui discutir sobre como otimizar esses dados a partir de ajustes em níveis mais baixos, como por exemplo a “blocagem” do seu sistema de arquivos e/ou o stripesize de seu RAID.

Blocos de Dados

Os blocos, também chamados de INODE (no caso de sistemas baseados em UNIX) ou CLUSTER (no caso de sistemas baseados em Windows) são a maneira que o sistema de arquivos armazena e gerenciam os blobs gravados no disco (que pode ser realmente um disco ou qualquer outro dispositivo de bloco como LUN, RAID, etc).  Por exemplo, se seu sistema de arquivos usa blocos com o tamanho de 14KB, os arquivos serão quebrados em unidades de 14KB de tamanho, o que quer dizer, que para cada leitura, de um arquivo, o disco terá que ler X blocos de 14KB por Y vezes.  Nesse senário hipotético um arquivo de 1MB (1024KB) seria dividido em aproximadamente 74 partes de 14KB, o que significa que a cabeça de leitura do disco seria reposicionada 74 vezes durante a leitura deste único arquivo. Esse senário “hipotético” é tão comum quanto você não imagina, pois na maioria das vezes, os administradores de sistema não se preocupam muito com a blocagem a ser utilizada no sistema de arquivos como fator de desempenho final.

Também podem existir casos extremos em que se usam uma blocagem grande para escrever arquivos pequenos, o que incide no espaço final que ficará disponível, pois os blocos tem tamanhos fixos e uma vez alocados para uma determinado arquivo, não serão utilizados para gravar outro arquivo, mesmo que exista espaço de sobra. Por exemplo: o sistema de arquivos foi formatado para blocos de 1MB, se você cria varios arquivos de 500KB, essa formatação é ineficiente, pois para cada arquivo de 500KB, estão sendo gerados blocos de 1MB, o que significa que metade do espaço disponível está sendo desperdiçado.

Não existe uma matemática exata da relação tamanho de arquivos X blocos, o que vale é o bom senso durante a escolha do tamanho dos blocos a depender do tipo e tamanho de arquivos que serão armazenados nesse disco.

Cíclos de CPU

A operação de leitura de cada bloco consiste em várias etapas que vão desde a localização deste bloco no disco pois os dados geralmente não são sequenciais e são passíveis de fragmentação, reposicionamento de cabeça de agulha e etc.

Quando se lê um arquivo de 1MB em um sistema de arquivos utilizando blocos de 14KB, você estará utilizando aproximadamente 75 ciclos de CPU e o mesmo número de I/O para realizar tal leitura. Cada ciclo de CPU é independente e faz com que aquele “core” fique ocupado e indisponível para outras chamadas até que o ciclo se complete ou seja interrompido (no caso de ciclos preemptivos).  É importante também observar a quantidade de IOPS (I/O Per Second) suportados pelo dispositivo de blocos, pois se chegar no máximo em apenas uma leitura, o desempenho do equipamento estará comprometido para outras operações, principalmente se for um storage que geralmente é compartilhado com outras aplicações e máquinas.

Ao utilizar blocos maiores, você estará diminuindo a quantidade necessária de ciclos de CPU e IOPS e aumentando o uso de banda disponível.  Num senário bastante realista os storages funcionam com fibras a velocidades de 8Gbit, o que resulta em uma largura de banda bastante generosa para acesso a dados, e ao se utilizar blocos maiores, você conseguirá aumentar seu desempenho utilizando esta banda disponível sem precisar sacrificar o processamento de seu hardware.

Vale salientar que…

Para um sistema operacional, é mais fácil gerenciar grandes arquivos do que pequenos arquivos. Já experimentou comparar a cópia de uma arquivo de 1GB e vários arquivos pequenos que resultam em 1GB? A cópia do único arquivo é muito mais rápida, pois o S.O. já tem indexado a localização dos blocos desse arquivo de maneira a antecipar a leitura no disco por exemplo, porém tal operação irá incidir em um maior consumo de banda no disco e memória RAM, enquanto que quando precisamos copiar varios arquivos, o S.O. precisa recorrer ao seu índice saber a localização dos blocos de cada arquivo que irá copiar, reposicionar as agulhas do disco, e então começar a operação de cópia. O mesmo vale para leitura.

Porém, no caso de uma varredura de dados, comum em SGDBs, a quebra dos arquivos grandes em arquivos médios, poderá facilitar tal operação. Pois apesar de otimizar o uso da banda quando precisar realizar um full table scan por exemplo, o mesmo terá de fazer em um blob grande, e em uma única operação, enquanto que utilizando vários arquivos, mesmo num full table scan, o SGDB se beneficiará do paralelismo entre os cores, podendo varrer vários arquivos correspondentes ao dados procurados de uma só vez.

Conclusão

Esse tipo de tuning deve levar em conta o ambiente, o tipo de dados e a proposta de performance que vai se querer extrair do mesmo. No caso de um file server talvez não compense utilizar blocos grandes, pois o número de arquivos menores poderá não compensar e acabar aumentando o gasto de espaço de forma desnecessária, mas no caso de grandes bancos de dados e de discos de máquinas virtuais, por exemplo, deverá sim ser levado em conta o tamanho dos blocos do sistema de arquivos. Atualmente os sistemas já projetados para virtualização vem preparados por padrão para grandes arquivos, como é o caso do VMFS, sistema de arquivos utilizados pelo VMware, que vem com uma blocagem padrão superior ao que é utilizado normalmente em sistemas operacionais comuns. Em resumo: quanto menor o bloco, maior economia de espaço, porém maior será o uso de ciclos de CPU e menor será a otimização no acesso aos dados, quanto maior o bloco, maior será o uso do espaço em disco, inclusive a chance de desperdício de espaço é maior também, porém no caso de acesso aos dados,  é necessário um número menor de ciclos de CPU resultando em maior performance e aproveitamento de banda e memória RAM disponíveis.

E você, o que acha? Me envia um email para ramongadelha@gmail.com e/ou deixa teu comentário logo abaixo deste artigo!

Anúncios

Como configurar replicação no MySQL.

junho 24, 2011 6 comentários

Este artigo foi baseado no seguinte ambiente:

Tipo de Host: físico
Quantidade de hosts: 2
Distribuição Linux: Red Hat Enterprise Linux 6.1
Versão do MySQL: 5.1.52 (community)
IP do Host1: 10.1.1.1
IP do Host2: 10.1.1.2

O artigo a seguir, descreve a replicação baseada em ativo / passivo, ou seja, master -> slave. O host principal, que será o master, irá receber todas as atualizações no banco especificado para a replicação, e irá replicar para outro MySQL localizado em outro host, que será o slave. A principal utilidade nisso na rápida recuperação em caso de desastres físicos e também para balanceamento de carga de consulta, entre outras utilidades. Vale lembrar, que este tipo de replicação não é considerado seguro para recuperação de falhas lógicas como por exemplo, inserções ou deleções por engano, porque os dados serão replicados exatamente como são na base master para a slave.

1 – Configurando o Master.

Tenha em mente que o master é o banco que irá receber toda a carga de inserts, updates e deletes, só ele poderá sofrer alterações, enquanto o slave estará em modo read-only (somente leitura). Para este artigo, considere que o banco a ser replicado será o fictício ‘testdb‘.

Primeiramente, teremos de adicionar algumas linhas no arquivo /etc/my.cnf :

log-bin = /var/log/mysql/mysql-bin.log
binlog-do-db=testdb
server-id=1

Uma vez feito, iremos reiniciar o SGDB para aplicar as novas configurações:

# /etc/init.d/mysqld restart

Considerando que você já criou um usuário para a replicação, iremos chamá-lo de slave_user, e iremos também aplicar o privilégio necessário para usá-lo durante a replicação. Para tal, executamos o SQL:

GRANT REPLICATION SLAVE ON *.* TO 'slave_user'@'%' IDENTIFIED BY 'alguma_senha';
FLUSH PRIVILEGES;

Feito, o master encontra-se configurado.

2 – Preparando o ambiente para a replicação e configurando o Slave.

Agora que temos um master, necessitamos de mais alguns passos para que possamos replicá-lo em outro host.

Primeiro, precisamos fazer um dump do banco que iremos replicar, mas com a devida precaução para que o mesmo não seja alterado antes de o master e o slave  estejam devidamente conectados e sincronizados. Esse trabalho é manual e pode tomar algum tempo dependendo do tamanho da base de dados bem como de sua infraestrutura. Para tal, precisamos executar o comando SQL para “travar” todas as tabelas do master:

USE testdb;
FLUSH TABLES WITH READ LOCK;

Uma vez  feito isso, devemos, em linha de comando, executar o binário mysqldump para jogar toda a base de dados em um arquivo de texto plano, para que assim possamos transportá-lo para o outro host que será o slave. Note que durante todo este processo, as tabelas do banco ‘testdb‘ estarão travadas. O exemplo abaixo considera que o usuário do master é  root e a senha é 123456. Execute no shell do Linux o seguinte comando:

# mysqldump -u root -p123456 –database testdb > testdb.sql

Uma vez que temos o banco inteiramente “dumpado” em um arquivo, agora você deve enviar da forma que mais lhe for conveniente para o outro host,  que será o slave.

Agora, devidamente conectado ao slave. Editaremos o arquivo /etc/my.cnf do mesmo, é incluiremos algumas linhas:

server-id=2
replicate-do-db=testdb

Então, devemos criar o banco para receber nosso dump que foi transferido do servidor master, para isso executaremos o comando SQL e criaremos o banco testdb no slave:

CREATE DATABASE testdb;

Deveremos então importar todos os dados do master, neste que será o slave, e logo após iremos reiniciar o SGDB slave. Para tal, execute na shell do Linux no host do slave o comando:

# mysql -uroot -p123456 testdb < testdb.sql
# /etc/init.d/mysqld restart

Após reiniciá-lo, iremos ativar a replicação, para tal devemos coletar algumas informações ainda o master como arquivo de log e posição do log. Para tal, execute o comando SQL no master:

SHOW MASTER STATUS;

Este comando deverá mostrar uma saída parecida com essa:

+---------------+----------+--------------+------------------+
| File          | Position | Binlog_do_db | Binlog_ignore_db |
+---------------+----------+--------------+------------------+
| mysql-bin.006 | 134      | testdb       |                  |
+---------------+----------+--------------+------------------+
1 row in set (0.00 sec)

Isso significa que o nome do arquivo de log para esta replicação é mysql-bin.006 e encontra-se na posição 134. Agora iremos executar no slave o seguinte comando SQL:

USE testdb;
CHANGE MASTER TO MASTER_HOST=10.1.1.1', MASTER_USER='slave_user', MASTER_PASSWORD='alguma_senha', MASTER_LOG_FILE='mysql-bin.006', MASTER_LOG_POS=134;
SLAVE START;

Caso encontre algum erro, confira se o suporte a networking está habilitado no master já que a replicação é feita através de TCP/IP e não de UNIX Sockets. Caso esteja habilitado e você continuar recebendo mensagens de erro ao executar tal comando, favor repetir os passos e / ou consultar este artigo novamente para saber se houve algum erro durante a implementação.

Para conferir que está tudo OK, você deve executar o comando:

SHOW SLAVE STATUS\G

Esse comando irá lhe reportar o status do cluster de replicação. Caso esteja tudo OK, é hora de “destravar” as tabelas no master, executando no master o comando SQL:

UNLOCK TABLES;

Pronto, a replicação do banco testdb está feita. Para certificar-se se está funcionando de maneira correta, faça alterações no master e veja se as mesmas são replicadas no slave.

3 – Finalizando o artigo.

Espero que este artigo tenha lhe sido útil. Caso encontre erros aqui e/ou deseja sugerir mudanças ou adicionar mais informações ao artigo, escreva nos comentários e as devidas alterações serão feitas dando os devidos créditos aos autores.