Есть ли здесь проблема параллелизма? Как это проверить во время разработки?
Сценарий: существует "n" команд, каждая из которых работает над своей виртуальной "стеной" (например, на стене Facebook). Каждая команда видит только свою стену и посты на ней. Сообщения могут быть отредактированы автором сообщения или другим членом команды (если это настроено. Предполагается, что это действительно так, поскольку это необходимо).
Дизайнерские / технологические решения: RESTful веб-приложение с использованием Restlet+ Glassfish/Java + Mysql (РЕДАКТИРОВАТЬ: Использование Apache DBUtils для доступа к БД. Нет ORM - кажется излишним)
Вопрос: Несколько команд входят в T1, T2 и T3 (скажем), каждая с некоторым количеством участников. Существует параллелизм при доступе к данным на уровне команды, но не между группами - т. Е. Разные группы получают доступ к несвязанным наборам данных. Чтобы оптимизировать частое чтение / запись из / в БД, мы рассматриваем TeamGateway, который контролирует доступ к БД для обработки параллелизма. Веб-сервер будет кэшировать данные, полученные командами, для ускорения чтения (а также для обновления списка сообщений на стене)
- Q1: Требуется ли это (TableGateway на команду + кэш)? Если нет, то как вы предлагаете справиться с этим?
- Q2: Если это так, нужно ли кодировать TableGateway (для каждой команды) как потокобезопасный (синхронизированный метод)?? Допустим, у нас есть класс / реестр TableGatewayFinder со статическим методом, который возвращает TableGateway для использования этой конкретной командой (используя хэш-карту).
Если по 6 человек из каждого T1 - T3 войдут в систему, тогда будет создано ТОЛЬКО 3 TableGateways, и это поможет перехватывать одновременные записи (простое сравнение временных меток перед фиксацией или добавлением с пометкой о конфликте) и эффективно управлять кэшированием (мы планируем иметь карты идентичности для сущностей - существует 4-5 разных сущностей, которые необходимо отслеживать. 4 сущности для иерархии композиции, а другая связана с каждой из 4)?
Как один модуль будет тестировать шлюз (на основе TDD или по факту)?
Заранее спасибо!
3 ответа
Если вы просто пишете в БД или в решение для кэширования поверх БД (например, Spring+Hibernate+EhCache и т. Д.), Вам не нужно беспокоиться о повреждении ваших таблиц и т. Д. Т.е. проблем с параллелизмом из низкоуровневой точки не возникает. зрения.
Если вы хотите написать кеш самостоятельно и решить проблемы с параллелизмом, это потребует определенных усилий. Если вы оскверняете кеш и имеете "глобальную блокировку" (т.е. synchronized
на общем мьютексе) на раздел и получить эту блокировку для любого доступа, который бы тогда работал, хотя это не самый эффективный способ сделать это. Но создание чего-то другого, кроме глобальной блокировки, потребовало бы довольно много работы.
Хотя это тривиально, я не знаю, зачем вам использовать идентификационную хеш-карту... Я не могу придумать какой-либо конкретной причины, по которой вы хотите это сделать (если вы думаете о производительности, то производительность обычной хэш-карты будет последней вещью, о которой вам нужно беспокоиться в этой ситуации!).
Если ваши сущности являются статьями, то у вас, вероятно, есть другая форма параллелизма Как тот, который решается с помощью программного обеспечения для управления версиями, такого как SVN, Mercurial и т. Д. То есть, если вы не включаете возможность слияния в свое приложение., Становится раздражающим, если кто-то редактирует чью-то статью только для того, чтобы обнаружить, что кто-то другой "совершил" другую редактировать перед вами и т. д. Нужно ли вам добавлять такую возможность, зависит от варианта использования.
Что касается тестирования вашего приложения. для параллелизма юнит-тестирование неплохое. Путем написания параллельных юнит-тестов намного легче выявлять ошибки параллелизма. Написание параллельных тестов очень сложно, поэтому я рекомендую вам прочитать хорошие книги, такие как "Параллелизм Java на практике", прежде чем писать их. Лучше поймать свои ошибки параллелизма перед интеграционным тестированием, когда становится трудно догадаться, что, черт возьми, происходит!
ОБНОВИТЬ:
@ Nupul: это сложный вопрос, чтобы ответить. Тем не менее, если вы наберете 18 человек, моя ставка будет записывать каждый раз, когда в БД все будет в порядке.
Если вы не сохраняете какое-либо состояние в другом месте (т.е. только в БД), вам следует избавиться от любого ненужного мьютекса (и вам не следует хранить какое-либо состояние в другом месте, кроме БД, если у вас нет веских причин сделать это в вашей ситуации ИМО).
Легко ошибиться и получить мьютекс, выполняя что-то вроде сетевой операции, и, следовательно, вызывать серьезные проблемы с юзабилити (например, приложение не отвечает в течение многих секунд и т. Д.). И также легко иметь неприятные ошибки параллелизма, такие как взаимные блокировки потоков и т. Д.
Поэтому я рекомендую сохранить ваше приложение. без состояния и просто писать в БД каждый раз. Если вы обнаружите какие-либо проблемы с производительностью из-за доступа к БД, то лучше всего обратиться к решениям для кэширования, таким как EhCache.
Если вы не хотите учиться у проекта или должны доставить приложение. с крайними требованиями к производительности, я не думаю, что написание собственного слоя кеша будет оправданным.
Ориентируясь на 2 вопроса в названии.
Есть ли здесь проблема параллелизма?
Да. Очевидно. Единственный способ избежать возможности возникновения проблем с параллелизмом - это сделать продукт однопоточным, что приведет к серьезным проблемам с производительностью и удобством использования.
Как это проверить во время разработки?
Это сложный вопрос.
Очевидно, вам нужны юнит-тесты. Но классические модульные тесты на самом деле не решают проблему с параллелизмом, потому что хитрые ошибки параллелизма обычно появляются редко.
Лучшим подходом является нагрузочное тестирование. как описано @Gnat.
Но для достижения наилучших результатов вы должны признать, что тестирование не является (целым) решением, и добавить следующее:
- Персонал, имеющий опыт разработки, кодирования и тестирования параллельных приложений.
- Обращая большое внимание на подход / рекомендации "Java - параллелизма на практике" Гетца и соавт.
- Множество обзоров дизайна и кода.
- Тщательное использование статических анализаторов кода для выявления потенциальных проблем параллелизма.
Модульное тестирование может быть не лучшим подходом к проблемам параллелизма. Вместо этого вы можете попробовать веб-инструмент для повышения производительности, такой как JMeter или Rational Performance Tester, чтобы проверить, как он работает, и что у вас есть действительное содержание стен по мере увеличения количества пользователей. С помощью этих инструментов вы можете назначить каждому пользователю свое поведение.