Есть несколько сотен тысяч XML файлов, которые нужно распарсить и выгрузить в БД. Для разбора использую XPATH. Проблема в том, что если их выгружать по одному процесс идет слишком медленно.
Стоит ли мне пытаться вынести каждый отдельный скрипт в поток? Или есть какие-то другие варианты?
Проблема еще в том, что я хочу парсить результат отработки каждого отдельного файла, чтобы знать прошла ли успешно обработка или данный файл имеет отличную от ожидаемой структуру. Иными словами сейчас я просто паршу выдачу скрипта.
Roman Kitaev, я в python не силен. Просто даю гарантированное решение, которое будет работать, обеспечивает решение задачи, горизонтальную масштабируемость и at least one delivery.
beduin01, вы делаете очередь в которую отправляете задания. На другом конце очередей может быть любое число обработчиков, которые параллельно получают оттуда задания и выполняют их. Таким образом вы получаете контролируемый набор заданий, которые никуда не пропадут если обработчик (один или все) умрет + в случае если надо сделать быстро то вы просто можете увеличить число обработчиков. Вы скорее упретесь в предел диска по IOPS чем в скорость обработки. Надо 1 воркер - пожалуйста, надо 1000 воркеров - да тоже пожалуйста, только серверов докиньте) вообще из хороших практик - 1 воркер на ядро, но это относительный показатель
beduin01 beduin01 Автор вопроса
Каким образом должен быть оформлен обработчик? Если обработчик упал (не смог распарсить файл) то он должен в БД это событие логгировать?
Документацию почитать лень?
Если обработчик упал (не смог распарсить файл) то он должен в БД это событие логгировать?
Обычные логи приложения просто чтобы вы знали из-за чего происходит падения. Сообщение должно вернуться в очередь если не дождется сигнала окончания обработки
И можно ли сделать подобное используя не очередь а БД? Просто из БД выгребать все таким же способом.
Можно еще спать на потолке. Удобно наверное, как думаете? От БД отказываться в любом случае не советую - туда имеет смысл сохранять задания и результат их исполнения, с временными метками и другими данными, которые вам понадобятся
Иван Шумов, я имею ввиду, я же из БД могу данные таким же макаром выгребать, зачем мне тогда вообще очередь нужна?
"Документацию почитать лень?"
Документацию по чему? По тому как очередь писать или как обработчики для очереди делать?
"Сообщение должно вернуться в очередь если не дождется сигнала окончания обработки"
Файл был не верного формата предположим. Зачем его обратно в очередь возвращать?
beduin01, по RabbitMQ (самый простой вариант для вас). Из БД вы можете выгребать, конечно. Что вы получите? То что вы будете делать это в 1 поток чтобы 2 раза ничего не обработать. Если будете делать в несколько потоков то вам придется придумывать как раздавать своим воркерам эти задания. То есть вы будете сами писать механизм очередей, гарантированно сделаете это через всем известное место и работать это будет по понятным причинам плохо, медленно и не качественно.
Давайте на пальцах объясню. Вы решили поесть суп. У вас есть суп. Вы взяли вилку и пробуете его есть вилкой. Я предлагаю вам ложку. Вам не нравится ложка по тому что она удобная и позволяет вам не заниматься фигней. Вы просите принести вам немного металла, газовую горелку и прочие инструменты, а так же инструкцию как сделать ложку с дырками.
Иван Шумов, так а если допустим сделать так: Создаю 100 потоков. Каждый поток ставит напротив файла пометку ФайлВзятВРаботу. Запускам обработку в отдельном потоке через executeShell (или как там его) запускам обработку внутри потока. Отрабатываем файл. Меняем флаг. И тоже самое делаем с остальными 99 потоками. В чем минус? Какие проблемы будут?
Pavel Denisov, это так и есть..)) В чем минусы то блин. В том что два потока одновременно попытаются одну и ту же запись обработать? Так флаги можно напротив строк ставить
beduin01, ещё смешнее. Sqlite это по сути файлики. Когда у вас туда одновременно несколько скриптов писать будет у вас появятся записи, которые один уже обновил, а другой ещё нет и в результате жесть. Вы пробовали в 1000 потоков, например, в текстовый файл писать? Попробуйте, вам не понравится
Иван Шумов, если бы в документации к sqlite было бы написано, что он однопоточный, у меня вопросов бы не было. А тут получается что он вроде как это умеет.
Я просто не совсем понимаю есть ли в БД какая-то атомарная блокировка или нет. Вот берет первый поток первую строку. Ставит ей флаг, что она в обработке. Получается второй может успеть захватить строку и тоже попытаться флаг поставить? Если так, то это во всех БД так или есть исключения?
beduin01, если коротко то sqlite это не база данных, а специальный формат хранения данных в одном файле и набор sdk для разных языков. Нормальная база имеет сервер, который и управляет потоками чтения и записи, а также ACID транзакциями
Иван Шумов, спасибо, поясните пожалуйста только про захват строки разными потоками. Возможно ли ситуация, пока один поток будет менять флаг "строкаЗанята" второй поток попытается захватить эту же строку и дальше произойдет ошибка. Просто я упорно пытаюсь понять отличие полноценной очереди от этого пусть и костыльного варианта.
beduin01, это может произойти и в обычной базе. Просто в sqlite вы это в принципе гарантированно получите. + Sqlite медленный из-за хранения данных в одном файле и работе напрямую с диском. Брокер очередей вам позволит избежать коллизий.
Ошибки там будут или повторные обработки это уже как получится. В любом случае это будет работать плохо и на отладку проблемы вы потратите МНОГО времени. Почему вы не хотите использовать инструмент, созданный для вашей задачи?
Иван Шумов, да просто потому что мне сходу не очевидны преимущества очереди. Очередь как я понял из всего написанного гарантирует, что данные будут браться поэлементно и не будет ситуации когда два потока попытаются захватить одну и ту же запись.
будете смеяться, но до меня тут вообще в качестве БД использовали ini файл и мне ту же SQLite внедрить потребовалось не мало усилий "код уже написано, не вижу смысла его переделывать". Увы такие аргументы у начальства бывают весьма часто.