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

Комментарии 33

А вы действительно хотите на КДПВ ракету привязанную задом наперёд? То есть птичка реактивно так полетит назад
Фраза «выстрелить в ногу» приобретает новые оттенки)
Вряд ли полетит. Она же направлена в землю, поэтому её размажет по поверхности. Scale Out =)
Тот неловкий момент, когда к интересной статье прикрепляют провокационную КДПВ.
Забавно, но именно это мы и делаем, только уже перешли на Akka-Streams и переписали под себя сериализацию протобафа.
А вы не пробовали использовать что-либо еще помимо протобафа для сериализации?
Отвечу за коллегу. Для персистенса у нас как раз используется Kryo, а переписанный протобаф – на транспортном уровне для общения с клиентами.
Заменим наш эрзац-журнал на что-то по-настоящему хорошее. В данном случае мы возьмем Cassandra, и будем использовать ее для хранения ивентов.
Есть же вроде специально для этих целей EventStore (плугин к Akka в наличии). Умеет хренить как события, так и снапшоты.
Это пукалака какая-то на javascript-е. Cassandra гораздо более матерое решение и вполне себе специализированное; хрнаить в ней эвенты — это то, что доктор прописал.
Вы бы хоть сначала посмотрели — JS там, конечно, есть, но как внутренний язык для проекций, а само оно написано на C#. А еще полезно посмотреть на автора…
Тем более :) Под линукс дистрибуция бинарем, нафиг надо.
А в чем проблема собрать сорцы?
Зачем вообще с этим связываться? Выбор NET как платформы для Linux крайне не удачнен. Вот представть себя админом, которому дают на выбор Cassandra, которая на Java без всяких so-шек или нечто на .NET портированное под линукс. Что там в вашем EventStore есть такого волшебного? Вот Cassandra — солидная штука с крутыми интсраляциями и так далее.
если подходить к вопросу с потребительской позиции то единственный аргумент — adoption в индустрии, да. всякий энтерпрайз действительно руководствуется такими аргументами и тут с вами спорить нет смысла.

EventStore не мой, я сам про него узнал впервые из статьи, просто дал себе труд посмотреть подробнее.

Объективно же, .net ничем не отличается от джавы в вопросе виртуальной машины, (а где-то и лучше её) и необходимости ставить среду выполнения.

Говорить, что .net приложения «портированы» под линукс — ошибка. Нормальные .net приложения пишутся сразу кроссплатформенно, точно также как на джаве.
Автор выбрал платформу Java. При наличии подходящего решения внутри платформы, использовать альтернативный кусок на другой платформе просто нерационально.
Как это не отличается? Оффициального .NET под Linux пока нет, тут Mono, Mono — в продакшне, ну его нафиг. Админить виндовый кластер, извольте.
Mono — в продакшне
Использую пятый год, полёт нормальный. С EventStore вообще поставляется специально под их нужды пропатченый билд Mono.
У меня есть знакомые которые что только не использует в продакшне. И D, и Rust. Это ваш выбор, который лично я не одобряю. Все это юношеским максимализмом попахивает.
>под их нужды пропатченый билд Mono.

Это вообще агонь. Нафиг-нафиг.
Как бы сказать. Четвёртая ссылка в гугле по запросу «event sourcing» ведёт именно на EventStore.
Потому что название удачное, ваш К.О.
А что плохого в кассандре-то? Для нее тоже есть плагин, который автор и юзает как раз.
В том, что кассандра — БД общего назначения, EventStore же писалась специально под нужды паттерна event sourcing. Вы с тем же успехом события и снапшоты можете в Postgres хранить, под него тоже плагин есть.
Кассандра ниразу не БД общего назначения, а как раз для таких штук вроде обработки событий и разрабатывалась. C Постгресом вообще сравнение не корректное.
Всегда возникали вопросы по архитектуре реативного приложения. Насколько я понимаю, реактивное программирование и CQRS предназначены для простой бизнес логики и слабо связанных данных. Основными проблемами данного подхода я вижу:
— невозможность свободной выборки данных из разных entity (то, что в ER делают JOIN-ы). Как выход предлагается денормализировать читаемые данные ввиде графа, чтобы выборка происходила по одной entity, которая включала бы в себя все необходимое. Но это далеко не всегда достижимо.
— отсутствие стабильного состояния в любой момент времени. То есть полное состояние — это то, что лежит в базе плюс все event-ы, разбросанные в данный момент по обработчикам. Как быть, если наш запрос — нечто более сложное, нежели атомарное изменение, а например: прочитать данные, проанализировать и в зависимости от этого выполнить ряд изменений разных сущностей? Без локов или транзакций состояние будет «уплывать», что ведет к потере целостности.
— большая сложность групповой обработки событий, например если нужно объединить несколько событий в одно большое. При декомпоновке событий очередность обработки не гарантируется.

