Pull to refresh

Comments 70

Микросервисы, как и любая другая архитектура или подход, хороши пока не ударяешься в радикализм. Т.е. выделить авторизацию, вспомогательные компоненты системы в отдельные сервисы — это хорошо и полезно. Но когда начинают дробить оперативную базу данных на части и на каждый чих нужно дёрнуть 2-3 сервиса, то это превращается в кошмар. Отдельно стоит упомянуть проблему коммуникации между сервисами. Во-первых к каждому такому запросу добавляются транспортные расходы, а также нужно затратить очень много усилий чтобы предусмотреть все отказы на сетевом уровне и не потерять данные или их целостность.
Часто оказывается, что если нужно дергать 2-3 сервиса на изменение данных, то или границы сервисов определены неверно, или неверно понята атомарность бизнес-транзакции.
Третий вариант ответа, допечатывайте, хайп проходит, люди трезвеют, но «опохмелиться» нужно.

Вот все говорят, что одно (если не главное) из преимущество микросервисов — горизонтальное масштабирование. Мол, не справляетесь — а выкатите еще несколько инстансов одним кликом! Ну это все хорошо в случае stateless инстансов. Но это гладко только в случае stateless. Есть состояние — ну все, куча головной боли.


И все тоже самое можно сделать и с монолитом. Если нехватка на уровне приложения — запустить несколько инстансов. Если бутылочное горлышко БД — это будет проблемой при обоих подходах. Только в случае монолита проблемы обеспечения согласованности распределенных данных начнутся только упершись в ограничения БД, а у микросервисов — сразу.


А еще увеличенная куча boilerplate кода. Передаем какой-нибудь объект из сервиса А (сериализуем) в сервис Б (десериализуем). Упс, и там и тут нам нужно два соответствующих класса. Давайте добавим общую библиотеку… Постойте, только что всю идею сломали.

Ну, в плане масштабирования у микросервисов плюс в том, что масштабировать можно более гибко по ресурсам, чем монолит. Грубо, если монолит жрёт 100 метров на запрос, какая-то его часть 20 из них, надо 1000 запросов обработать из которых половина приходится на эту часть, то дешевле дать 10 гигов только этой части, 40 остальным, чем 100 монолиту.
Если бутылочное горлышко БД — это будет проблемой при обоих подходах. Только в случае монолита проблемы обеспечения согласованности распределенных данных начнутся только упершись в ограничения БД, а у микросервисов — сразу


БД так же можно подробить — каждому виду микросервисов своя БД.

А это значит, что и нагрузка на БД будет размазана по большому числу серверов, пусть не столь гибко как с stateless, но все равно нагрузка на СУБД будет ниже.

… и тут вам в одном из сервисов надо(внезапно, естественно. И срочно!) сделать join данных с разных баз…
… и тут вам в одном из сервисов надо(внезапно, естественно. И срочно!) сделать join данных с разных баз…


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

Является ли легкая адаптация к изменившимся требованиям плохим продумыванием?
И почему вы противопоставляете микросервисам только монолит, а не что-то обеспечивающие модульность без лишних сетевых взаимодействий?
Является ли легкая адаптация к изменившимся требованиям плохим продумыванием?


Если адаптация легкая — это как раз является хорошим продумыванием.
И почему вы противопоставляете микросервисам только монолит, а не что-то обеспечивающие модульность без лишних сетевых взаимодействий?


Проследите нить разговора чуть выше.
Если адаптация легкая — это как раз является хорошим продумыванием.
Так как тогда возможность сделать join (т.е. легкая адаптация) является плохим продумыванием?

Проследите нить разговора чуть выше.
Я просто говорю о том, что для снижения нагрузки на бд можно использовать другие техники.
Так как тогда возможность сделать join (т.е. легкая адаптация) является плохим продумыванием?


Выглядит как «возможность сделать все что я хочу не думая ни о каких ограничения».
Но так не бывает.

Поскольку мы говорим о микросервисах — то давайте вспомним, что вся эта сложность придумана не для чего иного и не кем иным как гигантами веб-индустрии для горизонтального масштабирования.

