Прямоугольники и стрелочки – Telegram
Прямоугольники и стрелочки
803 subscribers
37 photos
44 files
60 links
Заметки по Архитектуре программного обеспечения и около того.
Ведущий Максим Юнусов.
Download Telegram
И снова о CAP

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

1. Чтобы условия "AP" CAP теоремы были, выполнены мало просто разрыва соединения. Надо еще, что бы клиент продолжал долбиться в оторванный сервис.
Вроде ничего не мешает ему переключиться на сервис, оставшийся в рабочем кластере, но нет. Хочется работать с конкретным инстансом. (т. н. полная доступность)
2. Если условия "AP" выполнены, линеаризуемость сообщений нарушается. То есть мы теряем возможность единообразно выстроить последовательность модификаций на всех инстансах (по какому-то условному времени).
Клиенты могут не заметить потери консистентности. (т. н. слабая согласованность, например причинная (casual consistency))
2.а. Например, если клиенты не работают с общими данными, они не заметят никаких проблем
3. Даже если линеаризуемость нарушена, никто не мешает нам восстановить ее позже, после восстановления соединения (т. н. строгая итоговая согласованность, strong eventual consistency). Возьмите все изменения и переупорядочите их. Получите корректный стейт.
Для этого зачастую достаточно знать что создание объекта всегда предшествует модификации, а модификация удалению. Хотя чаще требуются более хитрые алгоритмы.
4. Вопреки распространенному мнению итоговая согласованность (eventual consistency) без дополнительных усилий не восстанавливает линеаризуемость в итоге. Сколько не жди система не придет к консистентному (с т.з. данных) состоянию.
4.а. Итоговую согласованность можно обвешать дополнительными ограничениями, и в некоторых случаях это будет работать, т.е. опять таки клиент ничего не заметит.

Резюмируя:
1. CAP - не приговор. Есть возможность крутиться.
2. Итоговая согласованность - не согласованность в строгом смысле слова, но может таковой казаться конкретному клиенту при дополнительных ограничениях.

#CAPТеорема
🔥3
Поиск альтернативных решений

Ранее, рассматривая возможность использования ТРИЗ в архитектуре, я решал задачу поиска решения.
Коротко, цепочка такая:
1. Описываем ситуацию (требования)
2. Ищем проблему (противоречия)
3. Находим стандартное решение (подбор концепта)
4. Если не получилось, находим нестандартное решение (изобретение)

Однако поиск подходящего решения это для слабаков.
Архитектор должен уметь находить оптимальное решение.

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

Выборы без альтернативы - очевидный моветон.
Еще раз - не надо хватать и детально прорабатывать первое подходящее решение.
Пусть их будет минимум два.

Но что делать если ваш список паттернов краток, и в нем не нашлось не одной альтернативы?

Здесь может помочь простой трюк. Альтернативу можно "изобрести", перемещая во времени и пространстве основную ответственность (responsibility).

Например, нужно запустить пару клиентов в гео-распределёнке (много-цодовость).
Ограничение - хотелось бы избежать лишних меж-цодовых взаимодействий.
Основная ответственность - маршрутизация запросов.
А дальше играемся с пространством:
1. Поместим маршрутизацию на клиента
2. Поместим маршрутизацию на сервис в ЦОДе
3. Воткнем маршрутизацию где-то между клиентом и ЦОДом

Варианты есть. Отбрасываем отчетливо непригодные. Взвешиваем оставшиеся. Профит.

#АрхитектурныеРешения
🔥6👍1
Распределенный компонент (Distributed Component)

Постоянно рассматривая различные архитектуры, встречаю компоненты гордо именуемые "Сервис" (или даже "Микросервис")
при этом к сервисам отношение не имеющие.

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

Анти-паттерн известен и назван "Распределённый монолит".
А как назвать сам компонент? Устоявшегося термина нет.

Есть предпочтения?
Расчет эффективности кэша
Бот против человека.

На одном из каналов обсуждалась эффективность кэширования.
Кто-то предложил проконсультироваться у Chat GPT.

Недолго размышляя, я дал боту такую задачку:

Пусть мощность открытой системы (Throughput) -100 tps.
Пропускная способность кэша (Cache throughput) -100 000 tps.
Процент успешных запросов (Hit rate) - 90%.

