Рассмотрим задачу получения ограниченного количества данных из бесконечного источника (например, из памяти), например, Мне нужно извлечь 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 (может быть, Кассандра?) Также приветствуются.