Потребление памяти KDB/Q
У меня есть база данных KDB/Q, которая имеет около ~ 2 М записей в день, потребляя около ~ 2 Гб памяти. В конце дня он запускает некоторые элементы отчетности, которые соединяются между таблицами и выводят результат в файлы на диске. При вычислении использование памяти увеличивается до ~ 15G. Моя проблема в том, что как только эта операция заканчивается, память не возвращается и до перезапуска БД она потребляет все 15 ГБ памяти.
Я хотел бы сказать KDB, чтобы выгрузить некоторые таблицы из памяти (не отбрасывать их, хотя), но я не хочу перезапускать БД, так как некоторые другие приложения все еще подключаются к нему.
Есть ли способ сказать KDB выгрузить что-то из памяти?
EDIT:
Если кто-нибудь найдет это интересным, я предлагаю взглянуть на .Q.gc[]
для KDB 2.5+, выглядит многообещающим.
Ответы
Ответ 1
Вот итог моего исследования:
- KDB до вер. 2.5 выделяет 64 МБ памяти по мере необходимости и никогда не освобождает их. Он может использовать их снова.
- последние версии KDB допускают
.Q.gc[]
вызов, который является вызовом сборщика мусора по запросу (KDB использует ref. counting btw.)
- это особенно полезно, когда вы вызываете некоторые объемные вычисления, которые выделяют много памяти (в моем случае это было ~ 20 ГБ), и вы хотите освободить память после завершения вычислений.
- Вы всегда можете подумать о том, чтобы поместить сценарий с интенсивным использованием памяти в отдельный процесс Q, чтобы память была освобождена после завершения сценария.
Ответ 2
Это может быть очевидно, но в дополнение к проверке режимов сбора мусора для вашей версии q, убедитесь, что вы действительно избавились от данных в памяти, которые используют память. Если вы в порядке, чтобы избавиться от всей таблицы (например, это временная таблица, участвующая в вычислении), просто удалите ее из корневого пространства имен
delete table from`.
Если нет, вы можете удалить все его строки
delete from`table
Ответ 3
Для тех, кто пытается это в будущем, самым простым способом было бы:
- Запустите новый процесс KDB.
- Из этого запроса процесса выберите наименьшие ограниченные подмножества необходимых данных.
- Выполните любое объединение/вычисления/запись в файл из этого процесса.
(позволяя оригиналу выполнять запросы обработки)
- Закройте процесс, освободив всю память.
Как упоминалось выше, новые версии KDB освобождают память лучше, но не идеальны.
Там есть хорошая статья на веб-сайте нашей компании, где подробно описано управление KDB + Memory:
http://timestored.com/kdbGuides/memoryManagement
Ответ 4
http://code.kx.com/q4m3/12_Workspace_Organization/#125-expunging-from-a-context
Я использовал несколько разных команд. Пока ваша таблица хранится на диске, прежде чем вы ее удалите, вы должны быть в порядке.
Это сеанс перед созданием таблицы.
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$()