2012-05-31 4 views
1

Я разрабатываю автономное приложение Java, которое собирает данные из примерно 1000 измерительных устройств по сети и сохраняет данные в базе данных. Сбор данных может занять пару минут на каждое устройство из-за медленного выхода устройства и/или скорости сети. Сбор данных должен происходить в определенном временном окне, поэтому мне нужно работать параллельно.Java параллелизм/сетевой подход

Моим подходом было бы создать один поток на измерительное устройство, поместить данные в очередь и иметь один или несколько других потоков на другом конце преобразования очереди и сохранять данные.

Это жизнеспособный подход? Будет ли современная машина иметь возможность обрабатывать многие потоки и сетевые соединения? Насколько это масштабируемо, в какой момент мне нужно будет работать на нескольких машинах?

Я также был бы признателен, если бы вы могли дать мне указания относительно классов concurreny, которые вы рекомендовали бы (например, какая очередь, ThreadPoolExecutor и т. Д. - i havent используется java.util.concurrent еще, книга по почте) ,

Есть ли лучшие подходы?

UPDATE:

Спасибо за ответы до сих пор, здесь больше информации, запрошенной некоторые из вас.

Данные, получаемые с устройств, представлены в виде файлов размером менее 1 КБ. Возможно, что я получаю что-то вроде 25.000 файлов во время одной передачи, хотя обычно это намного меньше.

Преобразование данных не имеет большого значения cpu, в основном анализирует файл и преобразует его в типы данных java (файл содержит c-типы данных, такие как unsigned char и unix timestamps), плюс расчет CRC. Я создаю объект, содержащий содержимое одного файла, который я сохраняю в datbase, используя JPA (я думаю, я мог бы использовать простой JDBC для этого случая). В файлах измерений нет порядка, так как они содержат устройство s/n и временную метку.

В более поздний момент времени мне нужно будет добавить какое-то предупреждение, когда будут выполнены определенные критерии, но опять же это не должно быть интенсивным.

Из ответов до сих пор я собираю сетевые подключения и количество потоков не должно быть проблемой.

Единственное, о чем я забыл, - это подход к очереди. Альтернативой было бы позволить потокам сбора данных также вызвать метод DAO для сохранения файла. Наверное, я должен сделать DAO потокобезопасными в любом случае, но я думаю, что несколько потоков могут выполнить эту работу, так как основная часть времени будет потрачена на передачу сетевых данных.

Также я рассмотрю асинхронный ввод-вывод и некоторые фреймворки, которые его предоставляют.

Еще раз спасибо, я выберу ответ чуть позже, может быть, я буду получать больше некоторый вклад :)

+0

«положить данные в очереди» - какие данные вы собираетесь поместить в эту очередь.? –

ответ

1

С настройками по умолчанию вы получите около 1 ГБ памяти для стеков потоков, если вы работаете на 64-разрядной Linux, Oracle jdk (по умолчанию threadstacksize составляет 1 Мб на такой платформе). Я думаю, что для OpenJDK это одно и то же. Не считая буферов, выделенных os. , ,

Если это слишком много для ваших требований, вы можете взглянуть на http://netty.io. Эта структура использует java nio под капотом (может быть настроена на использование bio, btw). Таким образом, вам просто потребуется несколько потоков для выполнения фактического io (выполнение операций чтения/записи для заданного tcp-соединения). Ваша бизнес-логика (обновление db, вычисление некоторых измерений) затем должна быть выгружена в отдельный поток. Netty также включает поддержку этого.

Если вы хотите использовать 1 поток для каждого соединения (на измерительное устройство?), То, вероятно, нет никакой пользы от наличия еще одной группы потоков, выполняющих фактическую работу. Я предполагаю один поток на устройство, потому что вы сказали, что устройство может быть медленным и/или сеть может быть медленной. Оба узких места (сеть и устройство) не будут устранены, если вы используете несколько потоков (можно ожидать наоборот).

классы Параллелизм в целом: java.util.concurrent * да, оба больших пальца вверх

1

Для современной операционной системы и аппаратного обеспечения, обработки 1000 + изменить темы и сетевое подключение не должно быть проблема. Реальный вопрос: сколько данных вы собираете, и насколько сложны трансформации - вероятно, это будет определять, сколько одной машины может обрабатывать.

0

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

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

Смежные вопросы