Обновить
32K+

Распределённые системы *

Нюансы проектирования распределенных систем

24,34
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Наносервисы — как довести распределенные системы до логического конца

Уровень сложностиСредний
Время на прочтение13 мин
Охват и читатели10K

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

Какой подход выбрали коллеги и причем тут бог Солнца? Давайте выясним.

Читать далее

Новости

5ⁿ → 4n+1: сколько на самом деле дают редукции в explicit‑state model checking

Уровень сложностиСложный
Время на прочтение16 мин
Охват и читатели4.6K

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

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

Три результата, ради которых стоит читать дальше:

Читать далее

River OSS и Kafka: почему transactional outbox не гарантирует порядок событий агрегата

Уровень сложностиПростой
Время на прочтение32 мин
Охват и читатели6.2K

Меня зовут Василий Миловидов, я системный архитектор в крупной компании. Мы строим обмен между сервисами на событиях: сервис меняет агрегат в PostgreSQL, в той же транзакции кладёт задачу в outbox на River, воркер публикует событие в Kafka с ключом aggregate_id.

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

Статья написана для моей команды, чтобы у всех была одна картина проблемы и один язык для её обсуждения. Если она пригодится кому‑то ещё, тем лучше. Отдельно я старался, чтобы текст был понятен человеку, который только начинает работать с распределёнными системами: каждый механизм я объясняю с точки зрения того, что он делает и от чего защищает.

Всё, что касается поведения River, Kafka и PostgreSQL, проверено по документации, ссылки собраны в конце. Там, где утверждение является моим выводом, а не документированным поведением, я это отмечаю отдельно.

Читать далее

Мой тестовый харнесс нашёл баг в моей же реализации Raft. Рассказываю, как именно

Уровень сложностиСложный
Время на прочтение4 мин
Охват и читатели6.1K

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

Я писал реализацию Raft на TypeScript и построил вокруг неё музей багов: семь экспонатов, каждый выключает ровно одно правило алгоритма и требует, чтобы харнесс поймал это — с сидом и с именем нарушенного свойства.

Один экспонат появился не по плану. Харнесс нашёл баг в самой реализации: все пять свойств безопасности держались, логи совпадали, никто не падал — и на двадцать пятом сиде две реплики разъехались навсегда. Разбираю, почему так вышло, как устроен харнесс и чего этот метод не доказывает.

Читать разбор

Как мы заменили 30-минутный polling на IMAP IDLE и построили маленькую распределённую систему

Уровень сложностиСредний
Время на прочтение17 мин
Охват и читатели7.8K

Когда-то наш почтовый загрузчик был обычным методом с @Scheduled. Раз в 30 минут он подключался к ящикам, искал новые вложения и запускал их обработку. Решение было простым, понятным и долгое время вполне рабочим.

Через несколько итераций вокруг того же загрузчика уже существовали IMAP IDLE listener'ы, PostgreSQL leases, heartbeat экземпляров приложения, перебалансировка почтовых ящиков между pod'ами, UID checkpoints, постоянная идемпотентность и отдельная обработка FolderClosedException. В какой-то момент мы даже попробовали держать несколько IMAP-соединений к одному ящику, но затем сознательно удалили эту часть архитектуры.

Это история не о том, как мы «заменили polling на push» одной настройкой. Она о том, как безобидный интеграционный адаптер постепенно превратился в маленькую распределённую систему. И о границе параллелизма, которую мы сначала провели не там.

Получить письмо

Как создать архитектуру B2B-пайплайна, в которой не проверяется лишнее и не теряется нужное

Уровень сложностиСредний
Время на прочтение5 мин
Охват и читатели6.6K

На входе у нас вакансия, на выходе — проверенный контакт в одной из трёх кампаний. Между ними: дубли, таймауты, catch-all, неоднозначные SMTP-ответы и окно, в котором процесс может упасть после передачи контакта, но до сохранения статуса. Показываю, как мы расставили дешёвые и дорогие проверки и почему выбрали at-least-once.

Читать далее

Цена, которой не существовало: две недели поиска бага, который не видел мониторинг

Уровень сложностиПростой
Время на прочтение8 мин
Охват и читатели7K

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

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

Читать далее

Как тестировать распределенные системы: тайм-ауты, дубликаты, Saga и частичные отказы

Уровень сложностиСредний
Время на прочтение16 мин
Охват и читатели6.6K

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

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

Самое очевидное решение — повторить запрос. И получить второе списание.

В монолите подобные ситуации встречаются реже: операция обычно проходит внутри одного процесса или одной транзакции, поэтому место сбоя проще определить. В распределенной системе между началом и концом одной бизнес-операции могут быть несколько сервисов, брокер сообщений, разные базы данных и внешний API (интерфейс программирования приложений). У каждого компонента при этом свое состояние и свое представление о том, что уже произошло.

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

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

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

Возьмем простой пример — оплату заказа в интернет-магазине.

Читать далее

Книга: «Основы Go»

