Облачные функции для Firebase, убитых из-за превышения лимита памяти
Я постоянно получаю спорадическую ошибку от облачных функций для Firebase при преобразовании относительно небольшого изображения (2 МБ). В случае успеха функция занимает около 2000 мс или меньше, и в соответствии с документацией Image Magick я не должен видеть никаких проблем.
Я попытался увеличить размер буфера для команды, которая не позволяет внутри Firebase, и я попытался найти альтернативы .spawn()
, поскольку это может быть перегружено мусором и замедлить работу. Ничего не работает.
Ответы
Ответ 1
[обновление] Как сказал один из комментаторов, это больше не должно быть проблемой, поскольку функции firebase теперь поддерживают свои настройки при повторном развертывании. Спасибо, firebase!
Оказывается, и это не очевидно или документировано, вы можете увеличить выделение памяти для своих функций в Консоль функций Google. Вы также можете увеличить тайм-аут для длительных функций. Он решил проблему с перегрузкой памяти, и теперь все отлично работает.
Изменить: обратите внимание, что Firebase будет reset ваши значения по умолчанию при развертывании, поэтому вам не следует заходить на консоль и сразу же обновлять их. Я по-прежнему ищу способ обновить эти настройки с помощью CLI, обновится, когда найду его.
Ответ 2
Я был потерян в пользовательском интерфейсе, не мог найти никакой возможности изменить память, но наконец нашел ее:
- Перейдите в консоль Google Cloud Platform (не консоль Firebase)
- Выберите Облачные функции в меню
- Теперь вы видите свою функцию firebase здесь, если она правильная. В противном случае проверьте, правильно ли вы выбрали проект.
- Игнорировать все флажки, кнопки и пункты меню, просто нажмите на название функции.
- Нажмите на редактировать (верхнее меню) и только измените выделенную память и нажмите Сохранить.
Ответ 3
Вы можете установить это в своем файле облачных функций в Firebase.
const runtimeOpts = {
timeoutSeconds: 300,
memory: '1GB'
}
exports.myStorageFunction = functions
.runWith(runtimeOpts)
.storage
.object()
.onFinalize((object) = > {
// do some complicated things that take a lot of memory and time
});
Возьмите документы здесь: https://firebase.google.com/docs/functions/manage-functions#set_timeout_and_memory_allocation
Не забудьте затем запустить firebase deploy
из вашего терминала.
Ответ 4
Последняя команда firebase deploy перезаписывает выделение памяти по умолчанию 256 МБ и время ожидания до 60 с.
В качестве альтернативы, чтобы указать желаемое распределение памяти и максимальное время ожидания, я использую команду gcloud, такую как:
бета-функции gcloud развертывают YourFunctionName --memory = 2048 МБ --timeout = 540 с
Другие варианты, пожалуйста, обратитесь к:
https://cloud.google.com/sdk/gcloud/reference/beta/functions/deploy
Ответ 5
Обновление: похоже, что теперь они сохраняют настройки при повторном развертывании, поэтому вы можете безопасно изменять распределение памяти в облачной консоли!
Ответ 6
Кажется, что конфигурация ресурса ImageMagick по умолчанию в облачных функциях Firebase не соответствует фактической памяти, выделенной функции.
Запуск identify -list resource
в контексте Облачной функции Firebase дает:
File Area Memory Map Disk Thread Throttle Time
--------------------------------------------------------------------------------
18750 4.295GB 2GiB 4GiB unlimited 8 0 unlimited
Память по умолчанию, выделенная для FCF, составляет 256 Мбайт - по умолчанию экземпляр ImageMagick считает, что он имеет 2 ГБ и поэтому не выделяет буфер с диска и может легко попытаться перераспределить память, что приведет к сбою функции на Error: memory limit exceeded. Function killed.
Один из способов - увеличить требуемую память, как было предложено выше, - хотя по-прежнему существует риск, что IM попытается перераспределить в зависимости от вашего варианта использования и выбросов.
Безопаснее всего было бы установить правильный предел памяти для IM как часть процесса обработки изображений с помощью -limit memory [your limit]
. Вы можете выяснить, как использовать вашу память, используя вашу логику IM с помощью `-debug Cache '- она покажет вам все выделенные буферы, их размеры и если они были памятью или диском.
Если IM попадает в предел памяти, он начнет распределять буферы на диске (с отображением памяти, а затем с обычными дисковыми буферами). Вам нужно будет учитывать ваш конкретный баланс между производительностью ввода-вывода и стоимостью памяти. Цена каждого дополнительного байта памяти вы выделяете свой FCF, умножается на 100 мс использования - так что может быстро расти.
Ответ 7
Другой вариант здесь заключается в том, чтобы избежать использования .spawn()
вообще.
Существует большой пакет обработки изображений для node Sharp, который использует библиотеку footprint с низкой памятью libvips. Вы можете проверить образец облачной функции на Github.
В качестве альтернативы существует оболочка node для ImageMagick (и GraphicsMagick), называемая gm. Он даже поддерживает параметр - limit, чтобы сообщать о своих ресурсных ограничениях для IM.