Перейти к содержимому
Последнее обновление

Частые вопросы о проблемах с памятью

Для анализа памяти процесса BE Doris в основном используют журнал be/log/be.INFO, метрики памяти процесса BE (Metrics) и статистику Doris Bvar. При срабатывании OOM Killer необходимо собрать результаты выполнения dmesg -T. Для анализа памяти запросов или заданий загрузки данных необходимо собрать Query Profile. На основе этих данных можно проанализировать распространённые проблемы с памятью. Если решить проблему самостоятельно не удаётся, обратитесь за помощью к разработчикам Doris. Независимо от способа обращения (issue на Github, тема на форуме Doris, электронная почта или WeChat) добавьте перечисленные выше данные к описанию проблемы.

Сначала определите, к какому типу проблем с памятью относится наблюдаемое поведение, а затем продолжайте диагностику. Обычно в первую очередь нужно проанализировать журнал памяти процесса. См. Анализ журнала памяти. Ниже перечислены распространённые проблемы с памятью.

1 Ошибка ограничения памяти при выполнении запроса или загрузке данных​

Если сообщение об ошибке запроса или загрузки данных содержит MEM_LIMIT_EXCEEDED, это означает, что задание отменено из-за нехватки доступной памяти у процесса или превышения лимита памяти на одно выполнение задания.

ERROR 1105 (HY000): errCode = 2, detailMessage = (10.16.10.8)[MEM_LIMIT_EXCEEDED] xxxx .

Если сообщение об ошибке содержит Process memory not enough, процессу не хватает доступной памяти. Для дальнейшего анализа см. Ошибка запроса или загрузки данных: процессу не хватает доступной памяти.

Если сообщение об ошибке содержит memory tracker limit exceeded, задание превысило лимит памяти на одно выполнение. Для дальнейшего анализа см. Ошибка запроса или загрузки данных: превышен лимит памяти на одно выполнение.

2 Аварийное завершение BE Doris из-за OOM​

Если после аварийного завершения процесса BE в log/be.out нет сообщения об ошибке, выполните dmesg -T. Сообщение Out of memory: Killed process {pid} (doris_be) означает, что сработал OOM Killer. Для дальнейшего анализа см. Анализ аварийного завершения из-за OOM Killer.

3 Утечка памяти​

Если вы подозреваете утечку памяти, лучше всего обновиться до последней версии с трёхкомпонентным номером. Если вы используете Doris 2.0, обновитесь до последней версии Doris 2.0.x: вероятно, другие пользователи уже сталкивались с таким поведением, а большинство утечек памяти исправляется в последующих версиях.

Следующие признаки могут указывать на утечку памяти:

  • Мониторинг в Doris Grafana или на сервере показывает, что объём памяти процесса BE Doris линейно растёт и не уменьшается после остановки задания в кластере.

  • Memory Tracker учитывает не всю память; для анализа см. Memory Tracker.

Утечки памяти обычно сопровождаются неполной статистикой Memory Tracker, поэтому методы анализа также описаны в разделе [Memory Tracker].

4 Объём памяти процесса BE Doris не уменьшается или продолжает расти​

Если мониторинг в Doris Grafana или на сервере показывает, что объём памяти процесса BE Doris линейно растёт и не уменьшается после остановки задания в кластере, сначала обратитесь к Memory Tracker в разделе Memory Tracker, чтобы проверить, вся ли память учтена в статистике Memory Tracker. Если Memory Tracker учитывает не всю память, выясните причину.

Если пропусков в статистике Memory Tracker нет и большая часть памяти учтена, обратитесь к Обзору, чтобы выяснить, почему разные части процесса BE Doris занимают слишком много памяти и как уменьшить её потребление.

5 Большой объём виртуальной памяти​

В Memory Tracker запись Label=process virtual memory показывает текущий объём виртуальной памяти. Он совпадает с объёмом виртуальной памяти процесса BE Doris, который отображает top -p {pid}.

MemTrackerLimiter Label=process virtual memory, Type=overview, Limit=-1.00 B(-1 B), Used=44.25 GB(47512956928 B), Peak=44.25 GB(47512956928 B)

В Doris пока сохраняется проблема чрезмерного объёма виртуальной памяти процесса BE Doris. Обычно это связано с тем, что Jemalloc удерживает большое количество отображений виртуальной памяти, из-за чего Jemalloc Metadata также занимает слишком много памяти. Анализ памяти Jemalloc Metadata описан в разделе Анализ памяти Jemalloc.

