Cassandra & Beyond
رفتن به کانال در Telegram
Sharing of interesting links, thoughts, insights about Apache Cassandra and related technical topics (such as Java, perf, computer science)
نمایش بیشتر228
مشترکین
اطلاعاتی وجود ندارد24 ساعت
+27 روز
+330 روز
آرشیو پست ها
Reduce contention in MemtableAllocator.allocate on write, часть 1
Залил в trunk Cassandra ещё одну оптимизацию для записи: CASSANDRA-20226
Когда мы пишем данные в memtable, Cassandra должна отслеживать объём памяти, занятый всеми memtable, чтобы вовремя сбрасывать самые крупные из них на диск и освобождать память под новые данные. Этот механизм работает на уровне отдельных ячеек: при вставке строк содержимое ячеек клонируется, и на этом этапе вызывается логика MemtableAllocator.allocate, которая учитывает выделенную память и проверяет лимиты.
Если вставка идёт с высокой скоростью, а строки содержат много ячеек (batch insert или сложная схема с UDT/коллекциями), то MemtableAllocator.allocate вызывается очень часто и становится узким местом из-за конкуренции между потоками на внутренних счётчиках AtomicLong. Эффект усиливается для многоядерных машин.
Чтобы снизить contention, были применены следующие приёмы:
1) В местах, где нам нужно только увеличивать счётчик, но не использовать его значение немедленно, AtomicLong заменили на LongAdder.
2) Цикл с CAS на AtomicLong заменили на addAndGet.
3) Главное изменение: вместо выделения памяти под каждую ячейку по отдельности теперь заранее оценивается общий объём памяти, необходимый для всей операции, и он запрашивается одним крупным блоком. Затем отдельные ячейки размещаются в этом локальном для операции буфере. В результате число глобальных выделений памяти сокращается до одного на операцию (вместо одного на ячейку). Бонусом мы улучшаем локальность данных: ячейки одной строки лежат рядом в памяти и не перемешиваются при параллельной записи.
Java уже давно не просто язык для энтерпрайза — это мощная экосистема, которая развивается в сторону производительности, конкурентности и интеграции с AI.
Организаторы онлайн-конференции Podlodka Java Crew приглашают 17-21 ноября обсудить, как выглядит современная Java и что меняется в привычных инструментах.
📌 В программе:
• Горячие JEP. Григорий Вахмистров, Дмитрий Волыхин, Сергей Петрелевич и Дмитрий Константинов объяснят, какие изменения в Java 21–25 действительно двигают экосистему вперёд.
• Spring AI и паттерны AI-агентов. Михаил Поливаха (Spring АйО) объяснит, как строить интеграции с LLM и какие паттерны уже применяются в индустрии.
• Java 25 в действии. Григорий Кошелев (Контур) расскажет, почему миграция важна не только для Java-разработчиков, но и для тех, кто использует экосистемные инструменты вроде Кассандры и Кафки.
• Hibernate в новой реальности. Максим Сенокосов (Точка Банк) покажет, как меняется ORM и почему вам пора пересмотреть архитектурные решения.
💡 Все доклады с практикой, живыми примерами и ответами на реальные вопросы инженеров.
Подробности и билеты: https://podlodka.io/javacrew
А промокод cassandra_beyond дает скидку в 500р🥳
И еще, первым двум людям, кто попросит в комменте, пришлю промокод на бесплатный билет 😊
Repost from Тысяча фичей
56. Apache Cassandra, часть 1: клиент, сервер.
После этого выпуска вы сможете написать свой драйвер для Cassandra. В гостях Дима Константинов.
--
Альтер эго Саши @sashimi_pub
---
🎧 Слушать в Apple Podcasts | Spotify | YouTube | браузер
Для сильных духом, поговорили обстоятельно 🙂 с Сашей Пахомовым про Cassandra в формате подкаста. Это первая часть, в основном, про клиент (драйвер) логику.
В целом, у Саши очень много интересных интервью с разработчиками различных баз данных и не только, рекомендую!
Cassandra 5.0.6 released: https://github.com/apache/cassandra/blob/cassandra-5.0.6/CHANGES.txt
поучаствовал в нескольких тикетах в качестве reviewer
Async profiler 4.2 released
Вышел новый релиз Async profiler 4.2 - https://github.com/async-profiler/async-profiler/discussions/1563
из интересного конкретно для меня:
- добавлена возможность профилирования времени выполнения отдельных методов, через инструментацию (https://github.com/async-profiler/async-profiler/discussions/1497)
- VMStructs stack walking by default - более точный и безопасный метод снятия стек трейсов + больше деталей об уровне компиляции
Cheaper metrics
Метрики — очень полезная вещь, и их в Cassandra действительно много. Но за всё приходится платить: сочетание высокой нагрузки и большого числа собираемых метрик даёт заметные накладные расходы.
Например, в простом тесте на запись, где диск не является узким местом, около 11% CPU в Cassandra может тратиться на подсчёт метрик в процессе обработки запросов.
Есть два основных способа снизить эти расходы:
1) Собирать меньше метрик, то есть не тратить ресурсы на ненужные. На эту тему есть тикет в backlog: CASSANDRA-20332
2) Сделать подсчёт метрик дешевле.
В рамках CASSANDRA-20250 я пошёл вторым путём и, с подсказки Benedict Elliott Smith, реализовал thread-local счётчики: каждый поток имеет локальный счётчик и увеличивает только его, а при запросе значения метрики мы суммируем данные по всем потокам.
Это выглядит аналогично LongAdder (который использовался в оригинальной реализации Dropwizard Metrics), но там несколько потоков могут делить одну ячейку памяти, из-за чего операция инкремента получается дороже.
Аналогичную идею можно увидеть здесь: Java concurrent counters by numbers.
В результате этих изменений, вместе с дополнительными оптимизациями для логики Meter, удалось уменьшить накладные расходы на подсчёт Counter/Meter-метрик примерно в два раза (и есть еще идеи, как улучшить этот результат).
Другая область, где ещё есть потенциал для улучшений, — гистограммы.
Faster low-allocation compaction is coming
Nitsan Wakart (тот самый: psy-lob-saw) на днях представил очень интересный патч для compaction-логики в Cassandra: PR #4402 / CASSANDRA-20918. Его цель — повысить производительность и существенно снизить потребление памяти в рамках этой активности.
Compaction — это процесс слияния нескольких SSTable-файлов на диске. Он выполняется в фоновом режиме, но может заметно влиять на производительность базы, конкурируя за ресурсы с другими операциями. Кроме того, чем быстрее выполняется compaction, тем быстрее данные уплотняются и ускоряется чтение, поскольку уменьшается количество SSTable-файлов.
Замеры показывают, что время выполнения compaction сокращается в 3–5 раз, а потребление памяти уменьшается на несколько порядков и становится независимым от числа строк. Это достигается за счёт переиспользования ряда объектов (current partition key, row header, cell header) и перехода с итераторов на cursor-based подход.
Community Over Code 2025 talks playlist
Опубликовали записи с только что прошедшей в США Apache конференции
https://www.youtube.com/playlist?list=PLqcm6qE9lgKKvJ456OBZzcvMZ6YFpCyUg
Огромная благодарность Bernardo Botella за организацию записи
Вышел релиз следующей JDK LTS: JDK25
Для Cassandra я вижу следующие полезные фичи:
- Generational Shenandoah. Cassandra порождает весьма много короткоживущих объектов, поэтому поколения должны существенно улучшить эффективность сборки мусора, надо будет потестировать на практике.
- Compact Object Headers. Общее ускорение за счет того, что больше объектов будет помещаться в CPU caches, а также потенциально более компактные memtables. Однако, для одного из наиболее распространенных объектов в Cassandra java heap - Cell, к сожалению, не все так просто из-за выравнивания, так что придет приложить дополнительные усилия со стороны Cassandra. Про это я чуть более подробно рассказываю тут: https://youtu.be/13XY1RqSyxE?list=PLK4DgKoWPVSLEwmNu0oQt4SsnYgrs2Qey&t=1738
- Ahead-of-Time Method Profiling Более быстрый выход на пиковую производительность после рестарта
Cassandra 4.1.10 released
https://github.com/apache/cassandra/blob/cassandra-4.1.10/CHANGES.txt
В рамках этого релиза поправил ряд багов:
1) Fix IndexOutOfBoundsException in sstablemetadata tool when a range tombstone is a max clustering value (CASSANDRA-20855)
в sstablemetadata туле вылетало исключение, при попытке получить метаданные для некоторых SSTable файлов
2) Improve CommitLogSegmentReader to skip SyncBlocks correctly in case of CRC errors (CASSANDRA-20664)
в режиме игнорирования ошибок при commit log replay была проблема, которая приводила к бесконечному циклу и зависанию старта
Также в этом релизе есть пара обновлений 3rd party из-за security проблем
Оптимизация сброса TrieMemtable с помощью предварительных вычислений (part 2)
Первая мысль была упростить итерацию: не извлекать полноценные partition keys из TrieMemtable, а лишь подсчитывать их длину и пропускать ненужные данные. Но присмотревшись внимательнее, я понял, что в типичном случае можно вовсе избежать итерации по структуре, если посчитать нужные значения заранее — на этапе вставки данных. Поскольку структура разбита на single-writer shards, накладные расходы на такие вычисления оказываются минимальными. В итоге стоимость получения необходимой информации во время сброса стала пренебрежимо малой.
Реализовано и выдано в https://issues.apache.org/jira/browse/CASSANDRA-20760
Оптимизация сброса TrieMemtable с помощью предварительных вычислений
Продолжаю оптимизировать запись в Cassandra. И снова под прицелом оказалась логика сброса данных из памяти (TrieMemtable) на диск.
В начале этой операции мы считаем сколько у нас partition keys, а также их суммарный размер.
Эта информация необходима для построения вероятностных структур данных, таких как bloom filter и histogram, которые заполняются в процессе записи на диск. Поэтому эти размерности нужно знать заранее — посчитать их во время итерации по данным при самом сбросе не получится.
Чтобы определить эти значения, текущая логика итерируется по всем ключам TrieMemtable, вычисляя как их количество, так и суммарную длину в сериализованном виде. Разумеется, такой полный проход по TrieMemtable, типичный размер которой может достигать сотен мегабайт, обходится недешево. В моих тестах это выражается в 1–2 секундах дополнительного времени при операции flush, когда одно ядро процессора почти полностью занято этой задачей.
Записи докладов по Cassandra
Записи докладов со свежей встречи, организованной Uber: https://www.youtube.com/playlist?list=PLqcm6qE9lgKKqE0rUsy5dfSxrycnDS6Np
Записи с Community Over Code: https://www.youtube.com/@communityovercode/search?query=Cassandra%20Track
Updates about JDK versions support
Протащил очень маленький, но психологически важный тикет: теперь поддержка JDK 17 официально объявлена production-ready в Cassandra 5.0 — CASSANDRA-20681.
Также надеюсь на относительно скорое завершение работ по поддержке JDK 21 в ветке trunk: CASSANDRA-18831.
В целом, недавно прошло важное обсуждение и голосование по поводу общей схемы поддержки JDK-версий в Cassandra:
https://lists.apache.org/thread/7640gzjlwo07kjmoyjpt8gq80qk5qhn9
https://lists.apache.org/thread/vr7j2ob92k6fbcwvlfo60l3scylzdbft
Согласно новым договорённостям, trunk теперь должен поддерживать только одну LTS-версию. При переходе trunk на новую LTS, её поддержка также должна быть добавлена во все предыдущие поддерживаемые версии.
Эти изменения должны существенно ускорить адаптацию новых JDK и использование их возможностей в trunk. Посмотрим в ближайшие месяцы, как это будет работать на практике — особенно с учётом того, что осенью выходит следующая LTS-версия JDK.
Avoid new ByteBuffer allocation for each cell during flushing of offheap_objects memtable
На днях закончил очередную оптимизацию в Apache Cassandra.
Когда мы пишем в Cassandra, то данные сначала накапливаются во временном буфере в памяти (memtable) и дальше, при определенных условиях, memtable сбрасывается в виде файла на диск. Данные в memtable могут храниться в разном представлении, подробно об этом я рассказывал в докладе: ссылка. Когда используется режим offheap_objects, то данные лежат в offheap памяти, что уменьшает нагрузку на GC.
К сожалению, при сбросе данных на диск, для каждой ячейки выделялся ByteBuffer объект в heap, что вызывало всплеск аллокаций памяти и излишнюю нагрузку на GC, то есть мы теряли часть преимуществ от использования offheap. В рамках [CASSANDRA-20173] Avoid new ByteBuffer allocation for each NativeCell/NativeClustering during flushing of offheap_objects memtable я реализовал сброс данных напрямую из offheap на диск, минуя использование ByteBuffer, тем самым убрав этот всплеск.
Async profiler 4.0 released, new view: heatmap
Недавно вышел новый релиз async profiler 4.0 (https://github.com/async-profiler/async-profiler/releases/tag/v4.0). Большое спасибо Андрею Паньгину за создание и поддержку данной утилиты. Я ей пользуюсь регулярно при анализе производительности Cassandra.
В версии 4.0 появились 2 новые большие фичи:
1) профилирование нативной аллокации памяти (https://github.com/async-profiler/async-profiler/blob/master/docs/ProfilingModes.md#native-memory-leaks, https://krzysztofslusarski.github.io/2025/03/31/native.html)
2) heatmaps (https://github.com/async-profiler/async-profiler/blob/master/docs/Heatmap.md)
Последняя для меня особенно интересна, поскольку мне всегда не хватало возможности видеть динамику использования CPU во времени, теперь это возможно.
Пример heapmap для Cassandra write нагрузки, можно видеть характерные периоды:
1) обычный режим, где преобладает нагрузка на CPU от потоков, что декодируют запросы и вставляют в memtables
2) flush/compaction активности, когда memtable сбрасываются на диск и активируются на время соответствующие потоки
3) GC (периодические темные червячки на heatmap 😊)
Accord в trunk!
Ура, вчера произошел мерж accord транзакций в Apache Cassandra trunk: https://github.com/apache/cassandra/commits/trunk/
Теперь они уже совсем близко.
Объем изменений
общий:
1314 files changed, 116342 insertions(+), 10594 deletions(-)и модификаций в текущем коде, не считая тестов:
$ git diff trunk --stat $(git diff trunk --name-only --diff-filter=M src | egrep -v 'accord|journal|consensus' ) | tail -n1
427 files changed, 13366 insertions(+), 3443 deletions(-)
اکنون در دسترس! پژوهش تلگرام ۲۰۲۵ — مهمترین بینشهای سال 
