Один из лучших источников (главное часто обновляемый) это microservices.io
Задачу с магазином можно решать Saga, Event Sourcing, Transaction log tailing кроме того, как описано у меня применим Distributed Lock и даже Optimistic Locking (при условии что мы поменяем сценарий покупки)
1) В комментариях я уже писал, что Saga также внутри использует блокировку.
2) Для того чтобы делать сознательный выбор, программисты должны знать о разных подходах. Целью моего доклада было рассказать людям имено о блокировках, а не как решать пустяковую задачу. Простой пример, доходчиво объяснил откуда берется поле when, version и как реализовать в спринге разблокирование.
Вы все время путаете понятие масштабируемости и доступности. Масштабируемость — это возможность улучшить параметры (давайте для ясности сузим понятие до производительности) системы путем добавления новых инстансов. Когда мы проектируем CP систему мы сознательно принимаем решение о том что мы гарантируем консистентность © данных и возможность роста за счет (P), но конечно страдает доступность (A). Но облачный автоскейлинг продолжает работать добавляя/уменьшая инстансы и мы готовы встречать любую нагрузку. В реальной бизнес задаче никого не волнует что клиент получит ответ через 10 сек или 2 минуты, значительно важнее защита полученых данных.
вы как раз нарвались на что-то подобное?
Да, но это было связано не с временной задержкой, а именно невозможностью заблокировать запись которой еще нет в базе (два клиента могли прийти и создать один и тот же уникальный ключ — а на комите один из клиентов обязательно падал). Но в указанном в статье примере с доступом к удаленному банковскому сервису — идея была бы не в указании времени, а в том, что если блокировка (мгновенно) вернула эксепшен — мы можем, например, уведомить кастомера о плохой связи.
Теперь вы вводите менеджер блокировок.
Вы правы но в тоже время это не совсем так — я несколько раз писал об этом в ответах на коменты — блокировки и так присутсвуют, просто мы их можем вынести из скрытой под капотом внутри бд на уровень доступный программисту.
Боюсь вы банально путаете понятия — продукт от Spring GlobalLock и паттерн Distributed Lock, и для того чтобы показать как работает паттерн я использовал пример с книгами. Можете рассказать лучше — публикуйтесь
Вот скажите, где по тексту хоть небольшой намек на существование в нашем коде задержки со стороны лока? Описанное поведение говорит, что система бросает exception когда не может приобрести блокировку.
Далее все базы данных (!) используют блокировки (посмотрите thread где объясняется как Mongo вынуждена их использовать) и при этом никакие инстансы не лочаться, тем более тысячи.
Где вы видели лок таблиц?
Где вы видели в статье что мы используем глобальные блокировки? У нас используется распределенная блокировка, а название продукта действительно Spring Global Lock, что никак не связано. В свою очередь следует отметить, что распределенные блокировки используются в большинстве распределенных систем, посмотрите ниже большой thread где обсуждается, например, зачем нужна распределенная блокировка в Mongo
У нас в прод. базе зарегистрировано сто тысяч клиентов, в день приходит около 50 тысяч
p.s. И я заскриню ваш комент для следующих выступлений как раз про CAP теорему. (ну конечно без упоминания имен)
Хорошего вечера. Мои коментарии с ролбеками были к тому, что если вы не видите локов, это не означает что их нет. Их от вас спрятали под капот. На сегодняшний день известно лишь ограниченное число алгоритмов в которых реально избежать блокировок.
В любом случае спасибо за дискуссию — адекватная техническая беседа увы редкость.
Ну конечно «внутренности». Я это сразу и написал в моем комментарии выше:
разработчики вынуждены подключать механизмы распределенных транзакций (пусть вы их и не видите как пользователь)
Но то что механизм спрятан во внутрь (или вы его не знаете) не избавляет вас от ответственности и последствий.
Спасибо за внимательное прочтение статьи. Я не думаю что это стоит исправлять особенно в разрезе того что и Repeatable reads и Read Committed увы допускают phantom reads — что будет приводить к ошибкам во время валидации.
CP решения как раз хорошо скалируется. Иначе бы мы не писали «Partitioned» Определение скалирования: «...capability of a system, ... to handle a ... work, ... to be enlarged to accommodate that growth» С добавлением новых инстансов мы остаемся CP системой. Но статья не об этом, я скопирую текст из предыдущего комментария:
чтобы стать экспертом вы должны были где-то узнать, какие в принципе есть решения. Статья дает аудитории знания про существование механизма и несколько раз акцентирует: пример с книгами служит лишь для того чтобы рассказать о GlobalLock и его недостатках.
Я бы понял ваши усилия если бы они были направлены на то, чтобы предложить аудитории более удачный пример как просто объяснить механизм блокировок, зачем им нужна версия и дата экспирации. Но нет, вы тратите время на то чтобы показать как бы вы решали действительно пустяковую задачу используя весь арсенал современных технологий.
Именно поэтому я рассказываю, что лок должен быть точечным. И более того, лочаться не инстансы, а одна из записей в storage
смею вас уверить сам механизм репликации внутри реализован как механизм распределенной транзакции. Представим 1-master-1-slave конфигурацию, что должно произойти на мастере если slave сломался? Мастер (не достигший требования о majority) вынужден начать rollback на своей стороне и вернуть программисту ошибку.
Вы не поняли. Статья не про покупку книг. Вы как эксперт оценили какой-то пример и вынесли суждение (я даже не буду вступать в спор о том применимы GlobalLock / Saga или есть лучше microservices.io/i/data/saga.jpg — там видно про локальные транзакции, которые все равно блокируют), но чтобы стать экспертом вы должны были где-то узнать, какие в принципе есть решения. Статья дает аудитории знания про существование механизма и несколько раз акцентирует: пример с книгами служит лишь для того чтобы рассказать о GlobalLock и его недостатках.
Я бы понял ваши усилия если бы они были направлены на то, чтобы предложить аудитории более удачный пример как просто объяснить механизм блокировок, зачем им нужна версия и дата экспирации. Но нет, вы тратите время на то чтобы показать как бы вы решали действительно пустяковую задачу используя весь арсенал современных технологий.
Когда база сконфигурена на Master-Slave поддержку (читай репликация) и программист говорит: я хочу запись WriteConcern="majority" Монга вынуждена быть уверена что запись (результатов транзакции) произведена в том числе и на Slave инстансы. Значит разработчики вынуждены задействовать алгоритмы распределенных транзакций.
docs.mongodb.com/...n-w-majority.bakedsvg.svg
Вы описываете сценарий с точки зрения покупателя и такое поведение оправдано. Блокировки все равно будут в любой реализации когда вы начнете делать покупку (перекладывать из резерва).
Но давайте я проясню структуру статьи т.к. большинство комментаторов вкладываются в попытку улучшить именно этот алгоритм:
— Есть задача (не раскрою тайну NDA — она в десятки раз содержит больше сущностей, чем в примере 1 книги и эти сущности связаны между собой и валидация связей действительно требует блокировки)
— Есть возможность рассказать людям о GlobalLock
— Ваш выбор рассказать на 40 мин докладе о десятке сущностей (всем плевать) или об 1 книге и показать как GlobalLock можно применить?
Как и обещал, вот здесь я буду рассказывать о вашем коментарии:
GlobalLogic Kharkiv
Java Conference 2019
June 9
Доклад: 16:40 — 17:30 «Ignorance of CAP Is Not an Excuse»