Я внедряю продукт обработки естественного языка, состоящий из нескольких приложений в облачном литейном производстве.Эти приложения интенсивно используют процессор (в отличие от интенсивного ввода-вывода), обмениваются данными через rabbitMQ и в основном разрабатываются на Python3.
Одно из этих приложений Python3 [1] использует очередь кроликаи просто выполняет заданную задачу на основе полезной нагрузки полученного сообщения.Эта полезная нагрузка является автономной, то есть она содержит всю информацию, необходимую приложению для выполнения своей работы.
Другое приложение [2] должно дождаться выполнения определенных условий: длясначала ему нужно получить сообщение для «topic1», затем одно для «topic2», а затем приложение может выполнить свою работу.Обработка будет использовать обе полезные нагрузки из двух сообщений.
Теперь вопрос состоит в том, как обеспечить увеличение масштабов как [1], так и [2], чтобы не отставать от увеличенияобъем сообщения.
- Для [1] должно быть достаточно просто развернуть одно и то же приложение несколько раз (т. е. несколько работников) и позволить каждому использовать одну и ту же очередь в циклическом режиме.
- Для [2] необходимо поддерживать состояние (то есть видимые сообщения), поэтому недостаточно просто принять тот же подход, что и выше.Это связано с тем, что сообщение о 'topic1' может быть обработано первым работником, 'topic2' - вторым работником, и каждый работник не узнает о другом сообщении в отсутствие дополнительных структур данных.
Поэтому для [2] я вижу две опции:
- использовать многопроцессорность (не многопоточность из-за GIL, обнаруженного в нескольких средах выполнения Python): только один рабочий из [2] потребляет очередь кроликовкаждое сообщение отправляется другому процессу.Statefulness достигается через поточно-ориентированные структуры данных в памяти, совместно используемые различными процессами.В этом случае параллелизм прозрачен для кролика.
- использует внешнее хранилище (например, Redis или базу данных SQL): несколько рабочих из [2] используют очередь циклически, но совместно используют одно и то же хранилище (аналогичная роль, как структуры данных в памяти выше).В этом случае параллелизм известен кролику, потому что в очереди будет несколько потребителей.
Сообщения будут в основном состоять из простого текста и сериализованных вложенных 300-мерных вложений слов.Объем может достигать ~ 10 тыс. Сообщений в секунду.Обработка будет состоять из запуска библиотек Neural Network или NLP.
Любой совет, как наилучшим образом реализовать масштабируемую архитектуру?