Все публикации

Все материалы сайта в обратном хронологическом порядке

Эксплуатация Redis и карта выбора: когда он, а когда нет
📦

Базы данных

Эксплуатация Redis и карта выбора: когда он, а когда нет

Финал серии — про эксплуатацию Redis в бою и про трезвый выбор. Драйверы Go и Java и настройка пула соединений, что и как мониторить, типовые инциденты (latency-спайки, OOM, split-brain, шторм соединений) и их разбор. И главное — карта решений: когда Redis это правильный инструмент, а когда честнее взять полноценную БД, брокер или другое хранилище.

Тестирование распределённых систем: уровни, границы, асинхронность
📦

Архитектура

Тестирование распределённых систем: уровни, границы, асинхронность

Юнит-тесты не поймают то, что ломается между сервисами: несовместимый контракт, потерянное сообщение, гонку в eventual consistency. Как выстроить уровни для распределённой системы — юнит → интеграция (Testcontainers) → контрактные тесты (вместо хрупких e2e) → немного e2e, где тест-дубли ставить на границах, и как тестировать асинхронность и eventual так, чтобы тесты не были флаки. Стратегия, а не набор фреймворков

Streams, Lua и функции: программируемость Redis
📦

Базы данных

Streams, Lua и функции: программируемость Redis

Redis умеет не только хранить, но и выполнять логику на сервере. Разбираем три способа программируемости: Streams с consumer groups (журнал сообщений с подтверждениями), Lua-скрипты и Redis Functions (атомарные серверные процедуры), плюс обзор модулей. Честно проводим границу Streams vs Kafka — где Redis Streams достаточно, а где нужна полноценная брокерная платформа.

Keycloak на практике: realms, clients, потоки, деплой
📦

Безопасность

Keycloak на практике: realms, clients, потоки, деплой

От решения к практике: разворачиваем Keycloak 26.7.0 (Quarkus) в docker-compose с внешним PostgreSQL, разбираем анатомию realm (confidential vs public clients, redirect URI, realm- и client-роли, группы, client scopes), потоки authorization code + PKCE и client credentials, получаем первый access-token curl-ом к token endpoint и читаем реальный декодированный JWT (iss, aud=backend, exp, realm_access.roles). Realm-as-code через kc.sh export/import вместо click-ops, token lifespans и protocol mappers ролей.

Тестирование в разных языках: пирамида, Testcontainers, property-based
📦

Архитектура

Тестирование в разных языках: пирамида, Testcontainers, property-based

Одна дисциплина — пирамида тестов, дублёры, property-based и реальные зависимости через Testcontainers — в Go, Java и Python на одном домене. Что идиоматично, чем различаются экосистемы и почему на настройках по умолчанию property-тест находит реальный дефект ненадёжно во всех трёх сразу

Свой auth или готовый IdP: когда брать Keycloak
📦

Безопасность

Свой auth или готовый IdP: когда брать Keycloak

Не «как настроить Keycloak», а решение на уровень выше: когда вообще стоит брать готовый IdP вместо своего auth. Реальная цена «сделай сам» (восемь пластов — сессии, refresh, OAuth-флоу, MFA, passkeys, федерация — каждый отдельный проект и зона риска), что закрывает Keycloak, рамка «бай vs билд» (self-hosted vs managed Auth0/Cognito), РФ-угол on-prem и честная ops-цена stateful-сервиса

Защита от перегрузки: карта

Архитектура

Защита от перегрузки: карта

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

Память и вытеснение: как Redis живёт под давлением памяти
📦

Базы данных

Память и вытеснение: как Redis живёт под давлением памяти

Redis держит данные в оперативной памяти — значит, память рано или поздно закончится. Разбираем, что происходит на границе: как устроен аллокатор и откуда берётся фрагментация, какие есть политики вытеснения (LRU/LFU/по TTL/noeviction), что значит upper bound через maxmemory и что делает Redis при OOM. Плюс инструменты диагностики: MEMORY DOCTOR, INFO memory.

Сквозные гарантии и жизнь пайплайна
📦

Сообщения

Сквозные гарантии и жизнь пайплайна

Каждое звено обещает своё, а отвечать приходится за цепочку целиком: как at-least-once складывается в effectively-once, где заканчивается транзакция Kafka, почему дедуп на стоке обязателен и как пайплайн переживает replay, эволюцию схемы и битые события

Репликация, Cluster и Sentinel: Redis как распределённая система
📦

Базы данных

Репликация, Cluster и Sentinel: Redis как распределённая система

Один Redis — это одно ядро и один узел отказа. Разбираем, как из него собирают распределённую систему: асинхронная репликация, автоматический failover через Sentinel, шардирование по hash slots в Cluster. И честно про цену: асинхронность означает возможную потерю подтверждённых записей, split-brain реален, а Sentinel — не консенсус-протокол уровня Raft. Команда WAIT смещает границу, но не отменяет её.

Эволюция схемы: что ломается молча в Avro, Protobuf и JSON Schema
📦

Архитектура

Эволюция схемы: что ломается молча в Avro, Protobuf и JSON Schema

Девять изменений схемы через Avro, Protobuf и JSON Schema в двух направлениях, и три исхода вместо двух: прочиталось, отказ и — самый дорогой — прочиталось неверно. Одно изменение дало три разных операционных ответа: два декодера и реестр схем

Собираем пайплайн: PostgreSQL → Debezium → Kafka → ClickHouse
📦

Сообщения

Собираем пайплайн: PostgreSQL → Debezium → Kafka → ClickHouse

Сквозная цепочка от изменения в PostgreSQL до строки в витрине: Debezium как коннектор Kafka Connect, outbox event router, snapshot и переход в streaming, сток в ClickHouse. Не про механику WAL и не про внутренности Kafka — про то, как это собирается вместе и где проходят швы

TLS-фундамент: цепочка доверия, рукопожатие и что видно в трафике
📦

Безопасность

TLS-фундамент: цепочка доверия, рукопожатие и что видно в трафике

