Quando pensamos em performance no ambiente computacional, sempre direcionamos primeiramente nossa atenção para perguntas como: - Que processador devo escolher?!?!?! Quantos processadores?!?!?! Quanto de memória RAM precisamos ter para rodar determinada aplicação?!?! Com toda a certeza essas preocupações não são inválidas e temos que nos ate,r sim as essas características de hardware.
Entretanto, quando falamos em performance, sabemos que o dispositivo mais lento de todos os subsistemas que compõem o nosso hardware é o disco (Hard Drive). Mesmo com tecnologias como IDE, SCSI, SATA (SSD's até ficou melhor, mas ainda precisa evoluir e ter o seu custo melhorado), o acesso à disco praticamente será em 90% dos casos o culpado pela lentidão em nossos servidores.
Para entendermos melhor o funcionamento do Ext3 e como podemos ajustar alguns parâmetros para auxiliar na performance do mesmo, precisamos mencionar a principal diferença que existe entre os sistemas de arquivos Ext2 e Ext3: o journal.
Para definirmos o journal de maneira simples e direta, poderíamos dizer que o journal nada mais é do que uma área destinada para registrar todas as transações que serão executadas no disco, cuja a finalidade é, em caso de problemas (ex: desligamento súbito do sistema) obter um histórico de todas as transações e aplicá-las.
O journal do Ext3 trabalha de três maneiras que podemos configurar:
- Ordered (default): Somente os metadados dos arquivos são escritos na área de journal, porém força a escrita do conteúdo do arquivo no sistema de arquivos principal logo após os metadados terem sido gravados no journal. Este é o que oferece a melhor relação confiabilidade vs performance.
- Writeback: Somente os metadados são escritos na área de journal, porém o kernel irá definir quando o conteúdo do arquivo será escrito no sistema de arquivos principal (sync ou pdflush). O writeback oferece o melhor desempenho, porém em caso de queda do sistema, os dados podem ser reescritos fora de ordem os corrompendo.
- Journal: metadados e dados do arquivo (conteúdo do arquivo) são escritos na área de journal e depois escritos no sistema de arquivos principal, aumentando a confiabilidade porém oferecendo menos performance.
Para alterar como o seu sistema de arquivos irá tratar a área de Journaling, basta montá-lo passando o parâmetro -o data=, como o exemplo abaixo:
# mount -o data=writeback /dev/sda3 /home
Com essas definições claras, um fato que não será alterado em nenhuma das implementações acima é o seek time. Seek time é o tempo gasto na movimentação da cabeça de leitura/escrita do disco até a trilha/setor desejado. O que quero dizer é, mesmo só gravando os metadados no journal, a cabeça de leitura/escrita do disco necessita se movimentar até os setores destinados para a área de journal gravar os metadados e depois se movimentar para a área destinada aos dados dos arquivos, gerando um movimento demasiado da cabeça para grandes escritas.
Como uma boa prática para reduzirmos o seek time para essas operações, podemos colocar a área de journal em um disco dedicado, isto é, outro disco para controlar o I/O do journal, minimizando o movimento da cabeça de leitura/escrita do disco principal. A nova área do journal pode variar de tamanho entre 1024 até 102400 blocos do sistema de arquivos principal.
Demonstrarei como podemos retirar o journal de um sistema de arquivos que já o existente:
# mount | grep /teste
/dev/sda2 on /teste type ext3 (rw,data=journal)
# grep /teste /etc/fstab
LABEL=/teste /teste ext3 defaults,data=journal 0 1
# umount /teste
# tune2fs -l /dev/sda2 | grep -i has_journal
Filesystem features: has_journal ext_attr resize_inode dir_index filetype sparse_super large_file
# tune2fs -O ^has_journal /dev/sda2
tune2fs 1.41.9 (22-Aug-2009)
# tune2fs -l /dev/sda2 | grep -i has_journal
Agora o que temos que fazer é criar uma nova área de journal em outro disco e adicionar essa área para o nosso sistema de arquivos principal, contudo, não esqueça que a formatação do journal precisa manter o tamanho do bloco do sistema de arquivo principal:
# tune2fs -l /dev/sda2 | grep -i "block size"
Block size: 4096
# mke2fs -O journal_dev -b 4096 -L journal-ext-sda2 /dev/sdb1 102400
mke2fs 1.41.9 (22-Aug-2009)
Filesystem label=journal-ext-sda2
OS type:
Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
0 inodes, 102400 blocks
0 blocks (0.00%) reserved for the super user
First data block=0
0 block group
32768 blocks per group, 32768 fragments per group
0 inodes per group
Superblock backups stored on blocks:
Zeroing journal device: done
root@mmello ~]# tune2fs -j -J device=/dev/sdb1 /dev/sda2
tune2fs 1.41.9 (22-Aug-2009)
Creating journal on device /dev/sdb1: done
This filesystem will be automatically checked every 28 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
# tune2fs -l /dev/sda2 | grep -i journal
Filesystem features: has_journal ext_attr resize_inode dir_index filetype sparse_super large_file
Journal UUID: a9d8f11d-65c5-4071-8d07-3abc5adb8b16
Journal device: 0x0811
Journal backup: inode blocks
# blkid | grep -e "/teste" -e "journal-ext-sda2"
/dev/sda2: LABEL="/teste" UUID="9dc5a7e9-94b4-4836-b73f-363530a64108" EXT_JOURNAL="a9d8f11d-65c5-4071-8d07-3abc5adb8b16" SEC_TYPE="ext2" TYPE="ext3"
/dev/sdb1: LABEL="journal-ext-sda2" UUID="a9d8f11d-65c5-4071-8d07-3abc5adb8b16" TYPE="jbd"
# mount | grep /teste
/dev/sda2 on /teste type ext3 (rw,data=journal)
Pronto! Seu sistema de arquivos já possui uma disco dedicado para trabalhar o journal, assim diminuindo o seek time do disco principal do sistema.
Para os que não podem se dar o luxo de ter um disco específico para o journal, o parâmetro commit= define de quanto em quanto tempo em segundos o journal será comitado para disco. Exemplo:
# mount -o commit=10 /dev/sda2 /teste
Espero ter ajudado os amigos com algumas técnicas para reduzir o seek time do disco e com isso aumentando a performance de um dos subsistemas mais lentos para acesso que temos atualmente.
Abraços.