Настройка Apache Cassandra для веб-приложения требует не просто установки пакета. Без грамотного проектирования схемы и конфигурации кластера вы получите медленные запросы, горячие партиции и нестабильную работу под нагрузкой. За 5 лет работы мы настроили Cassandra для 30+ проектов: ленты событий, метрики, логи. Самая частая ошибка — неправильный первичный ключ. Игнорирование compaction и недостаток памяти для memtable приводят к падению производительности в 2-3 раза. Правильная настройка Cassandra с первого раза экономит недели переделок. Делимся проверенными приёмами.
Где Cassandra незаменима
Временные ряды с миллионами событий в секунду, ленты активности, системы логирования, IoT-телеметрия — там, где нужно писать быстро и много. Netflix, Discord, Apple используют Cassandra именно для этого. Discord хранит триллионы сообщений. Для OLTP со сложными транзакциями — не подходит. Мы применяем Cassandra для хранения метрик и логов: она даёт линейное масштабирование записи и отказоустойчивость без единой точки отказа.
Как установить и настроить Cassandra 4.1
Установка Cassandra 4.1:
echo "deb https://debian.cassandra.apache.org 41x main" > /etc/apt/sources.list.d/cassandra.sources.list
curl https://downloads.apache.org/cassandra/KEYS | apt-key add -
apt update && apt install -y cassandra
После установки отредактируйте cassandra.yaml:
cluster_name: 'MyAppCluster'
# Сеть
listen_address: 10.0.0.1
rpc_address: 10.0.0.1
seeds: "10.0.0.1,10.0.0.2,10.0.0.3"
# Директории
data_file_directories:
- /var/lib/cassandra/data
commitlog_directory: /var/lib/cassandra/commitlog # отдельный диск для скорости
hints_directory: /var/lib/cassandra/hints
saved_caches_directory: /var/lib/cassandra/saved_caches
# Производительность
concurrent_reads: 32
concurrent_writes: 32
concurrent_counter_writes: 16
memtable_heap_space: 2048
compaction_throughput_mb_per_sec: 64
# Репликация и консистентность
endpoint_snitch: GossipingPropertyFileSnitch
# JVM (в jvm11-server.options)
num_tokens: 256
Дополнительно настройте JVM, чтобы избежать длительных GC-пауз:
# /etc/cassandra/jvm11-server.options
-Xms8G
-Xmx8G
-XX:+UseG1GC
-XX:G1RSetUpdatingPauseTimePercent=5
-XX:MaxGCPauseMillis=300
-XX:InitiatingHeapOccupancyPercent=70
Сравнение стратегий уплотнения
| Стратегия | Назначение | Когда использовать |
|---|---|---|
| SizeTieredCompactionStrategy | По умолчанию | Универсальный вариант, подходит для большинства случаев |
| TimeWindowCompactionStrategy | Временные ряды | Данные с TTL, ленты событий — уменьшает количество файлов |
| LeveledCompactionStrategy | Частые обновления | Системы с большим количеством записей, требует больше дискового пространства |
Выбор compaction напрямую влияет на производительность чтения и записи. Например, TimeWindowCompactionStrategy уменьшает количество SSTable в 2-3 раза по сравнению с SizeTieredCompactionStrategy при работе с временными рядами. Мы рекомендуем TimeWindowCompactionStrategy для данных с TTL, а LeveledCompactionStrategy — для сценариев с интенсивными обновлениями.
Какую стратегию compaction выбрать?
Ориентируйтесь на характер данных. Если данные имеют TTL и записываются с постоянной скоростью — TimeWindowCompactionStrategy. Для частых обновлений и удалений — LeveledCompactionStrategy. SizeTieredCompactionStrategy — безопасный выбор, если не уверены.
Почему важен правильный выбор ключа партиционирования?
Ключ партиционирования определяет распределение данных по узлам. Если он выбран неправильно, одни узлы будут перегружены, другие простаивают. Например, для таблицы user_events мы используем user_id — это гарантирует равномерное распределение. Для временных рядов (таблица metrics) составной ключ (service, bucket, metric_name) позволяет сгруппировать метрики по сервису и временному окну. Никогда не используйте столбцы с малым количеством уникальных значений (boolean или enum) — это приведёт к горячим партициям.
Схема данных — Query-driven design
-- Keyspace с репликацией
CREATE KEYSPACE myapp
WITH replication = {
'class': 'NetworkTopologyStrategy',
'dc1': 3
} AND durable_writes = true;
USE myapp;
-- Лента событий пользователя
CREATE TABLE user_events (
user_id uuid,
occurred_at timestamp,
event_id uuid,
event_type text,
payload text,
PRIMARY KEY ((user_id), occurred_at, event_id)
) WITH CLUSTERING ORDER BY (occurred_at DESC)
AND compaction = {'class': 'TimeWindowCompactionStrategy',
'compaction_window_unit': 'DAYS',
'compaction_window_size': 7}
AND default_time_to_live = 7776000;
-- Статистика по пользователям
CREATE TABLE user_stats (
user_id uuid PRIMARY KEY,
total_orders counter,
total_spent counter,
last_active timestamp
);
-- Временные ряды метрик
CREATE TABLE metrics (
service text,
bucket timestamp,
metric_name text,
ts timestamp,
value double,
PRIMARY KEY ((service, bucket, metric_name), ts)
) WITH CLUSTERING ORDER BY (ts DESC)
AND compaction = {'class': 'TimeWindowCompactionStrategy',
'compaction_window_unit': 'HOURS',
'compaction_window_size': 1};
Интеграция с бэкендом на Node.js
import cassandra from 'cassandra-driver'
const client = new cassandra.Client({
contactPoints: ['10.0.0.1', '10.0.0.2', '10.0.0.3'],
localDataCenter: 'dc1',
keyspace: 'myapp',
credentials: { username: 'cassandra', password: process.env.CASSANDRA_PASSWORD! },
pooling: {
coreConnectionsPerHost: {
[cassandra.types.distance.local]: 3,
[cassandra.types.distance.remote]: 1
}
},
socketOptions: { readTimeout: 12000 }
})
await client.connect()
const insertEvent = await client.prepare(`
INSERT INTO user_events (user_id, occurred_at, event_id, event_type, payload)
VALUES (?, ?, ?, ?, ?)
`)
const selectEvents = await client.prepare(`
SELECT * FROM user_events
WHERE user_id = ? AND occurred_at >= ? AND occurred_at <= ?
ORDER BY occurred_at DESC
LIMIT ?
`)
async function writeEvents(events: UserEvent[]) {
const batch = events.map(e => ({
query: insertEvent,
params: [
cassandra.types.Uuid.fromString(e.userId),
new Date(e.occurredAt),
cassandra.types.TimeUuid.now(),
e.eventType,
JSON.stringify(e.payload)
]
}))
await client.batch(batch, { prepare: true, logged: false })
}
async function* fetchEvents(userId: string, from: Date, to: Date) {
const options = { prepare: true, fetchSize: 1000 }
let pageState: Buffer | undefined
do {
const result = await client.execute(selectEvents,
[cassandra.types.Uuid.fromString(userId), from, to, 1000],
{ ...options, pageState })
yield result.rows
pageState = result.pageState as Buffer | undefined
} while (pageState)
}
Уровни консистентности
| Уровень | Скорость | Надёжность | Пример использования |
|---|---|---|---|
| ONE | Быстро | Низкая | Аналитика, кэш |
| LOCAL_QUORUM | Средне | Высокая | Операции записи |
| QUORUM | Медленно | Максимальная | Критические данные |
const { types: { consistencies } } = cassandra
await client.execute(insertEvent, params, { consistency: consistencies.localQuorum })
await client.execute(selectEvents, params, { consistency: consistencies.one })
await client.execute(criticalQuery, params, { consistency: consistencies.quorum })
Мониторинг и диагностика
nodetool status
nodetool tpstats
nodetool cfstats myapp.user_events
nodetool compactionstats
nodetool cleanup myapp
Включите медленные запросы в cassandra.yaml: slow_query_log_timeout_in_ms: 500.
Типичные ошибки и их решение
- Горячие партиции из-за неправильного ключа: используйте составные ключи с высокой кардинальностью. Избегайте столбцов с малым количеством значений.
-
Высокое потребление памяти: уменьшите
memtable_heap_spaceили переключите G1GC на ParallelGC. -
Медленная запись: проверьте диск для commitlog — используйте отдельный SSD. Увеличьте
concurrent_writes.
Сколько времени занимает полная настройка?
Типовой проект с тремя узлами и интеграцией занимает 2-3 недели. Включает аудит требований, проектирование схемы, развёртывание кластера, оптимизацию конфигурации и написание адаптера для бэкенда. Сложные кластеры с несколькими дата-центрами могут потребовать до 5 недель. Получите точную оценку под вашу задачу — напишите нам.
Наши кейсы и гарантии
Мы выполнили более 30 проектов с Cassandra, включая системы метрик для рекламной платформы (100 млн событий в сутки) и лент активности для SaaS-сервиса. В каждом проекте мы гарантируем стабильную работу кластера в течение месяца после сдачи. Наши инженеры имеют 5+ лет опыта с Cassandra и смежными технологиями. Свяжитесь с нами для консультации — обсудим вашу архитектуру бесплатно.
Что входит в настройку под ключ
- Аудит текущей архитектуры и требований к нагрузке
- Проектирование схемы данных (query-driven design)
- Развёртывание кластера (bare-metal / облако / Docker)
- Оптимизация
cassandra.yaml, JVM и сетевых настроек - Интеграция с бэкендом (Node.js, Python, Go)
- Документация схемы и инструкции по эксплуатации
- Обучение команды и рекомендации по эксплуатации
- Гарантия стабильной работы кластера в течение месяца после сдачи
Закажите настройку Cassandra под вашу задачу — получите консультацию инженера с 5-летним опытом.







