Kas yra Apache Pinot ir kam jis skirtas
Jei kada nors bandėte realiu laiku analizuoti milijonus įvykių per sekundę, tikriausiai supratote, kad tradicinės duomenų bazės čia ne visai tinka. Štai čia ir ateina į pagalbą Apache Pinot – OLAP (Online Analytical Processing) duomenų bazė, kuri buvo sukurta LinkedIn inžinierių ir vėliau tapo Apache Software Foundation projektu.
Pinot yra skirtas scenarijai, kai reikia greitai atsakyti į sudėtingus analitinės užklausas dideliems duomenų kiekiams. Kalbame apie tokius atvejus kaip realaus laiko analitika, metrikų stebėjimas, anomalijų aptikimas ar vartotojų elgsenos analizė. Skirtingai nuo tradicinių OLTP duomenų bazių (kaip MySQL ar PostgreSQL), kurios optimizuotos transakcijoms, Pinot sukurtas būtent analitikai.
Įdomu tai, kad Pinot nėra dar viena „viską galinti” duomenų bazė. Jis turi labai konkretų tikslą – suteikti žaibiškai greitą atsakymą į analitines užklausas, net kai duomenys atkeliauja srautais ir nuolat keičiasi. Tai reiškia, kad jis puikiai integruojasi su Apache Kafka, Apache Flink ar kitomis stream processing sistemomis.
Architektūra ir pagrindiniai komponentai
Pinot architektūra yra gana įdomi ir paremta keliais pagrindiniais komponentais, kurie dirba kartu kaip gerai suderintas orkestras. Pirmiausia turime Controller – tai lyg dirigentė, kuri koordinuoja visą sistemą, tvarko metaduomenis ir užtikrina, kad visi komponentai žinotų, ką daryti.
Toliau eina Broker serveriai, kurie priima užklausas iš klientų ir paskirsto jas tarp atitinkamų serverių. Jie taip pat surenka rezultatus ir grąžina juos klientui. Galima sakyti, kad tai tarpininkai tarp jūsų aplikacijos ir duomenų.
Server komponentai yra tie, kurie faktiškai saugo duomenis ir atlieka užklausų vykdymą. Pinot turi du serverių tipus: realaus laiko serverius (real-time servers), kurie priima naujus duomenis iš srautų, ir istorinius serverius (offline servers), kurie dirba su jau apdorotais duomenimis.
Galiausiai turime Minion – tai background worker’iai, kurie atlieka įvairias priežiūros užduotis, tokias kaip duomenų perkėlimas iš realaus laiko į istorinę saugyklą, indeksų kūrimas ar duomenų valymas.
Visa ši sistema naudoja Apache Helix kaip cluster management framework’ą ir Apache Zookeeper koordinavimui. Tai leidžia Pinot būti atspariam gedimams ir lengvai masteliuojamam horizontaliai.
Duomenų modelis ir segmentai
Pinot duomenų modelis yra gana paprastas, bet efektyvus. Duomenys organizuojami į lenteles (tables), kurios skirstomos į segmentus (segments). Kiekvienas segmentas yra nepriklausoma duomenų dalis, kuri saugoma stulpelinėje (columnar) formoje.
Kodėl stulpelinė saugykla? Nes analitinėms užklausoms dažniausiai reikia skaityti tik kelis stulpelius iš daugelio eilučių, o ne visas eilutes. Pavyzdžiui, jei norite apskaičiuoti vidutinį užsakymo dydį per paskutinę valandą, jums reikia tik dviejų stulpelių: laiko žymos ir užsakymo sumos. Stulpelinė saugykla leidžia nuskaityti tik tuos duomenis, kurių reikia, o ne visą eilutę.
Segmentai Pinot sistemoje yra immutable – tai reiškia, kad kartą sukurti, jie nebekeičiami. Nauji duomenys ateina į naujus segmentus. Tai gali atrodyti neefektyvu, bet iš tikrųjų tai leidžia pasiekti geresnį našumą ir paprastesnę architektūrą. Nereikia rūpintis concurrent writes, locks ar kitais sudėtingais dalykais.
Kiekviena lentelė Pinot sistemoje turi schemą, kuri apibrėžia stulpelius, jų tipus ir kitas savybes. Schema palaiko įvairius duomenų tipus: INT, LONG, FLOAT, DOUBLE, STRING, BYTES ir kitus. Be to, galite apibrėžti, kurie stulpeliai bus indeksuojami ir kaip.
Indeksavimas ir užklausų optimizavimas
Vienas iš pagrindinių Pinot privalumų yra jo indeksavimo galimybės. Sistema palaiko kelis indeksų tipus, kiekvienas skirtas skirtingiems scenarijams.
Inverted index yra klasikinis pasirinkimas, kai reikia greitai rasti eilutes pagal tam tikrą reikšmę. Tai veikia panašiai kaip knygos indeksas – sistema žino, kuriose vietose (segmentuose) yra konkreti reikšmė.
Sorted index naudojamas, kai duomenys yra surūšiuoti pagal tam tikrą stulpelį. Tai leidžia labai greitai atlikti range užklausas (pavyzdžiui, „visi įvykiai tarp 10:00 ir 11:00”).
Bloom filter – tai probabilistinė duomenų struktūra, kuri gali labai greitai pasakyti, ar tam tikros reikšmės tikrai nėra segmente. Tai padeda išvengti nereikalingo segmentų skaitymo.
Star-tree index yra unikalus Pinot indeksas, skirtas agregacijų pagreitinimui. Jis iš anksto apskaičiuoja kai kurias agregacijas ir saugo jas specialioje duomenų struktūroje. Tai gali dramatiškai pagreitinti tokias užklausas kaip COUNT, SUM, AVG ir kitas.
Praktiškai, jums reikia gerai pagalvoti, kokius indeksus kurti. Per daug indeksų gali sulėtinti duomenų įkėlimą ir padidinti saugyklos naudojimą. Per mažai indeksų – užklausos bus lėtos. Paprastai pradedama nuo inverted index’ų dažniausiai filtruojamiems stulpeliams ir sorted index’o laiko stulpeliui.
Realaus laiko duomenų įkėlimas
Viena iš svarbiausių Pinot savybių yra gebėjimas dirbti su realaus laiko duomenimis. Sistema gali priimti duomenis iš Kafka, Kinesis ar kitų streaming platformų ir padaryti juos prieinamus užklausoms per kelias sekundes.
Realaus laiko duomenų įkėlimas veikia taip: jūs sukonfiguruojate lentelę su realaus laiko konfigūracija, nurodote Kafka topic’ą ir kitus parametrus. Pinot realtime serveriai pradeda skaityti duomenis iš Kafka, kaupia juos atmintyje ir periodiškai flush’ina į diskus kaip segmentus.
Štai paprastas lentelės konfigūracijos pavyzdys:
„`json
{
„tableName”: „events”,
„tableType”: „REALTIME”,
„segmentsConfig”: {
„timeColumnName”: „timestamp”,
„replication”: „3”,
„retentionTimeUnit”: „DAYS”,
„retentionTimeValue”: „7”
},
„tableIndexConfig”: {
„streamConfigs”: {
„streamType”: „kafka”,
„stream.kafka.topic.name”: „events-topic”,
„stream.kafka.broker.list”: „localhost:9092”
}
}
}
„`
Svarbu suprasti, kad realaus laiko segmentai pradžioje yra mutable – jie auga, kol pasiekia tam tikrą dydį ar laiko limitą. Tada jie „užšąla” ir tampa immutable. Šis procesas vadinamas segment completion.
Vienas iš iššūkių dirbant su realaus laiko duomenimis yra late arriving data problema. Kartais duomenys ateina ne chronologine tvarka. Pinot turi mechanizmus, kaip su tuo susidoroti, bet reikia gerai suprojektuoti savo duomenų srautus.
Užklausų kalba ir galimybės
Pinot naudoja SQL-like užklausų kalbą, kuri yra gana panaši į standartinį SQL, bet turi kai kurių skirtumų ir apribojimų. Jei mokate SQL, jums bus lengva pradėti.
Štai keletas pavyzdžių, ką galite daryti:
„`sql
SELECT COUNT(*)
FROM events
WHERE timestamp > 1609459200000
AND userId = ‘user123’
„`
Tai paprasta užklausa, kuri suskaičiuoja įvykius konkrečiam vartotojui per tam tikrą laiką. Pinot gali atsakyti į tokią užklausą per kelias milisekundes, net jei lentelėje yra milijardai įrašų.
Agregacijos taip pat veikia gerai:
„`sql
SELECT
country,
COUNT(*) as events,
AVG(duration) as avg_duration
FROM events
WHERE timestamp > now() – 3600000
GROUP BY country
ORDER BY events DESC
LIMIT 10
„`
Ši užklausa randa top 10 šalių pagal įvykių skaičių per paskutinę valandą ir apskaičiuoja vidutinę trukmę kiekvienai šaliai.
Pinot taip pat palaiko sudėtingesnes funkcijas kaip DISTINCT COUNT (naudojant HyperLogLog algoritmą), PERCENTILE, time window funkcijas ir kitas. Tačiau reikia žinoti, kad kai kurios SQL funkcijos nepalaiko arba veikia kitaip nei tradicinėse duomenų bazėse.
Vienas svarbus dalykas – Pinot neturi JOIN’ų tradicine prasme. Tai OLAP sistema, optimizuota single-table užklausoms. Jei reikia sujungti duomenis iš kelių lentelių, paprastai tai daroma aplikacijos lygmenyje arba denormalizuojant duomenis prieš įkeliant į Pinot.
Praktiniai patarimai diegiant Pinot
Jei planuojate naudoti Pinot savo projekte, štai keletas praktinių patarimų, kurie gali sutaupyti daug laiko ir nervų.
Pradėkite mažai. Neskubėkite diegti viso cluster’io su dešimtimis serverių. Pradėkite nuo vieno ar kelių serverių ir pažiūrėkite, kaip sistema elgiasi su jūsų duomenimis ir užklausomis. Pinot gali veikti net ant vieno serverio development tikslais.
Gerai suprojektuokite schemą. Pagalvokite, kokios bus jūsų užklausos ir atitinkamai sukurkite indeksus. Jei dažniausiai filtruosite pagal userId, sukurkite inverted index šiam stulpeliui. Jei dažnai darote range užklausas pagal laiką, įsitikinkite, kad turite sorted index.
Stebėkite metrikas. Pinot teikia daug metrikų per JMX ir kitus kanalus. Stebėkite užklausų laiką, segmentų skaičių, atminties naudojimą. Tai padės anksčiau pastebėti problemas.
Testuokite su reališkais duomenimis. Sintetiniai testai yra gerai, bet tikrasis testas yra su reališkais duomenų kiekiais ir užklausų šablonais. Sukurkite test environment’ą su production-like duomenimis.
Planuokite retention politiką. Pinot nėra skirtas saugoti duomenis amžinai. Apibrėžkite, kiek laiko jums reikia laikyti duomenis ir sukonfiguruokite retention atitinkamai. Tai padės valdyti saugyklos kaštus.
Naudokite upsert’us atsargiai. Nors Pinot palaiko upsert’us (duomenų atnaujinimą), tai turi performance overhead’ą. Jei galite išvengti upsert’ų, geriau to nedaryti.
Kada Pinot yra tinkamas pasirinkimas ir kada ne
Pinot nėra universalus sprendimas visoms problemoms. Yra scenarijai, kuriems jis puikiai tinka, ir scenarijai, kuriems geriau rinktis ką nors kita.
Pinot puikiai tinka:
– Realaus laiko analitikai, kai reikia greitai atsakyti į užklausas apie naujausius duomenis
– User-facing analytics – kai galutiniai vartotojai tiesiogiai daro užklausas (pavyzdžiui, dashboard’ai)
– Metrikų stebėjimui ir anomalijų aptikimui
– Event analytics – kai analizuojate didelius įvykių srautus
– Kai reikia low latency ir high throughput vienu metu
Pinot netinka:
– Transakciniams scenarijams (OLTP) – tam naudokite PostgreSQL, MySQL ar panašias DB
– Kai reikia sudėtingų JOIN’ų tarp daugelio lentelių
– Kai duomenys dažnai atnaujinami (frequent updates)
– Kai reikia ACID garantijų
– Labai sudėtingai analitikai, kuriai geriau tinka data warehouse sprendimai kaip Snowflake ar BigQuery
Praktiškai, daugelis organizacijų naudoja Pinot kartu su kitomis sistemomis. Pavyzdžiui, transakcijos vyksta PostgreSQL, duomenys srautu keliauja į Kafka, iš ten į Pinot realaus laiko analitikai, o batch analytics vyksta Spark ar panašioje sistemoje.
Ką reikia žinoti prieš pradedant
Apache Pinot yra galinga sistema, bet ji ateina su savo learning curve. Jei esate įpratę prie tradicinių reliacinių duomenų bazių, kai kurie dalykai gali atrodyti keisti ar neįprasti.
Pirma, pripratinkite prie minties, kad Pinot nėra general-purpose duomenų bazė. Tai specialized tool konkrečiai problemai spręsti. Nesitikėkite, kad jis pakeis jūsų PostgreSQL ar MongoDB – jis jas papildo, o ne keičia.
Antra, būkite pasirengę investuoti laiko į mokymąsi. Pinot dokumentacija yra gana gera, bet sistema turi daug niuansų. Verta prisijungti prie Pinot community Slack kanalo, kur galite užduoti klausimus ir gauti pagalbą iš kitų vartotojų.
Trečia, pradėkite nuo paprastų use case’ų. Nesistenkite iš karto spręsti visų savo analitikos problemų su Pinot. Pasirinkite vieną konkrečią problemą, išspręskite ją, išmokite sistemą, ir tik tada plėskite.
Pinot ekosistema nuolat vystosi. Apache bendruomenė aktyviai dirba prie naujų funkcijų ir patobulinimų. Tai reiškia, kad sistema tik gerės, bet taip pat reiškia, kad kartais reikės atnaujinti savo žinias ir prisitaikyti prie pasikeitimų.
Galiausiai, Pinot yra open source projektas, o tai reiškia, kad jei susidursite su problema ar trūkumu, galite patys prisidėti prie sprendimo. Bendruomenė yra draugiška ir atvira naujokams. Jei turite Java įgūdžių ir noro, galite tapti Pinot contributor’iu.