Десять поломок цепочки доверия на четырёх клиентах: исход везде одинаковый, а различает их сказанное — openssl называет все шесть причин отказа, Go и Java по четыре. Плюс имя сервера открытым текстом в первом же пакете и честный счёт сообщений 1.2 против 1.3

WAL на службе: репликация, CDC и PITR
📦

Базы данных

WAL на службе: репликация, CDC и PITR

WAL как источник изменений: физическая репликация (стриминг WAL) против логической (декодирование в события), CDC через Debezium (чтение WAL/binlog/oplog), PITR через WAL archiving — и подводные камни: переполнение слотов, retention, идемпотентность потребителя

Зачем бинарный формат и что он стоит: JSON, Avro и Protobuf на весах
📦

Архитектура

Зачем бинарный формат и что он стоит: JSON, Avro и Protobuf на весах

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

Шардирование на практике: цена распределённых данных
📦

Базы данных

Шардирование на практике: цена распределённых данных

Разложить данные по узлам — самая простая часть. Дальше начинается счёт: запрос без ключа шардирования идёт во все шарды, join между по-разному распределёнными таблицами Citus по умолчанию вообще отказывается планировать, глубокая страница тащит с шардов сотни тысяч строк ради двадцати, а добавленный узел сам по себе не берёт на себя ни одного шарда. Всё — замерами на живом кластере Citus

encoding/json/v2 в Go 1.27: вы уже переехали, не написав ни строки
📦

Go

encoding/json/v2 в Go 1.27: вы уже переехали, не написав ни строки

encoding/json в Go 1.27 работает поверх нового движка v2 по умолчанию — обновивший тулчейн уже переехал, ничего не переписывая. На бенчах стенда это стоит decode в полтора-два раза дороже, а поведение при этом не меняется вовсе: строгость и выигрыш по аллокациям даёт только явный переход на encoding/json/v2 и потоковый jsontext.

Персистентность Redis: RDB, AOF и границы надёжности
📦

Базы данных

Персистентность Redis: RDB, AOF и границы надёжности

Redis умеет переживать перезапуск — но насколько надёжно? Разбираем два механизма персистентности честно: RDB-снимки, AOF-журнал, гибридный режим и политики fsync. Главный вопрос статьи — что именно теряется при сбое и почему Redis по умолчанию ближе к кэшу, чем к источнику истины. Проводим границу durability явно, а не на ощущениях.

Слайсы и карты в Go: внутренности и подводные камни
📦

Go

Слайсы и карты в Go: внутренности и подводные камни

Слайс — это заголовок (указатель, длина, ёмкость) над общим backing-массивом, и отсюда растут коварные баги: append молча перезаписывает «соседа», nil и пустой слайс не одно и то же. Карты рандомизируют порядок обхода и роняют процесс при конкурентной записи. Разбираем внутренности и подводные камни на живых примерах

Один поток и событийный цикл: откуда у Redis скорость
📦

Базы данных

Один поток и событийный цикл: откуда у Redis скорость

Redis обрабатывает команды в одном потоке — и при этом отдаёт сотни тысяч операций в секунду. Разбираем, почему single-threaded не значит медленно: событийный цикл, I/O-мультиплексирование, threaded I/O в новых версиях, пайплайнинг. И честно про обратную сторону: где один поток становится узким местом и откуда берётся хвостовая latency.

Итераторы в Go: range-over-func и пакет iter
📦

Go

Итераторы в Go: range-over-func и пакет iter

Go 1.23 разрешил range по функции: iter.Seq и iter.Seq2 — это функции-«пуш-итераторы», которые получают yield и вызывают его на каждом элементе. Как это работает под капотом, как писать свои итераторы, как связаны slices/maps-итераторы, ранний break и очистка — на живых примерах

Goroutine leak profile в Go 1.27: ловим утечки горутин в проде
📦

Go

Goroutine leak profile в Go 1.27: ловим утечки горутин в проде

Go 1.27 добавил профиль утёкших горутин — он выделяет именно те, что навсегда заблокированы на примитиве синхронизации. Что новый профиль видит, чего не видят pprof/goroutine и goleak, на воспроизводимых классах утечек, и как встроить его в мониторинг.

Обработка ошибок в Go: значения, обёртки, паники
📦

Go

Обработка ошибок в Go: значения, обёртки, паники

Ошибки в Go — обычные значения, а не исключения: их возвращают, оборачивают через %w, проверяют errors.Is/As сквозь цепочку и объединяют errors.Join. Разбираем sentinel и типизированные ошибки, когда уместны panic/recover, и знаменитый баг «типизированный nil в error != nil»

Redis вглубь: структуры данных и их внутренние кодировки
📦

Базы данных

Redis вглубь: структуры данных и их внутренние кодировки

Redis — не «строковый кэш», а сервер структур данных. Разбираем strings/hashes/lists/sets/zsets/streams и то, что скрыто под ними: внутренние кодировки (listpack, intset, skiplist, quicklist) и правила переключения между компактным и «большим» представлением. Честно: когда какая структура уместна и во что она обходится по памяти и по времени.

Flink DataStream API: когда SQL мало
📦

Сообщения

Flink DataStream API: когда SQL мало

Flink SQL/Table API и DataStream — два API над общим runtime, и для оконных агрегатов с джойнами декларативного хватает. Но реакция по таймеру, произвольное состояние, корреляция двух потоков с кастомной логикой, обогащение через broadcast/async и маршрутизация в side output живут в Java-первом DataStream API. Где кончается SQL и что даёт спуск: KeyedProcessFunction, состояние руками, event-time vs processing-time таймеры, connect + CoProcessFunction

Интерфейсы в Go: неявность, itab и ловушка nil
📦

Go

Интерфейсы в Go: неявность, itab и ловушка nil

