Потребление памяти в 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
Для любого, кто попробует это в будущем, проще всего было бы:
- Начать новый процесс KDB.
- Из этого запроса процесса, чтобы выбрать наименьшие ограниченные подмножества данных, необходимых.
- Выполните любые соединения / вычисления / записи в файл из этого процесса. (позволяя оригиналу продолжать обработку запросов)
- Закройте процесс, освободив всю память.
Как уже упоминалось выше, новые версии 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$()