У меня есть список продуктов, хранящихся в Postgres. Мне нужно иметь возможность взять CSV-файл и получить список изменений — то, что в CSV-файле отличается от того, что есть в базе данных. Файл CSV содержит около 1,6 миллиона строк.
Наивный подход состоит в том, чтобы просто взять каждую строку, извлечь этот продукт из базы данных с помощью ключевого поля, выполнить сравнение, внести изменения (включая обновление базы данных), а затем перейти к следующей строке. Однако из-за такого количества циклов весь процесс занимает много времени (более двух минут). Я попытался локально кэшировать инвентарь в карте вне кучи (используя MapDB), что значительно улучшило производительность, так как мне нужно было только попасть в базу данных, чтобы записать измененные данные, но я не нашел способ сделать тот масштаб. Будет много запасов для разных клиентов. Возможно, потребуется какой-то подход к сегментированию, но тогда мне придется иметь дело с узлами, работающими как в сети, так и в автономном режиме. Возможно, здесь поможет Akka Cluster.
Есть ли хорошие подходы, которые я упускаю из виду?
Поскольку проблема, по-видимому, заключается в обходе, вы можете:
- либо выбрать локальное решение, с упомянутой вами проблемой масштабирования. (Вы все еще можете попытаться разделить задачу на несколько локальных узлов, каждый из которых отвечает за поддиапазон индексного пространства).
- или выбрать решение на базе данных, массово загружая ваши csv во временную таблицу, и позволить серверу базы данных очень эффективно работать с (индексированными) таблицами. Преимущество такого подхода в том, что вы достигнете масштабируемости самой базы данных. Вы можете точно настроить подход для любой схемы распределения, которая уже будет иметь место, если это уже распределенная база данных.
Еще несколько мыслей:
- если у вас много столбцов/полей для сравнения, вы можете рассмотреть возможность добавления хэш-кода для каждой строки, как в csv, так и в db (обновляемого при каждом изменении строки). Хэш-код будет вычисляться с использованием полей, которые важны для сравнения. Тогда поиск различий сводится к поиску новых и существующих строк с разницей в хэш-коде.
- В конечном счете, было бы эффективнее решать проблему в источнике, т.е. перехватывать события, которые приводят к изменению csv, или использовать некую временную метку последнего изменения. Но хорошо, это не всегда возможно.