Comments 54
Меня "Кабанчик" разочаровал. Столько рекламы его, и ... Через призму своего почти 20-летнего опыта внедрения DWH/DataLake/DataPlatform могу сказать, что подача материала там ужасна! Как можно так нудно, долго и неинтересно, порою очень уж сложно, писать о простых и интересных (для меня) вещах? Иногда аж засыпал под нее... Странно прозвучит, но многие статьи на хабре на темы глав этой книги намного интереснее)))
В общем, ИМХО, мне кажется книга сильно переоценина, просто когда-то почему-то из "инфлюэнсеров" ее начал рекомендовать. Плюс издание и автор известные. Поэтому и ругать ее как-то "моветон" стало. И дальше идет по инерции.
в обычный месяц приходится 30 тысяч ордеров о потерянных сумках, в сезон отпусков - 90 тысяч.
Вы 3 тысячи записей в день называете что-ли быстрорастущей базой? А если нет, то к чему был этот пример? Даже если умножить это на число аэропортов в мире (возьмем от фонаря 10000), даже это не будет большим объемом.
Для слабого сервера и такой объём большой. Тут не Uber, труба пониже - дым пожиже. И необходимость привлекательных условия для авиакомпаний и перевозчиков делает рентабельность бизнеса непривлекательной для собственников. Экономия на всём и раз в три года развлечение "продать слона".
2007 год, на сервере баз данных 2 процессора и MS SQL Server 2000 Work Group edition.
Ну что это именно 2007 - вышло как-то не очевидно. Но в целом я вас понял, наверное не самая крупная база, но при ограничениях на память и процессор, и очевидно без SSD - не самая мелкая. Два ядра - это вообще ну очень фигово, я бы сказал.
Да ладно, я в 2007 году спокойно делал 100 пишущих транзакций в секунду со сложной обработкой на тех же двух ядрах и не было с этим никаких проблем. Вот 10k пишущих транзакций в секунду на дешевом железе времен HDD - уже вызов, да.
Не, слабый сервер (с учетом того что это Windows) - это конечно не оправдание, но я пытался значительно позже (2015 примерно) на виртуалке с 4 ядрами и 4Gb оперативки записать лог транзакций с мосбиржи, не так и много, где-то миллионы в сутки примерно было нужно. Оказалось, что дисковый массив у нас тоже общий, и всего выдерживает 4000IOPS примерно, а мы в одиночку с нашей базой захотели порядка 5000. При этом переезд на нормальный сервер через полгода сделал эту задачу почти тривиальной. В общем, для MS SQL мало ресурсов - иногда реально мало ресурсов.
А зачем для записи лога транзакций там много IOPS? Можно же (и нужно) просто лить пачками. Ну а миллионы в сутки - это вообще 30 в секунду, откуда там появилось 5000 IOPS?
Да, память для MS SQL имеет значение, но в 2015м 4GB оперативки - вполне норм.
Оно и было пачками. Выж догадываетесь, что большой размер пачки требует памяти тоже? А ее мало. Да, оно в среднем примерно столько, просто биржа по ночам не работает, и вообще у нее поток сообщений сильно неравномерный.
Хм, все равно не понятно, откуда появилось 5000 IOPS даже для неравномерной нагрузки со средним в 30rps? При этом 5000 - странное число, для HDD слишком много, для SSD слишком мало.
Ну и вставки даже в 100 записей не сильно увеличивают требования по памяти (совсем не увеличивают), а производительность улучшают многократно. Я уж не говорю про bulk insert, который работает много эффективнее простого insert.
Т.е. интересно, во что точно вы упирались - но это не память и не IOPSы, а что-то совсем другое. И вряд ли тут проблема в MS SQL.
Ну и Клеппман пишет, по большей части, о более сложных сценариях, нежели описаны в статье. Возможно, автор никогда не сталкивался с действительно сложными и крупными базами и проблемами целостности в них.
Какие сложные сценарии? У "кабанчика" уровень сложности для студентов, причём главы про репликацию и транзакции студентам читать нежелательно, чтобы потом не переучиваться. Рецензенты должны были помочь Клеппану доработать эти главы. Могли бы ещё посоветовать написать про альтернативы секционированию. Глава про секционирование написана хорошо. Но в книге нет альтернатив. И это плохо для учебника. Из-за незнания альтернатив ученики могут применять секционирование там, где оно неуместно.
В моей статье только вступительная часть, старинный способ физического проектирования баз данных для оптимизации нагрузки на сервер и комментарии к трём главам "кабанчика". И никаких сценариев, только поясняющие примеры. Каждый пример поясняет какую-то идею или её полезность. Все примеры тут вторичны по отношению к идеям.
У меня тоже сложилось впечатление, что автор не работал с по-настоящему сложными и "Data Intensive Applications" и поэтому все описанное в книге звучит для него как "бред"
На самом деле проблема разделения баз на 'холодные' и 'горячие' данные актуальна до сих пор. Я в своей практике сталкивался со многими системами, долго работал в чистом дата-инжиниринге. И что странно, люди вообще как будто не видят проблемы хранить данные вместе.
Всего в одном месте я увидел полноценное разделение на DWH и OLTP. Причем со связью многие ко многим. Т.е абсолютно масштабируемая, можно сказать микросервисная архитектура БД, где каждый DWH или OLTP сегменты выполняют свою узкую задачу.
Тема действительно слабо освещена, но она актуальна всегда и везде. Делить на холодные и горячие данные надо. А если ещё и бить по сервисам - то проблем масштабирования данных не будет также как и проблем масштабирования микросервисных приложений с такими же плюсами и минусами.
Просто средства другие. А-ля Airflow вместо Kafka.
А почему согласованность это свойство приложения? Разве это не о внешних ключах и констрейнтах бд?
Не только о внешних ключах и констрейнтах бд (но в том числе и о них). Правила могут быть какие-угодно. Если правило на данные нельзя определить на уровне базы данных, то его реализует программист, пишет нужный код под свою ответственность.
Причём, не всегда правила на данные зависят от области деятельности. У компаний-конкурентов могут быть разные правила работы и разные требования к данным. Что разработчикам приложения закажут, то программисты и сделают. Какие транзакции в приложении нужны, такие и будут.
Правила на данные - свойства приложений. Да и сами транзакции зависят от приложения, программисты их реализовывают, когда приложение делают. Делить свойства ACID на свойства СУБД и приложений не надо. Правила на данные частично задаются ограничениями целостности, а частично реализуются программистами, и куда их отнести :)
По такой логике и изоляция свойство приложения. Ведь можно программно сделать транзакции идущими одна за другой?
ACID - свойства транзакций. Транзакции реализовывают программисты, а выполняются транзакции на СУБД. Не надо ACID делить на свойства СУБД и приложений.
Транзакции это прерогатива базы данных. У бд есть командная строка и она о целостности данных в приложении ничего не знает. Как вы реализовываете транзакции? Они уже реализованы в бд, вы их только используете.
Так можно далеко зайти в переложении ответственности и вообще непонятно будет где код, а где инфраструктура.
Вам нужен учебник. Рекомендую этот: "Дейт К.Д. Введение в системы баз данных."
То есть ответить вы не в состоянии?
Долго отвечать, это не формат комментариев. У Дейта тема транзакций разбита на две главы. Это самый авторитетный учебник, там всё правильно по теории.
Да, это известная отмазка когда нечего ответить. Кратко формулировать мысли вы умеете?
Как я понял, у вас проблема в том, что вы говорите о разных уровнях абстракции согласованности. На уровне бл и на уровне бд.
Не совсем. Я утверждаю, что согласованность на уровне бд обеспечивается транзакциями. В то время как согласованность бл обеспечивается механизмами приложения, например как в случае eventual consistency.
Автор утверждает что и бл и бд это свойство транзакции (C из ACID).
Транзакции надо изучать по учебникам, а не по Клеппману. Читайте Дейта!
Про вас есть выражение: "всё понимает, а сказать не может".
Ваше: "Транзакции это прерогатива базы данных.".
Вам надо пройти тему транзакций.
Конечно, в Кафке есть транзакции и можно реализовать транзакции самостоятельно в коде. Но не юродствуйте, ваш посыл был не об этом. Напоминаю, вы писали что когда транзакция выполняется на стороне бд, консистентность проверяется также приложением, а не только бд.
Не буду давать вам ценных советов и отсылать к авторитетам. Вот так кратко и всем понятно можно излагать свои мысли, для этого не надо ссылаться на две главы учебника.
Где я такое написал: "что когда транзакция выполняется на стороне бд, консистентность проверяется также приложением, а не только бд"?!
Не приписывайте мне лишнего.
Контроль выполнения транзакций бывает внешний и внутренний.
Внутренний - это когда вся транзакция находится внутри хранимой процедуры (ну и может другие хранимые процедуры вызывать). Все проверки правил внутри хранимых процедур.
Так вот. Выполнение транзакции на стороне СУБД - это про внутренний контроль. Т.е. вызвана хранимая процедура и в ней работает транзакция. И все проверки внутри хранимых процедур.
У меня к вам вопрос немного не по теме. Вы работали с монгой? А то мимо меня как-то она прошла стороной и на проде ни в каком проекте не использовали...
Монга советует придерживаться денормализации данных для избегания джойнов. Но в то же время имеет ограничение на размер документа (16мб, вроде и не мало). Но если у нас приложение (бл) основывается на пользовательском вводе, то в теории пользователь будет упираться в лимит документа при сохранении данных.
Было ли у вас такое? И если изначально нет никаких ограничений на размер документа (связей), не является ли реляционная база тогда лучшим выбором?
Просто сколько не видел примеров использования монги, везде данные нормализуются, из-за чего появляются джойны...
С этим не работал.
Это не просто избегание джойнов, а целая философия (DDD). Если вкратце, то есть у разработчиков мечта отказаться от бд(и вместе с ней sql, джойнов и прочей сложности) и хранить объекты в оперативке так же, как они заданы в коде. Но поскольку прогресс ещё не дошел до супер дешёвой оперативки, появилась технология nosql.
Эта философия накладывает сильные ограничения на архитектуру приложения. Например, вместо ограничений бд, за консистентностью следит рутовый объект(агрегат) документа монго. При этом агрегат составлен так, чтобы быть понятным бизнесу(аналитикам, менеджерам, клиентам) это фишка DDD.
DDD используется в основном для сложной бизнес логики, то есть если у вас CRUD, то DDD избыточен и как следствие в монго нет смысла, используйте реляционку. Если вы пошли по пути DDD то в вашей ответственности задать агрегаты вмещающимся в 16mb. А если агрегат хранит нечто не вписывающееся в бизнес логику, то лучше вынести это в S3.
Я как минимум 3 расшифровки DDD знаю, о каком именно идеи речь?)
Увы, но то, что вы описали как DDD - никак в Domain Driven Development не соотносится, это какие-то странные фантазии на тему скорее Вернона, нежели Эванса.
Да, я опираюсь на Вернона. Что вы находите странного в моём понимании?
Ну, сам Вернон к DDD относится, ээ, не очень, лучше уж Эванса читать.
Но вообще DDD ни в коем случае не про "против СУБД" или "против join". DDD - просто по подход к работе с предметной областью (иерархия доменов, использование словаря для выделения контестов, описание методов взаимодействия доменов) и некоторая терминология для реализации (агрегаты, value object, доменные события).
Никаких реальных технических паттернов ни в стратегии, ни в тактике нет (хотя в книжке и используется слово паттерн - это совсем не в смысле Банды Четырех или там Фаулера), есть только некоторый набор именованных концепций.
Ну и nosql, конечно, никак не связан с DDD (да и вообще слово без содержания). Ну и CRUD никак не противоречит DDD, собственно для круд-проектов DDD и применим лучше всего (для более сложных систем в DDD возникают проблемы).
Ну и надо еще помнить про DDD Trilema (т.е. DDD применим только для продуктов без существенных НФТ).
Естественно чистый DDD ничего про бд не говорит, как и про реализацию кстати. Но надо понимать что DDD нашёл своё применение в микросервисной архитектуре наряду с другими хорошими практиками как cqrs, event sourcing и т.д. Вот о таком расширенном понимании DDD я и пишу, возможно не совсем корректно. Про уход от бд было у Роберта Мартина, чья луковая архитектура идеально ложится под реализацию DDD.
В целом с вами согласен, кроме crud. Везде пишут что в случае crud DDD избыточен, есть даже обсуждение на stackoverflow ссылку приводить не буду, легко гуглится.
Ну, я бы не назвал event sourcing хорошей практикой, это крайне редко когда полезный подход, в очень, очень специфических условиях. CQRS, впрочем, тоже. И к DDD эти паттерны не имеют особого отношения, просто очередная попса. Впрочем, и микросервисы в большинстве случаев будут неудачным решением.
Луковая архитектура тоже никак не помогает уйти от БД, с чего бы это? Там точно так же нужно работать с сущностями и точно так же реляционки с этим справляются проще других подходов (а использование монги - вообще характерный признак проблем с архитектурой проекта).
Не понял, что значит фраза "в случае crud DDD избыточен"? Это бессмысленное утверждение, весь тактический DDD - про реализацию CRUD.
DDD, event sourcing, cqrs собираются как пазл когда нужно масштабироваться и внедрить микросервисы. В книгах типа Вернона(а также Уди Дахана, Криса Ричардсона и т.д.) описано как всё это работает в комплексе и почему так.
Луковая архитектура не помогает уйти от бд, я писал что Роберт Мартин упомянул об этом в книге Чистая архитектура, как прогноз на дальнейшее развитие.
DDD и CRUD. DDD уже переводится как предметно-ориентированное программирование. CRUD это 4 операции, где здесь предметная область? Вы откуда это взяли, дайте сылку? Я ещё раз только что гуглил - нет либо DDD либо CRUD.
Охх. DDD категорически не про масштабирование (так как работает только если нет существенных нефункциональных требований), впрочем и микросервисы не про масштабирование (по крайней мере - не про масштабирование решения, но может про масштабирование по числу команд разработки). CQRS тоже редко помогает при масштабировании, а уж Event Sourcing скорее мешает. И у Вернона и Ричардсона (остальных, увы, не читал) очень часто написаны довольно спорные утверждения.
Хм, пока не видно никаких поводов уходить от БД. Так что не понятно, с чего бы тут упоминать Мартина.
DDD - да, разработка, ориентированная на домен (перевод как "предметно-ориентированная" довольно сомнителен). CRUD - это как раз описание конкретных операций с элементами домена (агрегатами). CRUD - это просто четыре типа команд DDD (и, кстати, уже разделены command и query). И DDD - как раз про метод реализации CRUD (т.е. как именно реализовывать различные варианты create-read-update-delete). Не понятно, как можно вообще противопоставлять CRUD и DDD.
Scalability is a critical aspect of microservices architecture.
Источник: https://www.atmosly.com/blog/scaling-microservices-for-optimal-performance#:~:text=Scalability%20is%20a%20critical%20aspect,%E2%80%94%20smoothly%2C%20without%20compromising%20performance.
Это просто рандомная ссылка, но они блин все такие) Микросервисы позволяют масштабироваться горизонтально. А я посмотрю как вы будете монолит горизонтально масштабировать.
Microservice is a small, loosely coupled service that is designed to perform a specific business function and each microservice can be developed, deployed, and scaled independently.
Видите в определении микросервисы business function? Это DDD.
DDD и CRUD
https://stackoverflow.com/questions/23970567/ddd-and-avoiding-crud
CRUD for a BC that has very little domain complexity and DDD for an area with high complexity.
Вот цитата, CRUD для простых случаев, DDD для сложных.
Ещё раз прошу приведите ссылку откуда вы всё это взяли? Или это просто ваше мнение?
Эээ, меньше читайте разные кривые ссылки.
Микросервисы никак не лучше в масштабировании, нежели монолиты. Даже наоборот, в МСА больше взаимодействий, так что масштабирование в МСА сложнее, чем горизонтальное масштабирование монолита (тем более модульного монолита). И да, я много раз масштабировал монолит, никаких проблем с этим нет.
Business function - это не DDD, это просто про "бизнес-функции". Да и выделение сервисов по бизнес-функциям - довольно спорная идея, работающая, опять-таки, при отсутствии НФТ. И да, про " developed, deployed, and scaled independently" - это рекламная агитка, в реальности ничего из этого не получается (по вполне очевидным причинам).
Хм, вот чем комады в DDD - не CRUD? Или путаете CRUD с плохо понятым REST? Или CRUD - это когда у объекта ровно 4 метода? Но это все никак не про CRUD. В ссылке на SO - написано что-то очень странное, зачем такое читать?
А пишу я на основании своего и не только своего опыта, многочисленных книжек, обсуждений и докладов. Ну и просто базовой логики )
Только понимание прочитанных вами книжек и докладов противоречат и самим книгам и докладам и мнению сообщества.
-- Да и выделение сервисов по бизнес-функциям - довольно спорная идея
services are built around business capabilities
-- И да, про " developed, deployed, and scaled independently" - это рекламная агитка
services are independently deployable and scalable
-- Business function - это не DDD, это просто про "бизнес-функции"
Define services corresponding to Domain-Driven Design (DDD) subdomains. DDD refers to the application’s problem space - the business - as the domain.
https://microservices.io/patterns/decomposition/decompose-by-subdomain.html
По CRUD и DDD - вы Эванса то вообще читали (это не оскорбление, это удивление)? Методы и названия переменных берутся из существительных и глаголов универсального языка. Универсальный язык не состоит из 4 глаголов (создать, изменить, удалить, прочитать) это язык описания бизнес логики. Это главная суть DDD так-то - уход от CRUD.
Microservices and Domain-driven design are two different things but it comes hand to hand while implementing the microservices.
Вообще очень похоже на тонкий троллинг.
Не, не противоречат. Просто книжки надо читать внимательно.
1. В рамках МСА можно говорить о выделении сервисов по бизнес-функциям. Но далеко не всегда МСА является подходящим стилем для конкретного продукта, более того, часто гораздо удобнее использовать другие распределенные стили (от других вариантов SOA и до каких-нибудь pipes-and-filters). И да, большая часть компаний, говорящих об использовании МСА - использует что-то другое. Кстати, даже у Ньюмана в определении МСА - нет ничего про "around business capabilities". И, да, business capability - не то же, что и business function. Хотя разница там достаточно тонкая, да.
2. Угу. Но в реальности для МСА не получается ни индивидуального деплоя (так как сервисы зависят по API и не могут выкладываться полностью независимо) ни индивидуального масштабирования (так как сервисы зависят друг от друга и один тормозящий сервис авторизации убивает масштабирование всех прочих). Фаулер пишет не про априорное свойство МСА, а про стремление к выполнению этого свойства. В реальности, увы, это свойство крайне редко достижимо.
3. И каким образом из определения Problem space вылезли business functions (которые, вообще говоря, несколько про другое).
4. Я Эванса читал. И да, у тебя методы идут из языка. Поэтому для Create будет пара глаголов (по созданию агрегата), для Update еще с пяток (по разным изменениям агрегата, для Select - тоже несколько. Но это вообще не какое-то свойство DDD, это вообще база ООП. И в любом CRUD у тебя тоже будут разные методы для разных задач, но эти методы будут сводится к одному из 4х типов. Только не надо путать CRUD и дурно-понятный REST.
В вашем подходе (CRUD) действительно зависят. Но в DDD слои слабо зависят друго от друга и вы можете независимо от других слоёв вести разработку API. Кроме того есть совместимость которая запрещает ломать старый API.
В нормально построенных микросервисах (Event Sourcing) взаимодействие происходт асинхронно, и тормозящий сервис просто будет компенсирован Eventual Consistency.
Ещё раз. Язык не содержит CRUD методов. То есть конечно он может содержать метод Create, если у бизнеса есть такой термин. Но бизнес не говорит на языке CRUD (вместо "создай вакцину в шприце", "обнови кровь у пациента" бизнес испольует "поставь вакцину" - это фрагмент из книги, которую вы читали).
И даже в вашем примере ошибка - пара глаголов Create как бы намекают на разнесение в разные Bounded Context.
Хм, зависит в любом случае и дело тут не в слоях. В любом случае если сервис A и сервис B как-то взаимодействуют, то они зависят друг от друга. И в асинхронном взаимодействии эта зависимость гораздо больше (так как нет возможности нормально поддерживать версионирование).
Ну и Event Sourcing не обязательно про асинхронное взаимодействие. И торможение на, например, чтение (которое синхронное) никак и никто не компенсирует.
Так что это все легенды и мифы, в реальности автономность для раздельных сервисов получить очень сложно и, в реальности, не нужно.Язык не содержит слова create или update. Но issueCard или там changeName - это как раз вполне себе CRUD операции (create и update). Исключение - команды, меняющие множество агрегатов, но это вообще отдельная тема и в CRUD и в DDD.
И пара разных create могут быть в одном агрегате, не говоря уж про один BC (в котором может быть много агрегатов). Например создание разных вариантов одной сущности, типа createRectangle и createSquare на агрегате геометрических фигур.
Так а что с монгой?) Одно дело "безграничное хранилище" за счёт горизонтального масштабирования, другое - лимиты и производительность в вычислительных операциях.
Т.е. условно, какой смысл от монги, если в постгри есть jsonb?)
Ни в коем случае не хочу как-то принизить монгу, спрашиваю из-за того, что большинство статей по монге не объективны (на мой взгляд).
А, то есть приложение не проверяет консистентность транзакции? Следовательно C это свойство бд, а не бд и приложения?
Вот и у меня при прочтении сложилось впечатление что написана теоретиком для теоретиков. Всё описано слишком абстрактно, без конкретики, без примеров...
Моя рецензия на «кабанчика» Мартина Клеппмана и главная идея проектирования быстрорастущих баз данных