Потребление памяти в KDB/Q

У меня есть база данных KDB/Q, которая имеет около 2 миллионов записей в день, потребляя около 2 ГБ памяти. В конце дня он запускает некоторые отчеты, объединяет таблицы и выводит результаты в файлы на диске. Во время вычислений использование памяти увеличивается до ~15G. Моя проблема заключается в том, что, как только эта операция завершается, память никогда не освобождается и, пока БД не будет перезапущена, она потребляет все 15 ГБ памяти.

Я хотел бы попросить KDB выгрузить некоторые таблицы из памяти (но не удалять их), но я не хочу перезагружать БД, поскольку некоторые другие приложения все еще подключаются к ней.

Есть ли способ сказать KDB, чтобы выгрузить что-то из памяти?

РЕДАКТИРОВАТЬ:

Если кому-то это интересно, предлагаю посмотреть .Q.gc[] для KDB 2.5+ выглядит многообещающе.

4 ответа

Решение

Вот итог моего исследования:

  • KDB до вер. 2.5 выделяет 64 МБ памяти по мере необходимости и никогда не освобождает их. Это может использовать их все же.
  • последние версии KDB позволяют .Q.gc[] вызов, который является вызовом по запросу сборщика мусора (KDB использует ref. counting btw.)
  • это особенно полезно, когда вы вызываете некоторые объемные вычисления, которые выделяют много памяти (в моем случае это было ~20 ГБ), и вы хотите освободить память после окончания вычислений.
  • Вы всегда можете подумать о том, чтобы поместить сценарий с интенсивным использованием памяти в отдельный процесс Q, чтобы память была освобождена после завершения сценария.

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

delete table from`.

если нет, вы можете удалить все его строки

delete from`table

Для любого, кто попробует это в будущем, проще всего было бы:

  1. Начать новый процесс KDB.
  2. Из этого запроса процесса, чтобы выбрать наименьшие ограниченные подмножества данных, необходимых.
  3. Выполните любые соединения / вычисления / записи в файл из этого процесса. (позволяя оригиналу продолжать обработку запросов)
  4. Закройте процесс, освободив всю память.

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

На сайте нашей компании есть хорошая статья, в которой подробно рассказывается об управлении памятью KDB+: http://timestored.com/kdbGuides/memoryManagement

http://code.kx.com/q4m3/12_Workspace_Organization/

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

Это сеанс до создания таблицы.

q).Q.w[]
used| 290192
heap| 67108864
peak| 67108864
wmax| 0
mmap| 0
mphy| 8589934592
syms| 629
symw| 20704

Эта команда создает таблицу, а затем сохраняет ее на диск.

q)t:([]10000?"ab"; 10000?5)
q)save `t
`:t

Таблица все еще в памяти

q).Q.w[]
used| 437808
heap| 67108864
peak| 67108864
wmax| 0
mmap| 0
mphy| 8589934592
syms| 629
symw| 20704

Давайте вычеркнем переменную из памяти и соберем мусор.

q)delete t from `.
`.
q).Q.gc[]
0

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

q).Q.w[]
used| 290208
heap| 67108864
peak| 67108864
wmax| 0
mmap| 0
mphy| 8589934592
syms| 630
symw| 20730
q)\v
`symbol$()
Другие вопросы по тегам