Как стать автором
Обновить
-3
0

Пользователь

Отправить сообщение
Теперь как можно эмулировать «двухфазный» коммит при индексации через крон. Для каждой индексируемой сущности заводите поле updated_at с DateTime когда был послдений апдейт и реализуете версионность, можно хранить всего две версии — актуальную и предыдущую (причем это касается только индексируемых в солр полей сущности). Скрипт синхронизации с солр по крону достает из базы все сущности у которых updated_at больше временной метки последней синхронизации. И для актуальной версии каждой сущности делает запрос в солр на обновление данных, если солр выкидывает эксепшн и говорит что, например, данные каким то образом не валидны то вы пишите в актуальную версию данные из предыдущей версии для сущности и удаляете предыдущую. Т.о. мы реализуем механизм роллбэка в базе в случае фейла при записи в солр.


И теряете при этом данные.
Зачем писать индексируемые данные в отдельную таблицу log.


Это эмуляция журнала на уровне приложения. Все транзакционные БД имеют внизу такой-же журнал, но нескоолько в другом виде. Такие журналы — основа обеспечения консистентности и воссстановления после сбоев. Вот полезная книга об этом
Чем это грозит? Представьте что менеджер через какую-нибудь cms тулзовину отредактировала страницу и сохранила. Она видит что сохранение успешно прошло и забывает про эту страницу. Спустя секунду запускается скрипт синхронизации с солр. Он пытается индексировать актуальную версию страницы в солр но солр говорит например что данные не валидны, превышено кол-во символов или еще что нибудь. Тогда происходит откат в базе на пред. версию. И по итогу все изменения теряются, менеджер не в курсе что это произошло и данные не обновлены. Соотв. надо реализовать уведомление о такой ситуации и тд… По итогу это все перерастает в снежний ком всякого говна. Занавес.


если солр ответит ошибкой что данные не валидны, какой смысл повторять процедуру записи в солр, надо откатывать данные в таблице page следуя определению двухфазного коммита. Но механизма роллбэка нету. И надо идти руками править данные в базе, следуя вашей логике это надо сделать и в log и в page и потом опять вызывать крон команду чтобы протолкнуть изменения в солр

Так вы можете все солровские правила учесть при записи в таблицу log, чтобы не писалось в log и транзакция откатилась.
Solr не реализует ACID (https://ru.wikipedia.org/wiki/ACID) да ему это и не надо соотв. какой вообще может быть разговор о двухфазном коммите скажите мне?

А как связано наличие ACID и двухфазный коммит? 2PC можно сделать и в системах, не реализующих ACID. Вы повнимательнее определение 2PC почитайте и разберите его и поймете, что решение с таблицей log и кроном это частный случай 2PC.

Да мое решение не отказустойчиво в случае внезапного отказа оборудования. Но этого и не требуется. В случае отказа оборудования вы можете просто запустить переиндексацию и все синхронизируется. В 99% случаев синхронной синхронизации реализованной в бандле достаточно.


Ваше решение не отказоустойчиво даже в случае обычного перезапуска веб-сервера или сервера БД, какие там отказы. После каждой перезагрузки или останова предлагаете переиндексировать?

В ваших ответах столько эмоций, зачем? Я вас пытаюсь показать лучшее решение, а вы даже слушать не хотите, сразу в штыки и оскорбления — «это велосипед и костыли». В том виде, в котором я описал, индексирование реализуется очень просто, никакого велосипедостроения нет, это необходимо для реализации отказоустойчивости. Я так делал и я не один такой. Попробуйте, оно не так страшно, как представляется на первый взгляд. А у вас «крутая библиотека», которая не является велосипедом, и которая при этом не обеспечивает отказоустойчивости?

В 99% случаев синхронной синхронизации реализованной в бандле достаточно.

Как процент посчитали?

Прекрасно представляю. Вместо того, чтобы сразу писать в Solr пишем необходимые для индексирования данные в отдельную таблицу, назовем ее log в той же РСУБД в той же транзакции. Получится что-то вроде журнала событий. Можно в json или xml положить, будет гибко. В другом процессе (cron, например) читаем необработанные события из log индексируем в solr. Если при обработке события произойдет сбой, событие не отметится как обработанное и процедура повторится. Изменения в индексах типа Solr как правило идемпотентны и могут быть повторены (если например фейл произошел при пометке события обработанным). Вот вам и 2PC.
А с подходом в бандле сколько не смотри на исключения, не читай код доктрины, не пиши тестов — все равно может произойти рассинхронизация. Его нельзя назвать отказоустойчивым. Аварийный останов веб-сервера тут никак не обработать, а его нужно учитывать.
То что вы с SO привели — я с этим не совсем согласен. Eventual Consistency можно сделать. В MySQL можно вообще бинлог читать и на его основе выполнять индексирование. В Postgres тоже вроде что-то добавили в последних версиях.
Еще рассинхронизация может произойти при останове/перезапуске веб-сервера, отключении питания, сбоях в работе сети (плдключения к БД, не удалось запрос COMMIT отравить). Во всеъ этих случаях подход, используемый в бандле может привести к рассинхронизации. И дело даже не в том, что что-то не так запрограммировано — дело в принципе, положенном в основу бандла. Для отказоустойчивой синхронизации между БД и индексом нужен двухфаный коммит.
Хорошо, а если в Solr все запишется удачно, а транзакция откатится, например будет выброшено исключение в commit()?
А как обеспечивается согласованность между Реляционной БД и индексом? Допустим, если транзакция в БД закоммитилась, а Solr оказался недоступен по каким-то причинам?
Мне помог вот этот сценарий.
Большое спасибо за ответ!)
А чтобы узнать в указанном проекте конечную цену товара нужно было вызвать метод Product::price() или CartCalculator::price(product) или что-то в этом роде? CartCalculator используется внутри Product или снаружи?
Как вы считаете, в сущности можно внедрять зависимости через конструктор если они помогают достичь большей выразительности при создании методов? Например Product::price() может обращаться внутри к стратегии (PricingStrategy), которая определит цену товара исходя из скидочных кампаний, акций производителя и т.п.?
Вопрос очень серьезный. В Вебмастере должна быть принудительная возможность отклейки, либо разграничение прав, чтобы эту функцию можно было сделать недоступной при делегировании.
Так я смогу в будущем переключить выполнение команд с основного потока в очередь.
Сомневаюсь. Придется переделать UI, частино придется переделать валидацию, и, скорее всего, сами обработчики (чтобы ничего не возвращали). Прозрачно «переключить» точно не получится.
Да, совершенно согласен. Сам сталкиваюсь с этими же проблемами. Пытаюсь решать с помощью паттерна «Репозиторий» поверх ActiveRecord
Что насчет Symfony2?
Многие из перечисленных здесь недостатков характерны для Yii/Yii2
12 ...
10

Информация

В рейтинге
Не участвует
Откуда
Хабаровск, Хабаровский край, Россия
Зарегистрирован
Активность