Кроме того, известно, что в Join Operator и Column в Doris отсутствует повторное использование памяти. В некоторых сценариях это приводит к выделению большего объёма виртуальной памяти, которая в итоге кэшируется в Jemalloc Retained. Эффективного решения пока нет. Рекомендуется регулярно перезапускать процесс BE Doris.

6 Процесс BE занимает очень много памяти сразу после запуска​

Обычно это связано с большим объёмом метаданных, загружаемых в память при запуске процесса BE. Чтобы просмотреть Doris BE Bvar, см. Анализ памяти метаданных.

  • Если значение doris_total_tablet_num слишком велико, обычно причина в чрезмерном количестве партиций и bucket в таблице. Проверьте {fe_host}:{fe_http_port}/System?path=//dbs, чтобы найти таблицу с большим количеством tablet. Количество tablet в таблице равно произведению числа её партиций и числа bucket. Попробуйте уменьшить количество партиций и bucket. Также можно удалить устаревшие таблицы или партиции, которые больше не будут использоваться.

  • Если значение doris_total_rowset_num слишком велико, но tablet мало, обратитесь к документации SHOW-PROC, чтобы найти таблицы с большим количеством rowset и небольшим количеством tablet. Затем запустите compaction вручную или дождитесь завершения автоматического compaction. Подробности см. в документации по управлению метаданными. При сотнях тысяч rowset метаданные могут занимать несколько GB, и это нормально.

  • Если значение tablet_meta_schema_columns_count слишком велико и в сотни или тысячи раз превышает doris_total_tablet_schema_num, в кластере есть большие широкие таблицы с сотнями или тысячами столбцов. В этом случае то же количество tablet будет занимать больше памяти.

7 Запрос только сканирует данные без сложных операторов, но потребляет много памяти​

Память могут занимать Column Reader и Index Read, открываемые при чтении Segment. См. Анализ памяти метаданных, чтобы просмотреть изменения doris_total_segment_num, doris_column_reader_num, doris_ordinal_index_memory_bytes, doris_zone_map_memory_bytes и doris_short_key_index_memory_bytes в Doris BE Bvar. Такое поведение также часто наблюдается при чтении больших широких таблиц. При открытии сотен тысяч Column Readers потребление памяти может достигать десятков GB.

Если в Heap Profile в стеке вызовов, на который приходится большая доля памяти, встречаются поля Segment и ColumnReader, можно с высокой уверенностью заключить, что большой объём памяти расходуется при чтении Segment.

В этом случае остаётся только изменить SQL, чтобы уменьшить объём сканируемых данных, или уменьшить размер bucket, заданный при создании таблицы, чтобы открывалось меньше сегментов.

8. Зависание отмены запроса​

Часто встречается в версиях до Doris 2.1.3

Большую часть памяти, выделенной во время выполнения запроса, необходимо освободить при его завершении. Когда процессу хватает памяти, обычно не нужно обращать внимание на скорость завершения запроса. Однако при нехватке памяти некоторые запросы часто отменяются по определённой стратегии, чтобы освободить занятую ими память и избежать срабатывания OOM Killer для процесса. Если отмена запроса зависает и память не освобождается вовремя, это повышает риск срабатывания OOM Killer и может привести к отмене ещё большего числа запросов из-за нехватки памяти у процесса.

Если известно, что запрос был отменён, по его QueryID можно проверить, не зависла ли отмена. Сначала выполните grep {queryID} be/log/be.INFO, чтобы найти первую запись журнала с ключевым словом Cancel. Её время соответствует моменту отмены запроса. Найдите запись с ключевым словом deregister query/load memory tracker. Её время соответствует моменту завершения отмены запроса. Если в итоге сработал OOM Killer, а запись с ключевым словом deregister query/load memory tracker не найдена, значит, к моменту срабатывания OOM Killer отмена запроса ещё не завершилась. Обычно, если отмена запроса занимает более 3 с, она считается зависшей, и необходимо подробнее проанализировать журнал выполнения запроса.

Кроме того, если после выполнения grep {queryID} be/log/be.INFO вы видите запись с ключевым словом tasks is being canceled and has not been completed yet, следующий за ним список QueryID указывает на запросы, отмена которых ещё не завершилась на момент выполнения Memory GC. В этом случае Memory GC пропустит эти запросы и продолжит освобождать память в других местах. По этой информации можно определить, работает ли Memory GC ожидаемым образом.