Помогите трактовать heapdump


#1

Доброго времени суток!
Имею следующую проблемму - постепенно полностью выедается куча.
GC начинает безустанно трудистя и собственно всё плохо.
Пробовал делать 8ГБ кучу - всё равно не хватает.
Теперь пытаюсь понять, что собвенно выедает её.
Снал дамп, скормил его Memory Analizer-у, но не очень его понимаю.
Поэтому прошу помощи:

  1. массив чаров - это общий буфер или один документ? Судя по содержимому, либо не один документ, либо мне присылают ерунду.
  2. В дереве, по два раза указан и SnowballFilter и WordDelimiterFilter - это одно и тоже или складывать надо?
  3. Если первое - это один документ, то получается что WordDelimiter побил мне его на >40млн. токенов? (org.apache.lucene.util.AttributeSource$State) и собтвенно сюда ушла куча.


(Igor Motov) #2

А версия Elasticsearch какая?

Вы не могли бы раскрыть AttributeSource$State и прислать еще одну картинку?

Можно посмотреть на mappings и settings?

Вы параметры thread pool для bulk или index меняли?


#3

ES 2.4.3
thread pool - раньше менял, но поведение системы не менялось.
Поэтому давно всё вернуо по дефолту. Из всех настроек:
discovery под uniscat и
bootstrap.mlockall: true
gateway.recover_after_time: 5m
mapping и settings в личку пошлю.
Скрин вот такой еще есть:


Если не путаю, в каждом $State : 24 char c каким-либо слово и RefInt.
Если надо точнее - утром сделаю.


(Igor Motov) #4

Первое, что бросается в глаза, это использование keyword tokenizer. Он часто приводит к большому потреблению памяти на больших полях. Я не очень понимаю из вашей схемы чем оправдан этот выбор, но мне он кажется очень странным.

Да, было бы хорошо посмотреть на внутренности нескольких $State.


#5

Это мне сложно комментировать, т.к. создавал схему не я.
Мне этот проект недавно передали.
Опыта у нас мало, возможно перемудрили.
По большому счету, тут всё просто должно быть: имя файла и его содержимое для поиска.


#6

К сожалению, исходный дамп затёр. Сделал новый, ситуация 1 в 1.
Только разный размер AttributeSource$State и их количество.
Тут более 9 миллиона штук.

P.S. Тут видимо еще наш конвертер глючит - DOC -> TXT.


(Igor Motov) #7

Я обсудил эту проблему со знатоком Lucene. Он сказал, что проблема, действительно, в использовании keyword tokenizer на очень больших полях. Я думаю, если вы его замените на standard то проблема с памятью должна исчезнуть. Однако для этого все данные надо будет переиндексировать.


#8

Большое спасибо!
Насколько я понимаю, это можно сделать достаточно прозрачно через алиас и реиндекс?
Извиняюсь за назойливость, а на первый мой вопрос точного ответа нет?


(Igor Motov) #9

Прозрачно для поиска - да, но индексацию на это время надо будет прекратить.

Это какой вопрос? Почему в буфере токены вроде "учреждениягрузополучателя" появляются? Судя по вашему меппингу это, скорее всего ваш конвертер "-" между словами убивает. Это очень просто проверить - поищите по этому словосочетанию и посмотрите какой документ был послан.


#10

Не, на самый первый. Грубо говоря, что за 70-ти метровый char?


(Igor Motov) #11

Это как раз токен, который KeywordTokenizer создал для поля целиком. То есть у вас где-то был документ, в котором одно из полей было 77М. Эти буферы кэшируются на уровне thread local, поэтому даже после того, как такой документ обработан - память все-равно занята. Это как-раз причина по которой я рекомендовал перейти на StandardTokenizer.


#12

Не срастается у меня в голове: keyword tokenaizer - ладно, ну выжрал 77 метра. Но по аналайзеру то выходит, что больше съел AttributeSource$State. Что это?


(Igor Motov) #13

Анализатор работает с каждым токеном произведенным токенизатором в цикле. Как только он с первым токеном разобрался, он его освобождает и переходит к следующему. Это работает хорошо с маленькими строками или когда используется стандартный токенизатор, который откусывает по маленькому токену за раз. Токенизатор кeyword откусывает все сразу и потом сует этот огромный кусок в фильтр word_delimeter. Этот фильтр работает со всей строкой целиком с создает все токены для этой строки и держит их все в памяти до тех пор пока все не будет обработано. Токены эти гораздо больше чем исходная строка, потому что они содержат копию строки + дополнительные атрибуты (тип токена, положение токена в исходной строке, порядковый номер и т. д.). И это происходит на каждом треде из пула индексации.


#14

Вот тут еще не понял. При реиндексе нельзя писать в новый индекс пока он не закончится reindex?


(Igor Motov) #15

Можно, но нужно быть осторожным с установками reindex и с версиями записей которые добавляются в новый индекс. Есть несколько вариантов, в зависимости от того, как записи добавляются. У вас только новые записи всегда добавляются, или существующие записи будут обновляться во время ре-индексации?


#16

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


(Igor Motov) #17

Тут две проблемы - 1. не затереть новую версию старой и 2. куда писать обновленную запись, что бы ее можно было сразу найти и потом не потерять? Первую проблему можно решить установкой "conflicts": "proceed" и "op_type": "create". Пример можно найти в документации. Вторую проблему решить сложнее. Самый просто способ - во время ре-индексирования читать всегда из старого индекса, а писать все записи и в старый и в новый индексы.


(system) #18

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.