Sirin — плагин для Picodata, реализующий протокол Apache Cassandra. Мы сравнили его производительность с Cassandra 5.0.6 с помощью стандартного бенчмарка YCSB на пяти профилях нагрузки: от интенсивной записи до только чтения. Оба стенда ограничены 6 ядрами CPU.
| Тест | Sirin, rps | Cassandra, rps | Отношение |
|---|---|---|---|
| Workload A (50% чтения, 50% обновлений) | 41 585 | 31 888 | Sirin ×1.30 |
| Workload B (95% чтения, 5% обновлений) | 37 612 | 33 866 | Sirin ×1.11 |
| Workload C (100% чтения) | 44 540 | 40 919 | Sirin ×1.09 |
| Workload D (95% чтения, 5% вставок) | 63 591 | 53 396 | Sirin ×1.19 |
| Workload F (50% чтения, 50% RMW)¹ | 24 805 | 19 930 | Sirin ×1.24 |
¹ Для workload F пропускная способность указана в tps (транзакций в секунду по YCSB): одна транзакция — это либо одиночное чтение (READ), либо полный RMW-цикл (READ + UPDATE). Прямое сравнение с rps остальных профилей некорректно.
Введение
Sirin — плагин для распределённой СУБД Picodata, реализующий протокол Apache Cassandra. Благодаря этому плагину приложения, использующие драйверы CQL, могут работать с Picodata без изменения кода.
Целью данного документа является оценка производительности Sirin 1.3.0 в
сравнении с Cassandra 5.0.6 на нагрузке, генерируемой инструментом YCSB
(Yahoo! Cloud Serving Benchmark). YCSB использует плоскую таблицу
usertable: каждая запись содержит ключ и 10 текстовых полей по 100
байт (~1 КБ на строку), запросы обращаются к полному содержимому строки.
Это позволяет оценить поведение систем на типовых OLTP-сценариях с
разным соотношением операций чтения и записи.
YCSB предоставляет стандартный набор профилей нагрузки (workloads), широко используемых в индустрии для сравнительной оценки NoSQL-систем. Тестирование охватывает профили A, B, C, D и F: от смешанной нагрузки с равными долями чтения и обновления до полностью читающей нагрузки, сценария с вставкой свежих записей и нагрузки типа read-modify-write.
Измеряются пропускная способность, задержки выполнения запросов (p95, p99, min, max), потребление вычислительных ресурсов (CPU, RAM) и нагрузка на дисковую подсистему.
Условия
Стенд
Базы данных и генератор нагрузки запускались на отдельных виртуальных машинах и взаимодействовали через сеть, что исключало конкуренцию за ресурсы между тестируемой БД и инструментом нагрузки.
Конфигурация ВМ с базами данных:
| Ресурс | Значение |
|---|---|
| CPU | 8 ядер |
| RAM | 16 ГБ |
| Диск | 200 ГБ NVMe SSD |
Конфигурация баз данных
Обе системы тестировались без репликации данных. Лимит CPU в 6 ядер задавался через cgroups одинаково для обеих систем, чтобы обеспечить сравнимые условия.
| Система | Топология |
|---|---|
| Cassandra 5.0.6 | Кластер из 3 узлов на одной машине |
| Sirin 1.3.0 на Picodata 26.1.4 | Кластер из 4 узлов на одной машине |
Схема данных
YCSB использует стандартную схему с таблицей usertable. Каждая запись содержит ключ и 10 текстовых
полей по 100 байт, итоговый размер строки — около 1 КБ:
CREATE TABLE usertable (
y_id varchar PRIMARY KEY,
field0 varchar,
field1 varchar,
field2 varchar,
field3 varchar,
field4 varchar,
field5 varchar,
field6 varchar,
field7 varchar,
field8 varchar,
field9 varchar
);
Инструмент нагрузки
Тесты проводились утилитой YCSB с биндингом cassandra-cql.
Данные предварительно загружались командой ycsb.sh load, тесты запускались командой ycsb.sh run
с параметром -p maxexecutiontime=3600 (1 час на каждый тест).
Набор тестов
YCSB задаёт профиль нагрузки через файл workload, определяющий соотношение операций и распределение ключей. Zipfian — популярные ключи запрашиваются значительно чаще (горячее пятно, характерно для OLTP). Latest — чаще запрашиваются недавно вставленные записи.
| Тест | Операции | Распределение запросов | Записей в БД |
|---|---|---|---|
| Workload A | 50% чтение, 50% обновление | Zipfian | 30 000 000 |
| Workload B | 95% чтение, 5% обновление | Zipfian | 30 000 000 |
| Workload C | 100% чтение | Zipfian | 30 000 000 |
| Workload D | 95% чтение, 5% вставка | Latest | 30 000 000 |
| Workload F | 50% чтение, 50% read-modify-write | Zipfian | 30 000 000 |
Результаты
Workload A — update heavy (50% чтения, 50% обновлений)
Профиль моделирует системы с высокой долей мутаций, например, сессионные хранилища с частой записью последних действий пользователя.
Команда для запуска теста:
./bin/ycsb.sh run cassandra-cql \
-P workloads/workloada \
-p hosts=10.20.1.1 \
-p recordcount=30000000 \
-p operationcount=999999999 \
-p maxexecutiontime=3600 \
-p cassandra.readconsistencylevel=ONE \
-p cassandra.writeconsistencylevel=ONE \
-threads 96 \
-p cassandra.maxconnections=10 \
-p cassandra.coreconnections=10
Запросы (prepared statements):
-- Чтение
SELECT * FROM usertable WHERE y_id = ?
-- Обновление
UPDATE usertable SET field0=?,field1=?,field2=?,field3=?,field4=?,
field5=?,field6=?,field7=?,field8=?,field9=? WHERE y_id = ?
| Параметр | Sirin | Cassandra |
|---|---|---|
| Пропускная способность, rps | 41 585 | 31 888 |
| Время выполнения на чтение p95, мс | 2.58 | 8.04 |
| Время выполнения на чтение p99, мс | 3.76 | 33.98 |
| Время выполнения на чтение min, мс | 0.27 | 0.31 |
| Время выполнения на чтение max, мс | 100.35 | 500 |
| Время выполнения на обновление p95, мс | 2.42 | 5.42 |
| Время выполнения на обновление p99, мс | 3.54 | 30.77 |
| Время выполнения на обновление min, мс | 0.30 | 0.22 |
| Время выполнения на обновление max, мс | 100.35 | 407 |
| Потребление CPU, % | ~80 | ~80 |
| Потребление RAM, ГБ | 3.67 | 12 |
| Макс. запись на диск, IOPS | 77.62 | 17.76 |
| Макс. чтение с диска, IOPS | 15760 | 29 300 |
| Макс. запись на диск, МБ/с | 70 | 14 |
| Макс. чтение с диска, МБ/с | 200.5 | 519.4 |
Телеметрия
Телеметрия — Sirin
Пропускная способность по типам операций (rps) в течение теста
Загрузка CPU (%) по узлам кластера в течение теста
Потребление оперативной памяти (ГБ) по узлам кластера в течение теста
Дисковая активность: IOPS на чтение и запись
Дисковая активность: пропускная способность (МБ/с) на запись и чтение
Телеметрия — Cassandra
Пропускная способность по типам операций (rps) в течение теста
Загрузка CPU (%) в течение теста
Потребление оперативной памяти (ГБ) в течение теста
Дисковая активность: IOPS на чтение и запись
Дисковая активность: пропускная способность (МБ/с) на запись и чтение
Workload B — read mostly (95% чтения, 5% обновлений)
Профиль моделирует системы с преобладанием операций чтения и редкими мутациями, например, тегирование фотографий: большинство операций — чтение тегов, добавление тега — обновление.
Команда для запуска теста:
./bin/ycsb.sh run cassandra-cql \
-P workloads/workloadb \
-p hosts=10.20.1.1 \
-p recordcount=30000000 \
-p operationcount=999999999 \
-p maxexecutiontime=3600 \
-p cassandra.readconsistencylevel=ONE \
-p cassandra.writeconsistencylevel=ONE \
-threads 64 \
-p cassandra.maxconnections=10 \
-p cassandra.coreconnections=10
Запросы (prepared statements):
-- Чтение
SELECT * FROM usertable WHERE y_id = ?
-- Обновление
UPDATE usertable SET field0=?,field1=?,field2=?,field3=?,field4=?,
field5=?,field6=?,field7=?,field8=?,field9=? WHERE y_id = ?
| Параметр | Sirin | Cassandra |
|---|---|---|
| Пропускная способность, rps | 37 612 | 33 866 |
| Время выполнения на чтение p95, мс | 6.09 | 6.08 |
| Время выполнения на чтение p99, мс | 8.26 | 29.6 |
| Время выполнения на чтение min, мс | 0.28 | 0.28 |
| Время выполнения на чтение max, мс | 93.1 | 276 |
| Время выполнения на обновление p95, мс | 5.37 | 5.64 |
| Время выполнения на обновление p99, мс | 7.44 | 29.2 |
| Время выполнения на обновление min, мс | 0.31 | 0.26 |
| Время выполнения на обновление max, мс | 76.4 | 238 |
| Потребление CPU, % | ~82 | ~80 |
| Потребление RAM, ГБ | 3.8 | 12.12 |
| Макс. запись на диск, IOPS | 5.48 | 6.22 |
| Макс. чтение с диска, IOPS | 23 060 | 22 050 |
| Макс. запись на диск, МБ/с | 4.43 | 1.55 |
| Макс. чтение с диска, МБ/с | 284.36 | 476.16 |
Телеметрия
Телеметрия — Sirin
Пропускная способность по типам операций (rps) в течение теста
Загрузка CPU (%) по узлам кластера в течение теста
Потребление оперативной памяти (ГБ) по узлам кластера в течение теста
Дисковая активность: IOPS на чтение и запись
Дисковая активность: пропускная способность (МБ/с) на запись и чтение
Телеметрия — Cassandra
Пропускная способность по типам операций (rps) в течение теста
Загрузка CPU (%) в течение теста
Потребление оперативной памяти (ГБ) в течение теста
Дисковая активность: IOPS на чтение и запись
Дисковая активность: пропускная способность (МБ/с) на запись и чтение
Workload C — read only (100% чтения)
Профиль моделирует системы, в которых данные формируются внешним процессом (например, Hadoop-пайплайном), а сама БД обслуживает только операции чтения — например, кэш профилей пользователей.
Команда для запуска теста:
./bin/ycsb.sh run cassandra-cql \
-P workloads/workloadc \
-p hosts=10.20.1.1 \
-p recordcount=30000000 \
-p operationcount=999999999 \
-p maxexecutiontime=3600 \
-p cassandra.readconsistencylevel=ONE \
-p cassandra.writeconsistencylevel=ONE \
-threads 64 \
-p cassandra.maxconnections=10 \
-p cassandra.coreconnections=10
Запрос (prepared statement):
-- Чтение
SELECT * FROM usertable WHERE y_id = ?
| Параметр | Sirin | Cassandra |
|---|---|---|
| Пропускная способность, rps | 44 540 | 40919 |
| Время выполнения на чтение p95, мс | 4.31 | 4.31 |
| Время выполнения на чтение p99, мс | 5.60 | 25.02 |
| Время выполнения на чтение min, мс | 0.25 | 0.26 |
| Время выполнения на чтение max, мс | 118.1 | 312.3 |
| Потребление CPU, % | ~82 | ~80 |
| Потребление RAM, ГБ | 3.75 | 11.7 |
| Макс. запись на диск, IOPS | 1.58 | 7.22 |
| Макс. чтение с диска, IOPS | 25 070 | 23 970 |
| Макс. запись на диск, МБ/с | 1 | 0.05 |
| Макс. чтение с диска, МБ/с | 296.2 | 516.5 |
Телеметрия
Телеметрия — Sirin
Пропускная способность по типам операций (rps) в течение теста
Загрузка CPU (%) по узлам кластера в течение теста
Потребление оперативной памяти (ГБ) по узлам кластера в течение теста
Дисковая активность: IOPS на чтение
Дисковая активность: пропускная способность (МБ/с) на чтение
Телеметрия — Cassandra
Пропускная способность по типам операций (rps) в течение теста
Загрузка CPU (%) в течение теста
Потребление оперативной памяти (ГБ) в течение теста
Дисковая активность: IOPS на чтение
Дисковая активность: пропускная способность (МБ/с) на чтение
Workload D — read latest (95% чтения, 5% вставок)
Профиль моделирует системы, где пользователи в основном читают свежие данные — например, ленту статусов: новые записи добавляются непрерывно, и они же чаще всего читаются. В отличие от workload B, запросы используют распределение latest: недавно вставленные ключи запрашиваются с большей вероятностью.
Команда для запуска теста:
./bin/ycsb.sh run cassandra-cql \
-P workloads/workloadd \
-p hosts=10.20.1.1 \
-p recordcount=30000000 \
-p operationcount=999999999 \
-p maxexecutiontime=3600 \
-p cassandra.readconsistencylevel=ONE \
-p cassandra.writeconsistencylevel=ONE \
-threads 64 \
-p cassandra.maxconnections=10 \
-p cassandra.coreconnections=10
Запросы (prepared statements):
-- Чтение
SELECT * FROM usertable WHERE y_id = ?
-- Вставка
INSERT INTO usertable (y_id,field0,field1,field2,field3,field4,
field5,field6,field7,field8,field9) VALUES (?,?,?,?,?,?,?,?,?,?,?)
| Параметр | Sirin | Cassandra |
|---|---|---|
| Пропускная способность, rps | 63 591 | 53 396 |
| Время выполнения на чтение p95, мс | 3.05 | 2.92 |
| Время выполнения на чтение p99, мс | 4.64 | 14.6 |
| Время выполнения на чтение min, мс | 0.24 | 0.24 |
| Время выполнения на чтение max, мс | 120 | 198 |
| Время выполнения на вставку p95, мс | 3.11 | 3.11 |
| Время выполнения на вставку p99, мс | 4.69 | 16.1 |
| Время выполнения на вставку min, мс | 0.33 | 0.29 |
| Время выполнения на вставку max, мс | 118 | 148 |
| Потребление CPU, % | ~79 | ~82 |
| Потребление RAM, ГБ | 3.95 | 11.97 |
| Макс. запись на диск, IOPS | 80 | 36 |
| Макс. чтение с диска, IOPS | 15 480 | 15 330 |
| Макс. запись на диск, МБ/с | 72 | 33 |
| Макс. чтение с диска, МБ/с | 188 | 306 |
Телеметрия
Телеметрия — Sirin
Пропускная способность по типам операций (rps) в течение теста
Загрузка CPU (%) по узлам кластера в течение теста
Потребление оперативной памяти (ГБ) по узлам кластера в течение теста
Дисковая активность: IOPS на чтение и запись
Дисковая активность: пропускная способность (МБ/с) на запись и чтение
Телеметрия — Cassandra
Пропускная способность по типам операций (rps) в течение теста
Загрузка CPU (%) в течение теста
Потребление оперативной памяти (ГБ) в течение теста
Дисковая активность: IOPS на чтение и запись
Дисковая активность: пропускная способность (МБ/с) на запись и чтение
Workload F — read-modify-write (50% чтения, 50% RMW)
Профиль моделирует системы, где записи читаются и тут же модифицируются пользователем или для фиксации его активности — например, пользовательские базы данных с накопительными счётчиками. В отличие от слепого обновления (workload A), операция RMW всегда предваряется чтением той же строки, что удваивает количество обращений к хранилищу на одну логическую операцию. Пропускная способность для этого профиля измеряется в tps: YCSB считает одной транзакцией либо чистый READ, либо полный RMW-цикл — вне зависимости от числа фактических запросов к БД.
Команда для запуска теста:
./bin/ycsb.sh run cassandra-cql \
-P workloads/workloadf \
-p hosts=10.20.1.1 \
-p recordcount=— \
-p operationcount=999999999 \
-p maxexecutiontime=3600 \
-p cassandra.readconsistencylevel=ONE \
-p cassandra.writeconsistencylevel=ONE \
-threads — \
-p cassandra.maxconnections=10 \
-p cassandra.coreconnections=10
Запросы (prepared statements):
-- Чтение (в т.ч. первый шаг RMW)
SELECT * FROM usertable WHERE y_id = ?
-- Запись (второй шаг RMW)
UPDATE usertable SET field0=?,field1=?,field2=?,field3=?,field4=?,
field5=?,field6=?,field7=?,field8=?,field9=? WHERE y_id = ?
| Параметр | Sirin | Cassandra |
|---|---|---|
| Пропускная способность, tps | 24 805 | 19 930 |
| Время выполнения на чтение p95, мс | 7.08 | 10.1 |
| Время выполнения на чтение p99, мс | 10.19 | 36.38 |
| Время выполнения на чтение min, мс | 0.25 | 0.3 |
| Время выполнения на чтение max, мс | 126.7 | 443 |
| Время выполнения на RMW p95, мс | 11.94 | 21.34 |
| Время выполнения на RMW p99, мс | 16.77 | 41.63 |
| Время выполнения на RMW min, мс | 0.65 | 0.61 |
| Время выполнения на RMW max, мс | 137 | 448 |
| Потребление CPU, % | ~81 | ~80 |
| Потребление RAM, ГБ | 3.96 | 11.9 |
| Макс. запись на диск, IOPS | 63.6 | 15.5 |
| Макс. чтение с диска, IOPS | 19 340 | 27 590 |
| Макс. запись на диск, МБ/с | 58.7 | 12.6 |
| Макс. чтение с диска, МБ/с | 247.3 | 446.1 |
Телеметрия
Телеметрия — Sirin
Пропускная способность по типам операций (tps) в течение теста
Загрузка CPU (%) по узлам кластера в течение теста
Потребление оперативной памяти (ГБ) по узлам кластера в течение теста
Дисковая активность: IOPS на чтение и запись
Дисковая активность: пропускная способность (МБ/с) на запись и чтение
Телеметрия — Cassandra
Пропускная способность по типам операций (tps) в течение теста
Загрузка CPU (%) в течение теста
Потребление оперативной памяти (ГБ) в течение теста
Дисковая активность: IOPS на чтение и запись
Дисковая активность: пропускная способность (МБ/с) на запись и чтение
Выводы
Архитектурный контекст
В тестах использовалось 30 миллионов записей (~30 ГБ сырых данных при ~1 КБ на строку). Этот объём не помещается как в memtable систем, так и в дисковый кеш linux. В результате чтения обоих систем частично уходят на диск. Однако использование Zipfian подразумевает горячее пятно в данных, к которому обращается большая часть запросов, и, следовательно, эти данные всегда находятся в page cache.
Workload A
Оба стенда показывают постепенное снижение пропускной способности на протяжении всего часа: по графикам RPS Sirin падает с ~52 000 до ~35 000 rps, Cassandra — с ~45 000 до ~25 000 rps. Причина видна на графиках IOPS: по мере накопления обновлений новые LSM-уровни вытесняют горячие данные из буфера, и чтение всё чаще уходит на диск. У Cassandra дисковые чтения монотонно растут с ~12 000 до 29 000 IOPS к концу теста — именно это обеспечивает более резкое падение производительности. У Sirin рост IOPS сдержаннее (~12 000–15 000), а деградация мягче: ~33% против ~44% у Cassandra.
Средний результат за час — Sirin 41 585 против 31 888 rps (+30%). По хвостовым задержкам (tail latency) Sirin значительно лучше: p99 на чтение 3.76 мс против 33.98 мс, p99 на обновление 3.54 мс против 30.77 мс. Максимальная задержка у Cassandra достигает 500 мс против 100 мс у Sirin.
Workload B
При снижении доли обновлений с 50% до 5% картина меняется. По графикам IOPS у обеих систем дисковые чтения не растут, а постепенно снижаются к концу теста (Sirin: ~23 000→17 000 IOPS, Cassandra: ~22 000→18 000 IOPS) — кэш OS постепенно прогревается на читающей нагрузке. Несмотря на это, RPS обеих систем незначительно снижается к концу теста, что указывает на CPU как на основное ограничение в данном профиле.
Преимущество Sirin сокращается до 11% (37 612 против 33 866 rps). Хвостовые задержки (tail latency) остаются значительно лучше: p99 на чтение 8.26 мс против 29.6 мс, p99 на обновление 7.44 против 29.2 мс.
Workload C
Единственный профиль, на котором обе системы выходят на стабильный режим с первых минут и удерживают его без деградации до конца теста. Отсутствие записи исключает рост LSM-уровней и давление компакции, поэтому тест демонстрирует «чистую» читающую производительность при установившемся кэше. На графике RPS у Sirin кривая практически горизонтальна на протяжении всего часа.
Sirin опережает Cassandra на 9% (44 540 против 40 919 rps). P99 на чтение: 5.60 мс против 25.02 мс.
Workload D
Обе системы работают при сопоставимой дисковой нагрузке на чтение (~15 480 и ~15 330 IOPS соответственно), однако Sirin опережает Cassandra: 63 591 против 53 396 rps (+19%) при меньшем потреблении CPU (79% против 82%). Cassandra при этом читает с диска значительно больше байт — 306 МБ/с против 188 МБ/с у Sirin — при практически одинаковом числе операций: это означает, что Cassandra читает более крупными блоками и «подтягивает» больше лишних данных за один IOPS.
На стороне записи картина обратная: Sirin активнее пишет на диск (80 против 36 write IOPS, 72 против 33 МБ/с) — следствие более частых фоновых компакций Vinyl при поступлении новых вставок. Несмотря на это, на графике RPS Sirin держит стабильный уровень ~62–65 000 с характерными кратковременными просадками от компакций, а у Cassandra RPS ровный, но на ~19% ниже.
P99 на чтение: 4.64 мс против 14.6 мс; p99 на вставку: 4.69 мс против 16.1 мс.
Workload F
Sirin опережает Cassandra на 24%: 24 805 против 19 930 tps. Это наименьший абсолютный показатель пропускной способности среди всех профилей — закономерный результат: RMW-цикл требует двух последовательных обращений к БД (SELECT, затем UPDATE), и пока не завершится чтение, поток не может начать запись. Это увеличивает эффективную задержку на транзакцию по сравнению со слепым обновлением в workload A.
Хвостовые задержки (tail latency) отражают двухфазную природу RMW: p99 на RMW у Sirin составляет 16.77 мс против 41.63 мс у Cassandra (разрыв ×2.5). P99 на чистое чтение — 10.19 мс против 36.38 мс. Максимальные задержки у Cassandra достигают 443–448 мс против 127–137 мс у Sirin.
Картина дисковых операций близка к workload D: Cassandra читает с диска больше байт при большем числе IOPS — 446 МБ/с при 27 590 IOPS против 247 МБ/с при 19 340 IOPS у Sirin. Та же закономерность — Cassandra считывает более крупные блоки и «подтягивает» лишние данные, тогда как Sirin читает эффективнее. На стороне записи Sirin активнее пишет на диск (63.6 IOPS / 58.7 МБ/с против 15.5 IOPS / 12.6 МБ/с), что характерно для фоновых компакций Vinyl.
Потребление ресурсов
Sirin стабильно потребляет 3.6–4.0 ГБ оперативной памяти во всех тестах. Cassandra — 11.7–12.1 ГБ, то есть втрое больше. Разница принципиальна: при совместном размещении узлов или сервисов на одной машине это существенно влияет на допустимую плотность. По CPU обе системы в смешанных тестах выходят на ~80%, то есть вычислительное ядро нагружено сопоставимо.
Итог
Sirin опережает Cassandra по пропускной способности во всех пяти протестированных профилях: ×1.30 (A), ×1.11 (B), ×1.09 (C), ×1.19 (D), ×1.24 (F). На нагрузках со значительной долей записи (A, B) основным ограничивающим фактором для обеих систем является рост дисковых чтений при накоплении LSM-уровней; Sirin деградирует медленнее. На чисто читающей нагрузке (C), при вставках с latest-распределением (D) и при RMW-нагрузке (F) Sirin показывает более высокую эффективность при аналогичном числе дисковых операций: Cassandra читает с диска заметно больше байт за тот же IOPS, что снижает итоговую пропускную способность.
По задержкам Sirin стабильно лучше: p99 в 2.5–9 раз ниже, максимальные задержки у Cassandra достигают 198–500 мс против 93–137 мс у Sirin. Потребление RAM у Sirin втрое ниже при сопоставимой загрузке CPU.