Хабрахабр

[Перевод] Издержки согласования в коллективах

Это краткое отступление в текущей серии статей о том, как избегать введения сервисов для различных сущностей. Интересный разговор за ужином привёл к мыслям, которые я решил записать.
В 1967 году Джин Амдал представил довод против параллельных вычислений. Он утверждал, что рост производительности ограничен, поскольку только часть задачи поддаётся распараллеливанию. Размер остальной «последовательной части» отличается в разных задачах, но она есть всегда. Этот довод стал известен как закон Амдала.

Если построить график «ускорения» выполнения задачи в зависимости от количества выделенных ей параллельных процессоров, вы увидите следующее:


Это асимптотический график для фрагмента, который не поддаётся распараллеливанию («последовательная часть»), поэтому существует верхний предел максимального ускорения

В законе Амдала интересно то, что в 1969 году на самом деле было совсем немного многопроцессорных систем. Формула основана на другом принципе: если последовательная часть в задаче равна нулю, то это не одна задача, а несколько.

В нём используется два параметра: один для «конкуренции» (которая похожа на последовательную часть), а второй для «непоследовательности» (incoherence). Нил Гюнтер расширил закон Амдала на основе наблюдений за измерениями производительности многих машин и вывел универсальный закон масштабируемости (Universal Scalability Law, USL). Непоследовательность соотносится со временем, потраченным на восстановление согласованности, то есть общего взгляда на мир разных процессоров.

Когда одно ядро изменяет строку кэша, оно указывает другим ядрам извлечь эту строку из кэша. В одном CPU издержки согласования возникают из-за кэширования. (Это немного упрощённое описание… но в более точной формулировке всё равно есть издержки согласования). Если всем нужна одна и та же строка, они тратят время на её загрузку из основной памяти.

Штраф платится при изменении данных (как в случае транзакционных БД) или при чтении данных в случае согласованных в конечном счёте хранилищ. На всех узлах БД возникают издержки согласования из-за алгоритмов согласования и сохранения последовательности данных.

Если построить график USL в зависимости от количества процессоров, то возникнет такая зелёная линия:


Фиолетовая линия показывает, что предсказал бы закон Амдала

Это означает, что есть определённое количество узлов, при которых производительность максимальна. Обратите внимание, что зелёная линия достигает пика, а затем снижается. Я видел такое в реальном нагрузочном тестировании. Добавьте больше процессоров — и производительность снижается.

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

  1. Уменьшить последовательную часть
  2. Уменьшить издержки согласования

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

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

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

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

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

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

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

Напомним, что чрезмерное масштабирование вызывает снижение пропускной способности. Все эти методы направлены на уменьшение издержек согласования. Я видел коллективы, где казалось, что мы можем сократить половину людей и работать вдвое быстрее. Так что если у вас высокие издержки на согласование и слишком много людей, то команда в целом работает медленнее. Речь идёт о сокращении накладных расходов на обмен ментальными моделями. USL и издержки согласования теперь помогают понять, почему так происходит — это не просто очистка от мусора.

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

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

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

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

Разрывы между внутренними границами системы и расколы внутри команды. Ищите разрывы.

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

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

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть