Přeskočit na obsah
_CORE
AI & Agentic Systems Core Informační Systémy Cloud & Platform Engineering Data Platforma & Integrace Security & Compliance QA, Testing & Observability IoT, Automatizace & Robotika Mobile & Digital Banky & Finance Pojišťovnictví Veřejná správa Obrana & Bezpečnost Zdravotnictví Energetika & Utility Telco & Média Průmysl & Výroba Logistika & E-commerce Retail & Loyalty
Reference Technologie Blog Knowledge Base O nás Spolupráce Kariéra
Pojďme to probrat

Apache Cassandra — distribuovaná databáze pro velká data

14. 04. 2014 3 min čtení CORE SYSTEMSdata

Relační databáze nás provázejí celou kariérou. Ale co když potřebujete zapisovat miliony událostí za sekundu, data replikovat napříč datovými centry a přitom garantovat dostupnost 99,99 %? PostgreSQL ani Oracle na to nestačí. Začali jsme experimentovat s Apache Cassandrou.

Proč ne relační databáze?

Pro telco klienta jsme stavěli systém pro sběr CDR záznamů (Call Detail Records). Požadavky: 50 000 zápisů za sekundu, retence 2 roky, přístup k datům z dvou geograficky oddělených lokalit. Klasický přístup — PostgreSQL s partitioningem — narazil na limity vertikálního škálování. Přidávat RAM a CPU na jeden server má svůj strop.

Cassandra nabízí horizontální škálování — přidáte nový uzel do clusteru a data se automaticky přerozdělí. Žádný single point of failure, žádný master node. Každý uzel je rovnocenný.

Architektura: ring a partitioning

Cassandra organizuje uzly do logického kruhu (ring). Každý řádek dat má partition key, ze kterého se vypočítá hash. Hash určí, na který uzel data patří. S replikačním faktorem 3 se každý řádek uloží na tři uzly — pokud jeden spadne, data jsou stále dostupná.

CREATE KEYSPACE telco_cdr
  WITH replication = {
    'class': 'NetworkTopologyStrategy',
    'dc_prague': 3,
    'dc_brno': 3
  };

CREATE TABLE telco_cdr.call_records (
    phone_number text,
    call_date date,
    call_time timestamp,
    duration int,
    called_number text,
    cell_id text,
    PRIMARY KEY ((phone_number, call_date), call_time)
) WITH CLUSTERING ORDER BY (call_time DESC);

Klíčový je návrh partition key. Zvolili jsme kompozitní klíč (phone_number, call_date) — každá partice obsahuje záznamy jednoho čísla za jeden den. To zajišťuje rovnoměrné rozložení dat a efektivní dotazy typu „ukaž mi hovory čísla X za datum Y”.

Tunable consistency

Na rozdíl od relačních databází, kde máte ACID transakce, Cassandra nabízí nastavitelnou konzistenci. Pro každý dotaz volíte úroveň:

  • ONE — odpověď z jednoho uzlu, nejrychlejší, ale riskujete zastaralá data
  • QUORUM — odpověď z většiny replik, dobrý kompromis
  • ALL — odpověď ze všech replik, nejpomalejší, ale silná konzistence
  • LOCAL_QUORUM — quorum v rámci jednoho datového centra, ideální pro geo-replikaci

Pro zápisy CDR záznamů jsme zvolili LOCAL_QUORUM — data se potvrdí lokálně a asynchronně replikují do druhého DC. Pro čtení analytických reportů používáme také LOCAL_QUORUM, čímž garantujeme konzistenci čtení po zápisu v rámci jedné lokality.

Data modeling: query-first přístup

Největší mentální posun oproti relačním databázím: v Cassandře modelujete data podle dotazů, ne podle entit. Normalizace neexistuje. Duplikace dat je normální a žádoucí.

Pokud potřebujete stejná data zobrazit dvěma různými způsoby (podle čísla a podle buňky sítě), vytvoříte dvě tabulky se stejnými daty, ale různými partition keys. Zapisujete do obou současně. Disk je levný, latence dotazu drahá.

Operace v produkci

Compaction

Cassandra zapisuje data do immutable souborů (SSTables). Periodicky je slučuje proces compaction. Zvolili jsme DateTieredCompactionStrategy — optimální pro time-series data, kde se starší záznamy nemění. Compaction je CPU a I/O náročná operace, plánujeme ji mimo špičku.

Repair

Pokud uzel byl offline a zmeškal zápisy, data na něm mohou být neaktuální. Příkaz nodetool repair synchronizuje data mezi replikami. Spouštíme ho jednou týdně na každém uzlu — je to nutná údržba, ale zatěžuje cluster.

Monitoring

Cassandra exportuje metriky přes JMX. Sledujeme zejména: read/write latency (p99 pod 10 ms), compaction pending (nemá narůstat), heap usage a tombstone count. Příliš mnoho tombstones (mazání v Cassandře) zpomaluje čtení — proto preferujeme TTL nad explicitním DELETE.

Cassandra vs. MongoDB

Obě jsou NoSQL, ale řeší jiné problémy. MongoDB exceluje v flexibilním schématu a ad-hoc dotazech — je bližší relační databázi. Cassandra vyniká v zápisovém výkonu, horizontálním škálování a multi-DC replikaci. Pro naše CDR záznamy (write-heavy, time-series, geo-distribuované) byla Cassandra jasná volba.

Výsledky

Cluster šesti uzlů (3 v každém DC) zpracovává 80 000 zápisů/s s p99 latencí pod 5 ms. Čtení analytických dotazů (hovory jednoho čísla za měsíc) trvá 15–30 ms. Data se replikují mezi Prahou a Brnem s latencí pod 50 ms. Za šest měsíců provozu jsme měli nulový výpadek — i při plánované údržbě (rolling restart) cluster běžel bez přerušení.

Cassandra není náhrada relační databáze

Cassandra je specializovaný nástroj pro specifické use cases: write-heavy workloady, time-series data, geo-distribuované systémy. Pokud potřebujete JOINy, ad-hoc dotazy nebo ACID transakce, zůstaňte u PostgreSQL.

Ale pokud vaše požadavky odpovídají — a věříme, že s rostoucím objemem dat bude takových projektů přibývat — Cassandra je výjimečně spolehlivé řešení.

cassandranosqlbig datadistribuované systémy