Вот эта же статья, но перевод получше:
habrahabr.ru/company/flant/blog/347518
Видно, что автор статьи уделил внимание масштабам:
Размер команды
Можно ли усадить всю вашу команду за один большой стол?

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


Ну а если ваша СУБД потребует маштабирования, то возможность бездумного применения join сегодня приведет вас к неприятной дилемме:

1) Резкое снижение производительности в случае запуска СУБД распределенным образом на нескольких серверах, непримлимое снижение производительности.

2) Только вертикальное масштабирование возможно. Но крайне дорогое железо для него.

Я просто говорю о том, что для снижения нагрузки на бд можно использовать другие техники.


Из простых методов знаю — кэш в оперативной памяти или более быстрое железо, прежде всего диски. Наверняка все эти методы уже испробованы были до перехода на микросервисы.

Из сложных — тщательно пошевелить мозгами и спроектировать архитектуру не универсальной, а индивидуальной под задачу. Вон люди даже специальные СУБД пишут индивидуально под свои задачи. Будет дорого, долго. Да еще и при изменении задачи — нужно будет переделывать.
Занятно. Мы говорим о разных вещах. Скажем так, по вашим цитатам получается, что микросервисы по сути изолированные системы с изолированными командами. Я не спорю, что когда у вас сотня разработчиков, то делать единый монолит — не самая лучшая идея.

Однако, когда говорят о микросервисном безумии, то имеют в виду нечто другое. Например, у вас пять разработчиков и данные помещаются на одну бд. Вы зачем-то делаете три микросервиса, каждый со своей бд. И они больше связаны, нежели независимы. Это пример того, что называют безумием. И это реальность того, как используются микросервисы.

Выглядит как «возможность сделать все что я хочу не думая ни о каких ограничения».

В рамках описанных вами масштабов это скорее всего даже невозможно. Точно так же, как если бы я предъявлял бы в претензию стороннему продукту, что я не могу сделать join на их данные.

В рамках масштабов типичных (небольшая команда, данные в одной бд) невозможность сделать join является чем-то реально странным. Модульность модульностью, но если за неё вы платите реальным проседанием производительности системы, то вы облажались при продумывании.

Из простых методов знаю — кэш в оперативной памяти или более быстрое железо, прежде всего диски. Наверняка все эти методы уже испробованы были до перехода на микросервисы.

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

Но вообще есть еще: распределенные кеши, репликация, шардирование не по логической структуре, денормализация для ускорения чтения, снижение времени проводимого в транзакциях (многие современные системы держат транзакцию дольше, чем пишут данные), всякие точечные оптимизации. У всех техник свои недостатки. Примечание: но это техники снижения нагрузки, а не техники хендлинга большого количества данных.
Например, у вас пять разработчиков и данные помещаются на одну бд. Вы зачем-то делаете три микросервиса, каждый со своей бд. И они больше связаны, нежели независимы. Это пример того, что называют безумием. И это реальность того, как используются микросервисы.


Э… нет.

3 — это не микросервисы. Это просто сервисы.

И они вполне себе хорошо делятся.

Например — интернет-магазин:

1. Бэкенд «Каталог». Отображение товаров, поиск, иерархия, фильтры.

2. Бэкенд «Корзина» (то, что покупатели выбирают и откладывают, путешествуя по вашему интернет магазину) и «желаемые покупки».

3. Бэкенд «Заказы». Оформление товара, адрес, виды доставки, уведомления по email и sms

4. Фронтенд.

БД вполне себе независимые.

Может показаться нужным делать join в «Корзине» и «Заказе» для отображения наименований товаров в корзине и списка товаров при заказе.

Но вполне достаточно в БД сервисов «Заказы» и «Корзина» хранить только ID товара, отдавать ID товара на фронтенд, а дальше фронтэнд уже запросит у «Каталога» конкретное наименование по ID (запрос название цены и описания товара по ID легко кэшируется на стороне веб-клиента и не будет дергаться каждый раз)

Более того, БД всех 3 сервисов — могут быть разного типа, смотря что лучше для данной подзадачи.

Например, каталог с полнотекстовым поиском — это специализированная БД для полнотекстового поиска.
Корзина — какая-нибудь БД in-memory с сохранением состояния типа Tarantool
Ну а заказы — классическая реляционная СУБД.

Другое дело, что еще куча накладных расходов на оркестрацию. Впрочем, возможно что команда из 5 разработчиков работает над магазином не просто так, а цель — покорить весь мир а ля Амазон, АлиБаба или eBay.

И тут деление на сервисы позволит легко отмасштабироваться по мере роста посетителей.
3 — это не микросервисы. Это просто сервисы.
Окей, допустим. В таком случае поясните какая по вашему мнению разница между ними.
Может показаться нужным делать join в «Корзине» и «Заказе» для отображения наименований товаров в корзине и списка товаров при заказе.

Но вполне достаточно в БД сервисов «Заказы» и «Корзина» хранить только ID товара, отдавать ID товара на фронтенд, а дальше фронтэнд уже запросит у «Каталога» конкретное наименование по ID (запрос название цены и описания товара по ID легко кэшируется на стороне веб-клиента и не будет дергаться каждый раз)
Серьезно? Вы создали N+1 запросов на ровном месте. Без кеша это адское падение производительности. С кешом это по прежнему адское падение, потому что вы увеличили количество данных для кеширования и они теперь не помещаются в кеш! Да и еще предлагаете кеш втулить на клиент, что делает кеш еще менее влияющим на производительность бекенда. Просто жесть.
Более того, БД всех 3 сервисов — могут быть разного типа, смотря что лучше для данной подзадачи.

Например, каталог с полнотекстовым поиском — это специализированная БД для полнотекстового поиска.
Корзина — какая-нибудь БД in-memory с сохранением состояния типа Tarantool
Ну а заказы — классическая реляционная СУБД.
Ничто не мешает в монолите юзать три разные бд, если они нужны. Но при этом количество ситуация «не могу сделать join» будет в разы меньше.
Серьезно? Вы создали N+1 запросов на ровном месте. Без кеша это адское падение производительности. С кешом это по прежнему адское падение, потому что вы увеличили количество данных для кеширования и они теперь не помещаются в кеш! Да и еще предлагаете кеш втулить на клиент, что делает кеш еще менее влияющим на производительность бекенда. Просто жесть.


Кэш на клиенте в браузере — УЖЕ есть, он существует и используется браузером ВСЕГДА.

Он используется вашим браузером прямо сейчас.
Это снижает и загрузку и ваших каналов связи и каналов связи сервера Хабра и нагрузку на сервер Хабра.

Кэш на клиенте — это норма.

С кешом это по прежнему адское падение, потому что вы увеличили количество данных для кеширования и они теперь не помещаются в кеш!


Что?
Это снижает и загрузку и ваших каналов связи и каналов связи сервера Хабра и нагрузку на сервер Хабра.

Браузерный кэш ужасно уныло подходит для динамических данных. Т.е. да, его можно и нужно юзать. Но основное кеширование должно происходить на бекенде.

Что?

Допустим я хочу посмотреть детали заказа. В классической системе это один запрос к бд и один запрос к серверу. В описанной вами схеме это N+1 запросов к бд и N+1 запросов к серверам. Соответственно количество данных, которые нужно кешировать увеличивается. Но память ограниченная. Значит кеш теперь может спасать меньшее количество запросов.
Браузерный кэш ужасно уныло подходит для динамических данных. Т.е. да, его можно и нужно юзать. Но основное кеширование должно происходить на бекенде.


Наименование и описания товаров — никакие не динамические данные
Вообще в целом это довольно динамические данные, которые изменяются редко. Но не суть.

Перекладывать кэш полностью с бекенда на клиент имеет смысл только если у вас очень большое количество операций дублирующихся чтения в рамках одной сессии. Это верно не для всех систем.

Если во время одной сессии человек много работает с разными данными, то кеш на бекенде все так же нужен.
Если во время одной сессии человек мало работает с данными, то кеш на бекенде все так же нужен.

