Ajuda! Meu servidor está ficando sem memória e bloqueado, exigindo uma reinicialização

1

Eu tenho um VPS (com 256MB de memória) que foi suspenso mais de uma vez hoje. Ele congelou completamente e não estava acessível via SSH. Eu tive que executar o procedimento de "desligar a força" do meu provedor para trazê-lo de volta. Em seguida, o servidor durou algumas horas antes de fazê-lo novamente.

A primeira vez que houve uma mensagem sobre falta de memória e tentativa de matar o processo mysqld. O próximo eu consegui encontrar isso no arquivo syslog:

Sep 23 01:47:34: [16942.757665]  [out_of_memory+0x19e/0x1e0] out_of_memory+0x19e/0x1e0
Sep 23 01:47:34: [16942.758875] Out of memory: kill process 5983 (apache2) score 57519 or a child

Configurei o Apache e o MySQL para ter bastante atenção à baixa RAM, pelo menos até onde eu saiba, e gostaria de saber por que isso está acontecendo. Eu simplesmente preciso atualizar ou há algo errado?

Aqui está um trecho da minha configuração do Apache:

#
# Timeout: The number of seconds before receives and sends time out.
#
Timeout 30

#
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
#
KeepAlive On

#
# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
#
MaxKeepAliveRequests 200

#
# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
#
KeepAliveTimeout 3

##
## Server-Pool Size Regulation (MPM specific)
## 

# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild: maximum number of requests a server process serves
<IfModule mpm_prefork_module>
    StartServers          1
    MinSpareServers       1
    MaxSpareServers      3
    MaxClients          50
    MaxRequestsPerChild   1000
</IfModule>

E minha configuração do MySQL:

[mysqld]
#
# * Basic Settings
#

#
# * IMPORTANT
#   If you make changes to these settings and your system uses apparmor, you may
#   also need to also adjust /etc/apparmor.d/usr.sbin.mysqld.
#

user        = mysql
pid-file    = /var/run/mysqld/mysqld.pid
socket      = /var/run/mysqld/mysqld.sock
port        = 3306
basedir     = /usr
datadir     = /var/lib/mysql
tmpdir      = /tmp
language    = /usr/share/mysql/english
skip-external-locking
skip-locking
#
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address        = 127.0.0.1
#
# * Fine Tuning
#
key_buffer      = 16K
max_allowed_packet  = 1M
thread_stack        = 64K
thread_cache_size   = 4
sort_buffer     = 64K
net_buffer_length   = 2K
#max_connections        = 100
#table_cache            = 64
#thread_concurrency     = 10
#
# * Query Cache Configuration
#
query_cache_limit       = 500k #was 1M
query_cache_size        = 8M #was 16M, lowered for RAM
#
# * Logging and Replication
#
# Both location gets rotated by the cronjob.
# Be aware that this log type is a performance killer.
#log        = /var/log/mysql/mysql.log
#
# Error logging goes to syslog. This is a Debian improvement :)
#
# Here you can see queries with especially long duration
#log_slow_queries   = /var/log/mysql/mysql-slow.log
#long_query_time = 2
#log-queries-not-using-indexes
#
# The following can be used as easy to replay backup logs or for replication.
# note: if you are setting up a replication slave, see README.Debian about
#       other settings you may need to change.
#server-id      = 1
#log_bin            = /var/log/mysql/mysql-bin.log
expire_logs_days    = 10
max_binlog_size         = 100M
#binlog_do_db       = include_database_name
#binlog_ignore_db   = include_database_name
#
# * BerkeleyDB
#
# Using BerkeleyDB is now discouraged as its support will cease in 5.1.12.
skip-bdb
#
# * InnoDB
#
# InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/.
# Read the manual for more InnoDB related options. There are many!
# You might want to disable InnoDB to shrink the mysqld process by circa 100MB.
skip-innodb
#
# * Security Features
#
# Read the manual, too, if you want chroot!
# chroot = /var/lib/mysql/
#
# For generating SSL certificates I recommend the OpenSSL GUI "tinyca".
#
# ssl-ca=/etc/mysql/cacert.pem
# ssl-cert=/etc/mysql/server-cert.pem
# ssl-key=/etc/mysql/server-key.pem



[mysqldump]
quick
quote-names
max_allowed_packet  = 16M

[mysql]
#no-auto-rehash # faster start of mysql but no tab completition

[isamchk]
key_buffer      = 16M

