Как избежать переполнения памяти с помощью высокопроизводительного потока ввода-вывода JAVA от разъемов JDBC? - PullRequest
0 голосов
/ 09 июля 2019

Рассмотрим задачу получения ограниченного количества данных из бесконечного источника (например, из памяти), например, Мне нужно извлечь counts из огромной таблицы, состоящей из миллиардов и более записей, помеченных timestamp и foreign_key в пределах ограниченного, но, возможно, огромного временного окна. Но для последующего потребления мне нужно только максимально gridSize значения.

Примечание: Резервная база данных - это MariaDb, и мы используем пружинные данные jpa для подключения к базе данных.

Подход, основанный на одном потоке:

int stepSize = (int) (numberOfCountsInWindow / gridSize) + 1;

StreamUtils
     .zipWithIndex(countStream)
     .filter(countIndexed -> countIndexed.getIndex() % stepSize == 0)
        ...
        <intermediate steps>
        ...
     .collect(Collectors.toList())

Я пробовал много других, например:

  • пользовательский Collector, который использует AtromicLong, чтобы решить, будет ли следующее значение добавлено в окончательный список или просто проигнорировано,
  • Flux.defere (() ->), чтобы использовать управление обратным давлением Flux
  • Java 11
  • множество параметров MySQL, таких как "useCursorFetch = true" в сочетании с конечным размером предварительной выборки, равным @QueryHint()
  • ...

Однако все, что я пробовал, приводит к GC overhead limit exceeded (с размером кучи, ограниченным 2048, что по умолчанию для наших приложений).

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

То, что я действительно ожидал (или, по крайней мере, надеялся), был поток, чтобы «реализовать» фильтрацию и просто продолжить фактические вычисления, в лучшем случае используя 100% ЦП, и сборщик мусора для простого удаления неиспользуемых объектов, так как они все равно отфильтрованы и даже анализировать их не нужно (надеялся, что лень потока поможет здесь). Однако, похоже, это не сработало, как я надеялся.

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

РЕДАКТИРОВАТЬ: Альтернативы MariaDB (может быть, Кассандра?) Также приветствуются.

...