В описанных мною случаях отсутствие кеша на бекенде будет почти аналогично отсутствию кеша вообще.
Допустим я хочу посмотреть детали заказа. В классической системе это один запрос к бд и один запрос к серверу. В описанной вами схеме это N+1 запросов к бд и N+1 запросов к серверам. Соответственно количество данных, которые нужно кешировать увеличивается. Но память ограниченная. Значит кеш теперь может спасать меньшее количество запросов.


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

Но память ограниченная. Значит кеш теперь может спасать меньшее количество запросов.


Браузерный кэш на диске. И места там много.
Вы заоптимизировались под определенный путь навигации пользователя. Это очень хорошая оптимизация. Но она не будет и не может работать всегда. Это не решает проблему, хотя и очень сильно уменьшает её.

Откуда N+1? Обычно это 1+1.

В корзине/заказе обычно может быть больше одного товара. Поэтому N+1. Одна сущность + N связанных. Да, можно было бы реализовать балк-запрос на N связанных сущностей, но вылезут дополнительные трудности с кешом.

Балк-запрос я и имел в виду.


С кешом всегда трудности, с одной стороны, а, с другой, не особо он в кейсе корзины и нужен, если идти по пути 1+1 запросов.

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


Это почти ничего не стоит.
В сотни раз дешевле микросервисов.

Думаю, что все же испробовано.

распределенные кеши, репликация, шардирование не по логической структуре, денормализация для ускорения чтения


Не считается.
Ибо тут вы уже напрочь отходите от тех самых «легких и простых и дешевых» join с которых и начался наш разговор.
Это почти ничего не стоит.
В сотни раз дешевле микросервисов.

Думаю, что все же испробовано.

Вы смешной. Я вам говорю о том, что вижу с самого начала проекта. Это не какая-то сранная гипотетическая ситуация. Такие проекты реальны, я их видел.

Ибо тут вы уже напрочь отходите от тех самых «легких и простых и дешевых» join с которых и начался наш разговор.

Я не понимаю как распределенные кеши могут мешать делать join. Я не пониманию, как денормализация может мешать делать join. Шардирование — да, может, но количество таких ситуаций в идеале будет реже. Просто потому что разрез выбирается согласно данным, а не согласно фичам.
Я не понимаю как распределенные кеши могут мешать делать join. Я не пониманию, как денормализация может мешать делать join. Шардирование — да, может, но количество таких ситуаций в идеале будет реже.


При денормализации join не нужен. В этом и смысл денормализации.

Шардирование — мешает. Распределенный — кэш не мешает?
Поясните пожалуйста.
При денормализации join не нужен. В этом и смысл денормализации.

У вас же больше двух таблиц в бд. Вот здесь оптимизировали чтение, улучшилась общая отзывчивость бд. А вот здесь продолжаем использовать join.

Распределенный — кэш не мешает

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

Кеш есть, join есть. В чем проблема?
Кеш есть, join есть. В чем проблема?


В слове «распределенный»
Смотрите, есть какой-нибудь запрос: дай мне заказ со всеми товарами. Это один запрос к бд с использованием join.


join не нужен.
Вам нужен заказ — это (ID_товара, количество, сумма)
Сам товар — у нас уже в локальном кэше.
Напомните, а как вы инвалидируете локальный кэш?
В слове «распределенный»

Распишите, что с вашей точки зрения создает проблему.

Также заодно распишите почему браузерный кеш — ок, а распределенный кеш на бекенде — не ок. Реально интересно :-)
Я намекаю, что прежде чем оптимизировать БД вертикальным разрезанием надо хорошо подумать несколько раз.
(это даже не обсуждая, что 80% нагрузки будет от 20% микросервисов и оптимизировать так едва ли получится)

И да, внезапно бывает хорошо продуманная БД перестаёт удовлетворять требованиям. Не знаю при чем тут монолит.
… и тут вам в одном из сервисов надо(внезапно, естественно. И срочно!) сделать join данных с разных баз…


Ничего страшного. Огромные СУБД можно построить только как распределенные по множеству серверов.

Классический JOIN от реляционных баз данных — конечно же в такой ситуации себя показывает плохо. Поэтому подобные СУБД и не строятся как реляционные.
Вы же понимаете, что JOIN я там упомянул не как оператор SQL, а как некую тяжелую операцию над множествами?

Сможете ли вы сделать её через join в реляционной БД, или придумывать более экзотические решения — не существенно (а вот количество данных, прокачиваемых для этого через сеть — существенно).
Вы же понимаете, что JOIN я там упомянул не как оператор SQL, а как некую тяжелую операцию над множествами?


В том то и дело — что это ограничение не только реляционных СУБД.

Когда придумали концепцию «ура NoSQL лучше» выяснилось, что:

  1. NoSQL заведомо быстрее реляционных СУБД только пока нет join-подобных операций
  2. Сделать распределенную СУБД с полноценным ACID и высокой производительность — невозможно.


Пробовали, придумывали, но пока ничего не придуманно с быстрыми распределенными join.

Классические реляционные СУБД делают join быстрее почти всех. Но строго на одном компьютере.

Потому я и говорю, что в данном конкретном случае, когда речь идет о микросервисах,
то давайте не будем забывать, что все эти микросервисные заморочки мы терпим прежде всего из за прекрасной масштабируемости горизонтальной.

А join — плохо поддающаяся горизонтальной масштабируемости концепция.

Другими словами:
если у вас вся система (неважно, монолит она или микросервисная) дает нагрузку, которую может держать один сервер, то вы можете применять join без проблем.
Но — ровно до тех пор пока вам хватает одного сервера СУБД на вашу систему.

Как только у вас появляется нужда в горизонтальном масштабировании СУБД — от join придется или отказываться или строго ограничивать их использование.

Но изначально-то разговор об этом зашел почему?
Потому что я упомянул об одной из двух концепций в микросервисах — своя БД для каждого вида микросервисов.
Есть еще одна концепция — одна общая БД на все.
Что-то вы в кучу всё смешали, релиционное-nosql, распределенное-нераспределенное, ACID-BASE… Давайте теплое с мягким не путать.

> Сделать распределенную СУБД с полноценным ACID и высокой производительность — невозможно.

Этой новости минимум лет 20, так что она чуть постарше NoSQL.

> БД так же можно подробить — каждому виду микросервисов своя БД.

Я так понимаю, что это не про хорошее горизонтальное масштабирование. Это раньше у вас было 3 сервера с единой базой данных, а стало два с левой половинкой, и один с правой. Ну или было 300 типа одинаковых, а стало 200+100 — не суть.

> Классические реляционные СУБД делают join быстрее почти всех. Но строго на одном компьютере.

Раньше, пока вы не поделили инстансы БД по микросервисам, джойн левого с правым и работал бы на одном компьютере (любом из 300). То есть пока у нас база данных помещалась на одном компьютере, у нас проблемы с джойном не было вообще. Мы же микросервисы внедряем когда команда за столом перестает помещаться, а не БД на диске?

> прежде всего из за прекрасной масштабируемости горизонтальной.

Ну так ещё раз, было у вас 3 сервера и 3 инстанса БД. Вы выделили аутентификацию в отдельный микросервис, теперь у вас 3 сервера и до 6 инстансов БД. Что именно вы планируете выиграть от разделения БД при масштабировании, при том, что данные аутентификации занимают менее 1% ресурсов?
Ну так ещё раз, было у вас 3 сервера и 3 инстанса БД. Вы выделили аутентификацию в отдельный микросервис, теперь у вас 3 сервера и до 6 инстансов БД. Что именно вы планируете выиграть от разделения БД при масштабировании, при том, что данные аутентификации занимают менее 1% ресурсов?


Я выделил только один-единственный сервис для начала.
Чтобы выделить еще нужно хоть какой нибудь конкретный пример рассматривать.

Возьмем задачу интернет-магазина:

  • Так же легко и просто выделяется корзина.
  • И отдельно от корзины заказы товаров.
  • Статьи, которые многие сайты для SEO публикуют у себя.
  • Шлюз к платежной системе.
  • Уведомления по SMS
  • Уведомления по eMail
  • Каталог товара (без поиска), что потом прекрасно кэшируется на веб-клиенте — какой нибудь example.com/catalog/product_by_id_138 с использованием технологии etag, к примеру
  • Поиск по товару (да, да, да — БД не обязана отдавать найденную информацию, вполе достаточно, если она отдаст ID найденных товаров), ну поиск товара по ID будет уже простым, так как он уже закэширован на веб-клиенте.
  • Всевозможные нейросети для «рекомендации товаров» покупателю
  • Складской учет остатков
  • Мониторинги разного толка
  • и т.п.

Вы так отвечаете на вопрос «Что именно вы планируете выиграть от разделения БД»? Ответ, видимо «ничего, зато какая движуха была»© анекдот.

Для начала, у вас базу данных использует только 3 сервиса из перечисленного: учет, каталог и поиск. Кстати, а как вы производите поиск по каталогу товаров, если сам каталог в базе другого сервиса?
Вы так отвечаете на вопрос «Что именно вы планируете выиграть от разделения БД»? Ответ, видимо «ничего, зато какая движуха была»© анекдот.


От масштабов задачи зависит.
Для начала, у вас базу данных использует только 3 сервиса из перечисленного: учет, каталог и поиск. Кстати, а как вы производите поиск по каталогу товаров, если сам каталог в базе другого сервиса?


Я это описал уже.

Вариант А)

В полнотекстовом поиске/фильтрации — всего лишь ИД.
Сами элементы каталога там не обязательны.

То есть:
Ищите по слову «лабуда» с фильтром «цвет=зеленый».
В ответ вам возвращается: [123,778,345]

Обращаетесь к кэшу на веб-клиенте с целью получить что такое товары с кодами 123,778,345.
Если в кэше пусто — обращаетесь к каталогу и получаете что это за товары такие

Вариант Б)

Разве это не вы привели в качестве примера повышения производительности денормализацию?

Кто мешает держать в БД каждого сервиса свою копию списка товаров?
> Сами элементы каталога там не обязательны.

Давайте уточним:
каталог — это там где у нас привязка "[123,778,345] лежит в категории «валенки», так?
А карточку [123,778,345] мы уже из другого сервиса получаем?

> Ищите по слову «лабуда» с фильтром «цвет=зеленый».
> В ответ вам возвращается: [123,778,345]

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

> Разве это не вы привели в качестве примера повышения производительности денормализацию?

я?

> Кто мешает держать в БД каждого сервиса свою копию списка товаров?

Exactly.
То есть мы сначала поделим БД, а потом накостылим репликацию левой части в правую, что бы было удобно join делать? Напомните, а делили то зачем?
Давайте уточним:
каталог — это там где у нас привязка "[123,778,345] лежит в категории «валенки», так?


Это просто обобщенный список товара.

Вы можете получить этот список как содержимое группы валенки.
Вы можете получить ровно такой же список как содержимое ответа при поиске по названию товара.
И т.п.

А карточку [123,778,345] мы уже из другого сервиса получаем?


Да.

Для одного-единственного запроса это выглядит, согласен, странновато.

Но в реальности — никаких проблем производительности.

Так как типичное поведение пользователя — просматривать товары одной группы, заходить вновь и вновь, обдумываеть покупку, смотреть в корзину.

И там везде будет отображаться уже закэшированые названия товаров.

Ваш же вариант, когда нужно сразу отдавать пользователю полный результат иллюзорно эффективен.

При множестве запросов — у меня дешевле выходит.
То есть мы сначала поделим БД, а потом накостылим репликацию левой части в правую, что бы было удобно join делать? Напомните, а делили то зачем?


Ну если исключить эмоциональную окраску терминов — да.

Правда, я вам толкую за то, что join не нужен в данном случае. Его значение — преувеличено.

Вы рассуждаете шаблонно — видите только проблемы РОВНО ОДНОГО текущего запроса.

А ведь в реальности пользователи проводят на сайте много времени (ну по крайней мере так бы хотелось владельцам интернет-магазина). И на каждый чих ВНОВЬ и ВНОВЬ отдавать им все то же наименование товара — глупо и не эффективно с точки зрения производительности.

На каждый чих придется отдавать список ID товаров, так как затруднительно закэшировать все результаты поиска. Но список ID — это компактно и просто.

А получение полной информации из имеющегося ID — это уже из кэша.

Про денормализацию — это для другого моего оппонента приведено
Для nsinreal:
habrahabr.ru/company/piter/blog/348740/#comment_10662582
Сам бы я выбрал бы первый вариант.
> Так как типичное поведение пользователя — просматривать товары одной группы, заходить вновь и вновь, обдумываеть покупку, смотреть в корзину.

> И там везде будет отображаться уже закэшированые названия товаров.

И поэтому это можно и не обсуждать — нагрузку будет давать именно поиск.

> Ваш же вариант, когда нужно сразу отдавать пользователю полный результат иллюзорно эффективен.

Это не мой вариант, я с вами вообще про базу данных говорю. Не знаю зачем вы мне про взаимодействие с клиентом пытаетесь рассказать.

>> Напомните, а делили то зачем?
> Ну если исключить эмоциональную окраску терминов — да.

Ну, я так и понял.
Это не мой вариант, я с вами вообще про базу данных говорю. Не знаю зачем вы мне про взаимодействие с клиентом пытаетесь рассказать.


Вы рассматриваете задачу только с точки зрения базы данных. А не всей системы в целом.

О каких микросервисах можно говорить в таком случае?

Микросервисы — это как раз система грамотно разбитая на части.

Если вы хотите аргументировать что мне мешает отдавать данные кусочками из монолита — пожалуйста. Если нет — не понимаю почему взаимодействие с клиентом мне мешает грамотно делить(или не делить) систему на части.
Потому что я упомянул об одной из двух концепций в микросервисах — своя БД для каждого вида микросервисов.
Есть еще одна концепция — одна общая БД на все.

Есть ещё одна: своя БД для каждого микросервиса для записи и дергания по ключу и одна общая для чтения по всяким джойнам.

если не нужно, что бы была одна бд, одни данные. а чаще всего нужно.
если не нужно, что бы была одна бд, одни данные. а чаще всего нужно.


Конечно, нас система интересует только как единое целое.
И в этом смысле БД одна.

Но почему БД должна быть расположена строго на одном сервере?

Скажем, аутентификация пользователей и соответствующая БД — вполне безболезненно выносится отдельно во многих случаях.

Выносится, только репликацию делать придётся делать постоянно между базами. Всё это — усложнение. И, как в статье верно замечено, потенциальные точки отказа.
Такие же проблемы в Linux — множество сервисов, разные версии библиотек, слабо описанные API, история идёт по спирали, теперь и до web добралась.
Правильно приготовить микросервисы — относительно непросто. Нытье по этому поводу исходит от людей, которые, поддавшись хайпу, не рассчитали свои силы. Если это считать — безумием, оно закончится ровно тогда, когда основная масса хипстеров потрогает микросервисы и решит для себя, учиться дальше или забить.
Ещё вариант — не рассчитали способности админов/девопсов поддерживать сложную распределённую архитектуру.
А также нытье исходит от людей, которые пришли в проекты с микросервисным безумием имея достаточный бэкграунд, чтобы понять как легко ломается система
На самом деле, если вы работаете с сервисами, не сохраняющими состояния, лучше вообще не связываться с микросервисной конфигурацией и сразу попробовать бессервисную модель.


Кто может пояснить?
Что такое бессервисная модель?
Ошибка в переводе. В оригинале — serverless
Скорее всего это был перевод с serverless. Такие сервисы как например Amazon Lambda. В этом случае приложение является как бы функцией которая запускается по требованию.
Но как на этом написать ВСЮ систему?
Речь же об этом.
serverless актуален для различных облачных сред, где персистентное хранилище предоставляется как служба (тот же amazon dynamodb). Так что вполне можно разрабатывать только serverless код, а всю боль со stateless отдать на откуп провайдера. Я не думаю что многие разрабатывают по настоящему stateful приложения, которым очень нужен доступ к диску для корректной работы, обычно все ходят за данными во внешние сервисы (та же SQL/noSQL/kv база данных).

