LinuxForum.Fans
Тема

Cannot allocate memory и сервер уходит в офлайн

Автор: valet 50 сообщений 6007 просмотров
20.10.2014 14:40 #397322

Имеется сервер:
4 ядра Intel(R) Xeon(R) CPU E5-1410 v2 @ 2.80GHz (8 потоков), 64 Гб памяти, SSD
Конструкция

text
cat very_big_file|fgrep -x -f big_file > rez_file

съедает всю память и выдает примерно "Cannot allocate memory" при этом все остальные запущенные на сервере процессы тоже обрываются по подобной ошибке и сервер уходит в офлайн - приходится перезагружать.

Кто подскажет с чем это связано?
Файлы порядка 8 Гб, памяти аж 64 Гб да и насколько я знаю это конструкция спокойно отрабатывается на любых компьютерах и даже с намного меньшей памятью.
Что не так? Куда копать, что именно пожирает память и как перенастроить?

20.10.2014 15:00 #397324

Зачем вы используете cat?

Почему не просто так:

text

fgrep -x -f big_file very_big_file > rez_file
20.10.2014 16:17 #397331

"kostik87" написал:
Почему не просто так:
согласен

"kostik87" написал:
Зачем вы используете cat?
ну как бы вопрос не в этом, я понимаю что конструкция не совсем верная, но тем не менее она должна нормально работать и прекрасно работает на всех серверах (у меня 4 подопытных машины), а на этой причем на самой мощной она почему-то пожирает всю память - вот собственно почему...
20.10.2014 18:08 #397339
"valet" написал:
ну как бы вопрос не в этом, я понимаю что конструкция не совсем верная, но тем не менее она должна нормально работать и прекрасно работает на всех серверах (у меня 4 подопытных машины), а на этой причем на самой мощной она почему-то пожирает всю память - вот собственно почему...

размеры big_file и версии grep'а аналогичны?

20.10.2014 18:21 #397342
text
$ grep --version
grep (GNU grep) 2.12
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Mike Haertel and others, see <http://git.sv.gnu.org/cgit/grep.git/tree/AUTHORS>.

text
$ du -h big_file
7.3G    big_file
20.10.2014 18:32 #397344
"valet" написал:
$ grep --version
"valet" написал:
$ du -h big_file

я про те железки, на которых, якобы, работает...

20.10.2014 18:35 #397346

"Fat-Zer" написал:
я про те железки, на которых, якобы, работает...
Не очень понял, те тележки слабее чем эта и там работает, я 100500 раз испытывал подобную конструкцию - всегда все работало, впервые столкнулся с тем что это может сожрать память - ведь это по определению нелогично, система в любом случае должна быть достаточно умна чтобы подобного не случилось, тем более что файлы оба даже целеком влезут в ОП которой 64 Гб, так как они порядком 8 ГБ каждый.
20.10.2014 18:41 #397347

"Fat-Zer" написал:
якобы
якобы? мне кажется оно должно работать даже если файлы по 100500 гиг, разве меня должно интересовать что куда оно копирует - ОП или диск - мне надо получить результат, никогда не встречал чтобы такое сожрало память - это очень похоже на какой-то баг...
20.10.2014 19:11 #397348
"valet" написал:
это по определению нелогично, система в любом случае должна быть достаточно умна чтобы подобного не случилось

прям будто вчера первый раз линь поставил... если ты сказал системе прострелить тебе в ногу ни кто тебя от этого отговаривать не будет...

"valet" написал:
тем более что файлы оба даже целеком влезут в ОП которой 64 Гб, так как они порядком 8 ГБ каждый.

размер и влезет ли в память первый (very_big_file) значения не имеет... если бы просто grep жрал бы в разы больше, чем нужно — ответ то же был бы простой: оно так устроено...
а вот почему fgrep жрёт столько памяти уже действительно заставляет задуматься... даже если бы он жрал в 2-4 раза больше размера файла, то это можно было бы списать на внутреннее устройство... по моим экспериментам, сейчас выходит, что он требует в 5—20 раз больше ОП... так что возможно действительно:

