Eventual consistency
От: Slicer [Mirkwood] Россия https://ru.linkedin.com/in/maksim-gumerov-039a701b
Дата: 07.07.18 17:54
Оценка: 6 (1)
Всем привет.
Вот есть система, которой присущ сабж. Для конкретного примера — который меня вдобавок в первую очередь интересует — возьмем Elasticsearch.
Есть по меньшей мере три наиболее неприятных ситуации, которые могут возникать.
1) Пользователь выполняет создание некой сущности в каком-то веб-приложении, потом запрашивает список этих сущностей — но не видит в нем созданную, потому что приложение ищет через elasticsearch, и (как одна из причин) попадает на тот шард, который еще не успел получить реплику сущности. Как после этого пользователю открывать созданный документ — с ходу непонятно (хотя если дать кнопку "обновить" то вероятно постепенно привыкнет, но выглядит это как-то некрасиво).
2) Аналогично п.1, но еще подлее. Пользователь то видит в списке созданную сущность, то не видит — вплоть до того что например он открывает редактор созданной сущности, вносит изменения туда, а при попытке сохранить получает ошибку из-за того, что сущности якобы нет (потому что опять сходил не на тот шард). Конечно не все приложения при сохранения изменений пойдут в эластик искать там сущность (все-таки мало кто эластик использует как первичную БД), но если вместо эластика например Кассандра — вполне возможно; или могут упасть если они пытаются делать при сохранении UPDATE эластика, а он ведь вроде падает если документа с таким id не нашлось.
3) Код клиента вызывает после создания или сохранения сущности ее повторное чтение (ну например в форме редактирования кнопка "Сохранить" по замыслу не должна закрывать эту форму). И соответственно повторное чтение не может найти сущность или находит ее вариант до изменений. Ну хотя бы для этого сценария есть решение достаточно очевидное — структурировать код клиента так, чтобы не запрашивать данные заново с бека, а использовать те, которые мы отправляли на сохранение.

Так вот, как вы с этим в своих проектах справляетесь?
Ну я знаю что кто-то никак не заморачивается, дескать ну получит юзер ошибку — ну и ладно, значит бог его все равно не любит; а если не увидит документ то дадим ему кнопку Обновить. По 1-ой проблеме еще наверно можно как-то по websocket подписываться на апдейты и подтягивать автоматически, чтобы не заставлять обновлять самостоятельно; еще я слышал о людях которые добавляли к получаемому от бека списку фиктивные строки для только что созданных документов, но при запросах по одной странице — если пагинация используется — это будет конфликтовать с сортировкой, которая по идее проводится на бэке, ведь неясно на какую страницу должна попасть эта фиктивная строка.
Еще я читал про read own writes консистентность и про monotonic read консистентность, они бы позволили решить эти проблемы (монотонность решила бы хотя бы 2-ую). Но как их подружить с системой, которая изначально их сама не поддерживает (тот же эластик например), я не представляю. Вот например для read-own-writes в одной статье предлагали PouchDB применять как локальное хранилище для копии вносимых изменений, но если есть такой кэш, какие должны быть правила eviction для него? До каких пор держать в нем наши изменения? И что если сессии пользователя — не sticky, и следующий запрос его может прийти на другой инстанс приложения — уже в другой pouchdb? Или даже если они sticky например, но использовавшийся в последний раз инстанс — отвалился? Тут по идее надо распределенный кэш тогда вместо pouchdb — но опять возникают вопросы, ведь такой кэш тоже должен быть AP системой (как и сам эластик ну или там кассандра) и потому при переключении клиента на другую ноду может оказаться, что там в этот момент еще не самое свежее состояние сессии. Бида короче =) А, ну еще наверно можно было бы на стороне клиента держать кэш вместо этого, но там опять непонятно как настроить eviction так, чтоб кэш не разрастался безгранично.
Как прикрутить к эластику monotonic read consistency, если у него нет глобального понятия "версия всех данных", я тоже не понимаю.

Короче, какое бы решение я ни рассматривал, ко всякому вроде бы можно придумать такой сценарий, при котором клиент может не увидеть только что внесенные им изменения. Или то видеть их, то не видеть.

Slicer
Специалист — это варвар, невежество которого не всесторонне :)
Отредактировано 07.07.2018 18:27 Slicer [Mirkwood] . Предыдущая версия . Еще …
Отредактировано 07.07.2018 18:19 Slicer [Mirkwood] . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.