Время на прочтение2 мин
Охват и читатели8K

Привет, Хаброжители! Язык Go востребован в разработке облачных сервисов и распределенных систем благодаря простоте, высокой производительности и встроенной поддержке конкурентности. Книга выходит за рамки синтаксиса и фокусируется на проектировании гибких и масштабируемых архитектур.

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

Читать далее

ggrebalance: Часть 3. Выполнение ребаланса

Уровень сложностиСредний
Время на прочтение28 мин
Охват и читатели7.7K

В статье рассматривается исполнительная часть утилиты ggrebalance: механизм физического перемещения primary- и mirror-сегментов между хостами кластера Greengage DB (open-source форк Greenplum), устройство конечного автомата ребаланса, отслеживание статусов операций, обработка сбоев и реентерабельность, откат перемещений, а также практические рекомендации по эксплуатации и итоговое сравнение с альтернативными инструментами.

Читать далее

Необратимая операция: как печатать чек, если непонятно, напечатался ли он

Уровень сложностиСредний
Время на прочтение8 мин
Охват и читатели6.3K

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

Читать далее

Почему MCP-вызов разрывал сквозной трейс GenAI-приложения в OpenTelemetry Demo 3.0 и как мы это исправили

Уровень сложностиСложный
Время на прочтение10 мин
Охват и читатели7.3K

Для проверки сквозного трейсинга GenAI-приложения мы взяли OpenTelemetry Demo 3.0. В обновлённом стенде уже были сервисы chatbot, agentи mcp, а также ИИ-спаны. Оставалось направить телеметрию по OTLP в ProtoOBP и открыть готовую цепочку вызовов. Но все спаны приехали, а единой истории не получилось: один пользовательский запрос распался на два трейса на границе MCP.

Автоматическая HTTP-инструментация связь не восстановила. Мы проследили traceparent до MCP _meta, нашли место потери контекста и добавили небольшой слой над ClientSession. После исправления цепочка собралась в единый трейс из 27 спанов.

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

Читать далее

«Похоже, это база» больше не ответ: как ИИ меняет расследование аварий в цифровых системах

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели7.3K

Спросите себя, что было результатом расследования сбоя десять лет назад, пять, год. Ответ будет примерно одинаковый – скриншот графика в рабочем чате и фраза «похоже, это база». Давайте посмотрим, что поменялось в 2026-м и как выглядит разбор аварии с помощью ИИ-агента.

Читать далее

Ближайшие события

Предел PostgreSQL: как кеш AI-тестов вырос до миллиарда записей и переехал на ClickHouse

Уровень сложностиПростой
Время на прочтение5 мин
Охват и читатели7.2K

От проблем PostgreSQL к скорости ClickHouse. Рассказываем, как переработали архитектуру кеширования для AI-тестов, чтобы выполнять более 2 млн запросов и обрабатывать 20 млрд записей в день, сохранив среднюю задержку поиска элементов на уровне 250 мс.

Читать далее

Вам нужны не упорядоченные, а умные события

Время на прочтение11 мин
Охват и читатели6.9K

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

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

Читать далее

Погружаемся в пучины цифро-финансового безумия Думы РФ — обзор закона о криптовалюте

Уровень сложностиСредний
Время на прочтение15 мин
Охват и читатели9.8K

Ну вот оно и свершилось. Спустя 15 лет, и на 10 лет позже после мировых лидеров, наши чиновники родили не то сына, не то дочь, не мышонка, не лягушку, а неведому зверюшку. Иначе говоря - законом о цифровых валютах.

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

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

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

Начать погружение

Программирование как экспериментальная метафизика

Уровень сложностиСложный
Время на прочтение27 мин
Охват и читатели13K

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

Читать далее

ggrebalance: Часть 2. Планирование операции ребаланса

Уровень сложностиСредний
Время на прочтение18 мин
Охват и читатели7.6K

В статье рассматривается планирование ребаланса кластера Greengage DB (open-source fork Greenplum) после shrink, декомиссии и добавления хостов: формальная модель размещения primary- и mirror-сегментов, минимизация числа перемещений, сравнение точных и эвристических алгоритмов и реализация планировщика в ggrebalance

Читать далее

Как тестируют баги, которые невозможно воспроизвести

Уровень сложностиСредний
Время на прочтение17 мин
Охват и читатели16K

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

В статье разберём, как deterministic simulation testing помогает управлять временем, сетью и отказами, воспроизводить сложные сценарии по seed и проверять системные инварианты на примерах FoundationDB и TigerBeetle.

Читать далее

Как использовать Kafka на собеседовании по System Design

Уровень сложностиПростой
Время на прочтение17 мин
Охват и читатели15K

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

Но за словами “добавим Kafka” скрывается много важных деталей: как выбрать ключ, сохранить порядок сообщений, распределить разделы между потребителями и не создать горячий раздел. В статье рассмотрим архитектуру Kafka, репликацию, смещения, повторные попытки и политики хранения.

Читать далее
1
23 ...