"valet" написал:
это очень похоже на какой-то баг
"valet" написал:
я 100500 раз испытывал подобную конструкцию - всегда все работало

работало на файлах в несколько сот метров?

20.10.2014 19:23 #397350

"Fat-Zer" написал:
работало на файлах в несколько сот метров?
даже в несколько гиг, просто отрабатывало долго...

Могу специально проверить - так и быть перекачаю на самый слабенький сервер файлы и проверю...
20.10.2014 19:28 #397351
"valet" написал:
Могу специально проверить - так и быть перекачаю на самый слабенький сервер файлы и проверю...

top'ом посмотри использование памяти при этом...

20.10.2014 19:45 · отредактировано #397359

А может что с диском, где лежит ваш файл.

"Fat-Zer" написал:
top'ом посмотри использование памяти при этом...

Лучше atop - он подсвечивает, где критично

20.10.2014 19:58 #397360

"Fat-Zer" написал:
если ты сказал системе прострелить тебе в ногу ни кто тебя от этого отговаривать не будет...
не соглашусь, я использую более чем стандартные утилиты, с чего бы они должны сжирать память, они сами должны знать как правильно отработать, есть память - хорошо, исопльзуй, пожалуйста, но не до отказа же сервера, пиши своп, диск, куда угодно - я же не просил мне положить сервер (прострелить ногу) разве не так?
20.10.2014 20:00 #397361

Поставил это же на другом сервере, пока отрабатывает, о результатах отпишу...
Но уже вижу что будет все нормально, так как юзается 1 ядро, и 11,4% память - вижу по htop

20.10.2014 20:09 · отредактировано #397362
text
valet@valet-comp:~$ du -h very_big_file 
7.3G    very_big_file
valet@valet-comp:~$ du -h big_file 
64M    big_file
valet@valet-comp:~$ time cat very_big_file |fgrep -x -f big_file > rez_file

real 12m57.766s user 12m53.496s sys 0m4.908s valet@valet-comp:~$

Вот идеально отработало без каких либо проблем.
Чего и следовало ожидать, я же говорю - исопльзую подобные конструкции 100500 раз, никогда не замечал чтобы они сжирали память

20.10.2014 20:17 · отредактировано #397363
"valet" написал:
64M big_file
"valet" написал:
7.3G big_file

так где правда? и какое использоване памяти? с big_file в несколько сотен мб всё равно работает?

да кстати, локаль на сервере, где не работало какая? LC_ALL=C ситуацию нормализует?

ЗЫ: вот похожий баг, но числа там на порядок меньше... да и посчитали, что его пофиксили... https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=520446

20.10.2014 21:44 · отредактировано #397381

набросал минискриптик для тестирования использования памяти в зависимости от количества паттернов:

text
#!/bin/bash

shuf -i 0-1000000 -n 100000 >bar

printf "%11s | %6s | %13s | %6s\n" "patterns" "sz" "mem_usage" "matches"

for i in 1000{,0{,0{,0{,0}}}}; do shuf -i 0-$(($i*10)) -n $i >foo; mem=$(valgrind grep -F -x -f foo bar 2>&1 >output | sed -rn 's/.* ([0-9,]+) bytes allocated.*/\1/p'); printf "%11d | %6s | %13s | %6s\n" "$i" "$(du -h foo | cut -f 1)" "$mem" "$(wc -l output | cut -f 1 -d ' ')" done

Внимание на 3-ю колонку — там использовании кучи в байтах

gentoo grep-2.20
text

   patterns |     sz  |     mem_usage | matches
       1000 |   8,0K  |       326,151 | 96
      10000 |    60K  |     2,873,759 | 965
     100000 |   676K  |    28,661,655 | 10015
    1000000 |   7,6M  |   290,112,886 | 9971
   10000000 |    85M  | 2,943,611,614 | 9981