Каково будет ускорение по пропускной способности при внедрении кэша ?

Ответ от GPT:

Если пропускная способность системы до кэширования была 100 tps и если с добавлением кэша Hit rate = 90% и Cache efficiency = 1000, то после добавления кэша мы можем ожидать следующее:

- 90% из 100 запросов будут удовлетворены из кэша, т.е. кэш будет обслуживать 90 запросов в секунду
- Оставшиеся 10% запросов будут обслуживаться основной системой, которая обеспечивала пропускную способность в 100 tps до внедрения кэша
- Таким образом, общая пропускная способность системы после внедрения кэша должна быть равна суммарной пропускной способности кэша и основной системы:
- 90% от 100 tps = 90 tps, обслуживаемых кэшем
- 10% от 100 tps = 10 tps, обслуживаемых основной системой
- Итого: 90 tps + 10 tps = 100 tps

Таким образом, пропускная способность системы после внедрения кэша останется примерно равной её пропускной способности до внедрения кэша (с учетом погрешностей и ограничений системы).

Решение от программиста незнакомого с программной инженерией:
X
= 100.000 * 0.9 + 100 * 0.1 = 90 010 tps
Ускоряемся в 900 раз!

Резюме:
Оба решения абсолютно не верны.
Но все же, говорить, что ChatGPT сравним с начинающим архитектором-ошибочно.

Человек может ошибиться в расчетах и получить абсолютно неадекватный результат, но человек хотя бы понимает, что добавление кэша ведет к ускорению системы. Бот же, не обладая должными знаниями, не может дать даже качественную оценку.
🔥1
Архитектор и владелец продукта (product owner)

У многих коллег складывается мнение, что архитектор и владелец продукта (в agile) - антагонисты.

PO топит за фичи, архитектор за качества, и оба рвут на себя бэклог.

ИМХО здесь и да и нет, или классическое it depends )

Конкретно, все зависит от того, кто берет на себя риски по проекту.

До agile этим занимались менеджеры проекта (PM).

Если владелец риска выделен, то есть на проекте есть PM, то между архитектором и владельцем идет состязание за бэклог. Менеджер занимает сторону арбитра.

После гибких трансформаций в некоторых проектах менеджеров поуберали.
Риски на владельце.
Битва за бэклог происходит в одной голове.

Архитектору остается аккуратно перенести в эту голову все ощущаемые риски, желательно живо описав возможные последствия.
Это в общих интересах.

Сотрудничество )
👍9
Архитектор и тимлид

Еще одна пара соперников - архитектор и тимлид.

Тимлид отвечает за сроки. Ему важно вовремя выполнить все задачи итерации.
Архитектор активно мешает. Архитектору хочется чтобы было красиво и качественно.

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

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

И в другую сторону. Тимлид разгружая команду от ненужных активностей вполне может накидывать задачи на архитектора (архитектура как сервис).

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

Движение задач в обе стороны.
Если одна из этих труб забивается или вообще не предусмотрена по процессу - быть потопу )
👍1
Чего я не нашёл в ТРИЗ

ТРИЗ очень интересная теория. На практике активно применяю алгоритм АРИЗ, и честно говоря, доволен результатом.

Суть алгоритма можно выразить простой последовательностью (см. АРИЗ-77):
АП → ТП → ИКР → ФП → Р
где
- АП - административное противоречие
чего хочет стейкхолдер: требование, user story
- ТП - техническое противоречие
что мешает получить желаемое: технические ограничения, другие требования, принципы
- ИКР - идеальный конечный результат
как можно было бы решить проблему не имея ограничений, например обладая неограниченными ресурсами.
- ФП - физическое противоречие
какой элемент системы является причиной противоречия, например должен выполнять несовместимые функции
- Р - решение
некоторые, считают, что доведя задачу до осознания физических противоречий решение приходит само )

Более подробно расписывал этот процесс на ArchDays
И все казалось бы понятно, но ...

Где тут архитектурные задачи?!

Вместо административного противоречия
("я как ... хочу ... для того чтобы ...")
имеем риск
("при условии ... может случиться ... что приведёт к .... ")

Архитектор именно тот, кто выявляет риски и драйвит задачи по их смягчению.

Возможно ли административные противоречия обобщить на риски?
То есть к понятному "хочу чтобы всегда" добавить "хочу чтобы никогда"

Задумался 🤔
👍3
Долгая жизнь проекта
- Часть 1. Проблема

Все проходит.

На картинке жизненный цикл всего, так называемая S-кривая.

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

Отсюда глобальная цель архитектора - вытянуть S-ку, продлить жизнь продукту.

В чём проблема?

В каждом продукте есть решения, которые не возможно или очень сложно переиграть.
Фактически эти решения представляют собой закрытую (от модификации) систему, которая в силу объективных законов склонна к саморазрушению (2НТ).

Это как запрограммировать автомобильчик на долгую дорогу от Москвы до Владивостока и запустить его в путь. Чем больше изменений и не предсказанных событий - тем призрачнее шанс добраться до пункта назначения.

В архитектуре это выглядит примерно так:
Полгода разрабатывали продукт, вышли в прод. а там нагрузка. Требуется 40 инстансов PostgreSQL в режиме master-master. Переписываем.

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

Хотя есть альтернативное мнение )
Выступление с ArchDays добралось до ютюба )
👍1
Изобретение архитектурного решения

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

В докладе рассматриваются популярные методы принятия архитектурных решений с привязкой к теории решения изобретательских задач (ТРИЗ).

Пытаемся вместе ответить на вопросы:
— Правильно ли мы ставим архитектурные задачи?
— Достаточно ли знания паттернов и архитектурных тактик для решения сложных задач?
— Каковы ограничения выбора решения из множества вариантов?
— Является ли выбор варианта единственным доступным методом проектирования?
— Существует ли алгоритм, позволяющий выйти на оптимальное решение?

Смотреть: https://youtu.be/tmoOTqPgbFM
👍7🔥5
Долгая жизнь проекта
- Часть 2. Панацея
Первая часть - https://news.1rj.ru/str/rect_arrow/148

Как можно продлить жизнь проекта?
Очевидное решение - сократить число неподдающихся пересмотру решений (до нуля).

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

В архитектуре это:
Разбить систему на кучу маленьких независимых сервисов, каждый из которых может быть полностью переписан в две недели.

Архитектура как набор неизменяемых решений больше не нужна!
👍1
Долгая жизнь проекта
- Часть 3. Отрезвление

Озвученная в предыдущем посте идея - это основная идея так называемой эволюционной архитектуры от Нила Форда и к.

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

Но точно ли так?

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

Разбиение на сервисы становится тем решением, которое сложно, или невозможно изменить.

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

Увы, MSA не панацея.
Вечная жизнь проекту не грозит (

Все проходит.
👍7
Активаторы (Enablers)

Как вводить архитектурные задачи в бэклог?

Популярный фреймворк (каркас) SAFe предлагает особый вид задач, называемых Enablers (Активаторы).
Точнее, Architectural enablers - инструменты архитектуры.

По описанию Enabler - это активность, позволяющая реализовать определённую функцию, поддерживающую бизнес-функции.

Все бы хорошо, но, обосновывая архитектурные задачи, я часто иду от рисков.

Если я скажу, что эта активность добавит нам доступности (99.99) под функцию получения списков, то буду звучать неубедительно.

Если я скажу, что если мы НЕ выполним эту активность, то не выполним SLA и попадём под штрафы - меня как минимум выслушают.

Так что для меня Enablers формулируются как Disablers.

Профессиональная деформация )
😁3👍1
Активности SA по формированию архитектуры. Версия 5
👍7🔥1
ТРИЗ и архитектура ПО v1.pdf
780.3 KB
Небольшая презентация по использованию законов развития систем ТРИЗ при проектировании архитектуры ПО
🔥6👍1
systems-07-00039-s001.zip
35.5 KB
В работе "TRIZ for Digital Systems Engineering" Kari Lippert и Robert Cloutier предложили матрицу противоречий для построения программной архитектуры.

Предложены основные качества, но к сожалению не заполнено поле решений.

Выложу здесь, возможно кого-нибудь заинтересует, как заготовка.

Сам я несколько скептически отношусь к использованию матриц противоречий в нашей области.

