qkowlew: На Зилантконе меня сфоткали мыльницей. Мыльницам не позирую! (Default)
[personal profile] qkowlew
Есть подозрение, что свежайший (ну по крайней мере для FreeBSD и CentOS) memcached имеет memory-leak/buffer overflow баг, приводящий при некоем значении поступившего ему на вход url с буквами нац алфавитов (сорри, не нашёл точно в логах какой строкой это случилось) к выжиранию 2^32 байт памяти одной порцией (то есть вот так прямо +4 гигабайта в top ему прибавляется сей же секунд), причём ПРЕОДОЛЕВАЯ стоящее при запуске ему ограничение (там у меня было 1 гиг выделено). Всё это в достаточно типовом построении "nginx берёт из мемкешеда то, что туда положил php код вордпресса, битрикса или какой другой CMS"

От операционки вроде не зависит - в CentOs и FreeBSD эффект наблюдался примерно одинаково.

Это у меня два разных сервера стали недавно систематически падать и-или подвисать. Исследование показало, что, добавив им по 40 гигабайт свопа на тормознутом бекапном винте, я смог пронаблюдать "плавный" процесс "отжирания 4гиг мемкешедом" до того, как система впала в ошибку "не могу выделить свап спейс, пошли прибьём тут кого-нибудь..."

Особенная красота ситуации на одном из серверов заключалась в том, что кеширование объектов в WordPress "вдруг" переставало работать для подавляющего большинства страниц сайта, что приводило к возрастанию числа SQL запросов к базе с 10 до 740 и с 28 до 3000 и ещё более, в результате всё подыхало прямо на глазах. Пример честно закешированной как html файл такой страницы - вот тут. видно 747 запросов к MySQL 8-)

Сил раскопать самому этот кусок кода вот прям щас нету. :(

Date: 2018-Mar-19, Monday 06:46 (UTC)
vitus_wagner: My photo 2005 (Default)
From: [personal profile] vitus_wagner
Ну вот чую, -1 (32-битный) передали туда. А ограничение проверяется по знаковому типу.

Date: 2018-Mar-19, Monday 06:54 (UTC)
filin: (Default)
From: [personal profile] filin
Не обязательно ровно -1. Если старшим байтом числа оказался, скажем, ведущий байт из UTF-8, у которого старшие три-четыре бита 1, памяти отожрется _примерно_ 2^32.

Но могли и -1, который часто возвращают как код ошибки (size_t(-1), ага).

Date: 2018-Mar-19, Monday 07:25 (UTC)
vitus_wagner: My photo 2005 (Default)
From: [personal profile] vitus_wagner
Не, там как-то хитрее должно было бы быть. Там где можно за один вызов malloc отожрать 4Гб, sizeof(size_t) должно быть 8. Там где-то замешался каст в какой-то другой unsigned тип, поменьше.

Date: 2018-Mar-19, Monday 12:17 (UTC)
filin: (Default)
From: [personal profile] filin
Ровно 4 Гб - да. А _чуть меньше_, чем 4 Гб - почему нет?

Date: 2018-Mar-19, Monday 12:23 (UTC)
vitus_wagner: My photo 2005 (Default)
From: [personal profile] vitus_wagner
В 32-битных системах из 4Гб теоретически возможного адресного пространства минимум гиг уходит на ядро. Поэтому максимальный объем heap там СУЩЕСТВЕННО меньше 4Гб.