Мастерская IT-решений
149 subscribers
45 photos
2 videos
30 links
О проектировании систем и их взаимодействии. Теория и практические кейсы
Download Telegram
А вот и новость №6
Сегодня вылетаю на Merge Baltic!
Есть здесь те, кто тоже туда едет?
Forwarded from ИТ ПСБ
🐈 Наши коллеги едут в Светлогорск — чтобы представить ПСБ на Merge Baltic 2025.

➡️Роман Миловидов и Данила Шалыгин поделятся опытом выстраивания процесса управления потоком продуктовых задач в соответствии с целями бизнес-направления. Ответят на вопросы, как понять предназначение отдела, как использовать рефлексию в системах discovery и delivery, как визуализировать end2end процесс для управления потоком задач.

➡️Дарья Борисова расскажет реальную историю о том, как один аналитик смог создать интеграцию под ключ без командной работы. И обсудит, стоит ли аналитику брать на себя роль разработчика, где проходит грань между экономией бюджета и потерей качества, и каким может быть будущее профессии аналитика.

Merge — крупнейшая профессиональная конференция, где встречаются эксперты из самых разных сфер ИТ: от разработки до маркетинга.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🤩2👍1
Это ли не прекрасно...?
Виды кеширования и когда их выбирать

По расположению (архитектурный уровень)

🔹 Клиентское кеширование
Как работает: Браузер или мобильное приложение хранит статику (CSS, JS, картинки) и даже данные (via LocalStorage).
Когда использовать: Для снижения нагрузки на сервер и ускорения отклика для конечного пользователя. Рекомендуется использовать HTTP-заголовки Cache-Control, ETag.

🔹 Кеширование на прокси (CDN)
Как работает: Сеть доставки контента (Cloudflare, AWS CloudFront) кеширует статический и даже динамический контент на своих edge-серверах по всему миру.
Когда использовать: Для раздачи статики (изображения, видео) и динамического контента глобальной аудитории. Снижает задержку.

🔹 Веб-сервер / Кеш обратного прокси
Как работает: Nginx, Varnish кешируют целые HTML-страницы или API-ответы перед приложением.
Когда использовать: Для разгрузки backend-серверов. Идеально для страниц, которые одинаковы для многих пользователей (блог, новостная лента).

🔹 Кеширование приложения (In-Memory)
Как работает: Приложение хранит данные в своей оперативной памяти (например, HashMap в Java, dict в Python) или использует распределенный кеш (Redis, Memcached).
Когда использовать: Для кеширования результатов запросов к БД, тяжелых вычислений, сессий пользователей. Самый гибкий вид.

🔹 Кеширование базы данных
Как работает: Сама СУБД имеет внутренний кеш для результатов запросов и индексов.
Когда использовать: Работает "из коробки", но настраивается под конкретную СУБД. На него можно влиять, но основное управление — у базы данных.


По стратегии доступа

🔺Cache-Aside (Lazy Loading)
Как работает
1. Приложение ищет данные в кеше.
2. Если данные в кеше не найдены, берет из БД.
3. Приложение кладет данные в кеш

Простота, отказоустойчивость (при падении кеша система работает напрямую с БД).
Возможность пропуска кеша на каждый запрос, риск "стартового шторма" (т.е. когда за каждым запросом обращаемся в базу) после сброса кеша.

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

🔺 Read-Through
Как работает
Приложение всегда читает из кеша. Если данных нет, кеш сам загружает их из БД и возвращает приложению.

Чище архитектура приложения.
Требует от кеша возможности загружать данные (например, Redis Modules).

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

🔺 Write-Through

Как работает
Приложение записывает данные в кеш, а кеш синхронно записывает их в БД.

Гарантирует консистентность между кешем и БД.
Высокая задержка записи.

Когда использовать
Когда консистентность критически важна, а производительность записи — нет.


🔺 Write-Behind (Write-Back)
Как работает
Приложение записывает данные в кеш, который асинхронно (с задержкой) обновляет БД.

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

Когда использовать
Для данных, которые можно временно потерять или где запись очень частая (например, счетчики просмотров, лайки).
На что обратить внимание при внедрении кеша

🔛 Несогласованность данных
Самая частая проблема. Вы кешируете данные, они меняются в источнике, а в кеше остаются старые.
Решение: Грамотная стратегия инвалидации (TTL или по событию).

🔛 "Стартовый шторм" При перезапуске кеш пуст. Все запросы обрушиваются на базу данных и могут "положить" ее.
Решение: Предварительный "прогрев" кеша или использование постоянного хранилища для кеша.

