#статья #habr #taxi #experience #ru
Citymobil — пособие для стартапов по увеличению стабильности на фоне роста
Две статьи про опыт сервиса такси Citymobil и кейсы, с которыми столкнулась команда на стадии активного роста бизнеса.
https://habr.com/en/company/mailru/blog/444818/
В первой статье описывается путь, который прошла команда на этапе бурного роста:
1) Как считать потери от факапов
2) Выстраивание процесса разработки бекенда
3) Почему с налаженным процессом разработки появилась угроза стабильности
4) Цель - учиться на ошибках
https://habr.com/en/company/mailru/blog/445704/
Во второй статье рассматриваются самые распространенные виды аварий:
1) Плохой релиз, 500-ые ошибки
2) Плохой релиз, неоптимальный код, нагрузка на базу
3) Неудачное ручное вмешательство в работу системы
4) Пасхальное яйцо
5) Внешние причины
6) Плохой релиз, сломанная функциональность
Citymobil — пособие для стартапов по увеличению стабильности на фоне роста
Две статьи про опыт сервиса такси Citymobil и кейсы, с которыми столкнулась команда на стадии активного роста бизнеса.
https://habr.com/en/company/mailru/blog/444818/
В первой статье описывается путь, который прошла команда на этапе бурного роста:
1) Как считать потери от факапов
2) Выстраивание процесса разработки бекенда
3) Почему с налаженным процессом разработки появилась угроза стабильности
4) Цель - учиться на ошибках
https://habr.com/en/company/mailru/blog/445704/
Во второй статье рассматриваются самые распространенные виды аварий:
1) Плохой релиз, 500-ые ошибки
2) Плохой релиз, неоптимальный код, нагрузка на базу
3) Неудачное ручное вмешательство в работу системы
4) Пасхальное яйцо
5) Внешние причины
6) Плохой релиз, сломанная функциональность
Хабр
Citymobil — пособие для стартапов по увеличению стабильности на фоне роста. Часть 1
Этой статьей я открываю короткий цикл из двух статей, в которых подробно расскажу, как нам удалось за несколько месяцев в разы увеличить стабильность сервисов...
Anonymous Poll
23%
MongoDB
72%
PostgreSQL
5%
MySQL
Почему архитекторы терпят неудачу - и что с этим делать.
10 болезней, о которых вы должны знать.
Why software architects fail – and what to do about it
10 Diseases You Should Know About.
Выступление с конференции craft, которое озвучивает много проблем, которые я иногда обнаруживаю в себе (а на некоторые начну обращать внимание), но, к сожалению, дает не очень много ответов.
1. Over-Generalization Drive
Symptom: Seeing commonalities in everything and turning them into generic solutions
2. Domain Allergy
Symptom: Treating the domain as a negligible nuisance
3. Obsessive Specialization Disorder
Symptom: Believing every problem to be unique, even if it’s been solved 1,000 times
4. Unhealthy Complexity Attraction
Symptom: Being so smart you can’t be bothered by simple approaches.
5. Analysis Paralysis
Symptom: Taking longer to evaluate than to actually do it
6. Innovation Addiction
Symptom: Things become progressively less fun the closer you get to production
7. Severe Tunneling Fixation
Symptom: Enforcing an architectural apporach that clashes with the framework, libraries or tools you use.
8. Asset Addiction
Symptom: Becoming so attached to a particular tool / library / framework it becomes a fit for every problem.
9. Exaggerated Risk Aversion
Symptom: Sticking with horrible, horrible, HORRIBLE tools because they are there.
10. Impact Dissonance
Symptom: Becoming too detached from the actual system that is being delivered.
Видео
https://www.youtube.com/watch?v=AkYDsiRVqno&feature=youtu.be&t=272
вот тут есть краткая выжимка: https://retrosight.github.io/learning/why-architects-fail-tilkov.html
#видео #youtube #craft #en
10 болезней, о которых вы должны знать.
Why software architects fail – and what to do about it
10 Diseases You Should Know About.
Выступление с конференции craft, которое озвучивает много проблем, которые я иногда обнаруживаю в себе (а на некоторые начну обращать внимание), но, к сожалению, дает не очень много ответов.
1. Over-Generalization Drive
Symptom: Seeing commonalities in everything and turning them into generic solutions
2. Domain Allergy
Symptom: Treating the domain as a negligible nuisance
3. Obsessive Specialization Disorder
Symptom: Believing every problem to be unique, even if it’s been solved 1,000 times
4. Unhealthy Complexity Attraction
Symptom: Being so smart you can’t be bothered by simple approaches.
5. Analysis Paralysis
Symptom: Taking longer to evaluate than to actually do it
6. Innovation Addiction
Symptom: Things become progressively less fun the closer you get to production
7. Severe Tunneling Fixation
Symptom: Enforcing an architectural apporach that clashes with the framework, libraries or tools you use.
8. Asset Addiction
Symptom: Becoming so attached to a particular tool / library / framework it becomes a fit for every problem.
9. Exaggerated Risk Aversion
Symptom: Sticking with horrible, horrible, HORRIBLE tools because they are there.
10. Impact Dissonance
Symptom: Becoming too detached from the actual system that is being delivered.
Видео
https://www.youtube.com/watch?v=AkYDsiRVqno&feature=youtu.be&t=272
вот тут есть краткая выжимка: https://retrosight.github.io/learning/why-architects-fail-tilkov.html
#видео #youtube #craft #en
YouTube
Why software architects fail: and what to do about it - Stefan Tilkov | Craft 2019
We’ve all seen them: Ambitious projects, starting out with grand visions, ending up as costly lessons in what not to do, leaving behind the ruins of promising paradigms, technologies, tools, and careers. But why do architecture approaches sometimes hurt instead…
CQRS (Command and Query Responsibility Segregation) pattern
Сегодня про архитектурный паттерн CQRS, суть которого состоит в том, чтобы отделить операции изменения от операций чтения.
Плюсы:
— Независимое масштабирование читающей и пишущей моделей
— Оптимальные методы и схемы данных для записи и для чтения
— Безопасность (легко обеспечить, чтобы только разрешенные поставщики меняли данные).
— Разделение проблем читателей и писателей (бизнес-логика может остаться в модели изменения данных, при этом модель чтения окажется очень простой)
— Простые запросы.
Пример.
Функциональность "пользователь логинится в приложение, нужно отображать список активных пользователей" требует разные модели изменения состояния и чтения данных.
Следуя паттерну, такую функциональность легко разделить на команды (command): "пользователь активен" и запросы (query): "выбрать список активных пользователей".
Можно использовать event-log для хранения информации о времени активности пользователя и использовать ее как "источник правды".
В то же время, для запросов можно использовать более оптимизированное для чтение хранилище.
Таким образом, сохраняя команду "пользователь активен", мы синхронизируем ее с in-memory хранилищем активных пользователей c TTL, на который мы считаем пользователя активным. Читающие клиенты будут использовать ее для чтения.
По ссылке подробно про то, какие есть плюсы и минусы такого подхода, когда нужно и когда не нужно использовать этот паттерн, а также пример синхронизации моделей записи и чтения.
https://docs.microsoft.com/en-us/azure/architecture/patterns/cqrs
#pattern #microservices #practices #doc #en
Сегодня про архитектурный паттерн CQRS, суть которого состоит в том, чтобы отделить операции изменения от операций чтения.
Плюсы:
— Независимое масштабирование читающей и пишущей моделей
— Оптимальные методы и схемы данных для записи и для чтения
— Безопасность (легко обеспечить, чтобы только разрешенные поставщики меняли данные).
— Разделение проблем читателей и писателей (бизнес-логика может остаться в модели изменения данных, при этом модель чтения окажется очень простой)
— Простые запросы.
Пример.
Функциональность "пользователь логинится в приложение, нужно отображать список активных пользователей" требует разные модели изменения состояния и чтения данных.
Следуя паттерну, такую функциональность легко разделить на команды (command): "пользователь активен" и запросы (query): "выбрать список активных пользователей".
Можно использовать event-log для хранения информации о времени активности пользователя и использовать ее как "источник правды".
В то же время, для запросов можно использовать более оптимизированное для чтение хранилище.
Таким образом, сохраняя команду "пользователь активен", мы синхронизируем ее с in-memory хранилищем активных пользователей c TTL, на который мы считаем пользователя активным. Читающие клиенты будут использовать ее для чтения.
По ссылке подробно про то, какие есть плюсы и минусы такого подхода, когда нужно и когда не нужно использовать этот паттерн, а также пример синхронизации моделей записи и чтения.
https://docs.microsoft.com/en-us/azure/architecture/patterns/cqrs
#pattern #microservices #practices #doc #en
Docs
CQRS Pattern - Azure Architecture Center
Learn how to segregate operations that read data from operations that update data by using the Command Query Responsibility Segregation (CQRS) pattern.
RESTful API Patterns
Часто приходится изобретать одни и те же вещи при проектировании API.
В статье вместе с подробными примерами собраны концепции:
- пагинация
- фильтрация
- асинхронные операции
- версионирование
- агрегация
- локализация
https://levelup.gitconnected.com/restful-api-patterns-81930c43e494
#article #pattern #microservices #practices #en
Часто приходится изобретать одни и те же вещи при проектировании API.
В статье вместе с подробными примерами собраны концепции:
- пагинация
- фильтрация
- асинхронные операции
- версионирование
- агрегация
- локализация
https://levelup.gitconnected.com/restful-api-patterns-81930c43e494
#article #pattern #microservices #practices #en
Medium
RESTful API Patterns
There are so many ways to write an API that is REST architectural style compliant, I’ve grouped some of the solutions here.
Фильтр Блума
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-разработки, что просто не задумываемся о базовых проблемах. Взять, например, шардирование. Чего в нем разбираться, если в настройках базы данных...