Интерфейсы в Go удовлетворяются неявно, состоят из пары (тип, значение) и потому таят знаменитую ловушку: интерфейс с типизированным nil внутри сам НЕ равен nil. Разбираем маленькие интерфейсы, «accept interfaces, return structs», внутреннее устройство (itab), type assertions/switch и почему nil-интерфейс — не то, чем кажется

Flaky-тесты: почему мигают и как чинить
📦

Архитектура

Flaky-тесты: почему мигают и как чинить

Flaky-тест не «случайный» — у каждого мигания детерминированная причина: гонка, время, порядок выполнения, обход map, sleep вместо синхронизации. Разбираем пять классов на живом Go-стенде с реальной частотой мигания и настоящим детектором гонок, чиним каждый детерминизмом — а не ретраями

Память в Go: стек, куча и escape-анализ
📦

Go

Память в Go: стек, куча и escape-анализ

Где живёт значение — на стеке или в куче — в Go решает не программист, а escape-анализ компилятора. Что уводит переменную в кучу (возврат указателя, боксинг в interface, захват замыканием), как это увидеть через go build -gcflags=-m, чем это грузит сборщик мусора и как проверять бенчами — на живом стенде с реальным выводом

Конвейер для недоверенных файлов: архитектура, а не флаг
📦

Безопасность

Конвейер для недоверенных файлов: архитектура, а не флаг

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

Flink SQL, коннекторы и эксплуатация: от Table API до прода
📦

Сообщения

Flink SQL, коннекторы и эксплуатация: от Table API до прода

Писать Flink-джобы на низкоуровневом API нужно не всегда: Table API и Flink SQL закрывают большую часть задач декларативно, включая стриминговые джойны и агрегации. Плюс то, без чего не выйти в прод: коннекторы (Kafka, CDC, lakehouse), управление параллелизмом, диагностика backpressure, тюнинг чекпоинтов и апгрейд джобы через savepoint без потери состояния. Завершает погружение практикой эксплуатации

reflect в Go: когда оправдана рефлексия и чего она стоит
📦

Go

reflect в Go: когда оправдана рефлексия и чего она стоит

reflect даёт доступ к типам и значениям в рантайме — на нём стоят encoding/json, ORM, валидаторы. Но за гибкость платят: потеря типобезопасности, аллокации и заметное замедление. Разбираем Type/Value/Kind, изменяемость через reflect, три закона рефлексии и её цену — на бенчмарках рефлексия против прямого доступа

net/http вглубь: сервисы на стандартной библиотеке (и почему не gin)
📦

Go

net/http вглубь: сервисы на стандартной библиотеке (и почему не gin)

Стандартный net/http после Go 1.22 (роутинг по методу и пути, path values) + middleware-функции покрывают большинство HTTP-сервисов без фреймворка. Разбираем ServeMux, middleware, таймауты сервера и клиента — и дуализм gin: почему он самый популярный и почему для долгоживущего сервиса стоит держаться ближе к stdlib

Состояние и exactly-once в Flink: checkpoints, savepoints, 2PC
📦

Сообщения

Состояние и exactly-once в Flink: checkpoints, savepoints, 2PC

Стрим-процессор без надёжного состояния бесполезен: агрегаты, джойны, дедуп — всё это состояние, которое нельзя потерять при падении. Как Flink это решает: keyed vs operator state, state backends (heap vs RocksDB для состояния больше памяти), распределённые снапшоты через барьеры (алгоритм Chandy-Lamport), инкрементальные checkpoints и savepoints для апгрейда, и exactly-once end-to-end через two-phase commit в стоки

Отладка конкурентности в Go: race detector, утечки горутин, дедлоки
📦

Go

Отладка конкурентности в Go: race detector, утечки горутин, дедлоки

Как ловить конкурентные баги в Go: race detector по-настоящему (как читать отчёт, оверхед, место в CI), поиск утечек горутин через goleak и pprof, дедлоки и встроенный детектор, профили блокировок и мьютексов

Тихие отказы: сервис сломан, а логи чисты
📦

Безопасность

Тихие отказы: сервис сломан, а логи чисты

Повреждение кучи, которое никто не заметил: процесс отработал с кодом 0, в логах пусто. На стенде измерено, кто и когда ловит запись за границей буфера и сколько это стоит. Главная находка практическая: debug-аллокатор glibc обнаружил все проверенные смещения начиная с одного байта, обошёлся в единицы раз дороже по времени без заметного роста RSS — но по умолчанию он выключен, и включить его можно так, что он не включится.

Модель Flink: dataflow, event-time, watermarks и окна
📦

Сообщения

Модель Flink: dataflow, event-time, watermarks и окна

Что делает Flink настоящим стрим-процессором, а не «циклом по сообщениям»: dataflow-граф операторов на JobManager/TaskManager, различие event-time и processing-time (и почему первое — единственно честное для аналитики потоков), watermarks как механизм «мы уже видели всё до момента T», окна (tumbling/sliding/session) и что делать с опоздавшими данными. Фундамент серии про Flink

Тьюринг-полнота и выразительность: чему учит brainfuck
📦

Языки

Тьюринг-полнота и выразительность: чему учит brainfuck

Для чистых вычислений brainfuck покрывает тот же класс функций, что и Python, — все вычислимые по Тьюрингу, ни одной меньше. И при этом на нём ничего не пишут. Этот разрыв и есть тема: вычислительная мощность и выразительность — две разные оси, а мы их путаем, потому что обычные языки высоки по обеим. Brainfuck разводит их в чистом виде — и заодно объясняет, почему тьюринг-полнота в конфиге или системе типов чаще беда, чем достоинство

SBOM видит, сканер молчит: слепое пятно вендоренных зависимостей
📦

Безопасность

SBOM видит, сканер молчит: слепое пятно вендоренных зависимостей

Контролируемый эксперимент на живом стенде: один и тот же бинарник FFmpeg, упакованный под каноническим именем, получает 65 уязвимостей, а под вендорским — ноль. Разница только в имени пакета. Почему сканеры образов сопоставляют находки по идентичности компонента, а не по содержимому файла, что из-за этого пропускает Jellyfin, и как это чинить в своём конвейере.

