Недостаточно памяти у Кассандры на массивных вставках - PullRequest
4 голосов
/ 29 марта 2012

Я пытаюсь вставить данные с большими значениями столбца (1-25 МБ), и через пару секунд один из моих узлов умирает, либо выбрасывая OOM, либо застревая в бесконечном цикле GC.

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

Поскольку журнал посоветовал мне уменьшить размеры memtable / cache, я попытался выяснить, что израсходовало всю эту память, чтобы адаптировать мои настройки, поэтому я запустил nodetool flush / invalidaterowcache / invalidatekeycache и затем активировал GC через jconsole. *

К сожалению, мое использование памяти оставалось высоким (> 60%), даже если сервер не работает.

Итак, моя проблема: почему серверу не хватает памяти при вставке больших значений? а также, почему сервер не возвращает память?

Редактировать

Я сделал кучу, и куча заполнена байтом [], на который в основном ссылается org.apache.cassandra.io.sstable.IndexSummary$KeyPosition.

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

Ответы [ 2 ]

2 голосов
/ 30 марта 2012

Я исследовал дамп кучи с помощью MAT, и оказалось, что OutOfMemory произошел из-за того, что Thrift использовал много памяти.

Поскольку мне приходилось передавать большие порции данных для значений моего столбца, я изменилэти настройки на 128, чтобы «быть в безопасности»:

  • thrift_framed_transport_size_in_mb
  • thrift_max_message_length_in_mb

Но оказывается, что Thrift выделяет один byte[2 * thrift_max_message_length_in_mb] для получениянить, а у меня их было три.Поэтому я использовал 768Mb только для буферов приема ...

Изменение настроек на 32 исправило мою проблему.

2 голосов
/ 29 марта 2012

Мне кажется, что вы столкнулись с проблемой печально известной фрагментации памяти . Я не уверен, что Кассандра снимает некоторые проблемы фрагментации, но в целом в .NET и, возможно, в любой программе Windows может с этим столкнуться.

Когда вы выбираете что-либо больше 85000 байт (да, нечетное число, но оно есть), объекты сохраняются в куче больших объектов. LOH получает GC только в поколении 2, но, что еще хуже, он уплотняется никогда . Причиной частично является способ реализации ОС .

Результат: когда вы храните объекты, скажем, 2 МБ, 5 МБ, 3 МБ, 2 МБ, 3 МБ, а объекты размером 2 МБ получают GC, у вас потенциально может быть 4 МБ бесплатно. Но если вы затем попытаетесь создать новый объект размером 3 МБ, он не может быть помещен туда из-за фрагментации (2 отверстия по 2 МБ) и перемещается к вершине кучи. В конце концов, это не хватает места. Итак: может быть достаточно памяти, но вы получите OOM независимо от этой фрагментации .

Эта проблема в основном наблюдается в 32-битных x86-приложениях в 64-битной (WOW64) и 32-битной Windows. 64-разрядные приложения также имеют проблему фрагментации, но поскольку виртуальная память намного больше, вы сначала нажимаете на подкачку памяти (становясь очень медленной), прежде чем сталкиваетесь с фактическими проблемами фрагментации.

Если это действительно проблема (вы можете проверить фрагментацию визуально с помощью VMMap и WinDbg ), вы можете решить эту проблему, создав большой пул байтов и повторно используя свой собственный пул , таким образом предотвращая фрагментацию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...