quinta-feira, 17 de setembro de 2009

Semaforos, Kernel, Memoria Compartilhada e Cia

Há ocosiões onde é extramamente necessario que dois ou mais processos/threads acessem um único recurso comum. Caso esse tipo de paralelismo não ocorra de forma controlada, podemos fazer com que um processo "sequestre ou atropele" a operação do outro.
É ai que entram nossos sinalizadores, vulgo semaforos. Com eles, é possivel acesso controlado a processos, de forma que só havera disponibilidade quando a operacao em andamento for finalizada.
Processos, memoria compartilhada e filas de mensagens é a principal triade de recursos compartilhados necessarios em ambientes *NIX para a perfeita comunicação entre processos (System V IPC ou tambem conhecida em outros ambientes com IPC ou Inter-Process Communication).
Esses semaforos funcionam como indicadores (flags) que sinalizam para o ambiente se o mesmo esta ou não em utilização ( os metodos de sinalização não são pertinentes ao artigo, mas podemos didaticamente imaginar que pode ser 0 e 1, respectivamente 0 para indisponivel e 1 para disponivel). Assim, o processo de sinalização requer colaboração e troca de informações entre processos.
Dependendo da quantidade de aplicações que existem no ambiente, a quantidade inicial de semaforos pode não ser suficientes para um perfeito controle de todo o sistema. Na verdade, a maioria dos sistemas operacionais modernos oferecem essas funcionalidades, porem os padrões das diversas distribuições são tão baixos que não é necessario um super-servidor para saturar esses recursos (principalmente o legado BSD). Por exemplo:
Uma instalação consideravel do PostGreSQL pode "extirpar" rapidamente vários limites de recursos do sistema operacional, comumente usando 1 semaforo para cada instancia concorrente. Uma instalação comum de Oracle consome aproximadamente 70 semaforos.
Quando esses recursos são saturados, sua falta manifesta um erro conhecido como "Chamada de Sistema Ilegal". Nesse caso,  não ha nada a ser feito, a não ser remover recursos "gulosos" que na maioria das vezes não é possivel recompilar o nucleo do kernel. Para os escovadores de bits e curiosos os arquivos são:
/usr/src/linux/include/asm/shmparam.h
/usr/src/linux/include/asm/semaphore.h
/usr/src/linux/include/asm/semaphore-helper.h
/usr/src/linux/include/linux/shm.h
/usr/src/linux/include/linux/sem.h 
Nessa dica, alem de darmos uma explanação sobre somaforos, iremos demonstrar como corrigir esses problemas sem desinstalar aplicações e ou recompilar o kernel.
O sistema de arquivos proc   
Muitos parametros de kernel podem ser alterados atraves do sistema de arquivos /proc ou usando o sysctl. Voce pode consultar esses valores consultado:

cat /proc/sys/kernel/sem   #Semaforos
cat /proc/mdstat                 # RAID status
cat /proc/cpuinfo                # Processador
cat /proc/version                # Versão do Kernel

ou ainda, uma variedade de informações de todo o sistema via:

procinfo
sysctl -a

Como estamos falando de semaforos e recursos do sistema, vamos dar uma olhada nesses valores:

ipcs -la

Lembram da ganancia por recursos do Oracle? Observem agora esses limites (100). Levando em consideração que o proprio S.O ja esta utilizando parte deles, nossa cota esta proxima de estouro. Vamos conhecer um pouco mais sobre esses indicadores.

Parametros IPC (System V)

SEMMNI
Numero maximo de identificadores de semaforos (conjunto)

SEMMNS
Numero maximo de semaforos para todo o sistema.

SEMMSL
Numero maximo de semaforos por conjunto.

SEMMAP
Numero de entradas no mapa de semaforos. Deve ser definido como o produto de SEMMNI e SEMMSL (SEMMAP=SEMMNI * SEMMSL).

SEMVMX
Valor maximo de um semaforo. Pelo menos 1000, onde o padrão é geralmente 32767. Não mude a não ser quando solicitado!

Esses valores podem ser modificados via arquivo de sistema proc sem necessidade de reinicialização. A operação abaixo ilustra essa mudança:

sysctl -w kernel.sem="250     32000     100    128"

Como esses valores são perdidos numa inicialização do sistema, os mesmos podem ser colocados em um script executado durante a inicialização, como erroneamente utilizado em gateways/firewall para habilitar roteamento de pacotes.

echo "1" > /proc/sys/net/ipv4/ip_forward

Como alternativa correta para ambos os exemplos mostrados, pode ser utilizado sysctl, para controlar esses parametros. Como esse arquivo é processado durante a inicialização, as mudanças devem ser inseridas em /etc/sysctl.conf conforme o exemplo:

kernel.shmall = 134217728
kernel.shmmax = 134217728
net.ipv4.ip_forward = 1

A sintaxe para o /etc/sysctl.conf é bem simples. Remova /proc/sys dos caminhos mencionados anteriormente e substitua o / pelo . utilizando a mesma estrutua. Assim:

/proc/sys/net/ipv4/ip_forward = net.ipv4.ip_forward


abraços.

Creditos : Jairo Willian Pereira

Nenhum comentário:

Postar um comentário