E, caso isso aconteça, aqui está uma saída de ps aux de cerca de 20 a 30 minutos após a reinicialização:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.3   3992   920 ?        Ss   01:53   0:00 /sbin/init
root         2  0.0  0.0      0     0 ?        S<   01:53   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S<   01:53   0:00 [migration/0]
root         4  0.0  0.0      0     0 ?        S<   01:53   0:00 [ksoftirqd/0]
root         5  0.0  0.0      0     0 ?        S<   01:53   0:00 [watchdog/0]
root         6  0.0  0.0      0     0 ?        S<   01:53   0:00 [events/0]
root         7  0.0  0.0      0     0 ?        S<   01:53   0:00 [khelper]
root        18  0.0  0.0      0     0 ?        S<   01:53   0:00 [xenwatch]
root        19  0.0  0.0      0     0 ?        S<   01:53   0:00 [xenbus]
root        27  0.0  0.0      0     0 ?        S<   01:53   0:00 [migration/1]
root        28  0.0  0.0      0     0 ?        S<   01:53   0:00 [ksoftirqd/1]
root        29  0.0  0.0      0     0 ?        S<   01:53   0:00 [watchdog/1]
root        30  0.0  0.0      0     0 ?        S<   01:53   0:00 [events/1]
root        54  0.0  0.0      0     0 ?        S<   01:53   0:00 [kblockd/0]
root        55  0.0  0.0      0     0 ?        S<   01:53   0:00 [kblockd/1]
root        65  0.0  0.0      0     0 ?        S<   01:53   0:00 [kseriod]
root       104  0.0  0.0      0     0 ?        S    01:53   0:00 [pdflush]
root       105  0.0  0.0      0     0 ?        S    01:53   0:00 [pdflush]
root       106  0.0  0.0      0     0 ?        S<   01:53   0:00 [kswapd0]
root       107  0.0  0.0      0     0 ?        S<   01:53   0:00 [aio/0]
root       108  0.0  0.0      0     0 ?        S<   01:53   0:00 [aio/1]
root       124  0.0  0.0      0     0 ?        S<   01:53   0:00 [accel_watch/0]
root       125  0.0  0.0      0     0 ?        S<   01:53   0:00 [accel_watch/1]
root      2031  0.0  0.0      0     0 ?        S<   01:53   0:00 [kjournald]
root      2192  0.0  0.3  16848   944 ?        S<s  01:53   0:00 /sbin/udevd --daemon
syslog    3514  0.0  0.2  12296   728 ?        Ss   01:53   0:00 /sbin/syslogd -u syslog
root      3534  0.0  0.2   8132   592 ?        S    01:53   0:00 /bin/dd bs 1 if /proc/kmsg of /var/run/klogd/kmsg
klog      3537  0.0  0.8   5600  2292 ?        Ss   01:53   0:00 /sbin/klogd -P /var/run/klogd/kmsg
root      3556  0.0  0.4  50916  1160 ?        Ss   01:53   0:00 /usr/sbin/sshd
root      3776  0.0  0.8  36684  2152 ?        Ss   01:53   0:00 /usr/lib/postfix/master
postfix   3794  0.0  0.8  38740  2140 ?        S    01:53   0:00 pickup -l -t fifo -u -c
postfix   3795  0.0  0.8  38784  2228 ?        S    01:53   0:00 qmgr -l -t fifo -u
root      3802  0.0  0.2  12460   644 ?        Ss   01:53   0:00 /usr/sbin/dovecot
root      3815  0.0  1.0  71648  2876 ?        S    01:53   0:00 dovecot-auth
daemon    3816  0.0  0.1  16428   428 ?        Ss   01:53   0:00 /usr/sbin/atd
root      3829  0.0  0.3  18616   976 ?        Ss   01:53   0:00 /usr/sbin/cron
dovecot   3851  0.0  0.7  14148  1876 ?        S    01:53   0:00 imap-login
dovecot   3852  0.0  0.7  14148  1876 ?        S    01:53   0:00 imap-login
dovecot   3853  0.0  0.7  14148  1876 ?        S    01:53   0:00 imap-login
root      3875  0.0  0.2   3864   592 tty1     Ss+  01:53   0:00 /sbin/getty 38400 tty1
root      3913  0.0  1.1  68272  3116 ?        Ss   01:54   0:00 sshd: root@pts/0 
postfix   3917  0.0  1.1  41248  2964 ?        S    01:54   0:00 tlsmgr -l -t unix -u -c
root      3924  0.0  0.7  18908  2080 pts/0    Ss   01:54   0:00 -bash
root      3958  0.0  0.2   3864   592 ?        Ss   01:55   0:00 /sbin/getty 38400 console
root      4232  0.0  0.2   3944   608 pts/0    S    02:22   0:00 /bin/sh /usr/bin/mysqld_safe
mysql     4271  0.1  5.0 124404 13244 pts/0    Sl   02:22   0:02 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --pi
root      4272  0.0  0.2   5068   768 pts/0    S    02:22   0:00 logger -p daemon.err -t mysqld_safe -i -t mysqld
root      4415  0.0  3.6 201880  9516 ?        Ss   02:29   0:00 /usr/sbin/apache2 -k start
www-data  4527  0.5 11.9 225720 31340 ?        S    02:47   0:01 /usr/sbin/apache2 -k start
www-data  4539  0.6 12.2 226492 32092 ?        S    02:50   0:00 /usr/sbin/apache2 -k start
www-data  4541  2.3 12.1 226492 31992 ?        S    02:52   0:00 /usr/sbin/apache2 -k start
root      4544  0.0  0.4  15064  1088 pts/0    R+   02:53   0:00 ps aux

