O Drupal em um compartilhamento NFS tem um desempenho terrível

3

Temos uma configuração em que um site do Drupal 7 com a seguinte configuração - um servidor host VMware ESXi 4.1 executando uma VM da Web e uma VM do NFS. A VM da web está usando o Apache e o mod_php. O site ainda está em desenvolvimento, portanto, temos que desativar todas as formas de armazenamento em cache devido aos arquivos atualizados com freqüência.

Cada solicitação de página leva de 15 a 20 segundos para ser concluída. A criação de perfil do código PHP mostra que a grande maioria do tempo (normalmente acima de 90%) está tomando todas as chamadas de função is_dir (), is_file () que carregam os módulos.

Eu aumentei o tamanho do cache realpath do PHP para vários megas e um strace mostra que as chamadas lstat caem de 200 para cerca de 6 e stat () diminui um pouco (cerca de 600 chamadas). No entanto, enquanto isso reduziu bastante o tempo, simplesmente não consigo ultrapassar a barreira de 10 segundos por solicitação para a página mais exigente.

Existe uma maneira de obter melhor desempenho dessa configuração que não envolve o armazenamento em cache?

Edit: MySQL não é o problema, o cache de consulta significa que as solicitações levam no máximo um segundo para serem concluídas.

Configurações e estatísticas:

VM Host: CPU Xeon de núcleo quádruplo único

VMs:

web - Centos 6 64bt, 2,5 GB de RAM, priorização normal de CPU / HD (2 núcleos) nfs - Centos 6 64bt, 2GB de RAM, prioridade normal da CPU (4 núcleos), alta prioridade HD

PHP: 32M tamanho do cache realpath (é tão alto para fins de teste)

NFS:

~]# egrep -v '#|^$' /etc/nfsmount.conf 
[ NFSMount_Global_Options ]
 Defaultvers=4
 Ac=False
 Rsize=32k
 Wsize=32k
 Bsize=32k

Velocidade de leitura via NFS não é um problema dd de um arquivo de teste de 100M usando 32k blocos de retorno:

3200+0 records in
3200+0 records out
104857600 bytes (105 MB) copied, 1.84984 s, 56.7 MB/s

real    0m1.857s
user    0m0.007s
sys 0m0.330s 

Strace no processo do Apache com o cache real do caminho real:

    % time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 50.78    1.157452         337      3434        28 stat
 32.58    0.742656         628      1182       425 open
  9.29    0.211788         762       278         1 lstat
  3.17    0.072322           0    237865           write
  2.45    0.055839         490       114        13 access
  0.45    0.010262          43       237           brk
  0.34    0.007725          10       811        74 read
  0.28    0.006340           9       679           fstat
  0.22    0.005069          18       281           poll
  0.20    0.004533           6       698           getdents
  0.09    0.001960          10       190           mmap
  0.05    0.001065          14        74           accept4
  0.04    0.001000         333         3           chdir
  0.03    0.000750           4       190           munmap
  0.01    0.000339           0       836           close
  0.01    0.000247           3        75           writev
  0.00    0.000068           0       611           fcntl
  0.00    0.000063           1        77           shutdown
  0.00    0.000000           0         1           lseek
  0.00    0.000000           0         5           rt_sigaction
  0.00    0.000000           0         1           rt_sigprocmask
  0.00    0.000000           0         3           setitimer
  0.00    0.000000           0         5           socket
  0.00    0.000000           0         5         5 connect
  0.00    0.000000           0        74           getsockname
  0.00    0.000000           0        15           setsockopt
  0.00    0.000000           0         5           getcwd
  0.00    0.000000           0         1           futex
------ ----------- ----------- --------- --------- ----------------

