Вы можете создать дополнительные потоки в вашем обработчике запросов Django, и каждый из них будет иметь свое собственное соединение с базой данных. Но тогда возникает вопрос, насколько улучшится производительность вставки вашей базы данных с несколькими операциями?
Например, если ваша таблица имеет уникальные ограничения, это может замедлить одновременную запись. Тогда вы можете обнаружить, что ваше реальное узкое место - пропускная способность диска и что вы не сможете масштабировать, добавляя соединения.
Так что вы можете захотеть написать какой-нибудь быстрый и грязный тестовый код, чтобы попробовать многопоточные параллельные записи в соответствующую таблицу / базу данных, прежде чем вы зайдете слишком далеко с оптимизацией.
Насколько вы эффективно распределяете данные между потоками, зависит от формата ввода.
Если вы имеете дело с файлом формата Microsoft, таким как .xls
, тогда вы захотите использовать библиотеку для анализа этого ... Я успешно использовал xlrd
. Но это приводит к тому, что все данные вашей электронной таблицы хранятся в памяти одновременно ... вы не можете прочитать их по одной строке за раз. Но при условии, что вы можете справиться с использованием памяти, это упростит процесс создания потоков: как только вы прочитаете все данные в память, запустите несколько потоков записи, сообщив каждому диапазон номеров строк, за которые он отвечает. Затем основной поток запросов может просто присоединиться к потокам записи, а когда все они будут завершены, он может вернуть Ответ пользователю. Однако имейте в виду, что если ваш запрос занимает слишком много времени, время ожидания браузера истечет. Это другая проблема, и для этого я предлагаю посмотреть другой ответ, который я написал на днях о том, как использовать StreamingHttpResponse
:
Правильный способ отсрочки загрузки файла в Django
Теперь, если ваш входной формат - что-то вроде .csv
файла, который вы можете читать по одной записи за раз, возможный способ справиться с этим - создать очередь в памяти с использованием класса python Queue
( https://docs.python.org/2/library/queue.html). Запустите ваши потоки записи и попросите их прослушивать в очереди записи для записи в базу данных, затем ваш основной поток считывает из файла .csv
по одной записи за раз и помещает эти записи в очередь.
Все эти предложения направлены на обработку ваших данных прямо в запросе Django. Но если вы не хотите этого делать, вы можете разгрузить обработку различными способами. Вы, конечно, можете использовать rabbitmq
, как вы упомянули, и иметь несколько процессов слушателя, делающих запись. Это будет работать, но я не уверен, что это будет оптимально эффективно. Вам необходимо написать ВСЕ записи, поэтому не обязательно разбивать их, отправлять их в другой процесс, а затем отправлять оттуда в еще один процесс ... Если эти другие процессы не запущены на других машинах.
Если вы читаете данные из файла, который уже записан на диск, и это формат файла, который легко делится (опять же, например, CSV), простой (и очень классический) способ сделать это - разделите размер файла на количество потоков записи. Скажите каждому писателю начальное и конечное смещение файла, который вы хотите обработать. Каждый писатель (кроме начинающего со смещения 0) может искать вперед, пока не найдет разделитель записей (например, \r\n
). Затем он начинает считывать и обрабатывать входные записи по одной, пока не выполнит чтение до позиции, равной или превышающей конечное смещение.
Если вы читаете файл из запроса и хотите обработать его вне обработчика запроса, вы можете обнаружить, что более эффективно просто записать его на диск в виде одного большого файла, а затем обработать его потом, как описано выше.
Итак, попробуйте найти способы обработки данных, которые включают наименьшее количество операций чтения и записи. Обрабатывайте данные на месте, если можете, не перемещайте их, если не нужно. Избегайте записи в другие процессы, если они находятся на одной и той же машине, так как этот процесс требует большого объема диска. Если вы хотите, чтобы возможность легко масштабироваться на большее количество машин, попробуйте rabbitmq
. Я использую это, это хорошо, и быстро. Но это добавит накладных расходов, поэтому, если вы не получите реальную выгоду от разрушения, это может замедлить вас. Это делает межпроцессное взаимодействие очень простым.