gentoo grep-2.16
text

   patterns |     sz  |     mem_usage | matches
       1000 |   8,0K  |       222,721 |     97
      10000 |    60K  |     1,833,594 |    977
     100000 |   676K  |    18,192,446 |  10020
    1000000 |   7,6M  |   184,347,043 |   9920
   10000000 |    85M  | 1,877,114,991 |   9975

debian-lenny grep-2.5.3
text

   patterns |     sz  |     mem_usage | matches
       1000 |   8,0K  |       214,350 |     98
      10000 |    64K  |     1,702,670 |    999
     100000 |   668K  |    17,368,494 |  10002
    1000000 |   7,5M  |   169,192,302 |  20030
# на последний тест памяти не хватило

LC_ALL=C на числах даёт выигрыш всего ~1-2% по памяти...

20.10.2014 21:59 #397385
text
valet@valet-comp:~$ du -h very_big_file 
7.3G    very_big_file
valet@valet-comp:~$ du -h big_file 
64M    big_file

Ну это естественно, файлы называются вообще по-другому, я для понимания в первом посте указал такие имена чтобы было понятно что это какие-то крупные текстовые файлы, а на рабочем сервере уже и переименовал их соотвественно на big_file и very_big_file.

"Fat-Zer" написал:
и какое использоване памяти?
та никакое - там по htop этот процесс жрал 11.4% памяти, нагрузки вообще и не было (по load average), только на одно ядро 100% и все и отработало как видим за 12 минут.

"Fat-Zer" написал:
с big_file в несколько сотен мб всё равно работает?
работает в точности как я скопировал - я ж специально даже время засек - это реальная копия с консоли на этот раз с рассматриваемыми именами файлов.
20.10.2014 22:49 · отредактировано #397397

"Fat-Zer" написал:
набросал минискриптик для тестирования использования памяти в зависимости от количества паттернов:
У меня на проблемной машине ваш скрипт выдает следующее:
text
[valet@server ~] $ time ./test_mem 
   patterns |     sz  |     mem_usage | matches
       1000 |   8.0K  |               |      0
      10000 |    60K  |               |      0
     100000 |   676K  |               |      0
    1000000 |   7.6M  |               |      0
   10000000 |    85M  |               |      0

real 0m3.954s user 0m3.104s sys 0m0.344s [valet@server ~] $

То есть как я понимаю отрабатывает и то быстро, но память не показывает.

20.10.2014 23:05 · отредактировано #397399
"valet" написал:
То есть как я понимаю отрабатывает и то быстро, но память не показыва

valgrind не установлен?
и не забудь потом foo и bar снести...

"valet" написал:
та никакое - там по htop этот процесс жрал 11.4% памяти, нагрузки вообще и не было (по load average), только на одно ядро 100% и все и отработало как видим за 12 минут.

я прогуливал занятия телепатии в начальной школе и мне 11.4% ни о чём не говорит, но из того, что я нахватался рискну предположить, что это от 16-ти гигов... если так, то вполне уклаывается в результат, хотя для такой задачи это невероятно большой расход памяти... но grep так устроен...

"valet" написал:
Ну это естественно, файлы называются вообще по-другому, я для понимания в первом посте указал такие имена чтобы было понятно что это какие-то крупные текстовые файлы, а на рабочем сервере уже и переименовал их соотвественно на big_file и very_big_file.

так... чтобы расставить точки над и:

text
very_big_file: 7.3G
big_file: 64M

и точно так было когда боевая тачка навернулось от нехватки памяти, так? very_big и big точно местами не перепутал когда запускал?
ещё есть подозрение, что grep начинает непомерно кушать память когда в big_file есть повреждённая многобайтовая кодировка... сможешь удостовериться, что это не так?

Войдите или зарегистрируйтесь, чтобы ответить.