Как передать информацию между двумя Python приложениями
Что проверяют
Умеете ли вы выбрать канал под задачу, а не перечислить все известные. Для ML важны объём данных, задержка и то, что будет, если одна из сторон упадёт. Следом обычно спрашивают, как передать большой массив или датафрейм и чем его сериализовать.
Как отвечать
Разложите способы по сценариям:
- файлы и объектное хранилище: батчи признаков и предсказаний пишутся в Parquet в S3 или общий каталог. Писатель сохраняет во временный файл и делает атомарное переименование, чтобы читатель не открыл файл наполовину;
- HTTP или gRPC: синхронный запрос и ответ, например сервис инференса на FastAPI. gRPC с protobuf даёт строгую схему и меньше накладных расходов на сериализацию;
- брокер сообщений: Kafka, RabbitMQ, Redis Streams. Развязывают стороны во времени, переживают падение потребителя, позволяют масштабировать обработчиков. Цена: гарантия доставки чаще всего «хотя бы один раз», поэтому обработчик должен быть идемпотентным;
- одна машина:
multiprocessing.QueueиPipeдля процессов с общим родителем,multiprocessing.shared_memory(с Python 3.8), чтобы отдать массив NumPy без копирования, ZeroMQ для лёгкого обмена без брокера; - база данных: когда результат нужен надолго и его будут читать другие системы.
Отдельно проговорите формат. JSON подходит для небольших сообщений, для таблиц лучше Parquet или Apache Arrow: Arrow передаёт колонки почти без преобразований, а Arrow Flight строит на этом сетевой обмен.
Где спотыкаются
Передают данные через pickle между сервисами. Распаковка чужого pickle выполняет произвольный код, а объекты ломаются, если версии библиотек у сторон разные.
Работают с голым TCP-сокетом как с потоком сообщений. TCP не хранит границы: один send может прийти двумя recv и наоборот, нужна длина в заголовке или готовый протокол.
Выбирают REST для всего подряд. Гонять гигабайты признаков через JSON в HTTP медленно и дорого, а при недоступности приёмника данные просто теряются, если нет очереди или повторов.