PixelSmash: как 50-килобайтный видеофайл в папке роняет ваш сервер
📦

Безопасность

PixelSmash: как 50-килобайтный видеофайл в папке роняет ваш сервер

Разбор CVE-2026-8461: heap out-of-bounds write в декодере MagicYUV (FFmpeg/libavcodec) из-за рассинхронизации slice_height с chroma vertical subsampling. Срабатывает не от клика по видео, а от генерации превью в файловом менеджере или сканирования библиотеки медиасервера — фикс в FFmpeg 8.1.2, но кто реально уязвим к RCE, а кто просто падает, сильно разнится. Вывод — про изоляцию декодера как рубеж обороны, который не зависит от скорости патчей.

Модель памяти Go: happens-before и почему гонки — это не «иногда»
📦

Go

Модель памяти Go: happens-before и почему гонки — это не «иногда»

Что на самом деле гарантирует модель памяти Go: отношение happens-before, публикация данных через каналы, мьютексы и атомики, переупорядочивание операций и почему гонка данных делает программу некорректной — модель памяти перестаёт давать нужные гарантии, а не просто «изредка возвращает неверное значение»

Идентификаторы в разных языках и БД
📦

Архитектура

Идентификаторы в разных языках и БД

Как одна задача — сгенерировать UUIDv7/ULID/Snowflake — решается в Go, Java и Rust (и почему ops/sec между языками сравнивать нельзя), как типы колонок PostgreSQL (uuid/bytea/text) обходятся с этими значениями и как ::text-каст ломает индекс, и как согласовать идентификатор с ключом шардирования, чтобы монотонный ключ не устроил горячий узел.

Контекст в Go: отмена, дедлайны, values и анти-паттерны
📦

Go

Контекст в Go: отмена, дедлайны, values и анти-паттерны

context.Context — единый механизм отмены, дедлайнов и передачи request-scoped данных сквозь цепочку вызовов. Как отмена распространяется по дереву горутин, почему context идёт первым аргументом и не хранится в структуре, чем опасен WithValue и как не потерять отмену — на живом стенде

Тестирование в Go: table-driven, Testcontainers, -race
📦

Go

Тестирование в Go: table-driven, Testcontainers, -race

Практичное тестирование Go-сервиса: стандартный пакет testing и table-driven как фундамент, httptest для хендлеров, интеграционные тесты через testcontainers-go на реальных Postgres и Redis, детектор гонок -race и честное покрытие без самообмана — на одном сквозном стенде с живыми замерами

Документная модель и схема-дизайн: против реляционного рефлекса
📦

Базы данных

Документная модель и схема-дизайн: против реляционного рефлекса

BSON, embedding против referencing, денормализация и рост документа — как проектировать схему MongoDB запросом вперёд, а не таблицами, и где документ честная альтернатива JSONB в PostgreSQL, а где нет

Идентификаторы и производительность: локальность, bloat, WAL
📦

Базы данных

Идентификаторы и производительность: локальность, bloat, WAL

Случайный ID (UUIDv4) деградирует вставку в PostgreSQL: ниже плотность листьев B-tree, больше WAL, крупнее первичный индекс — измерено на стенде против bigint и монотонного UUIDv7. Плюс кросс-движковый разбор: миф «UUID-PK раздувает вторичные индексы» верен для MySQL/InnoDB и неверен для PostgreSQL; и когда монотонный ключ создаёт горячий шард (MongoDB ranged), а когда нет (ScyllaDB и Mongo hashed).

Shard-aware драйверы ScyllaDB: Go и Java на практике
📦

Базы данных

Shard-aware драйверы ScyllaDB: Go и Java на практике

Сколько реально даёт шард-осведомлённая маршрутизация в gocql и Java-драйвере, почему апстрим и форк ScyllaDB не могут сосуществовать в одном проекте, и как честно измерить эффект без JIT-искажений

Saga на практике: компенсации, изоляция, идемпотентность, tooling
📦

Архитектура

Saga на практике: компенсации, изоляция, идемпотентность, tooling

Концепция саги проста, а прод — нет: компенсация это не rollback, а обратное семантическое действие, и её порядок, идемпотентность и «а если компенсация упала» решают, работает система или разваливается. Плюс изоляция: сага даёт ACD, не ACID — грязные чтения и потерянные обновления реальны, и с ними борются семантическими локами и контрмерами. Разбираем классификацию шагов (compensatable/pivot/retriable), персистентность саги, tooling (Temporal/Camunda/Axon) и тестирование с инъекцией отказов

Как читать: дизассемблер и Plan 9-синтаксис
📦

Go

Как читать: дизассемблер и Plan 9-синтаксис

Как читать чужой Go-ассемблер: go tool objdump и -gcflags=-S, Plan 9-синтаксис (порядок операндов, суффиксы размера, псевдорегистры FP/SB/SP/PC) и разбор дизасма наивного dot product — доказательство того, что компилятор не векторизовал цикл

Конкурентность в Go: горутины, каналы и context без подводных камней
📦

Go

Конкурентность в Go: горутины, каналы и context без подводных камней

Как в Go на самом деле устроена конкурентность: дешёвые горутины и M:N-планировщик, каналы против мьютексов, context для отмены, рабочие паттерны (worker pool, fan-in/out, pipeline) и типичные подводные камни — гонки, утечки горутин и дедлоки

Выбор идентификатора: bigint, UUID, ULID, Snowflake

Базы данных

Выбор идентификатора: bigint, UUID, ULID, Snowflake

Идентификатор — проектное решение с отложенной ценой. Разбор bigint, UUIDv4, UUIDv7/ULID, Snowflake, ObjectId по осям, которые реально влияют на систему: кто генерирует, монотонность и сортируемость, размер ключа, что утекает наружу, вероятность коллизий. Главная ось — не «UUID или число», а случайный против монотонного; дерево выбора и разбор мифов.

