Я считаю, что трехфазный коммит - гораздо лучший подход. К сожалению, я не нашел никого, кто бы внедрил такую технологию.
http://the -paper-trail.org / блог / консенсус-протоколы-три фазы фиксации /
Вот основные части этой статьи:
Основная проблема с 2PC состоит в том, что, как только координатор принял решение о фиксации и сообщил его некоторым репликам, реплики продолжают работу и действуют в соответствии с оператором фиксации, не проверяя, получена ли каждая другая реплика. сообщение. Затем, если реплика, которая совершила сбой, падает вместе с координатором, система не может сказать, каков был результат транзакции (так как только координатор и реплика, получившая сообщение, точно знают). Поскольку транзакция, возможно, уже была зафиксирована в поврежденной реплике, протокол не может прервать пессимистически - поскольку транзакция могла иметь побочные эффекты, которые невозможно отменить. Точно так же протокол не может оптимистично принудить транзакцию к фиксации, поскольку исходное голосование могло прервать выполнение.
Эта проблема - в основном - обойдена путем добавления дополнительной фазы к 2PC, что неудивительно, что дает нам протокол трехфазной фиксации. Идея очень проста. Мы разбиваем второй этап 2PC - «принятие» - на два подэтапа. Первый этап - «подготовиться к принятию». Координатор отправляет это сообщение всем репликам, когда он получил единодушные голоса «да» на первом этапе. После получения этих сообщений реплики попадают в состояние, в котором они могут совершить транзакцию - с помощью необходимых блокировок и т. Д. - но, что принципиально, не выполняют никакой работы, которую они не могут впоследствии отменить. Затем они отвечают координатору, сообщая, что сообщение «подготовиться к принятию» было получено.
Цель этого этапа - сообщить результат голосования каждой реплике, чтобы можно было восстановить состояние протокола независимо от того, какая реплика умирает.
Последняя фаза протокола выполняет почти то же самое, что и первоначальная фаза «фиксация или прерывание» в 2PC. Если координатор получает подтверждение доставки сообщения «подготовиться к принятию» из всех реплик, тогда можно безопасно приступить к совершению транзакции. Однако, если доставка не подтверждена, координатор не может гарантировать, что состояние протокола будет восстановлено в случае его сбоя (если вы допускаете фиксированное число сбоев f, координатор может продолжить работу после получения f + 1. подтверждения). В этом случае координатор прервет транзакцию.
Если в какой-то момент координатор потерпит крах, узел восстановления может принять транзакцию и запросить состояние из любых оставшихся реплик. Если реплика, которая зафиксировала транзакцию, потерпела крах, мы знаем, что каждая другая реплика получила сообщение «подготовка к фиксации» (в противном случае координатор не перешел бы в фазу фиксации), и поэтому узел восстановления будет удалось определить, что транзакция была в состоянии совершить, и безопасно составить протокол до ее завершения. Если какая-либо реплика сообщает узлу восстановления, что он не получил «подготовиться к принятию», узел восстановления будет знать, что транзакция не была зафиксирована ни в одной реплике, и поэтому сможет либо пессимистически прервать, либо повторно запустить протокол. с самого начала.
Так 3PC решает все наши проблемы? Не выйтиэ, но это близко.В случае сетевого раздела колеса скорее отрываются - представьте, что все реплики, которые получили «готовятся к фиксации», находятся на одной стороне раздела, а те, которые не были, - на другой.Затем оба раздела продолжат работу с узлами восстановления, которые соответственно фиксируют или прерывают транзакцию, и при слиянии сети система будет иметь несовместимое состояние.Таким образом, 3PC имеет потенциально небезопасные прогоны, как и 2PC, но всегда будет прогрессировать и, следовательно, удовлетворяет своим свойствам живучести.Тот факт, что 3PC не будет блокировать отказы одного узла, делает его более привлекательным для услуг, где высокая доступность важнее, чем низкие задержки.