Фильтр Блума
https://en.wikipedia.org/wiki/Bloom_filter
Задача - есть база данных, которая хранит пользовательские заказы. В интерфейсе пользователю нужно отображать его заказы.
Допустим, пользователей у нас такое количество, что база перестает справляться с таким потоком запросов. В одной из прошлых записей я описывал механизм кэширования, но давайте представим, что заказов у нас так много, что они перестают эффективно помещаться в этот кэш.
Можно воспользоваться Блум-фильтром.
Создадим в сервисе хэш-таблицу фиксированного размера и заполним ее ключами пользователей, у которых есть активные заказы. Будем для каждого пользователя перед походом в базу данных проверять - есть ли его идентификатор в этой хэш-таблице.
Но ведь будут коллизии, следовательно, ложные срабатывания? - спросите вы и будете правы. Однако, в данной задаче ложные срабатывания не приведут к проблемам.
Когда мы находим совпадение в хэш-таблице - мы все равно идем в базу данных за заказами. Если их там не окажется (по причине коллизии в хэштаблице), мы возвратим пользователю пустой список.
Однако, мы исключим большое количество пользователей, которых в этой таблице точно нет.
Размеры такой хэш-таблицы можно подобрать исходя из ваших требований и ограничений.
https://en.wikipedia.org/wiki/Bloom_filter
#algo #doc #wiki #practices #ru
https://en.wikipedia.org/wiki/Bloom_filter
Задача - есть база данных, которая хранит пользовательские заказы. В интерфейсе пользователю нужно отображать его заказы.
Допустим, пользователей у нас такое количество, что база перестает справляться с таким потоком запросов. В одной из прошлых записей я описывал механизм кэширования, но давайте представим, что заказов у нас так много, что они перестают эффективно помещаться в этот кэш.
Можно воспользоваться Блум-фильтром.
Создадим в сервисе хэш-таблицу фиксированного размера и заполним ее ключами пользователей, у которых есть активные заказы. Будем для каждого пользователя перед походом в базу данных проверять - есть ли его идентификатор в этой хэш-таблице.
Но ведь будут коллизии, следовательно, ложные срабатывания? - спросите вы и будете правы. Однако, в данной задаче ложные срабатывания не приведут к проблемам.
Когда мы находим совпадение в хэш-таблице - мы все равно идем в базу данных за заказами. Если их там не окажется (по причине коллизии в хэштаблице), мы возвратим пользователю пустой список.
Однако, мы исключим большое количество пользователей, которых в этой таблице точно нет.
Размеры такой хэш-таблицы можно подобрать исходя из ваших требований и ограничений.
https://en.wikipedia.org/wiki/Bloom_filter
#algo #doc #wiki #practices #ru
Вы проектируете Netflix с нуля. Нужно сделать сервис, который будет отдавать пользователю рекомендуемые фильмы на главной.
Начальный DAU — 1 000 000, через год — 100 000 000.
Какой запас прочности в rps вы обеспечите на старте для этого сервиса?
Начальный DAU — 1 000 000, через год — 100 000 000.
Какой запас прочности в rps вы обеспечите на старте для этого сервиса?
Anonymous Poll
5%
100 rps
14%
500 rps
25%
1000 rps
12%
2000 rps
10%
5000 rps
21%
10000 rps
1%
15000 rps
4%
20000 rps
3%
30000 rps
5%
50000 rps
Стратегия обработки ошибок Circuit Breaker pattern.
https://medium.com/@kirill.sereda/стратегии-обработки-ошибок-circuit-breaker-pattern-650232944e37
В архитектуре, в которой есть межсервсисное взаимодействие, стоит иметь в виду, что какие-то запросы будут заканчиваться неудачей (проблемы с сетью, сегфолты, баги, итд).
На помощь обычно приходит классическое решение - ретраи, т.е. перезапросы к недоступному ресурсу в надежде с какой-то попытки добиться ответа (есть еще вариант с параллельной отправкой запросов в надежде дождаться ответа хоть одного, но он обычно дороже).
У ретраев есть одна проблема - при недоступности сервиса можно собрать лавину накопившихся запросов, которые сервис не будет в состоянии переварить при поднятии, они будут обрываться клиентом по таймауту и все повторяться по-новой, не давай возможности начать работать.
Одним из способов решения этой проблемы служит имплементация circuit breaker. Паттерн подразумевает "умное" управление перезапросами. Вместо того, чтобы каждый раз делать запрос в недоступный сервис, подсчитывается общая статистика отказов в скользящем окне, из которой можно будет понять - а стоит ли пытаться делать запрос (или перезапрос) в этот сервис, или в этот раз стоит деградировать эту функциональность.
Одна из самых известных имплементаций этого паттерна, которую можно изучить - это реализация компании Netflix Hystrix (btw: которую компания перестала разрабатывать).
https://medium.com/@kirill.sereda/стратегии-обработки-ошибок-circuit-breaker-pattern-650232944e37
#algo #doc #medium #pattern #practices #ru
https://medium.com/@kirill.sereda/стратегии-обработки-ошибок-circuit-breaker-pattern-650232944e37
В архитектуре, в которой есть межсервсисное взаимодействие, стоит иметь в виду, что какие-то запросы будут заканчиваться неудачей (проблемы с сетью, сегфолты, баги, итд).
На помощь обычно приходит классическое решение - ретраи, т.е. перезапросы к недоступному ресурсу в надежде с какой-то попытки добиться ответа (есть еще вариант с параллельной отправкой запросов в надежде дождаться ответа хоть одного, но он обычно дороже).
У ретраев есть одна проблема - при недоступности сервиса можно собрать лавину накопившихся запросов, которые сервис не будет в состоянии переварить при поднятии, они будут обрываться клиентом по таймауту и все повторяться по-новой, не давай возможности начать работать.
Одним из способов решения этой проблемы служит имплементация circuit breaker. Паттерн подразумевает "умное" управление перезапросами. Вместо того, чтобы каждый раз делать запрос в недоступный сервис, подсчитывается общая статистика отказов в скользящем окне, из которой можно будет понять - а стоит ли пытаться делать запрос (или перезапрос) в этот сервис, или в этот раз стоит деградировать эту функциональность.
Одна из самых известных имплементаций этого паттерна, которую можно изучить - это реализация компании Netflix Hystrix (btw: которую компания перестала разрабатывать).
https://medium.com/@kirill.sereda/стратегии-обработки-ошибок-circuit-breaker-pattern-650232944e37
#algo #doc #medium #pattern #practices #ru
Medium
Стратегии обработки ошибок: Circuit Breaker pattern
Сегодня хочу рассмотреть такие понятия, как микросервисы, возможные стратегии обработки и остановиться на паттерне Circuit Breaker.
Микросервисная архитектура хедж-фонда с нуля
Architecting Hedge Fund Microservices From Scratch
https://medium.com/@robertmaidla/designing-hedge-fund-microservices-from-scratch-c370e2fda4c8
#article #medium #microservices #practices #en
Architecting Hedge Fund Microservices From Scratch
https://medium.com/@robertmaidla/designing-hedge-fund-microservices-from-scratch-c370e2fda4c8
#article #medium #microservices #practices #en
Medium
Architecting Hedge Fund Microservices From Scratch
Part 1 — a journey from an idea to production
Materialized View Pattern
Давайте возьмем за пример такую задачу - в мобильном приложении нужно отображать топ-100 пользователей за последние 24 часа по количеству какой-то активности.
Пользователи хранятся в одной базе, активность хранится в другой базе (отсортированные в последовательности их создания).
Решение в лоб - на запрос топ-100 пользователей сделать запрос а базу за всей активностью за 24 часа, построить топ, сходить в базу данных пользователей (чтобы достать ники пользователей), закэшировать этот ответ и отдавать его, в том числе, другим пользователям какое-то время.
Какие есть проблемы:
- запросы в активность мимо кэша могут быть очень тяжелые - пользователи будут ждать
- когда кэш пустой у вас могут быть много одновременно пользователей, попавших мимо кэша и пытающихся одновременно построить топ и нагружать базы
Materialized View pattern подразумевает создание "виртуального" представления данных, которе будет эффективно работать для получение нужной информации:
Можем каждые несколько минут (по какому-нибудь крону) строить топ-100 пользователей за последние 24 часа, будем также получать всю нужную информацию о пользователях и из всего этого создавать новую View, например, в in-memory базе данных. Это и будет наш materialized view. На запросы пользователей на топ-100 мы просто будем быстро отдавать уже подготовленные данные.
https://docs.microsoft.com/ru-ru/azure/architecture/patterns/materialized-view
http://www.jeisystems.co.uk/tech-blog/programming-blog/materialized-view-pattern/
#pattern #practices #doc #ru #en
Давайте возьмем за пример такую задачу - в мобильном приложении нужно отображать топ-100 пользователей за последние 24 часа по количеству какой-то активности.
Пользователи хранятся в одной базе, активность хранится в другой базе (отсортированные в последовательности их создания).
Решение в лоб - на запрос топ-100 пользователей сделать запрос а базу за всей активностью за 24 часа, построить топ, сходить в базу данных пользователей (чтобы достать ники пользователей), закэшировать этот ответ и отдавать его, в том числе, другим пользователям какое-то время.
Какие есть проблемы:
- запросы в активность мимо кэша могут быть очень тяжелые - пользователи будут ждать
- когда кэш пустой у вас могут быть много одновременно пользователей, попавших мимо кэша и пытающихся одновременно построить топ и нагружать базы
Materialized View pattern подразумевает создание "виртуального" представления данных, которе будет эффективно работать для получение нужной информации:
Можем каждые несколько минут (по какому-нибудь крону) строить топ-100 пользователей за последние 24 часа, будем также получать всю нужную информацию о пользователях и из всего этого создавать новую View, например, в in-memory базе данных. Это и будет наш materialized view. На запросы пользователей на топ-100 мы просто будем быстро отдавать уже подготовленные данные.
https://docs.microsoft.com/ru-ru/azure/architecture/patterns/materialized-view
http://www.jeisystems.co.uk/tech-blog/programming-blog/materialized-view-pattern/
#pattern #practices #doc #ru #en
Docs
Шаблон материализованного представления - Azure Architecture Center
Создание предварительно заполненных представлений на основе данных из одного или нескольких хранилищ данных, когда данные не отформатированы для требуемых операций запросов.
Учения
Обычно написание кода подразумевает обработку ошибок. Тут запрос вернул 500, и мы подставили дефолтное значение; там ошибка при попытке записать на диск, и мы показали пользователю сообщение итд.
Код обработки ошибок, как и любой другой код, имеет свойство ломаться и устаревать, если он не работает. Я часто встречаюсь с тем, что код, который должен был спокойно обрабатывать ошибку приводит к каким-нибудь сегфолтам. При каких-то минорных неполадках в системе, которые должны легко парироваться, может прилечь весь бизнес.
Конечно, отличным решением может быть покрытие тестами вроде: если сервис А отвечает Б, то должно происходить В. Но если ресурсов на имплементацию таких вещей нет, то можно обойтись минимумом - учения.
Учения в этом случае - ручные тесткейсы интеграционного тестирования, которые можно провести прям на продакшн сервисе с целью понять, что ваша обработка ошибок работает так, как должна.
Что можно сделать и что проверяем:
— Гасить отдельные сервисы
проверяем: что пользователи этих сервисов умеют работать без них (graceful degradation)
— Гасить часть машин, отдельные ДЦ
проверяем: что сервис продолжает жить при таких вещах, как выход из строя оборудования (например, пожар), что остальные машины справляются с возросшей нагрузкой
— Отключать функциональность
проверяем: что функциональность, которая должна быть отключаемой - остается отключаемой.
#reliability #practices #ru
Обычно написание кода подразумевает обработку ошибок. Тут запрос вернул 500, и мы подставили дефолтное значение; там ошибка при попытке записать на диск, и мы показали пользователю сообщение итд.
Код обработки ошибок, как и любой другой код, имеет свойство ломаться и устаревать, если он не работает. Я часто встречаюсь с тем, что код, который должен был спокойно обрабатывать ошибку приводит к каким-нибудь сегфолтам. При каких-то минорных неполадках в системе, которые должны легко парироваться, может прилечь весь бизнес.
Конечно, отличным решением может быть покрытие тестами вроде: если сервис А отвечает Б, то должно происходить В. Но если ресурсов на имплементацию таких вещей нет, то можно обойтись минимумом - учения.
Учения в этом случае - ручные тесткейсы интеграционного тестирования, которые можно провести прям на продакшн сервисе с целью понять, что ваша обработка ошибок работает так, как должна.
Что можно сделать и что проверяем:
— Гасить отдельные сервисы
проверяем: что пользователи этих сервисов умеют работать без них (graceful degradation)
— Гасить часть машин, отдельные ДЦ
проверяем: что сервис продолжает жить при таких вещах, как выход из строя оборудования (например, пожар), что остальные машины справляются с возросшей нагрузкой
— Отключать функциональность
проверяем: что функциональность, которая должна быть отключаемой - остается отключаемой.
#reliability #practices #ru
Consistent hashing
Когда наступает пара масштабироваться, встает вопрос "как" делить пользовательские запросы между несколькими инстансами. Если у вас stateless сервисы, то от запроса к запросу одного и того же пользователя можно направлять на разные инстансы - никаких проблем нет.
Проблемы появляются, когда у вас есть какой-то state (например, кэш авторизаций пользователей). Ну ничего, можно приземлить пользователей на какой-то один инстанс, если взять его id по модулю количества этих инстансов (instance_id = user_id % instances_count - 1).
Но что, если вам требуется добавить один новый инстанс? Если мы оставим нашу формулу, то большинство клиентов сменит инстанс, что приведет к потере state (и, например, валу перезапросов на сервис авторизации).
Особый вид хэширования Consistent hashing служит для того, чтобы бОльшая часть пользователей (будут переназначены только user_id_count/instances_count ключей) осталась "жить" на том же инстансе при добавлении нового.
В статье объясняется принцип его работы с картинками на основе кольцевого массива.
https://medium.com/better-programming/load-balancers-and-consistent-hashing-in-6-minutes-b5fc460aea4e
#practices #medium #en
Когда наступает пара масштабироваться, встает вопрос "как" делить пользовательские запросы между несколькими инстансами. Если у вас stateless сервисы, то от запроса к запросу одного и того же пользователя можно направлять на разные инстансы - никаких проблем нет.
Проблемы появляются, когда у вас есть какой-то state (например, кэш авторизаций пользователей). Ну ничего, можно приземлить пользователей на какой-то один инстанс, если взять его id по модулю количества этих инстансов (instance_id = user_id % instances_count - 1).
Но что, если вам требуется добавить один новый инстанс? Если мы оставим нашу формулу, то большинство клиентов сменит инстанс, что приведет к потере state (и, например, валу перезапросов на сервис авторизации).
Особый вид хэширования Consistent hashing служит для того, чтобы бОльшая часть пользователей (будут переназначены только user_id_count/instances_count ключей) осталась "жить" на том же инстансе при добавлении нового.
В статье объясняется принцип его работы с картинками на основе кольцевого массива.
https://medium.com/better-programming/load-balancers-and-consistent-hashing-in-6-minutes-b5fc460aea4e
#practices #medium #en
Medium
How Consistent Hashing Is Used by Load Balancers to Distribute Requests
Load balancers and consistent hashing in six minutes
Forwarded from Teamlead Good Reads – ежедневные советы про менеджмент людей и команд (Andrey Gomenyuk) via @like
Полагаю, все здесь знают, что такое 1-1 (или one on one, 1:1, один-один, тет-а-тет). Я считаю, что этот формат общения — один из самых важных инструментов в рукаве тимлида/руководителя, но очень недооценен. Про него обе сегодняшние статьи.
Мне 1:1 довольно долго не заходил, пока я где-то не наткнулся на хороший материал про этот формат (к сожалению, найти его уже не могу). Основная идея в том, что он предназначен не для получения статуса по задачам от подчиненного, а для обсуждения успехов, неудач, планов и т.д. Если сделать 1:1 откровенными, честными, открытыми, то можно будет узнавать о людях очень много такого, чего в обычной обстановке они бы не рассказали: свои взгляды на карьеру, чего хочется, что не нравится. Вам, как руководителю, остается только использовать эту информацию для роста человека и предотвращения кризисов. Статья уровня “сейчас я научу вас жизни”, но в ней есть интересные мысли. https://medium.com/@zackbloom/youre-doing-one-on-ones-wrong-dfc27f36f204
Наверное, не сильно ошибусь, если скажу, что большинство тимлидов и руководителей на этом канале так или иначе вышли из разработки/тестирования/администрирования, в общем, люди с техническим бэкграундом. По своему опыту, таким людям не всегда легко дается открытое общение с начальством/подчиненными. Следующая статья как раз про то, что хорошие 1:1 получаются тогда, когда вам “неловко”: вы перешагиваете через себя и рассказываете о своих мыслях, мечтах, планах, неудачах. В статье есть примеры вопросов/тем, которые подталкивают к открытому общению. https://medium.com/@mrabkin/the-art-of-the-awkward-1-1-f4e1dcbd1c5c (есть вторая часть про то, как получать честный фидбек о себе — тоже рекомендую).
От себя хочу добавить, что большинство менеджерских инструментов, включая 1:1, можно применять снизу вверх. Если вы считаете, что 1:1 с вашим руководителем могут проходить эффективнее, сами предложите поменять формат. Если вы видите, что вашему руководителю не о чем с вами поговорить, заведите разговор сами, например, расскажите, каким вы видите свой рост, как вы развиваетесь, спросите совета по застрявшим проектам/задачам и т.д.
А вы считаете 1:1 полезными? (Отвечайте отрицательно, если не проводите/с вами не проводят).
Мне 1:1 довольно долго не заходил, пока я где-то не наткнулся на хороший материал про этот формат (к сожалению, найти его уже не могу). Основная идея в том, что он предназначен не для получения статуса по задачам от подчиненного, а для обсуждения успехов, неудач, планов и т.д. Если сделать 1:1 откровенными, честными, открытыми, то можно будет узнавать о людях очень много такого, чего в обычной обстановке они бы не рассказали: свои взгляды на карьеру, чего хочется, что не нравится. Вам, как руководителю, остается только использовать эту информацию для роста человека и предотвращения кризисов. Статья уровня “сейчас я научу вас жизни”, но в ней есть интересные мысли. https://medium.com/@zackbloom/youre-doing-one-on-ones-wrong-dfc27f36f204
Наверное, не сильно ошибусь, если скажу, что большинство тимлидов и руководителей на этом канале так или иначе вышли из разработки/тестирования/администрирования, в общем, люди с техническим бэкграундом. По своему опыту, таким людям не всегда легко дается открытое общение с начальством/подчиненными. Следующая статья как раз про то, что хорошие 1:1 получаются тогда, когда вам “неловко”: вы перешагиваете через себя и рассказываете о своих мыслях, мечтах, планах, неудачах. В статье есть примеры вопросов/тем, которые подталкивают к открытому общению. https://medium.com/@mrabkin/the-art-of-the-awkward-1-1-f4e1dcbd1c5c (есть вторая часть про то, как получать честный фидбек о себе — тоже рекомендую).
От себя хочу добавить, что большинство менеджерских инструментов, включая 1:1, можно применять снизу вверх. Если вы считаете, что 1:1 с вашим руководителем могут проходить эффективнее, сами предложите поменять формат. Если вы видите, что вашему руководителю не о чем с вами поговорить, заведите разговор сами, например, расскажите, каким вы видите свой рост, как вы развиваетесь, спросите совета по застрявшим проектам/задачам и т.д.
А вы считаете 1:1 полезными? (Отвечайте отрицательно, если не проводите/с вами не проводят).
Medium
You’re Doing One-on-Ones Wrong
One-on-ones are a common management tool where you have a (wait for it) one on one meeting with a direct report who works with you. Like…
Saga Pattern
Большую головную боль в микросервисной архитектуре приносит с собой вопрос - как добиться согласованных изменений в нескольких микросервисах?
Паттерн Сага пытается решить этот вопрос. Он подразумевает, что каждый сервис выполняет транзакции (по ACID принципам) в той зоне, за которую он ответственен. Также сервис должен поддерживать компенсационную транзакцию, которая будет откатывать изменения, если что-то пошло не так.
Набор таких транзакций и есть "сага".
Есть два способа того, как вести сагу, отличающиеся тем, кто в схеме оркестрирует изменениями:
- Choreography, где каждый сервис сам тригерит следующую транзакцию
- Orchestration, при которой есть один общий оркестратор, который берет на себя ответственность за последовательность саги
https://microservices.io/patterns/data/saga.html
UPD: из чата посоветовали еще несколько полезных материалов по теме:
#en - https://medium.com/swlh/microservices-architecture-what-is-saga-pattern-and-how-important-is-it-55f56cfedd6b
#ru - https://habr.com/en/company/avito/blog/426101/
#en - https://speakerdeck.com/caitiem20/distributed-sagas-a-protocol-for-coordinating-microservices
#ru - https://habr.com/en/company/oleg-bunin/blog/418235/
#pattern #microservices #practices #doc #en #ru
Большую головную боль в микросервисной архитектуре приносит с собой вопрос - как добиться согласованных изменений в нескольких микросервисах?
Паттерн Сага пытается решить этот вопрос. Он подразумевает, что каждый сервис выполняет транзакции (по ACID принципам) в той зоне, за которую он ответственен. Также сервис должен поддерживать компенсационную транзакцию, которая будет откатывать изменения, если что-то пошло не так.
Набор таких транзакций и есть "сага".
Есть два способа того, как вести сагу, отличающиеся тем, кто в схеме оркестрирует изменениями:
- Choreography, где каждый сервис сам тригерит следующую транзакцию
- Orchestration, при которой есть один общий оркестратор, который берет на себя ответственность за последовательность саги
https://microservices.io/patterns/data/saga.html
UPD: из чата посоветовали еще несколько полезных материалов по теме:
#en - https://medium.com/swlh/microservices-architecture-what-is-saga-pattern-and-how-important-is-it-55f56cfedd6b
#ru - https://habr.com/en/company/avito/blog/426101/
#en - https://speakerdeck.com/caitiem20/distributed-sagas-a-protocol-for-coordinating-microservices
#ru - https://habr.com/en/company/oleg-bunin/blog/418235/
#pattern #microservices #practices #doc #en #ru
microservices.io
Microservices Pattern: Pattern: Saga
Implement transactions using a saga, which is sequence of local transactions
Graceful degradation
Должна ли какая-то функциональность ломать весь сервис? — Заданный таким образом вопрос, конечно же, получит ответ "нет".
А что, если сломается какая-то core функциональность? Например, в вашем сервисе пользователь получает какую-то услугу за деньги и ломается модуль, отвечающий за оплату. Отдавать пользователю при этом его покупку?
И, конечно, ответ на вопрос зависит от бизнес требований, но я бы сказал, что в большинстве случаев — ответ такой же — нет.
В случае, когда есть выбор — сломаться совсем или сделать хоть что-то (если это не приведет, конечно, к неконсистентному состоянию) почти всегда нужно выбирать сделать хоть что-то.
В такой парадигме мышления, любой сервис должен быть построен таким образом, чтобы без проблем отстреливалась любая функциональность.
Я где-то прочитал хороший пример, попробую воспроизвести:
Если вы показываете персонализированный топ фильмов пользователю и ...
... у вас отвалились персональные рекомендации — просто показывайте фильмы, которые пользователь еще не смотрел
... у вас отвалились пользователи — просто показывайте общий топ
... у вас сломалось совсем все — показывайте какой-нибудь статичный файл со списком фильмов
Сегодня доклад моего коллеги про Graceful degradation
https://habr.com/en/company/yandex/blog/438606/
#practices #speech #habr #ru
Должна ли какая-то функциональность ломать весь сервис? — Заданный таким образом вопрос, конечно же, получит ответ "нет".
А что, если сломается какая-то core функциональность? Например, в вашем сервисе пользователь получает какую-то услугу за деньги и ломается модуль, отвечающий за оплату. Отдавать пользователю при этом его покупку?
И, конечно, ответ на вопрос зависит от бизнес требований, но я бы сказал, что в большинстве случаев — ответ такой же — нет.
В случае, когда есть выбор — сломаться совсем или сделать хоть что-то (если это не приведет, конечно, к неконсистентному состоянию) почти всегда нужно выбирать сделать хоть что-то.
В такой парадигме мышления, любой сервис должен быть построен таким образом, чтобы без проблем отстреливалась любая функциональность.
Я где-то прочитал хороший пример, попробую воспроизвести:
Если вы показываете персонализированный топ фильмов пользователю и ...
... у вас отвалились персональные рекомендации — просто показывайте фильмы, которые пользователь еще не смотрел
... у вас отвалились пользователи — просто показывайте общий топ
... у вас сломалось совсем все — показывайте какой-нибудь статичный файл со списком фильмов
Сегодня доклад моего коллеги про Graceful degradation
https://habr.com/en/company/yandex/blog/438606/
#practices #speech #habr #ru
Habr
Graceful degradation. Доклад Яндекс.Такси
Сервисы необходимо писать так, чтобы минимальная функциональность сохранялась всегда — даже если откажут критически важные компоненты. Илья Сидоров, руководитель одной из команд продуктовой разработки...
Monolith to Event-Driven Microservices with Apache Kafka
Сегодняшняя статья интересна тем, что рассказывает не о том, как нужно строить правильную микросервисную архитектуру с самого начала, а о том, что, собственно, можно делать с такой штукой, как разросшийся монолит.
В статье с помощью последовательного применения кучки умных паттернов рассматривается метод преобразования монолита к микросервисной архитектуре, где в центре всей концепции находится хранилище событий вашей системы.
https://medium.com/swlh/monolith-to-event-driven-microservices-with-apache-kafka-6e4abe171cbb
#monolith #pattern #microservices #practices #en
Сегодняшняя статья интересна тем, что рассказывает не о том, как нужно строить правильную микросервисную архитектуру с самого начала, а о том, что, собственно, можно делать с такой штукой, как разросшийся монолит.
В статье с помощью последовательного применения кучки умных паттернов рассматривается метод преобразования монолита к микросервисной архитектуре, где в центре всей концепции находится хранилище событий вашей системы.
https://medium.com/swlh/monolith-to-event-driven-microservices-with-apache-kafka-6e4abe171cbb
#monolith #pattern #microservices #practices #en
Medium
Monolith to Event-Driven Microservices with Apache Kafka
Event-Driven Architecture refer to rather old concept of Software Engineering that gained a lot of relevancy recently due to the need for…
Ретроспектива
После окончания большого проекта правильно устраивать ретроспективу. Ретроспектива — попытка порефлексировать на тему того, что было сделано хорошо, что можно было бы сделать лучше и нагенерировать какие-то экшн-поинты на будущее. На какой-то конференции я слышал выражение "без рефлексии нет развития". По-моему, это подходит как для личности, так и для команды.
В статьях выделены плюсы проведения ретроспективы. Она помогает:
— увидеть необходимость постоянных улучшений в работе
— замотивировать участников на достижение будущих целей
— перенимать знания
— развивать участников команды
— управлять улучшениями и изменениями
— управлять знаниями, пополнять их
— повышать уровень сотрудников
https://donskih.ru/2016/09/retrospektiva-proekta/
https://tproger.ru/blogs/retrospective-analysis/
#practices #people #ru
После окончания большого проекта правильно устраивать ретроспективу. Ретроспектива — попытка порефлексировать на тему того, что было сделано хорошо, что можно было бы сделать лучше и нагенерировать какие-то экшн-поинты на будущее. На какой-то конференции я слышал выражение "без рефлексии нет развития". По-моему, это подходит как для личности, так и для команды.
В статьях выделены плюсы проведения ретроспективы. Она помогает:
— увидеть необходимость постоянных улучшений в работе
— замотивировать участников на достижение будущих целей
— перенимать знания
— развивать участников команды
— управлять улучшениями и изменениями
— управлять знаниями, пополнять их
— повышать уровень сотрудников
https://donskih.ru/2016/09/retrospektiva-proekta/
https://tproger.ru/blogs/retrospective-analysis/
#practices #people #ru
Консалтинговая группа Донских
Ретроспектива проекта
Ретроспектива проекта - собрание, встреча команды после завершения какого-либо проекта для того, чтобы подвести итоги, поделиться полученным опытом и составить планы на будущее. Это всегда очень важный шаг для развития компании, который направлен на повышении…
Microservices: don’t use them yet!
Микросервисы: пока не используйте их!
От теории к практике. В статье рассказывается про занимательный опыт быстрого роста проекта и команды. Автор делится своими выводами, полученными опытным путем:
— Количество микросервисов должно быть меньше, чем количество разработчиков
— Методы сервиса теперь обязательно должны иметь REST api и валидации
— Переключения контекста реально дороги
— Монорепозиторий - серебряная пуля
https://medium.com/teamzerolabs/micro-services-dont-use-them-yet-f58a2758d8f9
#monolith #microservices #practices #en
Микросервисы: пока не используйте их!
От теории к практике. В статье рассказывается про занимательный опыт быстрого роста проекта и команды. Автор делится своими выводами, полученными опытным путем:
— Количество микросервисов должно быть меньше, чем количество разработчиков
— Методы сервиса теперь обязательно должны иметь REST api и валидации
— Переключения контекста реально дороги
— Монорепозиторий - серебряная пуля
https://medium.com/teamzerolabs/micro-services-dont-use-them-yet-f58a2758d8f9
#monolith #microservices #practices #en
Medium
Microservices: don’t use them yet!
10 reasons to reconsider using microservices
Шардирование по географии - скорее всего, плохое решение для вас.
Достигая какой-то критической массы нагрузки своего сервиса, вы приходите к шардированию - осмысленному разделению обработки данных (для примера, клиентских запросов) по несвязанным кластерам.
Одна из самых простых вещей, которая приходит в голову - это разделить пользователей по географии, например, по городам: пользователи из города N будут всегда обрабатываться на кластере 1, пользователи из города M будут всегда будут приходить на кластер 2.
Но за простотой реализации такого подхода стоит достаточно сложная оркестрация (и, даже, жонглирование) нагрузки. У вас есть 2 кластера: на одном отправляются запросы из города N, на другой - из города M, нужно держать в голове:
— В какой кластер добавлять запросы из третьего нового города
— Что делать, если границы города N сильно меняются и этот кластер уже не выдерживает
— Как перераспределять ресурсы, если какой-то город выключается
Хотя преимущества тоже есть:
— Проблемы в кластере, который обрабатывает один набор городов не влияют на остальные
— Если вынос какого-то города подразумевает уменьшение требуемых на обработку ресурсов (например, если вы делаете роутинг и вам нужно держать в памяти граф. Географическое разделение поможет сэкономить ресурсы)
По теме шардирования, можно почитать неплохой доклад с конференции HighLoad:
https://habr.com/en/company/oleg-bunin/blog/433370/
Достигая какой-то критической массы нагрузки своего сервиса, вы приходите к шардированию - осмысленному разделению обработки данных (для примера, клиентских запросов) по несвязанным кластерам.
Одна из самых простых вещей, которая приходит в голову - это разделить пользователей по географии, например, по городам: пользователи из города N будут всегда обрабатываться на кластере 1, пользователи из города M будут всегда будут приходить на кластер 2.
Но за простотой реализации такого подхода стоит достаточно сложная оркестрация (и, даже, жонглирование) нагрузки. У вас есть 2 кластера: на одном отправляются запросы из города N, на другой - из города M, нужно держать в голове:
— В какой кластер добавлять запросы из третьего нового города
— Что делать, если границы города N сильно меняются и этот кластер уже не выдерживает
— Как перераспределять ресурсы, если какой-то город выключается
Хотя преимущества тоже есть:
— Проблемы в кластере, который обрабатывает один набор городов не влияют на остальные
— Если вынос какого-то города подразумевает уменьшение требуемых на обработку ресурсов (например, если вы делаете роутинг и вам нужно держать в памяти граф. Географическое разделение поможет сэкономить ресурсы)
По теме шардирования, можно почитать неплохой доклад с конференции HighLoad:
https://habr.com/en/company/oleg-bunin/blog/433370/
Habr
Теория шардирования
Кажется, мы так глубоко погрузились в дебри highload-разработки, что просто не задумываемся о базовых проблемах. Взять, например, шардирование. Чего в нем разбираться, если в настройках базы данных...
Forwarded from Teamlead Good Reads – ежедневные советы про менеджмент людей и команд (Egor Tolstoy)
Хорошая статья CTO Dodo Pizza про то, как меняется роль технического руководителя при росте команды в 4-14-40-140 человек.
https://medium.com/@alex4Zero/4-14-40-140-8ac3bc6c1fdd
https://medium.com/@alex4Zero/4-14-40-140-8ac3bc6c1fdd
Medium
4. 14. 40. 140.
Это не IP адрес. Это не случайный набор чисел. Это не координаты долготы и широты.Это логика роста лидеров в IT, которую я вижу по своему…
Event Sourcing
https://martinfowler.com/eaaDev/EventSourcing.html
Долго думал как подступиться к этой обширной теме. Сама идея кажется просто замечательной — вместо того, чтобы в stateful сервисе безвозвратно менять этот самый state (например, апдейтом в базу данных), можно вести event-log изменений. Этот лог изменений можно будет накатывать на ту же базу данных и иметь ее последнюю версию, можно полностью восстановить текущее состояние с нуля, можно получить снапшот на абсолютно любой момент времени в прошлом, можно даже сделать rollout (из предположения, что у эвента будет тривиальная обратная операция). Из практических целей стоит отдельно отметить возможность ретрансляции эвентов в другие системы, например, аналитические без каких-то специальных телодвижений.
Помимо очевидных плюсов, тако подход встречается в паре с CQRS, где подобный event-log будет единым источником правды.
Но самое интересное, это, конечно, минусы. В "каноническом описании" по ссылке ниже все очень подробно расписано, я лишь остановлюсь на некоторых:
— Дороговизна. Если эвентов очень много, нужно искать трейдофы на хранение, восстановление, сохранение снапшотов.
— Усложнение кода. Получить результат из системы с event-sourcing может быть сложной задачей.
— Интеграция с сервисами, не живущие в такой же идеологии (тут рекомендуют писать обертки для таких сервисов, что тоже своего рода усложнение).
Делитесь своими комментариями, ссылками и успешными примерами использования в чате.
https://martinfowler.com/eaaDev/EventSourcing.html
https://microservices.io/patterns/data/event-sourcing.html
#pattern #microservices #practices #doc #en
https://martinfowler.com/eaaDev/EventSourcing.html
Долго думал как подступиться к этой обширной теме. Сама идея кажется просто замечательной — вместо того, чтобы в stateful сервисе безвозвратно менять этот самый state (например, апдейтом в базу данных), можно вести event-log изменений. Этот лог изменений можно будет накатывать на ту же базу данных и иметь ее последнюю версию, можно полностью восстановить текущее состояние с нуля, можно получить снапшот на абсолютно любой момент времени в прошлом, можно даже сделать rollout (из предположения, что у эвента будет тривиальная обратная операция). Из практических целей стоит отдельно отметить возможность ретрансляции эвентов в другие системы, например, аналитические без каких-то специальных телодвижений.
Помимо очевидных плюсов, тако подход встречается в паре с CQRS, где подобный event-log будет единым источником правды.
Но самое интересное, это, конечно, минусы. В "каноническом описании" по ссылке ниже все очень подробно расписано, я лишь остановлюсь на некоторых:
— Дороговизна. Если эвентов очень много, нужно искать трейдофы на хранение, восстановление, сохранение снапшотов.
— Усложнение кода. Получить результат из системы с event-sourcing может быть сложной задачей.
— Интеграция с сервисами, не живущие в такой же идеологии (тут рекомендуют писать обертки для таких сервисов, что тоже своего рода усложнение).
Делитесь своими комментариями, ссылками и успешными примерами использования в чате.
https://martinfowler.com/eaaDev/EventSourcing.html
https://microservices.io/patterns/data/event-sourcing.html
#pattern #microservices #practices #doc #en
martinfowler.com
Event Sourcing
Capture all changes to an application state as a sequence of events.
Plug-in Architecture
Имплементируя фичу за фичей вы начинаете замечать, что компоненты начинают переплетаться между собой, создавай достаточно сложные для понимания и удержания в голове зависимости. Рано или поздно это приводит к проблемам — знакома ли вам ситуация, когда только написанный код в одном месте поломал вообще, с первого взгляда, несвязанную функциональность?
Еще пример: команда начинает "раздувать" текущий код, гонясь, в первую очередь, за быстрым продуктовым результатом, мы получаем лонгрид в функциях, в файлах с кодом, который тяжело читать, невозможно поддерживать и легко сломать.
Рецепт, о котором сегодняшняя статья, предлагает подумать над организацией архитектуры приложения таким образом, чтобы изолировать ваше ядро от добавляемой функциональности.
Здесь ядро — основная функциональность вашего приложения, предоставляющая интерфейсы для расширения с помощью концепции плагинов.
Плагины — расширения, которые by design не оказывают влияние на другие плагины, не могут повредить ядро, так как оказывают влияние через безопасные интерфейсы.
Вся концепция предоставляет ряд преимуществ:
— расширяемость — концепция позволяет достаточно легко подключать новую функциональность через плагины.
— безопасность — если считать, что каждый плагин можно легко отстрелить, если он по какой-то причине не работает, то модификация плагинов не будет влиять на основную функциональность приложения.
— изолированность — плагины изолированы друг от друга и связаны с ядром через определенный интерфейс, что предотвращает губительные зависимости.
https://medium.com/omarelgabrys-blog/plug-in-architecture-dec207291800
#practices #medium #article #en
Имплементируя фичу за фичей вы начинаете замечать, что компоненты начинают переплетаться между собой, создавай достаточно сложные для понимания и удержания в голове зависимости. Рано или поздно это приводит к проблемам — знакома ли вам ситуация, когда только написанный код в одном месте поломал вообще, с первого взгляда, несвязанную функциональность?
Еще пример: команда начинает "раздувать" текущий код, гонясь, в первую очередь, за быстрым продуктовым результатом, мы получаем лонгрид в функциях, в файлах с кодом, который тяжело читать, невозможно поддерживать и легко сломать.
Рецепт, о котором сегодняшняя статья, предлагает подумать над организацией архитектуры приложения таким образом, чтобы изолировать ваше ядро от добавляемой функциональности.
Здесь ядро — основная функциональность вашего приложения, предоставляющая интерфейсы для расширения с помощью концепции плагинов.
Плагины — расширения, которые by design не оказывают влияние на другие плагины, не могут повредить ядро, так как оказывают влияние через безопасные интерфейсы.
Вся концепция предоставляет ряд преимуществ:
— расширяемость — концепция позволяет достаточно легко подключать новую функциональность через плагины.
— безопасность — если считать, что каждый плагин можно легко отстрелить, если он по какой-то причине не работает, то модификация плагинов не будет влиять на основную функциональность приложения.
— изолированность — плагины изолированы друг от друга и связаны с ядром через определенный интерфейс, что предотвращает губительные зависимости.
https://medium.com/omarelgabrys-blog/plug-in-architecture-dec207291800
#practices #medium #article #en
Medium
Plug-in Architecture
and the story of the data pipeline framework
Все, что можно сделать на бэкенде — нужно делать на бэкенде
Несколько лет назад я придерживался следующей позиции разделения ответственности между клиентов и сервером. В клиенте должно программироваться все относящееся к визуализации и пользовательскому взаимодействию: экраны, переходы, лейблы, кнопки, тексты итп, тогда как бэкенд в клиент-серверном взаимодействии должен присылать структурированные данные, которые клиент должен как-то по-своему интерпретировать. Бэкенд ничего не знает про то, как эти данные будут отображаться.
Однако, огромный минус, который перевешивает плюсы, основан на времени деплоя клиентских приложений — это негибкость конфигурирования клиента.
Давайте возьмем противоположную позицию — бэкенд все знает про клиент и отвечает за всю визуализацию. Он присылает на клиент детальную информацию об экранах, текстах, кнопках — да вообще по-максимуму. Прямо из коробки это дает возможность быстрого изменения клиентов, нивелируя весь лаг деплоя приложения в сторы. Можно проводить А/Б тестирования, даже на лету менять часть какой-то функциональности, если это позволяет ваше АПИ.
С точки зрения бэкенда все еще не очень круто сервисам, которые занимаются, например, расчетом внутренней бизнез-логики, отвечать за отображение GUI на клиентах. Но это легко решить, поставив, еще один сервис, который будет отвечать именно за упаковку бизнес-логики в формат представления GUI, понятный клиенту.
В сегодняшней заметке ссылка на видео Highload++ 2017 по теме
https://www.youtube.com/watch?v=G-AiDkZLOIs
#practices #backend #client #video #highload #youtube #ru
Несколько лет назад я придерживался следующей позиции разделения ответственности между клиентов и сервером. В клиенте должно программироваться все относящееся к визуализации и пользовательскому взаимодействию: экраны, переходы, лейблы, кнопки, тексты итп, тогда как бэкенд в клиент-серверном взаимодействии должен присылать структурированные данные, которые клиент должен как-то по-своему интерпретировать. Бэкенд ничего не знает про то, как эти данные будут отображаться.
Однако, огромный минус, который перевешивает плюсы, основан на времени деплоя клиентских приложений — это негибкость конфигурирования клиента.
Давайте возьмем противоположную позицию — бэкенд все знает про клиент и отвечает за всю визуализацию. Он присылает на клиент детальную информацию об экранах, текстах, кнопках — да вообще по-максимуму. Прямо из коробки это дает возможность быстрого изменения клиентов, нивелируя весь лаг деплоя приложения в сторы. Можно проводить А/Б тестирования, даже на лету менять часть какой-то функциональности, если это позволяет ваше АПИ.
С точки зрения бэкенда все еще не очень круто сервисам, которые занимаются, например, расчетом внутренней бизнез-логики, отвечать за отображение GUI на клиентах. Но это легко решить, поставив, еще один сервис, который будет отвечать именно за упаковку бизнес-логики в формат представления GUI, понятный клиенту.
В сегодняшней заметке ссылка на видео Highload++ 2017 по теме
https://www.youtube.com/watch?v=G-AiDkZLOIs
#practices #backend #client #video #highload #youtube #ru
YouTube
Как мы поддерживаем 100 разных версий клиентов в Badoo / Ярослав Голуб (Badoo)
Приглашаем на конференцию Saint HighLoad++ 2025, которая пройдет 23 и 24 июня в Санкт-Петербурге!
Программа, подробности и билеты по ссылке: https://highload.ru/spb/2025
________
HighLoad++ 2017
Презентация и тезисы:
http://www.highload.ru/2017/abstracts/3023.html…
Программа, подробности и билеты по ссылке: https://highload.ru/spb/2025
________
HighLoad++ 2017
Презентация и тезисы:
http://www.highload.ru/2017/abstracts/3023.html…
Code review checklist for distributed systems
https://medium.com/swlh/code-review-checklist-for-distributed-systems-b3fb94be5bfa
Автор через призму многолетнего опыта пытается обобщить требования к коду, который будет работать в продакшене в распределенной системе. Получилось весьма сумбурно, обо всем сразу, но по чуть-чуть.
Ниже краткий конспект рекомендаций в виде чеклиста:
При межсервисных запросах:
Что делать, когда запросы во внешний сервис возвращают ошибку?
— иметь ветвь обработки ошибки
— иметь сценарии восстановления после ошибки
Что делать, когда внешний сервис недоступен?
— всегда ставить таймауты на запросы
— делать какое-то явно определенное число перезапросов
— использовать circuit breaker
— не обрабатывать таймауты как ошибки
При построении сервиса, который другие сервисы будут использовать:
— все интерфейсы API должны быть идемпотентными
— явно определить времена ответа и пропускную способность
— определить и лимитировать батчевые запросы
— думать о мониторингах сервисов без потребности смотреть внутрь самих сервисов
Общие рекомендации:
— более агрессивно кэшировать
— определить единицу сбоя при ошибках
— инкапсулировать внутренние структуры сервисов и не размазывать их по системе
https://medium.com/swlh/code-review-checklist-for-distributed-systems-b3fb94be5bfa
#practices #article #microservices #en
https://medium.com/swlh/code-review-checklist-for-distributed-systems-b3fb94be5bfa
Автор через призму многолетнего опыта пытается обобщить требования к коду, который будет работать в продакшене в распределенной системе. Получилось весьма сумбурно, обо всем сразу, но по чуть-чуть.
Ниже краткий конспект рекомендаций в виде чеклиста:
При межсервисных запросах:
Что делать, когда запросы во внешний сервис возвращают ошибку?
— иметь ветвь обработки ошибки
— иметь сценарии восстановления после ошибки
Что делать, когда внешний сервис недоступен?
— всегда ставить таймауты на запросы
— делать какое-то явно определенное число перезапросов
— использовать circuit breaker
— не обрабатывать таймауты как ошибки
При построении сервиса, который другие сервисы будут использовать:
— все интерфейсы API должны быть идемпотентными
— явно определить времена ответа и пропускную способность
— определить и лимитировать батчевые запросы
— думать о мониторингах сервисов без потребности смотреть внутрь самих сервисов
Общие рекомендации:
— более агрессивно кэшировать
— определить единицу сбоя при ошибках
— инкапсулировать внутренние структуры сервисов и не размазывать их по системе
https://medium.com/swlh/code-review-checklist-for-distributed-systems-b3fb94be5bfa
#practices #article #microservices #en
Medium
Code review checklist for distributed systems
Avoid these simple coding mistakes for a stable system