CQRS на практике: проекции, rebuild, консистентность, tooling
📦

Архитектура

CQRS на практике: проекции, rebuild, консистентность, tooling

Разделить чтение и запись — идея на слайде. На проде всё в проекциях: как строить read-модели, как жить с их отставанием (read-your-writes ломается), как пересобирать проекцию без даунтайма (blue-green, чекпоинты, идемпотентное применение) и когда CQRS оправдан без Event Sourcing, а когда тащит его за собой. Разбираем sync vs async проекции, несколько read-моделей на запрос, tooling (Axon/EventStoreDB/Marten) и типовую ошибку — CQRS поверх обычного CRUD

Go assembly: зачем оно вообще и где живёт в stdlib
📦

Go

Go assembly: зачем оно вообще и где живёт в stdlib

Зачем в Go может понадобиться ассемблер, где он реально работает в stdlib (crypto, math/bits, bytes.IndexByte, runtime) и почему в 99% случаев правильный ответ — не писать asm. Знакомство со сквозным примером серии — dot product для []float64

MirrorMaker 2 и геораспределённый Kafka: репликация между кластерами, DR, active-active
📦

Сообщения

MirrorMaker 2 и геораспределённый Kafka: репликация между кластерами, DR, active-active

Один кластер Kafka живёт в одном дата-центре — а бизнесу нужны катастрофоустойчивость и присутствие в нескольких регионах. Разбираем два подхода: растянутый (stretch) кластер против репликации отдельных кластеров через MirrorMaker 2; что MM2 на самом деле переносит (топики, offset’ы, ACL, конфиги) и как работает трансляция offset при failover; топологии active-passive/active-active/hub-and-spoke; RPO/RTO, failover и failback; цена латентности и трафика между регионами. С живым стендом из двух KRaft-кластеров и MM2.

Kafka-клиенты в разных языках: драйверы, родословные, различия
📦

Сообщения

Kafka-клиенты в разных языках: драйверы, родословные, различия

Клиент Kafka делает куда больше, чем «подключиться»: партиционирование, батчинг, сжатие, управление offset, ребаланс, идемпотентность, транзакции — и всё это разные библиотеки реализуют по-разному. Три родословные (референсный JVM-клиент, обёртки над librdkafka на C, чистые реализации протокола), почему у Go сразу несколько драйверов (franz-go/sarama/segmentio/confluent) и чем они отличаются, и что из этого следует для фич, производительности и деплоя. С живыми примерами produce/consume на Java, Go, Rust, Python, C#, C++, Scala

ClickHouse, TimescaleDB, DuckDB: что выбрать под аналитику
📦

Базы данных

ClickHouse, TimescaleDB, DuckDB: что выбрать под аналитику

Карта выбора аналитической БД по нишам: масштабная аналитика на ClickHouse, аналитика и time-series внутри экосистемы PostgreSQL на TimescaleDB, встроенная локальная аналитика на DuckDB — с учётом стоимости и эксплуатации

Когда нужна ScyllaDB и как думать данными: моделирование под wide-column
📦

Базы данных

Когда нужна ScyllaDB и как думать данными: моделирование под wide-column

Чем wide-column-модель отличается от реляционной, как проектировать партиции «запрос-первым», почему плохой ключ партиции убивает производительность — на живых числах ScyllaDB

Event Sourcing на практике: event store, проекции, снапшоты, replay
📦

Архитектура

Event Sourcing на практике: event store, проекции, снапшоты, replay

Концепцию Event Sourcing легко полюбить и трудно эксплуатировать: где хранить события (EventStoreDB vs Kafka vs Postgres), как строить и перестраивать проекции (read models), зачем снапшоты и как их делать, как реплеить историю, что такое upcasting при эволюции событий, оптимистичный конкаренси-контроль через expected version — и как жить с append-only, когда приходит GDPR-запрос на удаление

ClickHouse и S3: многоуровневое хранение и внешние данные
📦

Базы данных

ClickHouse и S3: многоуровневое хранение и внешние данные

Две грани S3 в ClickHouse: многоуровневое хранение (hot/cold-тиринг MergeTree через storage policies и TTL MOVE на S3, separation of storage/compute) и S3 table function для запроса и загрузки Parquet прямо из объектного хранилища. С живым стендом на MinIO

Работающий кластер ещё не значит восстановимый: четыре отказа при bootstrap Kubernetes на Talos

Kubernetes

Работающий кластер ещё не значит восстановимый: четыре отказа при bootstrap Kubernetes на Talos

Разбор четырёх отказов, случившихся при развёртывании Talos-кластера с нуля: дедлок helm –wait, незеркалированный реестр, переехавший чарт-репозиторий и PROXY protocol без прокси. Ни один не виден на работающем кластере, три из четырёх сломали бы восстановление прода. С разбором ложных гипотез и границей доказанного.

22 минуты вместо двух: как контейнер на каждый тест съедал прогон — и что помогло
📦

Performance

22 минуты вместо двух: как контейнер на каждый тест съедал прогон — и что помогло

Интеграционные тесты Go-сервиса шли 22 минуты и случайно падали по таймауту — списывали на медленную машину. Причина оказалась арифметической: 266 вызовов тестового хелпера поднимали 266 контейнеров Postgres. Разбираем переход на один контейнер и CREATE DATABASE … TEMPLATE, замеры до и после (×10 и ×36), воспроизводимый стенд, границы приёма — права, FORCE, размер шаблона, параллельность пакетов — и честную границу между тем, что измерено, и тем, что осталось правдоподобной гипотезой

Эксплуатация и тюнинг ClickHouse: merges, mutations, мониторинг, backup
📦

Базы данных

Эксплуатация и тюнинг ClickHouse: merges, mutations, мониторинг, backup

Что нужно знать про ClickHouse в проде: parts и фоновые merges, почему mutations (ALTER UPDATE/DELETE) дорогие и асинхронные, мониторинг через system.*-таблицы, backup/restore и тюнинг — codec-сжатие колонок, гранулярность индекса, память запроса. С живыми числами и продакшн-чеклистом