🔛 Несанкционированное прокникновение
Запросы по несуществующим ключам (например, user_id=-1) постоянно пролетают мимо кеша и бьют по БД. Решение: Кешировать сам факт отсутствия данных (например, положить null с коротким TTL).

🔛 Разрушение кеша
Одновременная инвалидация очень популярного ключа (например, по истечению TTL), что приводит к лавине запросов в БД для его пересчета.
Решение: Использование механизма "блокировки" (mutex), чтобы только один поток пересчитывал значение, а остальные ждали.

🔛 Проблема "горячего" ключа
Один ключ (например, данные супер-популярного товара) получает огромное количество запросов, создавая нагрузку на один узел распределенного кеша.
Решение: Репликация "горячего" ключа на несколько узлов или его дублирование в локальном L1-кеше приложения.


С чего начать при внедрении кеша?
Небольшой план действий для начинающего кошатника 🐱 КЕШатника:
1. Измерьте и найдите самое медленное место.
2. Выберите тип кеша, который поможет в решении этой проблемы.
3. Внедрите простую стратегию (например, Cache-Aside с TTL).
4. Продумайте инвалидацию.
5. Мониторьте эффективность (количество попаданий и промахов кеша) и будьте готовы к подводным камням.

Часто самый большой выигрыш дает кеширование на уровне веб-сервера (Nginx) для статики и HTML и использование Cache-Aside паттерна с Redis/Memcached для данных приложения.
1👏1
Хотите несколько практических задач?
Такой опрос я проводила на одном из докладов, попробуем в онлайне такое провести. Здесь и задачи усложнились, и времени на подумать будет больше.

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

Варианты ответов

1️⃣ Кеш на уровне БД: Использовать встроенный кеш запросов базы данных. Время жизни — 10 минут.

2️⃣ Кеш на уровне приложения: Разместить в памяти приложения (например, с помощью Redis) объект "Профиль пользователя". Использовать стратегию LRU (Least Recently Used) и время жизни (TTL) 5 минут.

3️⃣ Кеш на уровне клиента: Отправлять заголовки HTTP-кеширования браузеру пользователя со временем жизни 1 час.

Пишите в комментарии свой вариант.
Ответ будем разбирать вечером.
🔥3
Правильный вариант:
2️⃣
(Кеш на уровне приложения).

Разбираем почему так.

• Почему НЕ вариант 1 (БД)
Кеш на уровне БД снимет нагрузку с движка базы, но не уменьшит количество самих запросов к ней. Он также негибкий — при изменении одного профиля инвалидировать кеш сложно.

• Почему НЕ вариант 3 (Клиент)
Данные профиля персональны и могут меняться. Если закешировать их в браузере на час, пользователь может не сразу увидеть свои обновления или изменения на странице друга. Кроме того, этот кеш не снимет нагрузку с серверной части.

• Почему вариант 2 (Приложение)
Это идеальный компромисс.
Расположение: Кеш в Redis расположен близко к приложению, снимает нагрузку с базы данных и drastically уменьшает количество запросов к ней.
Стратегия вытеснения: LRU отлично подходит для соцсети, так как вытесняет профили наименее активных пользователей, оставляя в кеше "горячие" данные.
Время жизни (TTL): 5 минут — разумный баланс между актуальностью данных (изменения станут видны в течение 5 минут) и эффективностью кеша.

Совпало?
будем делать еще задачку?
❗️Новая задачка! Потренируемся?

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

Варианты решения:

1️⃣ Кеш на уровне приложения: Кешировать баланс пользователя в Redis на 30 секунд для снижения пиковой нагрузки на систему.

2️⃣ Кеш на уровне БД: Настроить репликацию базы данных и читать историю операций с реплики, которая может отставать на несколько секунд.

3️⃣ Без кеширования: Не использовать кеш для этих данных вообще. Все запросы отправлять непосредственно в основную базу данных.

Кидайте свои варианты в комментарии. Разбирать будем вечером
Правильный вариант:
3️⃣ (Без кеширования), с оговоркой на вариант 2️⃣ для некоторых данных.

Объяснение
🟩 Почему вариант 3️⃣ — основной: Для строго консистентных данных, где критична абсолютная актуальность (например, текущий баланс), кеширование опасно. Пользователь может увидеть устаревшие данные и, например, совершить платеж, думая, что у него есть деньги. Любой TTL > 0 создает риск расхождения.

