Senzorické informace jsou typicky kategorie “time series”, tedy jednoduché zprávy obsahující nějakou naměřenou hodnotu. Nejsem expert na data, ale z pohledu celkové architektury jsem se chtěl podívat jak se problém ukládání tohoto typu dat rámcově řeší.
Jak vypadají time series data
V zásadě pro každý senzor musíme mít jeho identifikaci a kategorizaci, tedy například, že se nachází v prvním patře, v budově A, v Praze, je vlastněn společností XY a tak dále. V zásadě jsou to nějaké tagy, tedy jakékoli informace, podle kterých pak chceme třídit či vyhledávat.
Druhý typ informace je co měříme, tedy teplotu, vlhkost, obsah oxidu uhličitého apod.
Třetí informací je samotná naměřená hodnota. Ta na rozdíl od dvou předchozích nebude typicky indexována, tedy práce s daty nebude optimalizovaná na vyhledávání míst, kde je teplota 20 stupňů. Víc nás bude zajímat jaká byla průměrná teplota v Praze v nějakém časovém okně.
Co od systému potřebujeme
Základní dimenzí (chcete-li primárním klíčem) je vždy čas. V případě time series data prakticky nikdy nepotřebujeme modifikovat nějaký záznam ani selektivně mazat. Data ze senzorů jsou tak jak jsou a spíše budeme odmazávat velké bloky zastaralých dat. Engine je tak možné pro tento typ práce optimalizovat.
V každém případě můžeme očekávat velké množství stále rostoucích dat (a typicky se zvětšujícím se timestamp) , takže systém by měl disponovat velkou škálovatelností a třeba i automatickým promazáváním (například chceme si držet jen údaje za poslední týden).
Pro time series jsou obvyklé specifické operace, na které tradiční databáze nejsou optimalizované. Například možnost provádět automatický downsampling, tedy třeba sbírat data ve vteřinových intervalech, ale takto je ukládat jen jeden den. Agregované údaje po minutách (s možností volby agregační funkce typu mean, median, percentile, min, max) odlévat do druhé databáze s retencí jeden měsíc a z této potom do časově neomezené databáze s agregací po hodinách.
Další časová specialita je vypořádání se s chybějícími daty. Senzory často nejsou nijak dokonale spolehlivé nebo robustně připojené a běžně se stane, že nějaká data prostě nedorazí. Další varianta je, že reportují nepravidelně. Databáze by mohla mít schopnost (ideálně na požádání při čtení, ne nějakou logikou při zápisu) data usadit do časových “tiků” dle naší volby (třeba do 5-minutových bodů). Pokud tam takové údaje nejsou, tak dotaz nesmí zkolabovat, ale má vrátit třeba null nebo nulu a nebo dokonce chybějící údaje dopočítat, například ukázat poslední známou hodnotu nebo lineárně proložit předchozí a následující.
Klíčovou vlastností time series databáze jistě musí být agregace údajů do časových intervalů (chci výstup seskupený v minutových intervalech), agregační funkce nad hodnotami (mean, median, percentil, min, max či složitější vzorce) a filtrování podle indexovaných tagů (chci jen ČR, Maďarsko ne).
Co můžeme použít?
Time-series specialista
Dobrou volbou jsou určitě NoSQL databáze optimalizované přímo konkrétně na time series data. Nejznámější je v tomto světě InfluxDB, kterou si na těchto stránkách ještě vyzkoušíme.
Relační DB
Další varianta je držet údaje v tradičnější relační databázi s ACID vlastnostmi, kde každé měření senzoru bude řádek v tabulce. Tyto DB rozhodně nejsou na tyto operace optimalizované, velkou část logiky budete muset vyřešit aplikačně a v tomto scénáři neškálují dobře. Vezměme v úvahu, že pokud bychom odečítali hodnoty každou vteřinu, tak jediný senzor měřící teplotu, vlhkost, UV záření a koncentraci CO2 vygeneruje 10 milionu záznamů měsíčně. Tím pádem jedna velká budova je třeba miliarda záznamů, jedno město bilion – a to je na tradiční řešení dost.
Wide-column NoSQL
Velmi dobře poslouží wire-column NoSQL databáze jako je Cassandra. Tam uložíte senzor na jeden řádek a každé měření bude nový sloupec, což vám bude škálovat až do milionu sloupců (pokud máte dat víc tak buď využijete automatické expirace, takže Cassandra bude ty nejstarší odmazávat, nebo musíte záznam rozdělit, což ale může aplikaci trochu komplikovat). Cassandra je dostatečně univerzální, aby uložila v obrovské škále co potřebujete, ale některé specifické time series vlastnosti budou na vás (třeba interpolace). Podobné závěry platí třeba i pro HBase a další databáze tohoto typu, třeba Azure Table Storage.
NewSQL
Zajímavou variantou je NewSQL databáze Vertica. Ta je v principu relační a má ACID vlastnosti, takže ji můžete použít i tam, kde je zvláštní důraz na konzistenci časosběrných dat (například pro forenzní účely). Na rozdíl od klasických SQL systémů je ale DB optimalizována pro analytické operace, což je co potřebujeme (prakticky vždy nás budou zajímat průměrné teploty za určité období, trendy apod. spíše, než že si vyžádáme jednotlivou informaci typu kolik naměřil teplotní senzor na Malé Straně včera tři vteřiny po půlnoci). Vertica má speciální režim pro time series operace a dokáže dokonce sama lineárně interpolovat chybějící údaje.
Jak to spolehlivě posbírat a analyzovat?
Představte si tu obrovskou křižovatku dat ze všech senzorů jak se snaží reportovat své údaje a někam je zapsat. Na druhé straně může být vícero příjemců těchto údajů s tím, že každého mohou zajímat jiné údaje. Tak třeba všechny hodnoty chceme uložit do nějaké probírané time series databáze pro jejich krátkodobější uložení a následnu agregaci. Vybrané údaje ale chceme v reálném čase zpracovávat a reagovat na ně například automatickým přenastavením klimatizace, takže data typu teplota a vlhkost chceme posílat ještě do streaming analyzátoru typ Apache Storm či Spark Streaming. Některá měření chceme zahrnout do nějaké velmi sofistikované dlouho trvající analýzy a umístit je do HBase, přímo do HDSF nebo jiný způsobem připravit pro noční Hadoop chroupání. Shrnuto – někdy chceme ukládat a dělat jednodušší agregace, někdy chceme provádět složitejší výpočty v reálném čase a někdy chceme data umístit do šelmostroje, který provede sofistikovanou analýzu dávkovým způsobem.
Typicky se tedy mezi senzory (generátory dat) a příjemce umisťuje robustní messaging frontovací systém. Pro svoji obrovskou škálovatelnost je v tomto populární Apache Kafka, pokud jedete v Azure, použijete Event Hub.