Распределённый ClickHouse: шардирование, репликация, Keeper
📦

Базы данных

Распределённый ClickHouse: шардирование, репликация, Keeper

Как ClickHouse масштабируется горизонтально: шардирование и репликация через ClickHouse Keeper, ReplicatedMergeTree и Distributed-таблицы, что ломается при падении узла — реплика недоступна против шард недоступен. Живой кластер 2 шарда × 2 реплики

Go 1.20 и RSA: что на самом деле замедлилось — и как ловить регрессии производительности
📦

Performance

Go 1.20 и RSA: что на самом деле замедлилось — и как ловить регрессии производительности

В Go 1.20 crypto/rsa перешёл на constant-time bigmod ради защиты от тайминговых атак — и просел по скорости. Разбираем на живой матрице версий, где просело сильнее (спойлер: подпись подорожала на 34–61%, а публичные проверка и шифрование — в 5–7 раз), почему, что это значит для JWT, и как поставить CI-гейт, который ловит такие регрессии до прода

Материализованные представления и real-time агрегации в ClickHouse
📦

Базы данных

Материализованные представления и real-time агрегации в ClickHouse

Материализованные представления в ClickHouse как триггеры на вставку, предагрегация через AggregatingMergeTree и SummingMergeTree, чтение потока из Kafka через Kafka engine, TTL и ретеншн, проекции — как строить обновляемые в реальном времени агрегаты

ClickHouse-драйверы: когда какой (ch-go, clickhouse-go, JDBC, HTTP)
📦

Базы данных

ClickHouse-драйверы: когда какой (ch-go, clickhouse-go, JDBC, HTTP)

Драйвер ClickHouse — половина производительности: низкоуровневый колоночный ch-go против эргономичного clickhouse-go (native и database/sql), clickhouse-java client-v2 против clickhouse-jdbc, и HTTP-интерфейс. Живой бенчмарк вставки и запроса, когда какой оправдан, карта выбора

Индексы и языки/ORM: зависимость и особенности
📦

Базы данных

Индексы и языки/ORM: зависимость и особенности

Зависят ли индексы от языка программирования и как ORM влияют на их использование: генерируемые запросы и N+1, неявные приведения типов, prepared statements и план, миграции индексов и как из кода проверить, что индекс реально работает

ClickHouse из Go и Java: MergeTree, вставки и запросы
📦

Базы данных

ClickHouse из Go и Java: MergeTree, вставки и запросы

Как устроено семейство MergeTree (ORDER BY, PRIMARY KEY, партиционирование), почему в ClickHouse нельзя вставлять по одной строке и что дают async inserts, и как всё это выглядит из клиентов clickhouse-go и clickhouse-java — нативный протокол против HTTP

Kafka: лог, топики, партиции — ментальная модель
📦

Сообщения

Kafka: лог, топики, партиции — ментальная модель

Kafka — это распределённый лог, а не очередь: топики и партиции, offset, producer и consumer, как ключ определяет партицию и порядок, зачем репликация. Вводная серии «Kafka вглубь»: правильная ментальная модель и когда Kafka уместен, а когда нет

Надёжность распределённых систем: карта

Архитектура

Надёжность распределённых систем: карта

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

Когда нужен OLAP: ClickHouse против PostgreSQL для аналитики
📦

Базы данных

Когда нужен OLAP: ClickHouse против PostgreSQL для аналитики

Чем OLAP-нагрузка отличается от OLTP, как колоночное хранение и векторное исполнение делают ClickHouse быстрым на аналитике, в какой момент PostgreSQL перестаёт тянуть агрегаты по большим таблицам — и где ClickHouse категорически не подходит

Паттерны и антипаттерны индексирования
📦

Базы данных

Паттерны и антипаттерны индексирования

Что делать и чего избегать с индексами: over-indexing и write-amplification, неиспользуемые и дублирующие индексы, bloat и обслуживание, covering под горячие запросы, online-создание без блокировок, индексы под пагинацию — и антипаттерн «индекс на всё»

Мульти-хранилищный стенд: один сценарий по всем БД и карта выбора
📦

Базы данных

Мульти-хранилищный стенд: один сценарий по всем БД и карта выбора

Финал серии: единый сценарий (списание с инвариантом «баланс не в минус») реализован поверх PostgreSQL, Redis, MongoDB и ScyllaDB и прогнан одним нагрузчиком. Что каждая система гарантирует из коробки, что ломается под конкуренцией, цена корректности — и итоговая карта выбора

Брокеры и стриминг: транзакции в очереди и логе — RabbitMQ и Kafka
📦

Базы данных

Брокеры и стриминг: транзакции в очереди и логе — RabbitMQ и Kafka

Что значит «транзакция» в брокере: AMQP-транзакции RabbitMQ против publisher confirms, транзакционный producer и exactly-once в Kafka, consume-process-produce и read_committed, границы EOS и outbox-паттерн как мост к БД. Примеры на Go и Java

Как выбирать и использовать индексы
📦

Базы данных

Как выбирать и использовать индексы

Практика индексов: селективность и кардинальность, покрывающие индексы и index-only scan, составные индексы и порядок колонок, частичные и функциональные, и главное — почему индекс НЕ используется и как это увидеть

Вероятностные структуры: Bloom-фильтры и компания — когда эффективны, когда нет
📦

Performance

Вероятностные структуры: Bloom-фильтры и компания — когда эффективны, когда нет

Bloom-фильтры, Cuckoo, HyperLogLog, Count-Min Sketch и родственники: как они экономят память и время ценой приблизительности, где реально эффективны (LSM-БД, кэш/CDN, дедупликация, аналитика уникальных), а где только вредят — с прикидкой параметров и примерами на Go и Java

KV и документные: «транзакций» почти нет — Redis, MongoDB, ScyllaDB
📦

Базы данных

KV и документные: «транзакций» почти нет — Redis, MongoDB, ScyllaDB

