Как создать сервер, раздающий рабочие единицы клиентам?

Мне нужно Java-приложение, которое должно управлять базой данных для распределения рабочих единиц своим клиентам. По сути, это грид-приложение: база данных заполняется входными параметрами для клиентов, и все ее кортежи должны быть распределены по запросам клиентов. После того, как клиенты отправят свои результаты, сервер соответствующим образом модифицирует базу данных (например, пометит вычисленные кортежи).
Теперь давайте предположим, что у меня есть база данных (SQLite или MySQL), заполненная кортежами, и что клиенты выполняют запрос для группы входные кортежи: я хочу, чтобы группа рабочих единиц отправлялась исключительно уникальному клиенту, поэтому мне нужно пометить их как «уже запрошенные другим клиентом». Если я запрашиваю базу данных для первых (например, 5) запросов, а тем временем другой клиент делает тот же запрос (в многопоточной серверной архитектуре и без какой-либо синхронизации), я думаю, что есть вероятность, что оба клиента получат одни и те же рабочие единицы. .

Я предположил, что решения могут быть следующими:
1) создать однопоточную серверную архитектуру (ServerSocket.accept() вызывается снова только после того, как предыдущий клиентский запрос был обслужен, так что доступ к серверу может быть осуществлен только клиентом в время)
2) в многопоточной архитектуре синхронизируйте операции запросов и блокировок кортежей, чтобы получить своего рода атомарность (эффективно сериализующие операции над базой данных)
3) использовать атомарные операции запросов для сервер базы данных (или файл, в случае SQLite), но в этом случае мне нужна помощь, потому что я не знаю, как обстоят дела на самом деле...

Однако я надеюсь, что вы поняли мою проблему: это очень похоже на seti@home, который распределяет свои рабочие единицы, но пересечение всех распределенных единиц для множества клиентов равно нулю (теоретически). Мои нефункциональные потребности заключаются в том, что язык — java, а база данных — SQLite или MySQL.


person StefanoS    schedule 01.04.2011    source источник


Ответы (2)


Некоторые отзывы для каждого из ваших потенциальных решений ...

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

ServerSocket.accept() не позволит вам сделать это, вам может понадобиться какой-то другой тип синхронизации, чтобы только один поток мог находиться в ситуации getting tuples. Это в основном приводит вас к вашим решениям (2).

2) в многопоточной архитектуре синхронизируйте операции запроса и блокировки кортежей, чтобы я получил своего рода атомарность (эффективно сериализуя операции над базой данных)

Осуществимый, простой в реализации и распространенный подход к проблеме. Единственная проблема заключается в том, насколько вы заботитесь о производительности, задержке и пропускной способности, потому что, если у вас много таких клиентов, а временной интервал рабочих единиц очень короткий, клиенты могут в конечном итоге 90% времени застрять в ожидании, чтобы получить «токен».

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

assigned_node_id = work_unit_id % number_of_working_nodes

Этот метод, называемый pre-allocation, не работает для всех типов проблем, поэтому он зависит от вашего приложения. Используйте этот подход, если у вас много быстро выполняющихся процессов.

3) использовать атомарные операции запроса к серверу базы данных (или файлу, в случае SQLite), но в этом случае мне нужна помощь, потому что я не знаю, как обстоят дела на самом деле...

По сути, это то же самое, что и (2), но в случае, если вы можете сделать это, что я сомневаюсь, что вы можете сделать только с SQL, вы в конечном итоге будете привязаны к некоторым конкретным функциям вашей СУБД. Скорее всего, вам придется использовать некоторые нестандартные процедуры SQL для достижения этих решений. И это не устраняет проблемы, которые вы могли бы найти с решением 2.

Summary

Решение 2 с большей вероятностью сработает в 90% случаев, чем длиннее задачи, тем лучше для этого решения. Если задачи очень короткие по времени, обязательно используйте алгоритм на основе pre-allocation.

С решением 3 вы отказываетесь от портативности и гибкости.

DRY: try some other Open Source systems ...

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

http://www.gridgain.com/

http://www.jppf.org/

person Manuel Salvadores    schedule 02.04.2011

Я советую вам прочитать несколько статей, например эту. , чтобы увидеть, как DB может выполнить работу по синхронизации за вас.

person Serhiy    schedule 01.04.2011