Насколько Gemfire устойчив к коллизиям и дублированию записей?
Я пишу документы по дизайну для приложения Java, в котором два избыточных процесса считывают элементы из очереди сообщений, и мы хотим, чтобы они оба сохранили элемент в хранилище gemfire с тем же ключом, целью которого является наличие ряда приложения, выполняющие непрерывные запросы, обрабатывают эти элементы и затем сохраняют результаты в другом регионе Gemfire.
Я только начинаю разбираться с Gemfire, и у меня нет возможности настроить многосерверный тестовый стенд на данный момент, поэтому я решил задать несколько вопросов, пока буду заниматься исследованиями.
Предполагая, что оба процесса сохраняют элемент в gemfire одновременно, это вызовет какие-либо проблемы?
Если ключ записан дважды, будет ли элемент просто перезаписан, и я могу столкнуться с какими-либо проблемами (производительностью или иным образом) с заблокированным ключом?
Если у меня запущен непрерывный запрос, который соответствует элементу, получу ли я два "хита"/(События?) По запросу или только первый вызов сгенерирует попадание?
Как это могло бы быть иначе, если бы у меня было 4 процесса, пишущих одинаковые предметы с одинаковыми ключами в магазин?
1 ответ
Сценарий, который вы описали, будет работать нормально, если регион, в который вы пишете, разделен. В этом случае будет блокировка первичного ключа только на время, необходимое для создания копии объекта на другом узле. Основное внимание здесь уделяется скорости вашей сети. Вторая запись перезапишет первую. То, будет ли это хорошо для вашей производительности, будет зависеть от того, сколько объектов у вас передается в секунду.
Вот некоторые альтернативы для рассмотрения: 1) Вы можете создать долговременную очередь и запустить CQ только на одном клиенте. Если клиент терпит неудачу, вы просто перезапустите его, и у вас все еще будет согласованность. 2) Создайте разделенную область "транзакции" на сервере. На вашем клиенте поместите объект, возвращенный из вашего CQ, в область "транзакции" и добавьте метку времени CQ как часть ключа. В асинхронном приемнике событий для области "транзакция" обновите целевой регион и удалите объект в области "транзакция". 3) Создайте разделенную область "транзакция", которая находится рядом с вашей целевой областью. Создайте функцию onRegion(partitionedTransactionRegion).withFilter(ключ).withArguments(объект и метка времени CQ). Ваш клиент вызывает функцию с вышеуказанной подписью. Функция проверяет, был ли ключ + отметка времени уже добавлен в область "транзакции". Если это так, игнорируйте операцию. Если нет, установите ключ (key + CQ timestamp) в области "транзакции" и обновите целевой регион. Установите политику истечения срока действия в регионе "транзакции", чтобы срок действия истекал через час или день или по вашему усмотрению.