Налаштування бази даних Cassandra для веб-застосунку

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Налаштування бази даних Cassandra для веб-застосунку
Складна
~3-5 робочих днів
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Налаштування Apache Cassandra для веб-додатку

Apache Cassandra — розподілена NoSQL база з лінійним масштабуванням запису та високою доступністю без однієї точки отказу. Вона проектується навколо шаблонів запитів, а не нормалізації даних: спочатку визначаєтеся, як читатимуться дані, потім будуєте схему. Це кардинально змінює підхід до дизайну.

Коли вибирають Cassandra

Часові ряди з мільйонами подій на секунду, стрічки активності, системи логування, IoT-телеметрія — місця, де потрібно писати швидко та багато. Netflix, Discord, Apple використовують Cassandra саме для цього. Discord зберігає трильйони повідомлень у Cassandra. Для OLTP зі складними транзакціями не підходить.

Встановлення 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       # IP поточного вузла
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
num_tokens: 256

Налаштування JVM

# /etc/cassandra/jvm11-server.options
-Xms8G
-Xmx8G
-XX:+UseG1GC
-XX:G1RSetUpdatingPauseTimePercent=5
-XX:MaxGCPauseMillis=300
-XX:InitiatingHeapOccupancyPercent=70

Схема даних — проектування на основі запитів

-- 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,  -- JSON
    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;  -- 90 днів

-- Статистика користувача
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()

// Підготовлені запити — обов'язкові в production
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)
}

Моніторинг та діагностика

# Статус кластера
nodetool status

# Навантаження на вузол
nodetool tpstats
nodetool cfstats myapp.user_events

# Повільні запити (увімкнути в cassandra.yaml)
# slow_query_log_timeout_in_ms: 500

# Статус компакції
nodetool compactionstats

# Очищення непотрібних даних
nodetool cleanup myapp

Репліка та консистентність

// Різні рівні консистентності для різних операцій
const { types: { consistencies } } = cassandra

// Запис — LOCAL_QUORUM для балансу швидкості та надійності
await client.execute(insertEvent, params, {
  consistency: consistencies.localQuorum
})

// Читання аналітики — ONE для максимальної швидкості
await client.execute(selectEvents, params, {
  consistency: consistencies.one
})

// Критичні дані — QUORUM
await client.execute(criticalQuery, params, {
  consistency: consistencies.quorum
})

Терміни

Налаштування трьохвузлового кластера Cassandra з базовою схемою: 3–4 дні. Проектування схеми для конкретних запитів додатку + інтеграція з backend + тестування навантаження: 1–2 тижні. Міграція даних з реляційної бази в Cassandra з трансформацією моделі: 2–4 тижні.