#ТРИЗ
Матрица противоречий в архитектуре ПО

На прикреплённой картинке дерево атрибутов качества используемых мною в работе.
Простых комбинаций типа FURPS мне, увы, не хватает.

Если бы я строил матрицу противоречий, то потянул бы все эти качества.

Почему я даже не пытаюсь построить такую матрицу?

1. При формировании решения я получаю противоречие, но в этом противоречии участвует сразу несколько качеств.
Например, классическое: нужны одновременно низкое время отклика (responsiveness) и высокая пропускная способность (capacity) при высокой эффективности, то есть против ресурсоёмкости (resource consumption)
В двумерной матрице искать решение на троих не удобно. На пять качеств это уже мучение (

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

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

Подожду, пока что-то подобное построят другие )

#ТРИЗ
👍1
Механизация архитектуры. Матрица противоречий

В тему предыдущего поста - несколько разъяснений.

- Матрица противоречий (ТРИЗ) используется при решении типовых задач, "механизируя" поиск решений.
- Если нам удалось свести задачу к простому противоречию, то в матрице мы найдём список приемов, решающих проблему.
- Строки матрицы представляют позитивные типовые параметры (что хотим улучшить)
- Столбцы матрицы представляют негативные типовые параметры (что при этом ухудшается)
- Номера приемов в ячейках на пересечениях противоречащих параметров.

Классическая матрица ТРИЗ была построена Альтшуллером для технических систем на основе анализа более 40000 идей и решений.

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

На прикреплённом рисунке фрагмент такой матрицы для основных качеств производительности.

Здесь каждое качество определено, количественно измеряемо и положительно, с т.з стейкхолдера.

Эффективность показывает насколько оптимально используется железо. Чем больше ресурсов при прочих равных метриках, тем ниже эффективность

Мощность - предельная пропускная способность.

Отзывчивость определяется временем отклика.

В теории, построив такую матрицу, мы механизируем активность архитектора по поиску решения процентов на 90.
Если, конечно, архитектор не использует принцип Technology First )

#ТРИЗ
👍3
The Essential Guide To Queueing Theory.pdf
1.5 MB
Книга по теории массового обслуживания

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

Когда-то распространялась бесплатно. Сейчас сайт перепрофилировался.

Выложу тут.



#Книга #Производительность
🔥8
Как правильно масштабировать микросервисы?

Существует два подхода:
1. Исключительно горизонтально. По одному потоку (ядру) на сервис. (Прям как в Redis)
2. По возможности вертикально. То есть добавлять побольше ядер и настраивать параллелизм в самом сервисе.
При этом потоки (threads) всё чаще уступают место сопрограммам (корутинам)

За первый подход
1. 8й фактор (из тех 12-ти): VIII. Параллелизм. Где сказано: "Масштабируйте приложение с помощью процессов".
2. Предсказуемость масштабирования. Контролируемая балансировка между ядрами на уровне сервисов.
3. Низкая когнитивная нагрузка. Разработчику сервиса не нужно заботиться о гонках и тупиках (deadlock).
4. Простая модель конкурентного доступа к ресурсам (чаще всего Actor Model).

За второй подход
1. Экономия памяти. (например, одна общая jdk)
2. Синергия, возможность переиспользования данных других потоков (например, общий кэш)
3. "Размазано" влияние служебных процессов. (GC - на одном потоке из одного или из 16-ти ?)

Каждому из этих аргументов легко можно противопоставить контраргумент и с удовольствием похоливарить.

Chat GPT ответит: "it depends" )

Я же зайду от производительности и закину свой кейс.

Предположим, вам нужна высокая пропускная способность при низкой задержке.
Существует точка Кляйнрока (Kleinrock), в которой пропускная способность максимальна, и время отклика минимально (см. рисунок)
- левее – зона недозагрузки
- правее - зона высокой латентности

Мы должны удерживать сервис в точке Кляйнрока, нагружая его M задачами.
Где М = Dmax/D. D - потребность в ресурсе (время).

Забавное следствие
Если сервис использует только один ресурс (например CPU), то Dmax=D, и самым эффективным будет однопоточный вариант.

#Производительность #Микросервисы #Масштабирование
👍4