Producer-Consumer в Java, Go и Rust: как выбрать уровень решения
Разбор трёх способов связать производителей и потребителей через ограниченный буфер. Выбор зависит от требований к задержке, а не от языка.
В Java блокирующая очередь останавливает производителя при заполненном буфере, в Go это делает буферизированный канал, в Rust кольцевой буфер с атомарными операциями позволяет убрать блокировки.
Сравнение трёх уровней решения пригодится разработчикам многопоточных систем. Начинайте со стандартной очереди, а атомарные алгоритмы выбирайте под измеренный предел задержки.
Разбор трёх способов связать производителей и потребителей через ограниченный буфер. Выбор зависит от требований к задержке, а не от языка.
В Java блокирующая очередь останавливает производителя при заполненном буфере, в Go это делает буферизированный канал, в Rust кольцевой буфер с атомарными операциями позволяет убрать блокировки.
Сравнение трёх уровней решения пригодится разработчикам многопоточных систем. Начинайте со стандартной очереди, а атомарные алгоритмы выбирайте под измеренный предел задержки.
Как искать баги, которые не воспроизводятся в тестах
В обстоятельном разборе трёх расследований повреждение SQLite, потеря сообщений в TCP-сервисе и гонки в биллинге сводятся к одной методике: редкий сбой ищут телеметрией из рабочей среды, а не догадками.
Гонка между контрольной точкой SQLite и записью прожила минимум 16 лет. В TCP-сервисе четыре счётчика показали потерю: сервер разобрал 100 000 строк, но отправил 99 987 ответов, потому что принимал вызов
Ставьте счётчики на границах слоёв, меняйте по одной переменной и подтверждайте исправление положительным сигналом. Читать бэкенд-разработчикам и инженерам эксплуатации, которые расследуют редкие сбои в продакшене.
В обстоятельном разборе трёх расследований повреждение SQLite, потеря сообщений в TCP-сервисе и гонки в биллинге сводятся к одной методике: редкий сбой ищут телеметрией из рабочей среды, а не догадками.
Гонка между контрольной точкой SQLite и записью прожила минимум 16 лет. В TCP-сервисе четыре счётчика показали потерю: сервер разобрал 100 000 строк, но отправил 99 987 ответов, потому что принимал вызов
read() за готовое сообщение.Ставьте счётчики на границах слоёв, меняйте по одной переменной и подтверждайте исправление положительным сигналом. Читать бэкенд-разработчикам и инженерам эксплуатации, которые расследуют редкие сбои в продакшене.
Отредактировал снимок билета без сброса криптографической даты
В стандарте C2PA подпись связывает провенанс с содержимым, а штамп времени фиксирует создание подписи. Но спецификация позволяет исключать произвольные диапазоны байтов из расчёта хеша привязки.
Дэвид Бьюкенен показал, как обойти защиту: он исключил из расчёта весь файл целиком. Хеш изображения превратился в хеш пустой строки, поэтому изменение пикселей не нарушало подпись с прежним штампом времени. Для демо автор снял лотерейный билет до тиража, а после публикации результатов вписал выигрышные числа.
Сервер времени работал штатно, подпись корректна, а выигрыш остался демонстрационным. В эксперименте автора проверка подписи проходит: валидаторы принимают манифест, дата предшествует тиражу, хотя изображение подписью не защищено. Инженерный урок: исключения из хеша должны строго ограничиваться стандартом и валидаторами, иначе заверяется пустота.
@prog_stuff
В стандарте C2PA подпись связывает провенанс с содержимым, а штамп времени фиксирует создание подписи. Но спецификация позволяет исключать произвольные диапазоны байтов из расчёта хеша привязки.
Дэвид Бьюкенен показал, как обойти защиту: он исключил из расчёта весь файл целиком. Хеш изображения превратился в хеш пустой строки, поэтому изменение пикселей не нарушало подпись с прежним штампом времени. Для демо автор снял лотерейный билет до тиража, а после публикации результатов вписал выигрышные числа.
Сервер времени работал штатно, подпись корректна, а выигрыш остался демонстрационным. В эксперименте автора проверка подписи проходит: валидаторы принимают манифест, дата предшествует тиражу, хотя изображение подписью не защищено. Инженерный урок: исключения из хеша должны строго ограничиваться стандартом и валидаторами, иначе заверяется пустота.
@prog_stuff
Go расширил экспериментальный SIMD без ассемблерных вставок
В Go 1.27 разработчики представили пакет
Пример из статьи — разворот порядка бит в байтах через матричное умножение GFNI константой
Инструкции требуют проверок фич CPU (
@prog_stuff
В Go 1.27 разработчики представили пакет
simd/archsimd (включается флагом GOEXPERIMENT=simd): эксперимент для amd64 (AVX, AVX2, AVX-512) начался в 1.26, а в 1.27 добавили arm64 (NEON) и wasm (128-битный SIMD). Вместо си-интринсиков предложены методы вроде ShiftAllLeft, а выражение x.Add(y).Masked(m) на AVX-512 компилируется в одну инструкцию VPADD. Разницу платформ учли в именах: PermuteOrZero на amd64 обнуляет байт при отрицательном индексе, а LookupOrZero на arm64 и wasm обнуляет байт при любом индексе вне диапазона от 0 до 15.Пример из статьи — разворот порядка бит в байтах через матричное умножение GFNI константой
0x8040201008040201: 64 байта обрабатываются за один шаг без таблиц поиска и сдвигов. Также авторы сформулировали три правила для надежности и скорости.Инструкции требуют проверок фич CPU (
archsimd.X86.AVX512() и других): иначе на неподдерживаемом процессоре программа упадет с SIGILL, а компилятор не сможет объединять операции. Границы стрид-цикла советуют писать как i < len(src)-v.Len()+1, чтобы оптимизатор убрал проверки среза. Наконец, векторы не стоит заворачивать в большие структуры или массивы: ABI Go пока выгружает крупные композитные типы из регистров в память.@prog_stuff
Как Apache Hudi отсекает лишние партиции и файлы
Это первая часть обстоятельного разбора индексной подсистемы Hudi. Материал объясняет, как таблица метаданных ускоряет поиск записей и помогает не читать заведомо лишние данные.
Таблица метаданных сама устроена как Hudi Merge-on-Read и разделена по типам индексов. В HFile ключи отсортированы, а индекс блоков помогает найти нужный блок в памяти и прочитать его с диска.
По умолчанию работают индексы файлов, статистики столбцов и статистики партиций. Для условия
Индексы обновляются в той же транзакции, что и данные, а уплотнение запускается после каждых 10 операций записи в таблицу метаданных. Инженерам данных стоит сверить набор индексируемых столбцов: без явной настройки Hudi берёт первые 32.
Это первая часть обстоятельного разбора индексной подсистемы Hudi. Материал объясняет, как таблица метаданных ускоряет поиск записей и помогает не читать заведомо лишние данные.
Таблица метаданных сама устроена как Hudi Merge-on-Read и разделена по типам индексов. В HFile ключи отсортированы, а индекс блоков помогает найти нужный блок в памяти и прочитать его с диска.
По умолчанию работают индексы файлов, статистики столбцов и статистики партиций. Для условия
price >= 300 Hudi сначала отбрасывает партиции по максимумам цен, затем файлы по статистике отдельных столбцов.Индексы обновляются в той же транзакции, что и данные, а уплотнение запускается после каждых 10 операций записи в таблицу метаданных. Инженерам данных стоит сверить набор индексируемых столбцов: без явной настройки Hudi берёт первые 32.
Почему BPF LPM trie замедляется с ростом таблицы префиксов
Обстоятельный разбор сбоя Cloudflare в продакшене начинается с блокировки процессора: освобождение BPF-карты с миллионами записей заняло более 10 секунд. Автор объясняет устройство trie, поиск самого длинного префикса и ограничения реализации в ядре Linux.
Узлы лишь с двумя потомками заставляют плотную карту проходить цепочку однобитовых сравнений; сжатия уровней нет. Разрозненные адреса узлов дают промахи кэша L1, а примерно с 80 000 записей узким местом становятся промахи dTLB при преобразовании адресов. При миллионе записей скорость поиска падает примерно до 1,5 млн операций в секунду.
Читать стоит разработчикам сетевых сервисов и тем, кто эксплуатирует BPF-карты. Прогоните поиск и освобождение карты на своей плотности ключей и объёме данных: распределение префиксов определяет эффективность сжатия путей.
Обстоятельный разбор сбоя Cloudflare в продакшене начинается с блокировки процессора: освобождение BPF-карты с миллионами записей заняло более 10 секунд. Автор объясняет устройство trie, поиск самого длинного префикса и ограничения реализации в ядре Linux.
Узлы лишь с двумя потомками заставляют плотную карту проходить цепочку однобитовых сравнений; сжатия уровней нет. Разрозненные адреса узлов дают промахи кэша L1, а примерно с 80 000 записей узким местом становятся промахи dTLB при преобразовании адресов. При миллионе записей скорость поиска падает примерно до 1,5 млн операций в секунду.
Читать стоит разработчикам сетевых сервисов и тем, кто эксплуатирует BPF-карты. Прогоните поиск и освобождение карты на своей плотности ключей и объёме данных: распределение префиксов определяет эффективность сжатия путей.
Как подготовить Rails-код к параллельной работе через Ractor
Глубокий разбор адаптации Rails-кода к Ractor. У каждого Ractor своя блокировка виртуальной машины, что позволяет исполнять Ruby-код параллельно. Цена этого: запрет делить изменяемые объекты между Ractor.
В карте такого рефакторинга разобраны четыре узла:
Глубокая заморозка объектов через
удаление мемоизации или перенос вычисления в
Read-Copy-Update для настроек: скопировать значение, изменить, заморозить и заменить;
новый API для публичных изменяемых значений без поломки обратной совместимости.
Небольшие приложения команда уже запускает на Ractor, но крупные Rails-приложения с множеством гемов пока остаются целью. Читать Ruby-разработчикам, которые хотят начать аудит с изменяемых констант, ленивых вычислений и настраиваемых API.
Глубокий разбор адаптации Rails-кода к Ractor. У каждого Ractor своя блокировка виртуальной машины, что позволяет исполнять Ruby-код параллельно. Цена этого: запрет делить изменяемые объекты между Ractor.
В карте такого рефакторинга разобраны четыре узла:
Глубокая заморозка объектов через
Ractor.make_shareable;удаление мемоизации или перенос вычисления в
initialize либо freeze;Read-Copy-Update для настроек: скопировать значение, изменить, заморозить и заменить;
новый API для публичных изменяемых значений без поломки обратной совместимости.
Небольшие приложения команда уже запускает на Ractor, но крупные Rails-приложения с множеством гемов пока остаются целью. Читать Ruby-разработчикам, которые хотят начать аудит с изменяемых констант, ленивых вычислений и настраиваемых API.
Как изолировать медленного WebSocket-клиента
При блокирующей отправке клиент, который не успевает читать события, задерживает общий цикл: остальные тоже ждут. Обстоятельный разбор обратного давления показывает, как локализовать перегрузку.
Каждому клиенту выделяют отдельную ограниченную очередь, а события кладут в неё без ожидания. Если очередь заполнена, новое событие отбрасывают только для этого клиента, учитывают потерю и переходят к следующему. В архитектуре NomadCrew буфер вмещает 256 событий.
Отбрасывание оставляет пробел в данных. Поэтому клиенту нужен путь повторной синхронизации: заново запросить текущее состояние. Так он восстановит актуальную картину, но не историю пропущенных событий.
Для WebSocket-хаба проверьте три вещи: очереди ограничены, пропуски видны в метриках, клиент может перечитать текущее состояние после отставания.
При блокирующей отправке клиент, который не успевает читать события, задерживает общий цикл: остальные тоже ждут. Обстоятельный разбор обратного давления показывает, как локализовать перегрузку.
Каждому клиенту выделяют отдельную ограниченную очередь, а события кладут в неё без ожидания. Если очередь заполнена, новое событие отбрасывают только для этого клиента, учитывают потерю и переходят к следующему. В архитектуре NomadCrew буфер вмещает 256 событий.
Отбрасывание оставляет пробел в данных. Поэтому клиенту нужен путь повторной синхронизации: заново запросить текущее состояние. Так он восстановит актуальную картину, но не историю пропущенных событий.
Для WebSocket-хаба проверьте три вещи: очереди ограничены, пропуски видны в метриках, клиент может перечитать текущее состояние после отставания.
Автоматизация обслуживания ScyllaDB в Discord: устройство задач и сценариев
Инженерный разбор замены хрупких скриптов системой управления кластерами. Команда Discord обслуживает сотни узлов ScyllaDB и перед обновлениями создаёт временные копии кластеров, которые получают те же чтения и записи, что и рабочие базы.
В разборе Scylla Control Plane показаны задачи на Rust и сценарии в YAML. Перед выполнением задачи проверяются условия безопасности. Повторный запуск должен давать тот же результат, что и однократный: это требование делает повторы при сбоях безопасными. Ограничения параллелизма позволяют перезапускать узлы по одной зоне размещения, не более двух одновременно внутри неё.
Для инженеров инфраструктуры здесь есть ориентир: порядок шагов, проверки состояния и допустимый параллелизм задаются явно, а не остаются в голове оператора.
#архитектура #разборы
Инженерный разбор замены хрупких скриптов системой управления кластерами. Команда Discord обслуживает сотни узлов ScyllaDB и перед обновлениями создаёт временные копии кластеров, которые получают те же чтения и записи, что и рабочие базы.
В разборе Scylla Control Plane показаны задачи на Rust и сценарии в YAML. Перед выполнением задачи проверяются условия безопасности. Повторный запуск должен давать тот же результат, что и однократный: это требование делает повторы при сбоях безопасными. Ограничения параллелизма позволяют перезапускать узлы по одной зоне размещения, не более двух одновременно внутри неё.
Для инженеров инфраструктуры здесь есть ориентир: порядок шагов, проверки состояния и допустимый параллелизм задаются явно, а не остаются в голове оператора.
#архитектура #разборы
Детерминированные тесты TigerBeetle: проверки внутри реплик
Обстоятельный разбор тестирования распределённой базы с доступом к состоянию каждой реплики. Проверки через публичный API показывают поведение базы для клиента, но не охватывают все внутренние гарантии.
Симулятор запускает настоящий код базы, заменяет сеть и диски управляемыми моделями и ускоряет время. Он воспроизводит разрывы сети, повреждения дисков и падения реплик; найденный сбой можно повторить.
При фиксации каждой операции симулятор сверяет её контрольную сумму между репликами. Разбор также показывает, как проверки хранения связаны с требованием побайтового совпадения данных. В рабочей базе нарушение проверяемой гарантии останавливает реплику.
Для разработчиков распределённых систем это карта проверок за пределами API. Условие подхода: код базы должен выполняться детерминированно.
#разборы #архитектура
Обстоятельный разбор тестирования распределённой базы с доступом к состоянию каждой реплики. Проверки через публичный API показывают поведение базы для клиента, но не охватывают все внутренние гарантии.
Симулятор запускает настоящий код базы, заменяет сеть и диски управляемыми моделями и ускоряет время. Он воспроизводит разрывы сети, повреждения дисков и падения реплик; найденный сбой можно повторить.
При фиксации каждой операции симулятор сверяет её контрольную сумму между репликами. Разбор также показывает, как проверки хранения связаны с требованием побайтового совпадения данных. В рабочей базе нарушение проверяемой гарантии останавливает реплику.
Для разработчиков распределённых систем это карта проверок за пределами API. Условие подхода: код базы должен выполняться детерминированно.
#разборы #архитектура
Ускорение строковых агрегаций в DuckDB через таблицу измерений
SQL-гайд по замене повторяющихся строк числовыми ключами показывает, как сократить обработку текста при группировке. Таблица измерений хранит каждое название один раз вместе с ключом: запрос считает группы по числам и возвращает названия после агрегации.
Пример построен на 380 959 записях об остановках поездов и 537 названиях станций. Для них хватает двухбайтового USMALLINT. Ключи назначаются в алфавитном порядке, поэтому сортировка по ключу сохраняет порядок названий. LEFT JOIN сохраняет строки без станции, с NULL вместо ключа.
Для инженеров данных разобраны два варианта: сохранить ключи в основной таблице или соединять её со справочником при каждом запросе. Первый требует переписать таблицу один раз; второй оставляет обработку строк при каждом соединении.
#производительность #гайды
SQL-гайд по замене повторяющихся строк числовыми ключами показывает, как сократить обработку текста при группировке. Таблица измерений хранит каждое название один раз вместе с ключом: запрос считает группы по числам и возвращает названия после агрегации.
Пример построен на 380 959 записях об остановках поездов и 537 названиях станций. Для них хватает двухбайтового USMALLINT. Ключи назначаются в алфавитном порядке, поэтому сортировка по ключу сохраняет порядок названий. LEFT JOIN сохраняет строки без станции, с NULL вместо ключа.
Для инженеров данных разобраны два варианта: сохранить ключи в основной таблице или соединять её со справочником при каждом запросе. Первый требует переписать таблицу один раз; второй оставляет обработку строк при каждом соединении.
#производительность #гайды
Адаптивное разбиение HashJoin в Bolt: меньше повторных выгрузок на диск
При соединении таблиц через хеш-таблицу нехватка памяти вынуждает Bolt разбивать строки на разделы и писать их на диск. Если раздел снова не помещается в память, цикл повторяется: чтение, разбиение, запись.
В техническом разборе адаптивного разбиения первая нехватка памяти служит оценкой вместимости. Bolt сопоставляет число обработанных строк с общим числом строк: при 10 млн строк и вместимости около 800 тысяч фиксированных 4 разделов мало, а адаптивный выбор может дать 16 или 32.
В статье показан путь статистики строк до решения о разбиении. Число разделов только увеличивается; ширина строк влияет на точность оценки, а перекос ключей всё ещё может создавать слишком крупные разделы. Разработчикам аналитических движков здесь есть что учесть при диагностике повторных выгрузок.
#производительность #разборы
При соединении таблиц через хеш-таблицу нехватка памяти вынуждает Bolt разбивать строки на разделы и писать их на диск. Если раздел снова не помещается в память, цикл повторяется: чтение, разбиение, запись.
В техническом разборе адаптивного разбиения первая нехватка памяти служит оценкой вместимости. Bolt сопоставляет число обработанных строк с общим числом строк: при 10 млн строк и вместимости около 800 тысяч фиксированных 4 разделов мало, а адаптивный выбор может дать 16 или 32.
В статье показан путь статистики строк до решения о разбиении. Число разделов только увеличивается; ширина строк влияет на точность оценки, а перекос ключей всё ещё может создавать слишком крупные разделы. Разработчикам аналитических движков здесь есть что учесть при диагностике повторных выгрузок.
#производительность #разборы
Bolt
Adaptive Spill Partitioning: Using Runtime Row Counts to Reduce Recursive HashJoin Spill
When the build side of a HashJoin exceeds its memory budget, the hash table has to be split by hash partition and written to disk. The basic mechanism is straightforward: split build rows into partitions, read partitions back one by one, rebuild the hash…
Как StarTree проверяет релизы Apache Pinot под нагрузкой и при отказах
В инженерном разборе StarTree показывает устройство сервиса проверки релизов своей аналитической платформы на Apache Pinot. Стенд совмещает приём данных и запросы с перебалансировкой таблиц и случайными перезапусками серверов.
Сервис на FastAPI принимает задания, а Argo Workflows управляет их выполнением. Команда сохраняет структуру клиентских запросов, скрывает чувствительные имена и значения и создаёт синтетические данные. Результаты преобразования строк сравнивают на текущей и следующей версиях, чтобы выявить несовместимость до обновления.
Разбор для разработчиков распределённых систем: здесь есть многодневные проверки и сценарии одновременных операций. Успешная проверка перебалансировки сама по себе не показывает, как система выдержит её на фоне интенсивного приёма данных.
#разборы #архитектура
В инженерном разборе StarTree показывает устройство сервиса проверки релизов своей аналитической платформы на Apache Pinot. Стенд совмещает приём данных и запросы с перебалансировкой таблиц и случайными перезапусками серверов.
Сервис на FastAPI принимает задания, а Argo Workflows управляет их выполнением. Команда сохраняет структуру клиентских запросов, скрывает чувствительные имена и значения и создаёт синтетические данные. Результаты преобразования строк сравнивают на текущей и следующей версиях, чтобы выявить несовместимость до обновления.
Разбор для разработчиков распределённых систем: здесь есть многодневные проверки и сценарии одновременных операций. Успешная проверка перебалансировки сама по себе не показывает, как система выдержит её на фоне интенсивного приёма данных.
#разборы #архитектура
Бенчмарки TidesDB и RocksDB: где настройки определяют результат
Обстоятельный разбор сравнения TidesDB 10.0.0 и RocksDB 11.8.1 на двух серверах показывает, почему вместе со скоростью нужно читать условия замеров. В основе пять нагрузок, от смешанных операций до корзины покупок.
Основное сравнение использует настройки по умолчанию, но сжатие отключено у обеих баз. TidesDB отдельно хранит крупные значения; у RocksDB аналогичная возможность проверена дополнительным прогоном. Каждый замер длится 60 секунд, результат берётся как медиана трёх повторов.
На большом сервере преимущество TidesDB сокращается. Но меняется не только диск: потоки закреплены за ядрами, а база заново заполняется перед каждым замером. Инженерам производительности здесь стоит сверить методику своих тестов: различия между серверами нельзя объяснить одним накопителем.
#производительность #разборы
Обстоятельный разбор сравнения TidesDB 10.0.0 и RocksDB 11.8.1 на двух серверах показывает, почему вместе со скоростью нужно читать условия замеров. В основе пять нагрузок, от смешанных операций до корзины покупок.
Основное сравнение использует настройки по умолчанию, но сжатие отключено у обеих баз. TidesDB отдельно хранит крупные значения; у RocksDB аналогичная возможность проверена дополнительным прогоном. Каждый замер длится 60 секунд, результат берётся как медиана трёх повторов.
На большом сервере преимущество TidesDB сокращается. Но меняется не только диск: потоки закреплены за ядрами, а база заново заполняется перед каждым замером. Инженерам производительности здесь стоит сверить методику своих тестов: различия между серверами нельзя объяснить одним накопителем.
#производительность #разборы
👍1
Forwarded from Нейроканал
Showboat и Rodney помогают показать работу ИИ-агента
Саймон Уиллисон собирает демонстрации кода с помощью двух своих инструментов. Showboat выполняет команды и записывает их вывод в документ. Rodney управляет Chrome из командной строки и делает скриншоты интерфейса.
Эту команду автор предлагает дать агенту: в справке есть всё необходимое, чтобы тот создал документ с демонстрацией новой функции.
Уиллисон замечал и обход механизма: агент напрямую правит текст отчёта. Тогда записанный вывод может расходиться с реальным запуском. Содержимое демонстрации тоже требует проверки.
#ии #инструменты
Саймон Уиллисон собирает демонстрации кода с помощью двух своих инструментов. Showboat выполняет команды и записывает их вывод в документ. Rodney управляет Chrome из командной строки и делает скриншоты интерфейса.
uvx showboat --helpЭту команду автор предлагает дать агенту: в справке есть всё необходимое, чтобы тот создал документ с демонстрацией новой функции.
Уиллисон замечал и обход механизма: агент напрямую правит текст отчёта. Тогда записанный вывод может расходиться с реальным запуском. Содержимое демонстрации тоже требует проверки.
#ии #инструменты
Forwarded from Нейроканал
Вспомните последний раз, когда ИИ сделал для вас рабочий результат: код, тесты, документацию или требования. Как вы его проверяли?
Anonymous Poll
15%
Внимательно разобрал сам
38%
Проверил на практике: тесты, запуск, реальные данные
24%
И разобрал, и проверил на практике
2%
Отдал на ревью коллеге
13%
Не проверял, сразу использовал
5%
Не было такого случая или не помню
3%
Другое (напишу в комментариях)