Наиболее подходящий дизайн связи между узлом и сервером

#python #oop #asynchronous #concurrency #parallel-processing

#python #ооп #асинхронный #параллелизм #параллельная обработка

Вопрос:

Я борюсь с проектированием части моего проекта. Идея заключается в том, что N узлов (каждый с одной камерой) будут непрерывно отправлять кадры на сервер для обнаружения объекта, а затем сервер повторно отправит ответ на каждый узел с некоторой информацией.

Цель состоит в том, чтобы обрабатывать каждый узел, возможно, независимо и иметь возможность получать следующий кадр и обрабатывать предыдущий одновременно.

Как и в Python, параллельные потоки не доступны, я рассматриваю несколько подходов (при условии, что у меня есть процессор, способный обрабатывать N * 2 потока параллельно:

1) Сервер будет порождать два процесса (взаимодействующих друг с другом) для каждого узла (один для приема фреймов и один для обнаружения объекта). (эти процессы будут выполняться независимо от основного процесса)

2) Сервер будет однопоточным и асинхронным. Каждый полученный кадр будет отправлен в пул процессов для обнаружения.

3) Сервер будет создавать поток для каждого узла (один поток будет обрабатывать прием кадров с одного узла). Каждый полученный кадр будет отправлен в пул процессов для обнаружения объекта.

4) Сервер будет создавать поток для каждого узла и два отдельных потока внутри этого потока, один для приема и один для обнаружения объекта

Какой подход, по-видимому, имеет наибольший смысл? Не могли бы вы предложить что-то другое?

Ответ №1:

Я люблю архитектурные проблемы, вот что я бы сделал, если бы мне пришлось выполнять этот проект.:
Рабочий процесс:

  1. Узел отправит запрос на сервер, включая фреймы и идентификатор узла
  2. На основе идентификатора узла и фреймов сервер создаст задание в очереди, используя redis в хранилище памяти, чтобы отслеживать задания, отправленные узлами, а также сохранять каждый запрос в БД
  3. Сервер будет обрабатывать каждое задание, запуская worker на сервере, который будет извлекать и обрабатывать каждое задание из очередей redis.
  4. Обновить запись задания: после выполнения задание будет помечено как выполненное, а результат будет сохранен.
  5. Узел может вызвать сервер, чтобы получить статус каждого задания, размещенного узлом.

Вам нужно создать интерфейс REST API на сервере, чтобы опубликовать задание с узла и сохранить этот запрос в БД и создать задание на основе этого запроса, а также отправить его в очередь redis. Рабочий автоматически извлекает задания из очередей redis и обновляет запись базы данных на основе результата обработки.

На стороне сервера необходимо следующее:
— REST API
Ссылка на очередь Redis (RQ)
— Сервер БД

Используя эту архитектуру, вы можете легко немедленно возвращать клиенту взвешенный результат и сохранять все задания в процессе обработки. Архитектура RESTful — широко используемая архитектура, но для выполнения трудоемких заданий мы используем процессоры очередей, и клиент отправит нам запрос на проверку статуса любых заданий, отправленных на сервер. Если вам нужно, я могу нарисовать архитектуру, включая гораздо больше деталей.

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

Комментарии:

1. Глядя на ваш исчерпывающий ответ, мне трудно не согласиться с тем, что вам нравятся архитектурные проблемы. Большое вам спасибо, мне нужно больше прочитать о Redis (до этого момента я считал, что это просто типичная база данных) и REST API. Мое текущее понимание заключается в следующем: при таком подходе мне может не потребоваться открытое соединение между каждым узлом и сервером, но каждый отдельный узел может отправлять запросы, а затем запрашивать результаты или статус задания

2. Моя главная проблема заключается в том, что после отправки задания узел может повторно отправлять вызовы серверу (с некоторым временем ожидания (T) между ними), пока он не ответит, что задание выполнено, но я на самом деле хочу, чтобы сервер повторно отправил ответ как можно скорее, и именно поэтому я все еще считаю, что в этом случае какой-то асинхронный подход может быть лучше. (потому что, если задание заняло (T 1) время, узел может начать получать его через (2T) время, поскольку после (T) оно не было готово)

3. нет необходимости, сервер может помещать все задания в очередь и обрабатывать одно за другим, а также обновлять статус и результат задания в БД. Если вы хотите отправить уведомление на узел, используйте веб-сокеты или толкатель.