Strace depois que os caminhos reais são armazenados em cache

    % time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 60.14    1.371006         484      2831        28 stat
 31.79    0.724705         627      1155       425 open
  3.53    0.080354           0    237865           write
  2.65    0.060433         530       114        13 access
  0.43    0.009913          99       100           brk
  0.38    0.008730          11       804        74 read
  0.35    0.007910          12       675           fstat
  0.30    0.006775          10       654           getdents
  0.13    0.003065          11       281           poll
  0.09    0.002000         333         6         1 lstat
  0.07    0.001545           2       807           close
  0.05    0.001063          14        74           accept4
  0.04    0.001000           6       179           mmap
  0.02    0.000404           2       179           munmap
  0.01    0.000271           4        75           writev
  0.01    0.000212           0       611           fcntl
  0.01    0.000129           2        77           shutdown
  0.00    0.000022           0        74           getsockname
  0.00    0.000000           0         1           lseek
  0.00    0.000000           0         5           rt_sigaction
  0.00    0.000000           0         1           rt_sigprocmask
  0.00    0.000000           0         3           setitimer
  0.00    0.000000           0         3           socket
  0.00    0.000000           0         3         3 connect
  0.00    0.000000           0        15           setsockopt
  0.00    0.000000           0         5           getcwd
  0.00    0.000000           0         3           chdir
------ ----------- ----------- --------- --------- ----------------

Montagem:

nfs.xxx.xxx.xxx:/path/to/website/files on /path/to/website/files type nfs (rw,hard,intr,noac,vers=4,addr=xx.xx.xx.xx,clientaddr=xx.xx.xx.xx)

Qualquer ajuda é, naturalmente, apreciada.

    
por Marcus 03.09.2012 / 22:39

2 respostas

1

Para ser franco, o Drupal no NFS é um verdadeiro porco. No máximo, você quer compartilhar o diretor de "arquivos" {y, ies} via NFS ou algo parecido com gluster. O problema com a execução do DocRoot no NFS é que, somadas, todas as chamadas lstat (2) e access (2) são killer, sem falar dos getdents (2) e amigos que você verá nos diretórios do módulo. Algo como o APC ajudará significativamente a leitura real (2) vezes, bem como a remoção dos atrasos de compilação, mas o PHP ainda fará lstat (2) e access (2) em cada arquivo. Para acelerar ainda mais as coisas, você pode definir apc.stat = 0, mas isso não ajudará se, como você disse, você está constantemente alterando arquivos PHP, a menos que você esteja disposto a reiniciar o Apache (ou limpar manualmente o APC cache via apc.php) toda vez que você fizer essa mudança.

As práticas recomendadas recomendam armazenar o DocRoot em um dispositivo dedicado e otimizado (como uma SAN) ou separadamente em cada webhead. O diretório "arquivos" geralmente deve ser compartilhado via gluster / nfs / etc., Mas como alternativa, você também pode periodicamente rsync-lo entre servidores, dependendo do caso de uso e se o LB na frente suporta sessões pegajosas. Você também pode eliminar completamente o diretório de arquivos usando um CDN ou um serviço como o S3 da Amazon ou o Swift da BlackMesh.

Um provedor de hospedagem com conhecimento detalhado e especializado do Drupal pode ajudá-lo com algumas dessas preocupações arquiteturais; Você pode querer contatar Acquia ou BlackMesh (eu trabalho para o último). Não sei se Acquia o faz, mas sei que o BlackMesh também oferece assistência externa onde trabalhamos com seu provedor de hospedagem existente ou hospedagem no local para otimizar a solução para o Drupal.

Boa sorte com o seu site!

    
por 10.10.2012 / 22:55
0

A montagem com noac em geral é um matador de desempenho.

Por que você está usando?

EDIT: Eu vejo acima em um comentário que você diz que está adicionando mais servidores web e um balanceador de carga mais tarde. Como a BMDan sugeriu, você deve procurar em um sistema de arquivos de cluster (por exemplo, OCFS2) se seu aplicativo exigir que você use noac .

Felicidades

    
por 10.10.2012 / 23:41