Какие стратегии я могу использовать для обработки периодически долго выполняющихся блокирующих задач базы данных в Django

На моем веб-сайте есть интерфейс проверки достоверности предоставляемых научных данных. По сути, он выполняет пробную загрузку данных и сообщает, прошла ли пробная загрузка успешно, а если нет, то выдает отчет об ошибках и предупреждениях, которые возникли во время пробной загрузки.

Все это выполняется внутри атомарной транзакции. Поэтому, если два пользователя одновременно отправляют данные на проверку, один из процессов будет заблокирован до тех пор, пока не завершится первый.

Большинство таких задач занимают несколько секунд, так что это не страшно, но иногда пользователь отправляет большой объем данных на проверку, и в худшем случае на всю обработку может уйти чуть меньше минуты, и тогда любая другая проверка столкнется с тайм-аутом.

В настоящее время я рассматриваю варианты смягчения или решения этой проблемы.

В идеале, должен быть какой-то способ сообщить базе данных, что вся эта работа не будет зафиксирована, и игнорировать любые другие одновременные операции с базой данных, потому что вся эта работа все равно будет отброшена. Я уверен, что такой возможности не существует, но если бы я представлял, как это будет работать, я бы просто передал какой-то аргумент атомарному декоратору и сказал: «Игнорируйте блокировки базы данных, потому что я обещаю не фиксировать».

Поскольку это, скорее всего, фантазия, и я не могу добиться здесь истинного параллелизма, я решил, что лучшим решением будет использовать что-то вроде celery, чтобы позволить заданиям избежать тайм-аута.

Но я хотел бы быть прозрачным для пользователя. Я могу реализовать что-то вроде индикатора выполнения, чтобы показать, что их работа продолжается. Я могу давать небольшие обновления во время процесса, но я хотел бы также быть прозрачным в том, что их работа ждет, пока другие задания освободят свои блокировки на модели/строки базы данных. То есть я хотел бы сообщить им, что они ожидают в очереди и что перед ними, например, два пользователя.

Итак, мой вопрос заключается в том, можно ли способом, не зависящим от архитектуры базы данных, узнать, сколько пользователей имеют задания на проверку в очереди для этих заданий на проверку базы данных перед отправкой любого одного задания?

Моя база данных - база данных postgres, и я понял, как определить, какие операции базы данных в настоящее время заблокированы, но с точки зрения одного конкретного задания я не могу сказать, каков порядок ожидания. Я также не знаю, как сделать такой запрос, чтобы при замене базы данных на другую он все равно работал, независимо от того, какая у нас архитектура базы данных.

По моему мнению, это тоже невозможно, по крайней мере, не зависит от базы данных. Я не очень хорошо знаком с celery. Я играл с ним раньше и заставил его работать в тестовом случае для простых прогресс-баров, но это было очень давно. И поскольку он предназначен для одновременного выполнения процессов, мне кажется, что его неправильно применять для таких заданий, как эти, которые, по сути, должны выполняться последовательно.

Кто-нибудь уже сталкивался с подобной проблемой? Какие у меня есть варианты?

Примечание: задания валидации также могут быть заблокированы заданиями по загрузке данных, которые выполняются на бэкенде кураторами, обрабатывающими присланные данные. Эти задания по загрузке занимают гораздо больше времени, чем валидация, например, более часа. Безусловно, есть некоторые задачи по повышению эффективности/оптимизации, которые могут смягчить все это, но факт остается фактом: мы обрабатываем много данных, и это не может быть мгновенным. Поэтому мой план по работе с нагрузкой заключается в планировании простоев, чтобы эти нагрузки возникали.

Вернуться на верх