🟥 Почему не вариант 1️⃣ (Приложение): 30 секунд — это огромное окно неконсистентности для финансовых данных. Стратегия абсолютно неприемлема в контексте финансов.

🟧 Оговорка про вариант 2️⃣ (БД): Для истории операций, которая только добавляется, но не удаляется, можно использовать чтение с реплик (это форма кеширования). Пользователь может не заметить отставание в пару секунд, а нагрузка на основную базу снизится. Но для баланса это недопустимо.

Вывод: не все данные можно и нужно кешировать. Консистентность и актуальность иногда важнее производительности.
Хочу поделиться с вами статьей, тема которой сегодня волнует, я думаю, многих.

Что с ИТ-рынком?
Дефицит кадров? Перенасыщение? Что делать и куда бежать?
https://habr.com/ru/companies/ddosguard/articles/960606/

Статья холиварная (особенно в комментах).

От себя добавлю: в целом согласна с мнением редакции, но есть пара пунктов....

Работа для айтишника не может закончиться
Может. Для тех кто работает на создание ПО. Кто на поддержке, у того ситуация стабильнее.

В январе 2025 «Бизнес FM» стращал массовыми сокращениями в IT-отрасли (в реальности, если судить по приведенной Минцифры статистике, произошло прямо противоположное)
Противоположное? Серьёзно? На конференциях осеннего сезона я активно собираю статистику этого аспекта. И ещё никто не сказал мне "сокращения в моей компании? Не, не слышал..."

Мне интересно, что вы скажете. Что думаете о рынке? Что задело в статье? Что планируете делать дальше?
Делитесь!))
Ну очень приглянулось 😅
Весёлых вам праздников!
3
Немного о пагинации

Часто ли вы задумываетесь о пагинации при проектировании API? Честно говоря, я не задумывалась. Просто шла по накатанной (limitFrom, limitSize) и все. В кулуарах одной из конференций об этом зашел разговор, и я поняла, что у меня есть пробелы. А теперь делюсь с вами тем, что накопала по этому вопросу.
Оказалось, пагинация затрагивает архитектуру, производительность, UX и бизнес-логику.

Первый и главный вопрос: какую пагинацию использовать? Здесь есть два основных конкурента и один гибридный вариант.

🌖 На основе смещения (Классика)

📿 Как работает: limitFrom, limitSize (как я писала выше)

Плюсы:
- Проста для понимания и реализации.
- Позволяет пользователю прыгать на произвольную страницу (например, с 1 на 10)

Минусы:
- Низкая производительность на больших смещениях: Запрос в базу со смещением 10000 и размером 20 заставит БД пройтись по 10020 записям, прежде чем вернуть 20. Это считается "тяжелым" запросом.
- Если между запросами в набор данных добавились или удалились записи, страницы "поплывут". Пользователь может увидеть дубли или пропустить записи (если запись с предыдущей страницы сместилась вперед).

🔧 Когда использовать?
Для небольших, относительно статичных наборов данных, где важна возможность произвольного перехода по страницам, а производительность не критична.

🌖 На основе курсора

📿 Как работает: Вместо номера страницы используется указатель на конкретную запись. Обычно это уникальный, последовательно возрастающий столбец (например, id, created_at).

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

Минусы
- Нельзя прыгнуть на страницу 10, не пройдя предыдущие 9. Только "Вперед/Назад".
- Сложнее в реализации, потому что требует передачи курсора на клиент и правильной обработки на бэкенде.
– Курсор жестко привязан к конкретному порядку сортировки. Если нужно сортировать по разным полям, нужны разные курсоры.

🔧 Когда использовать?
Для больших, часто обновляемых наборов данных, где важны производительность и консистентность (ленты социальных сетей, бесконечный скролл, ленты транзакций).


🌖 Keyset
Разновидность курсорной. Более продвинутая форма, где курсором может быть составной ключ (например, (date, id)), что позволяет эффективно работать со сложными сортировками.

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

💰 Бизнес-требования и UX
Ниже привела вопросы, которые можно задать бизнесу для принятия решения.

1. Прогнозируйте поведение пользователя. Нужен ли произвольный доступ к страницам? Или это "бесконечный скролл"?
2. Насколько критично, чтобы данные на 2-й странице были абсолютно актуальными? Можно ли допустить аномалии вроде дублей?
3. По каким полям возможна сортировка? От этого напрямую зависит выбор типа пагинации.
4. Требуется ли возможность выгружать большие объемы данных? Пагинация здесь может быть не лучшим решением, возможно, стоит предусмотреть асинхронную генерацию отчетов.

💽 На бекенде

1. Производительность БД:
- Всегда используйте индексы для полей, по которым делаете сортировку и которые используются в курсоре.
- Для пагинации по смещению оцените максимально возможное смещение.
2. Ответ API должен быть единообразным и содержать не только данные, но и мета-информацию.
3. Клиент не должен в явном виде знать данные для курсора. Это значит, у клиента не должно быть сырого id, он должен быть закодирован.
4. Если для получения данных нужны тяжелые джойны или агрегации (читай, сложная бизнес-логика), пагинация может стать очень дорогой. Рассмотрите кеширование, материализованные представления или денормализацию.

🎆 Фронтенд и Клиентская часть

1. Подумайте, какое представление вам подойдет: бесконечный скролл, классическая нумерация страниц, кнопка "Загрузить еще"?
2. Клиент должен корректно обрабатывать состояние "загрузки следующей страницы" и избегать дублирующих запросов.
3. При использовании пагинации с заменой URL (например, ?page=2), нужно обеспечить корректную работу кнопок "Назад/Вперед" в браузере.
👍2
🩼 Осторожно, грабли!
Завершаем цикл заметок по пагинации граблями, на которые можно наступить.

🔸 N+1 проблема при курсорной пагинации. Вы получили 20 id из основного запроса, но для каждой записи нужно подтянуть связанные данные (например, имя автора). Решение: жадная загрузка всех необходимых данных в одном ответе.

🔸 Неуникальный курсор. Если поле курсора (например, created_at) не уникально, записи могут "потеряться" на стыке страниц. В таких случаях используйте уникальный составной ключ, например, created_at и id.

🔸 Слишком большой page_size. Большой размер страницы может убить и БД, и сеть, и клиент. Вводите разумные ограничения и валидируйте входные параметры.

🔸 Отсутствие сортировки. Всегда явно указывайте order_by. Без этого порядок записей не гарантирован, и пагинация будет работать некорректно. Базы данных не обязаны возвращать данные в порядке первичного ключа по умолчанию.

🔸 Совместимость с фильтрацией и поиском. Пагинация должна корректно работать в сочетании с любыми фильтрами. Убедитесь, что индексы покрывают комбинацию полей для фильтрации и сортировки.

🔸 Подсчет количества записей Для Offset-пагинации запрос COUNT(*) на больших таблицах может быть очень медленным. Рассмотрите:
- Приблизительные подсчеты (например, из статистики БД).
- Отказ от подсчета общего числа страниц ("Показать еще" вместо "Страница 5 из 1000").
- Кеширование значения.

♎️ Чеклист для проектирования

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


У меня получилось вас убедить, что пагинация — это не просто "сделать запрос с LIMIT/OFFSET"?
Это комплексное архитектурное решение, которое напрямую влияет на отзывчивость приложения.
Кто идет на Analyst Days? Делитесь!
Forwarded from Analyst Days Channel
Media is too big
VIEW IN TELEGRAM
🚀Видео-анонс докладов Analyst Days 21!

Дарья Борисова "Практические аспекты реализации согласованности данных: паттерн Сага против Two-phase commit"
14.11 секция С 11:00
Также анонс можно посмотреть в ВК видео и YouTube😉

Analyst Days - территория новых идей!
14-15 ноября, Москва + онлайн-участие!❤️


Вас ждут:
2 дня, полных новых открытий и знаний
71 доклад, мастер-классов и круглых столов, где вы сможете получить ответы на все свои вопросы
600+ участников для обмена опытом
5 секций, чтобы углубиться в интересующие вас темы

⚡️программа
⚡️билеты
⚡️афиша
⚡️скидки
⚡️видео

#анонсad21
Осенний сезон конференций 2025 завершился! Формально это был мой второй сезон выступлений (первый состоялся этим летом на ЛАФ), однако по личным ощущениям полноценным сезоном стал именно этот период.

За два месяца я посетила четыре конференции, каждую из которых анонсировала заранее, но так и не успела подробно рассказать о результатах. Теперь же, когда эмоции утихли и остались лишь четкие выводы, готова представить небольшой анализ прошедших мероприятий. Я понимаю, что многие ждут сравнительного обзора, мол, какая конференция оказалась лучше или хуже. Однако каждая из них настолько уникальна, что прямое сравнение было бы неуместно. Вместо этого я хочу поделиться собственными впечатлениями и буду рада вашим ответным комментариям.
🔥1