Что означает «транзакция» там, где нет классического ACID-движка: Redis MULTI/EXEC без rollback и WATCH-CAS, multi-document транзакции MongoDB поверх snapshot, LWT на Paxos в ScyllaDB и почему BATCH — это не транзакция. Примеры на Go и Java

Транзакции в реляционных БД на практике: PostgreSQL, изоляция и нагрузочный стенд
📦

Базы данных

Транзакции в реляционных БД на практике: PostgreSQL, изоляция и нагрузочный стенд

PostgreSQL как эталон управляемой изоляции: уровни в деле, SELECT FOR UPDATE, SERIALIZABLE с retry на 40001, advisory locks. Примеры на Go (pgx) и Java (JDBC) плюс нагрузочный стенд, воспроизводящий lost update и write skew под конкуренцией

Индексы в БД: зачем нужны, какие бывают и как устроены
📦

Базы данных

Индексы в БД: зачем нужны, какие бывают и как устроены

Фундамент про индексы: зачем они (ускорение поиска ценой записи и места), какие бывают — B-tree, hash, bitmap, инвертированный (GiN), GiST, BRIN, R-tree, LSM — и как каждая структура устроена, что ускоряет и чем платит

Сканирование уязвимых зависимостей (SCA): Dependabot, osv-scanner, govulncheck
📦

Безопасность

Сканирование уязвимых зависимостей (SCA): Dependabot, osv-scanner, govulncheck

SCA на практике: почему Dependabot показывал 0, а osv-scanner нашёл полсотни; чем различаются базы advisory (GitHub Advisory, OSV, Go vuln DB, RustSec) и методы (presence-based против call-graph govulncheck); плейбук починки транзитивных CVE по экосистемам (Go, Maven, Python, Rust) и честная работа с no-fix и ложными срабатываниями

Go modules: go.mod, версионирование и управление зависимостями

Go

Go modules: go.mod, версионирование и управление зависимостями

go.mod, go.sum, семантический импорт версий, minimal version selection, replace/exclude, vendoring и workspaces (go.work). Как Go решает, какие версии зависимостей брать, почему MVS отличается от других менеджеров пакетов, и как этим управлять на практике

Бэкапы ценного: фото, эскизы, проекты и готовность к потере

Инфраструктура

Бэкапы ценного: фото, эскизы, проекты и готовность к потере

Как защитить необратимые данные — фото, свои эскизы и проекты: правило 3-2-1, проверка дисков и тест восстановления простыми словами, готовые бытовые сценарии без командной строки и облака (зашифрованный диск у близких) и что делать, если облако кажется дорогим

slog: структурированное логирование в стандартной библиотеке Go
📦

Go

slog: структурированное логирование в стандартной библиотеке Go

log/slog (Go 1.21) — структурированное логирование в стандартной библиотеке: уровни, атрибуты, группы, JSON и text-хендлеры, With для контекста и связка с context. Как устроены Handler/Record, как писать свой хендлер и почему slog вытесняет самописные обёртки над log — на живых примерах вывода

Полнотекстовый поиск в OpenSearch: запросы, анализаторы и подсветка результатов
📦

Базы данных

Полнотекстовый поиск в OpenSearch: запросы, анализаторы и подсветка результатов

Как устроен полнотекстовый поиск в OpenSearch: типы запросов, анализаторы для русского и английского языков, подсветка результатов, оптимизация релевантности и сравнение с полнотекстовым поиском в PostgreSQL и MongoDB

Гарантии доставки и идемпотентность: как получить effectively-once
📦

Архитектура

Гарантии доставки и идемпотентность: как получить effectively-once

Вся событийная архитектура держится на одной связке, которую редко проговаривают вслух: at-least-once доставка + идемпотентный консьюмер = effectively-once. Разбираем, почему сквозной exactly-once недостижим в принципе, чем at-least-once отличается от at-most-once, как сделать консьюмер идемпотентным (ключи идемпотентности, dedup-хранилище, естественная идемпотентность, окно дедупа) и где эта связка уже работает в серии — в outbox, saga и проекциях

Досрочное погашение и архитектурные решения: почему ранняя коррекция курса обходится дешевле

Архитектура

Досрочное погашение и архитектурные решения: почему ранняя коррекция курса обходится дешевле

Аннуитетный кредит как модель технического долга. Интерактивный калькулятор, реальные ставки ЦБ РФ и архитектурная аналогия: чем раньше вы меняете курс – тем дешевле это стоит

Что кладём в событие: notification vs event-carried state transfer
📦

Архитектура

Что кладём в событие: notification vs event-carried state transfer

Самое базовое решение событийной архитектуры — что положить в событие: тонкое уведомление (просто «заказ изменился», ID) или толстое событие с полным состоянием. Первое слабо связывает, но провоцирует «GET-storm» обратно на источник; второе автономно, но раздувает payload, устаревает и тащит связанность по данным. Разбираем два паттерна из таксономии Фаулера, их компромиссы (связанность ↔ автономность ↔ staleness), версионирование нагрузки, приватность в событии и когда что выбирать

Хореография vs оркестрация: кто знает бизнес-процесс
📦

Архитектура

Хореография vs оркестрация: кто знает бизнес-процесс

Многошаговый процесс между сервисами координируют двумя способами: хореография — сервисы реагируют на события, единого дирижёра нет, поток эмерджентный; оркестрация — центральный координатор явно ведёт шаги и обрабатывает отказы. Разница не в технологии, а в том, ГДЕ живёт знание о процессе: размазано по сервисам или собрано в одном месте. Разбираем компромиссы, антипаттерны (event-спагетти vs god-оркестратор), когда что и почему реальные системы почти всегда гибрид

sqlc и SQL-builders в Go: генерация кода из SQL vs конструирование запросов

Go

sqlc и SQL-builders в Go: генерация кода из SQL vs конструирование запросов

Два подхода к работе с SQL в Go без ORM на одном домене: sqlc генерирует типизированный код из SQL, а SQL-builders (squirrel, goqu) конструируют запросы программно. Где каждый силён, где кусается и как их комбинировать

Streams в RabbitMQ: Kafka-подобный лог и можно ли заменить Kafka
📦

Сообщения

Streams в RabbitMQ: Kafka-подобный лог и можно ли заменить Kafka

Что такое streams в RabbitMQ — append-only лог с offset-чтением и репликацией, как их объявлять и читать (native stream-протокол и AMQP), super streams для партиционирования, честное сравнение с Kafka и разбор, где RabbitMQ Streams реально заменяет Kafka, а где нет

HTTP/2 Bomb: как склейка двух старых приёмов кладёт веб-сервер

Безопасность

HTTP/2 Bomb: как склейка двух старых приёмов кладёт веб-сервер

Разбор атаки HTTP/2 Bomb: HPACK-бомба и удержание через нулевое flow-control окно по отдельности известны десять лет, но вместе кладут nginx, Apache, IIS, Envoy и Pingora за секунды. Как устроен механизм на уровне фреймов, кто уязвим и что пропатчено, почему Angie (и khorost.tech) не тронут, как проверить свой сервер — и почему эту склейку первым увидел ИИ

Terraform для Docker-хостов и сетей: где проходит граница пользы
📦

Инфраструктура

Terraform для Docker-хостов и сетей: где проходит граница пользы

Где Terraform реально помогает в Docker-инфраструктуре — хост, firewall, генерация Ansible inventory, — а где только добавляет слой абстракции: lifecycle контейнеров и docker-сети. С рабочим примером стыка Terraform → Ansible из digital-cookbook

Ansible и Docker Compose: раскатываем сервисы без ручной магии
📦

Инфраструктура

Ansible и Docker Compose: раскатываем сервисы без ручной магии

Как использовать Ansible для управления Docker Compose стеками: inventory, group_vars для нескольких окружений, шаблоны compose и .env, секреты через ansible-vault и модуль community.docker.docker_compose_v2 — с рабочим примером из digital-cookbook

Proxmox + Terraform: автоматизируем создание VM и контейнеров в домашней лаборатории
📦

Инфраструктура

Proxmox + Terraform: автоматизируем создание VM и контейнеров в домашней лаборатории

Как использовать Terraform для автоматического создания и управления виртуальными машинами и LXC-контейнерами в Proxmox VE: провайдер bpg/proxmox, cloud-init шаблоны, примеры VM и CT, типичные ошибки

Распределённые конфигурации: etcd, Consul, Vault и когда они действительно нужны
📦

Архитектура

Распределённые конфигурации: etcd, Consul, Vault и когда они действительно нужны

Когда конфигурация через env и файлы перестаёт работать, какие задачи решают etcd, Consul и Vault, чем они отличаются и как не усложнить систему раньше времени

Сквозной итоговый кейс: собираем рабочую систему лунной базы

Архитектура

Сквозной итоговый кейс: собираем рабочую систему лунной базы

Финальная статья архитектурно-аналитической серии: один сценарий лунной базы, пройденный целиком — от problem statement и требований через доменную модель, C4, взаимодействия и согласованность до эксплуатации, чтобы увидеть, как все решения складываются в одну систему

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

Архитектура

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

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

Согласованность данных: где нужна строгая, а где достаточно «в итоге»

Архитектура

Согласованность данных: где нужна строгая, а где достаточно «в итоге»

Статья архитектурно-аналитической серии на примере лунной базы: как выбирать уровень согласованности данных под реальные сценарии — строгая, eventual или пакетная — и почему «согласованность везде» ломает систему так же, как её отсутствие

Взаимодействия и интеграции: где ломается кажущаяся простота

Архитектура

Взаимодействия и интеграции: где ломается кажущаяся простота

Статья архитектурно-аналитической серии на примере лунной базы: как аналитика и архитектура по-разному смотрят на синхронные и асинхронные взаимодействия, REST, события, команды и очереди — и где простая на схеме интеграция оказывается дорогой

C4-модель для аналитика: не рисовать красиво, а думать точно

Архитектура

C4-модель для аналитика: не рисовать красиво, а думать точно

Статья архитектурно-аналитической серии на примере лунной базы: как использовать C4-модель не как способ рисовать красивые схемы, а как инструмент точного разговора между аналитикой, архитектурой, разработкой и инженерными командами

Как доменная модель ломает и спасает архитектуру

Архитектура

Как доменная модель ломает и спасает архитектуру

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

Паттерны снижения трения при работе с AI-ассистентами: разбор статьи Rahul Garg

AI

Паттерны снижения трения при работе с AI-ассистентами: разбор статьи Rahul Garg

Разбор статьи с martinfowler.com о пяти паттернах эффективной работы с AI-ассистентами в разработке: Knowledge Priming, Design-First Collaboration, Context Anchoring, Encoding Team Standards и Feedback Flywheel — с микропримерами, личным опытом и критическим взглядом

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

Инструменты

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

Универсальный гайд по настройке рабочего окружения для изучения любого языка: установка runtime, выбор редактора, первый запуск, менеджер зависимостей и альтернативный путь через Docker

Java для backend и контейнеров: где она по-прежнему очень сильна

Java

Java для backend и контейнеров: где она по-прежнему очень сильна

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

System Design без культа идеальных схем

Архитектура

System Design без культа идеальных схем

Системный дизайн без академизма и культа «идеальных схем»: с чего начинать проектирование, как думать про контекст и trade-offs, и почему хорошая архитектура почти никогда не выглядит как красивая универсальная диаграмма

OpenTelemetry Collector: зачем он нужен и как на него правильно смотреть

Наблюдаемость

OpenTelemetry Collector: зачем он нужен и как на него правильно смотреть

Зачем нужен отдельный слой сбора телеметрии, как Collector устроен, сколько ресурсов потребляет, какие deployment-паттерны бывают, типичные ошибки и когда он действительно оправдан