Буду рад, если поправите.
невозможность свободной выборки данных из разных entity
Как правило для этих целей собирается отдельный денормализованный view, на который прилетают все события относящиеся к одному aggregate root.
отсутствие стабильного состояния в любой момент времени
Да, у нас нет strong consistency всей системы, однако внутри аггрегата у нас поддерживается консистетное состояние в любой момент времени. В большинстве случаев этого достаточно для корректной работы приложения. Если бизнес-логика требует консистентное состояние в любой момент времени, то в данном случае не следует использовать CQRS/ES. Кстати, а вы бы не могли привести пример из реального мира, когда нам нужно иметь консистентное состояние всей системы в любой момент времени?
При декомпоновке событий очередность обработки не гарантируется
Если я ничего не перепутал, то для решения подобных проблем используются conflict-free replicated data types, которые позволяют обработать события даже если они пришли не в том порядке.
Насчет примера: любой банк. Каждый день в XX:YY часов открывается окно для межбанковских операций. Нужно посчитать к этому моменту все операции за день и изменения счетов, и выставить суммарный счет каждому из контрагентов. К этому моменту нужно, чтобы все операции были завершены и состояние всей БД было стабильно.

Дугой пример из того же банка. Сделали асинхронные транзакции, по одному актору на один счет. Все шустро и независимо работает: сообщения о денежных переводах роутятся к акторам, каждый актор смотрит баланс своего счета, и если он становится негативным, то операция запрещается. Теперь менеджер захотел, чтобы для определенных клиентов операция разрешалась, если суммарный баланс всех счетов одного клиента был бы неотрицательный, тогда как каждый счет в отдельности может стать негативным. Можно сделать новый тип акторов, который бы пропускал через себя все транзакции к счетам каждого клиента, но это потребует архитектурных изменений и затруднит совмесную работу со старыми акторами. Возвращаемся к блокировкам.

В CQRS моделях набор выполняемых операций ограничен, операции достаточно просты, чтобы быть выполненными внутри одного аггрегатора, а логика их выполнения не зависит от выполнения других операций или данных, лежащих вне аггрегатора. Для многих бизнес задач операция требует синхронного изменения сразу многих объектов. Выделить операции в атомарные акторы не представляется возможным, так как одни и те же данные используются разными операциями. Поэтому приходится искусственно создавать блокировки, либо использовать уже готовые средства, предоставляемые dbms.

Если я ничего не перепутал, то для решения подобных проблем используются conflict-free replicated data types

Необходим конечный автомат с персистентным состоянием, который бы ловил эти события, коррелировал бы их в группы и применял бы какое-нибудь правило типа: если получили A, B, C (в любом порядке), то выкинуть X. Если получили A, C, D, то выкинуть Y, etc…
Насчет примера: любой банк. Каждый день в XX:YY часов открывается окно для межбанковских операций. Нужно посчитать к этому моменту все операции за день и изменения счетов, и выставить суммарный счет каждому из контрагентов. К этому моменту нужно, чтобы все операции были завершены и состояние всей БД было стабильно.

Так это же не «в любой момент», это в конкретный момент. И как раз для этого eventual consistency прекрасно подходят.
любой банк
Интересным фактом является то, что исторически, когда письма доставлялись на повозках и кораблях, и время доставки письма могло доходить до нескольких месяцев, банки прекрасно работали, бюджеты сводились, и никто не разорялся. И все это работало без каких-либо транзакций, сплошная eventual consistency.
Ну, если судить абстрактно, то вообще существует только eventual consistency. Просто транзакционная модель контролирует многие аспекты, среди которых — «поймать» этот момент consistency, гарантировать атомарность, snapshot-чтение данных, etc… Проблема в том, что в распределенной среде синхронизация данных осуществляются медленно (хотя все относительно — игровые серверы живут и процветают), и люди делают выбор в пользу BASE и асинхронной архитектуры. Но это всегда в разы усложняет логику, поскольку контроль над выборочной consistency полностью ложится на разработчика. Поэтому «реактивная» парадигма — это не панацея и не новый модный подход, а вынужденная необходимость. Там, где можно использовать ACID, нужно использовать ACID.

P.S. Да. Но чтобы добиться eventual consistency банки устраивали «учетный день» или даже «учетную неделю», когда денежные операции не принимались, или складывались в очередь, но не выполнялись. В современном мире невозможно, хотя в Европе большинство банков работают с клиентами до 14:00, а дальше, видимо, время eventual consistency :) Говорят, что и рождественские каникулы существуют для того, чтобы спокойно привести годовой баланс в порядок и закрыть бюджет :)
Разрабы Akka очень сильно не рекомендуют создавать акторы через оператор new. Этот вариант имеет проблемы с персистентностью. Лучше использовать Props(classOf[ActorClassName], args...)
И ещё более не рекомендуют делать context.actorOf(new SomeActor) в теле другого актора (а не в объекте-компаньоне, как делают обычно), т. к. неявно захватывается this outer класса.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий