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

Пользователь

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


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


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

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

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

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

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

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

Про денормализацию — это для другого моего оппонента приведено
Для nsinreal:
habrahabr.ru/company/piter/blog/348740/#comment_10662582
Сам бы я выбрал бы первый вариант.
Давайте уточним:
каталог — это там где у нас привязка "[123,778,345] лежит в категории «валенки», так?


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

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

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


Да.

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

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

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

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

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

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


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

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


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

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

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

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


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


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


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

Вариант А)

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

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

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

Вариант Б)

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

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


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

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

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

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


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

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

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


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


Э… нет.

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

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

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

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

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

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

4. Фронтенд.

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

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

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

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

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

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

И тут деление на сервисы позволит легко отмасштабироваться по мере роста посетителей.
Вы же понимаете, что JOIN я там упомянул не как оператор SQL, а как некую тяжелую операцию над множествами?


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

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

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


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

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

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

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

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

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

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


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

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

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

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


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

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

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

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


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

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


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

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


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


Проследите нить разговора чуть выше.
если не нужно, что бы была одна бд, одни данные. а чаще всего нужно.


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

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

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

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


Внезапно?
Вы намекаете на то, что монолит прощает плохо продуманную БД?
Но как на этом написать ВСЮ систему?
Речь же об этом.
выходить с инициативами к руководителю, не опасаясь за свою зарплату


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

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

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


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


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

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

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность