Сохранёнки программиста
6.51K subscribers
1.24K photos
59 videos
10 files
1.96K links
Заметки и ссылки на будущее, чтобы изучить когда будет время.

Разместить рекламу: @tproger_sales_bot

Правила общения: https://tprg.ru/rules

Другие каналы: @tproger_channels

Другие наши проекты: https://tprg.ru/med
Download Telegram
Как батчинг меняет производительность OLTP в TigerBeetle

Перенос привычной схемы работы с SQL-базой в TigerBeetle может дать слабый результат. Множество клиентов, отправляющих по одной транзакции, не раскрывает возможности движка.

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

Пока клиент ждёт ответа на текущий запрос, он собирает новые операции в следующий батч. Отдельная искусственная задержка для накопления не нужна. Сетевые и репликационные издержки распределяются на несколько операций.

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

#производительность #разборы
Почему счёт записывают в TigerBeetle последним, а проверяют первым

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

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

Допустим, процесс упал после записи в PostgreSQL, до сохранения результата шага. Пока счёта нет в TigerBeetle, переводы отклоняются. При восстановлении шаг повторяется: те же данные считаются успехом, затем создаётся счёт в TigerBeetle. Другие данные означают конфликт и остановку.

#архитектура #разборы
👏1
Как leaky bucket ограничивает допуск нагрузки

Leaky bucket задаёт вместимость и скорость освобождения ёмкости. Новая операция занимает часть объёма; если места не хватает, её отклоняют. Состояние меняется с течением времени, независимо от завершения запросов.

В разборе механизма admission control показаны два варианта: измеритель разрешает работу сразу, а очередь удерживает её до выпуска. В варианте измерителя не нужен фоновый процесс, который постоянно «осушает» ведро: достаточно хранить прежний уровень и время проверки, затем пересчитать уровень при обращении.

На примере GraphQL API Shopify разобрана стоимость запросов: она зависит от запрошенных данных. После выполнения разница между оценкой и фактической стоимостью корректирует состояние ведра.

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

#алгоритмы #архитектура
Почему разработчик планирует отдавать больше задач Claude

Винсент Шмальбах описал план перераспределить расходы на ИИ: больше работы отдавать Claude, а Codex сохранить для части задач.

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

В личном разборе Шмальбах связывает эти эпизоды с условиями подписки и затратами на собственные проекты.

#ии #инструменты

🐸 Библиотека ИИ для айтишников
Please open Telegram to view this post
VIEW IN TELEGRAM
Как Cloudflare проверяет выводы ИИ-агентов

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

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

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

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

#архитектура #разборы
Как Uber ограничивает лавину повторных запросов

Сервис C вернул ошибку. B повторил запрос к C, а после неудачи сообщил об ошибке A. Если A тоже повторит запрос, вся цепочка запустится заново. Даже небольшой лимит ретраев на каждом уровне усиливает нагрузку.

В разборе Uber используется error ownership: инфраструктура сопоставляет входящие и исходящие ошибки, чтобы определить, где сбой возник, а где его только передали дальше.

Если C объявил себя источником ошибки, B может повторить обращение к нему в пределах retry budget. Когда ошибка уходит выше, B снимает признак владения: A уже не должен повторять всю цепочку.

В статье есть схема передачи x-uber-error-claim и обработка сложных случаев: потерянного контекста и совпавших независимых ошибок. Подход требует понимания зависимостей сервисов — одного общего правила «повторять любой 500» для этого недостаточно.

#архитектура #разборы
Почему реплики для чтения могут замедлять запись

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

В разборе новой Git-архитектуры GitHub описывает разделение этих задач. Данные репозиториев планируют хранить в Azure Blob Storage, а запросы обслуживать вычислительными воркерами с кешем. Дополнительная мощность для чтения тогда не требует новой полной реплики.

Согласование хотят сосредоточить на обновлении ссылки Git. Хранение объектов и проверки можно выполнять параллельно с другими записями, а compaction и сборку мусора вынести с серверов, обслуживающих запросы.

Это развивающаяся архитектура. Заявленное увеличение пропускной способности записи до 35 раз получено во внутренних бенчмарках; такой результат не обещает ускорить каждый пользовательский push в 35 раз.

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

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

В экспериментах PlanetScale сравнивают pglz и LZ4. Для превью left(body, 200) pglz позволяет ограничить объём читаемых сжатых данных. Для LZ4 PostgreSQL сначала получает значение целиком. На проверенных больших текстах это дало около 1 мс против 16 мс.

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

Цифры относятся к конкретным данным и запросам. Перед сменой хранения измерьте свою нагрузку. И учтите: изменение настройки сжатия само по себе не перекодирует уже сохранённые значения.

#postgresql #производительность
Как Spotify проверяет качество при ускорившейся разработке

В августе число слитых изменений в Spotify выросло примерно с 8 100 до 17 000 за год. Команда увидела, что проверка, тестирование и наблюдаемость должны успевать за новым темпом.

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

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

В рассмотренных инцидентах команда не нашла существенного прямого вклада ИИ-кода. При этом рост размера PR и сложности кода остаётся поводом для наблюдения — пороги пока не меняют.

#разработка #разборы
Почему уменьшение ответа API не всегда ускоряет запрос

Чтобы построить историю звёзд репозитория, инструменты выгружали страницы пользователей и оставляли только даты. Для React это требовало примерно 2500 запросов.

В разборе GitHub показано, почему простая замена пользователей дневными счётчиками не решала проблему. База сначала группировала все звёзды, сортировала результат и лишь затем применяла LIMIT и OFFSET. Маленький JSON всё ещё требовал большой работы.

Новый API сначала переводит страницу в диапазон дат по индексу created_at, затем считает звёзды только внутри него. Один ответ покрывает до 30 недель. Для React полная выгрузка сократилась примерно до 24 запросов.

При оптимизации отчётов проверьте, где именно ограничивается выборка: после агрегации или до неё. Размер ответа этого не показывает.

#базыданных #производительность
Как общий кеш выдавал пустые ответы MySQL

У крупного клиента Hyperdrive примерно 0,001% запросов возвращали пустой результат, хотя строки должны были быть. Ошибка появлялась только с включённым кешем.

В расследовании Cloudflare причиной оказались разные представления ответа MySQL. Hyperdrive и пользовательский драйвер могли согласовать разные возможности протокола: в одном случае набор строк завершается пакетом OK, в другом нужен EOF.

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

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

#кеширование #разборы
Почему одинаковое число ядер даёт разную мощность

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

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

Коэффициенты пришлось уточнять по реальной нагрузке: синтетических тестов оказалось недостаточно, а Kafka и Cassandra по-разному используют одни и те же серверы.

Для Kafka такой подход сократил выделенное число ядер примерно на 8%. Это результат конкретного внедрения. При переносе сервиса между поколениями CPU стоит сравнивать время выполнения и запас под пиковую нагрузку, а не только число ядер.

#инфраструктура #производительность