Alguém pode me ajudar aqui?

    
por redwall_hp 23.09.2009 / 03:55

4 respostas

2

Você realmente precisa aparar seus serviços. Melhor ainda, você pode querer considerar o uso de inetd ou xinetd (o que se aplica à sua instalação). Em vez de deixar vários serviços lançados e aguardando (e monopolizando a preciosa RAM), talvez você esteja melhor com um desempenho de CPU ao iniciar um serviço quando necessário. E foi para isso que o inetd / xinetd foi feito - eles tinham a intenção de fornecer uma maneira de pouca memória para permitir que os serviços fossem lançados sob demanda, em vez de mantê-los por perto o tempo todo. É claro, sua milhagem pode muito - você ainda pode acabar com problemas de recursos de memória - mas se você ficar em um ponto difícil por enquanto ...

Acompanhamento de onde começar (do comentário):

Eu gostaria de ver o apache sendo transferido primeiro. Reduza a contagem máxima de filhos para apenas 2 - a menos que você esteja atendendo mais usuários do que você, é pouco útil ter 3 processos em execução.

Para o dovecot, especificamente os processos imap-auth, você precisa apenas de um. Você poderia executá-lo no inetd também, embora pareça ser bastante fino. Se você não usa IMAP ou POP no seu servidor, desative-o. Na pior das hipóteses, você volta a ler e-mails em uma linha de comando - não é bonita, mas funcional.

Você também pode mover o sshd, embora eu inicialmente fizesse isso em um número de porta alternativo e confirme que ele se conecta antes de você ligar o switch.

Considere mudar para o Exim se possível (que é a instalação padrão para configurações Debian / Ubuntu). Eu amo o Postfix e não uso o Exim, mas o Debian o escolheu como padrão por uma razão - ele requer poucos recursos e é bastante seguro.

Observe sua configuração / proc / sys / vm / swappiness ( echo /proc/sys/vm/swappiness ) e determine se ela está muito alta ou muito baixa. Um número maior ajudará a liberar memória (trocando para VM antes do tempo), mas quando estiver muito alto você irá trocar como louco. A maioria das instalações diz "60", mas para pouca memória, provavelmente deveria ser mais como 85. Não recomendo 100 em sua configuração.

Por fim, pense em "tela verde". Você está falando sobre o uso de técnicas que existem há muito tempo em sistemas muito mais antigos (porque eles eram recursos restritos também). É um pouco antiquado fazer as coisas dessa maneira, mas se você puder fazer seu trabalho em um programa cliente em um shell, em vez de lançar serviços, você expandirá seus recursos de computação muito mais.

    
por 23.09.2009 / 06:39
1

Fique de olho no número de processos httpd que estão sendo executados e na quantidade de memória que eles estão usando. Eu acho que o seu servidor web está trocando, talvez porque a diretiva MaxClients está excedendo o valor ideal para o seu servidor. Você precisa calcular a média de RAM necessária para cada processo do apache (de acordo com os resultados de ps é de cerca de 30M) e definir MaxClients com um valor que não excede o total de RAM disponível com espaço suficiente para outros processos como o MySQL.

    
por 23.09.2009 / 04:58
1

Se você digitar o comando 'free' quando o servidor começar a desacelerar, você verá o uso da memória e estou disposto a apostar, como disse o HD, que o seu servidor está atingindo o espaço de swap. Indo por sua saída de PS, você está quase em 256M lá.

Você pode querer mover MaxSpareServers para 2 ou até mesmo 1. Além disso, existem alternativas para o Apache, por exemplo lighttpd que é deveria ser leve e usar menos memória.

Eu tenho uma opinião pessoal, e tenho certeza que alguns irão discordar, que você não deve ter menos de 512M ou 1G de RAM em um servidor.

    
por 23.09.2009 / 06:00
0

Rodar o Apache, o MySQL e provavelmente o PHP em um VPS de 256 MB é uma espécie de jogo tight. 256 MB de RAM não é muito para executar esses serviços, pelo contrário, é muito, muito pouco. A primeira coisa a fazer seria considerar se não conseguir um VPS melhor é uma opção.

Então, se conseguir um VPS melhor não é uma opção, um conselho sério: abandone o Apache completamente!

O Apache tornou-se um verdadeiro explorador de memória naqueles dias e, como você não tem o luxo de ter memória livre em massa, o Apache realmente deveria ir.

Pegue o Nginx, que também é bastante poderoso, mas leva muito menos recursos para ser capaz de fornecer!

E, claro, no caso de usar PHP, você precisa instalar o PHP-FPM em conjunto com o Nginx e então você precisa configurar o seu pool apropriadamente.

Você também pode querer ajustar os vários caches no MySQL, o que significa provavelmente reduzir seus tamanhos!

    
por 31.07.2014 / 15:37