Вероятно serverless? По контексту именно оно. Azure Functions/Amazon Lambda

Спасибо за внимательность, поправили
У нас, например, примерно четверть кода занимает взаимодействие гуй <> сервис (имеется в виду сервис windows). После перехода на UniGUI отказались от разделения сервиса на части, обработка сильно упростилась и стабилизировалась.
До до, микросервисы это зло. Лепите все одним комом на ПиЭчПи ;)
сервисы\микросервисы — как дальнейшее развитие монолита…

со временем (не один год) кодовая база разрастается, нужно поддерживать текущие функции системы, создавать новые, приходят новые люди в компанию, новые технологии…

вынос функции\функций из большого блока (монолит) — и обращение через, пусть даже внутренний API не видимый миру — нормальная практика, и было это дело задолго до микросервисного хайпа…

оттого и проектировать изначально как микросервис — наверное глупо, разработка такого решение в разы сложнее, оттого дольше и дороже, а бизнес ждать не может.
Честно говоря, не понимаю почему столько копий ломается на эту тему. Не соглашусь с автором статьи что MSA это не про архитектуру — на мой взгляд вполне себе архитектурный стиль. Другое дело что это если взять тот же togaf, то этот стиль влияет прямо на 1 домен архитектуры предприятия.
В целом же прежде чем что-то менять и имплементировать, надо подумать зачем. Микросервисы это довольно дорого как по ресурсам железа, так и по людям. Спецов по классическому подходу гораздо больше, чем ребят, реально хорошо сделавших микросервисы в проме. Развернутый на 1 ноуте кластер кубера с 2-3 тестовыми сервисами не в счет :)
Да, с развитием контейнеризации и оркестрации сделать правильный msa стало более реально. Но всегда перед тем как что-то делать надо задать себе вопрос «в чем профит?». Правильных ответов на мой взгляд 2: «Без msa вот прям никак не будет работать» и «так дешевле. Я все-все просчитал и так дешевле». В остальных случаях вы должны понимать что скорее всего реализуете свои амбиции и жажду знаний за счет работодателя.

В чём выражается "довольно дорого по ресурсам железа"? Один из плюсов (микро)сервисов — экономия на железе при прочих равных, даже если не брать гибкие скейлинги в облаках.


По людям тоже спорно. На разработку большинства микросервисов (не архитектуры, самих сервисов) можно как раз брать менее квалифицированных спецов — они архитектурно не смогут нарушить изоляцию модуля, с одной стороны, а, с другой, для некритических частей можно брать более дешевый стек в целом. Грубо, не писать всё приложении на C++ с ассемблерными вставками из-за того, что один модуль очень требователен к производительности, f только этот модуль на нём, а остальное на PHP :)

Один из плюсов (микро)сервисов — экономия на железе при прочих равных, даже если не брать гибкие скейлинги в облаках.

На мой взгляд, все же больше. Помимо резервирования мощности для скейлинга, там еще реализация интеграционной обвязки, превращение stateful в стейтлесс, да и сама оркестрация и непростой мониторинг и аудит.
По людям тоже спорно. На разработку большинства микросервисов (не архитектуры, самих сервисов) можно как раз брать менее квалифицированных спецов — они архитектурно не смогут нарушить изоляцию модуля, с одной стороны, а, с другой, для некритических частей можно брать более дешевый стек в целом. Грубо, не писать всё приложении на C++ с ассемблерными вставками из-за того, что один модуль очень требователен к производительности, f только этот модуль на нём, а остальное на PHP :)

Тут скорее история про опыт людей работы в командах изолированных сервисах и их «софт скиллз». Если вы возьмете команду монолита и рассадите их по модулям, то первый же релиз скорее всего будет ужасен. Взаимное возлагание вины за баги, непонимание общей картины как оно должно работать. «С моей стороны пуля вылетела...».
Sign up to leave a comment.