KDB+ databasis: van finansies tot Formule 1

KDB+, maatskappyproduk KX is 'n wyd bekende in nou kringe, uiters vinnige, kolomvormige databasis wat ontwerp is vir die stoor van tydreekse en analitiese berekeninge wat daarop gebaseer is. Aanvanklik was (en is) dit baie gewild in die finansiële bedryf – dit word deur al die top 10 beleggingsbanke en baie bekende verskansingsfondse, beurse en ander organisasies gebruik. Onlangs het KX besluit om sy kliëntebasis uit te brei en bied nou oplossings in ander gebiede waar daar 'n groot hoeveelheid data is, georganiseer volgens tyd of andersins - telekommunikasie, bioinformatika, vervaardiging, ens. Hulle het ook 'n vennoot van die Aston Martin Red Bull Racing-span in Formule 1 geword, waar hulle help om data van motorsensors te versamel en te verwerk en windtonneltoetse te ontleed. In hierdie artikel wil ek jou vertel watter kenmerke van KDB+ dit superpresteer, hoekom maatskappye bereid is om baie geld daaraan te spandeer, en laastens, hoekom dit nie regtig 'n databasis is nie.
 
KDB+ databasis: van finansies tot Formule 1
 
In hierdie artikel sal ek probeer om jou in die algemeen te vertel wat KDB+ is, watter vermoëns en beperkings dit het, en wat die voordele daarvan is vir maatskappye wat groot hoeveelhede data wil verwerk. Ek gaan nie in op die besonderhede van die implementering van KDB+ of die besonderhede van sy Q-programmeertaal nie. Beide hierdie onderwerpe is baie wyd en verdien aparte artikels. Baie inligting oor hierdie onderwerpe kan gevind word by code.kx.com, insluitend 'n boek oor Q - Q For Mortals (sien skakel hieronder).

Sommige terme

  • In-geheue databasis. 'n Databasis wat data in RAM stoor vir vinniger toegang. Die voordele van so 'n databasis is duidelik, maar die nadele is die moontlikheid van dataverlies en die behoefte om baie geheue op die bediener te hê.
  • Kolomdatabasis. 'n Databasis waar data kolom vir kolom gestoor word eerder as rekord vir rekord. Die grootste voordeel van so 'n databasis is dat data van een kolom saam op skyf en in geheue gestoor word, wat toegang daartoe aansienlik versnel. Dit is nie nodig om kolomme te laai wat nie in die navraag gebruik word nie. Die grootste nadeel is dat dit moeilik is om rekords te wysig en uit te vee.
  • Tyd reeks. Data met 'n datum- of tydkolom. Tipies is tydsortering belangrik vir sulke data, sodat jy maklik kan bepaal watter rekord die huidige een voorafgaan of volg, of om funksies toe te pas waarvan die resultate afhang van die volgorde van die rekords. Klassieke databasisse is gebou op 'n heeltemal ander beginsel - verteenwoordig 'n versameling rekords as 'n stel, waar die volgorde van die rekords in beginsel nie gedefinieer is nie.
  • Vektor. In die konteks van KDB+ is dit 'n lys van elemente van dieselfde atoomtipe, byvoorbeeld getalle. Met ander woorde, 'n verskeidenheid elemente. Skikkings, anders as lyste, kan kompak gestoor en verwerk word deur gebruik te maak van vektorverwerkerinstruksies.

 

Historiese inligting

KX is in 1993 gestig deur Arthur Whitney, wat voorheen by Morgan Stanley Bank op die A+-taal gewerk het, die opvolger van APL - 'n baie oorspronklike en op 'n tyd gewilde taal in die finansiële wêreld. Natuurlik het Arthur in KX in dieselfde gees voortgegaan en die vektor-funksionele taal K geskep, gelei deur die idees van radikale minimalisme. K-programme lyk soos 'n mengelmoes van leestekens en spesiale karakters, die betekenis van tekens en funksies hang af van die konteks, en elke bewerking dra baie meer betekenis as wat dit in konvensionele programmeertale doen. As gevolg hiervan neem 'n K-program minimale spasie op - 'n paar reëls kan bladsye teks in 'n breedvoerige taal soos Java vervang - en is 'n supergekonsentreerde implementering van die algoritme.
 
'n Funksie in K wat die meeste van die LL1-ontledergenerator implementeer volgens 'n gegewe grammatika:

1. pp:{q:{(x;p3(),y)};r:$[-11=@x;$x;11=@x;q[`N;$*x];10=abs@@x;q[`N;x]  
2.   ($)~*x;(`P;p3 x 1);(1=#x)&11=@*x;pp[{(1#x;$[2=#x;;,:]1_x)}@*x]  
3.      (?)~*x;(`Q;pp[x 1]);(*)~*x;(`M;pp[x 1]);(+)~*x;(`MP;pp[x 1]);(!)~*x;(`Y;p3 x 1)  
4.      (2=#x)&(@x 1)in 100 101 107 7 -7h;($[(@x 1)in 100 101 107h;`Ff;`Fi];p3 x 1;pp[*x])  
5.      (|)~*x;`S,(pp'1_x);2=#x;`C,{@[@[x;-1+#x;{x,")"}];0;"(",]}({$[".s.C"~4#x;6_-2_x;x]}'pp'x);'`pp];  
6.   $[@r;r;($[1<#r;".s.";""],$*r),$[1<#r;"[",(";"/:1_r),"]";""]]}  

 Arthur het hierdie filosofie van uiterste doeltreffendheid met 'n minimum liggaamsbewegings beliggaam in KDB+, wat in 2003 verskyn het (ek dink dit is nou duidelik waar die letter K in die naam vandaan kom) en niks anders is as 'n interpreteerder van die vierde weergawe van die K nie. taal. 'n Meer gebruikersvriendelike weergawe is bo-op K K genaamd Q bygevoeg. Q het ook ondersteuning bygevoeg vir 'n spesifieke dialek van SQL - QSQL, en die tolk - ondersteuning vir tabelle as 'n stelseldatatipe, gereedskap om met tabelle te werk in geheue en op skyf, ens.
 
So vanuit 'n gebruiker se perspektief is KDB+ bloot 'n Q-taaltolk met ondersteuning vir tabelle en SQL-agtige LINQ-styl uitdrukkings vanaf C#. Dit is die belangrikste verskil tussen KDB+ en ander databasisse en die belangrikste mededingende voordeel daarvan, wat dikwels oor die hoof gesien word. Dit is nie 'n databasis + gedeaktiveerde hulptaal nie, maar 'n volwaardige kragtige programmeertaal + ingeboude ondersteuning vir databasisfunksies. Hierdie onderskeid sal 'n deurslaggewende rol speel in die lys van al die voordele van KDB+. Byvoorbeeld…
 

Grootte

Volgens moderne standaarde is KDB+ eenvoudig mikroskopies in grootte. Dit is letterlik een sub-megagreep uitvoerbare lêer en een klein tekslêer met sommige stelselfunksies. In werklikheid - minder as een megagreep, en vir hierdie program betaal maatskappye tienduisende dollars per jaar vir een verwerker op die bediener.

  • Hierdie grootte laat KDB+ goed voel op enige hardeware - van 'n Pi-mikrorekenaar tot bedieners met teragrepe geheue. Dit beïnvloed op geen manier die funksionaliteit nie; boonop begin Q onmiddellik, wat dit moontlik maak om dit onder andere as 'n skriftaal te gebruik.
  • Op hierdie grootte pas die Q-tolk heeltemal in die verwerkerkas, wat die uitvoering van die program bespoedig.
  • Met hierdie grootte van die uitvoerbare lêer neem die Q-proses weglaatbare spasie in die geheue op; jy kan honderde daarvan uitvoer. Verder, indien nodig, kan Q met tiene of honderde gigagrepe geheue binne 'n enkele proses werk.

veelsydigheid

Q is ideaal vir 'n wye reeks toepassings. Proses Q kan optree as 'n historiese databasis en bied vinnige toegang tot teragrepe inligting. Ons het byvoorbeeld tientalle historiese databasisse, in sommige waarvan een ongecomprimeerde dag se data meer as 100 gigagrepe in beslag neem. Onder redelike beperkings sal 'n navraag na die databasis egter binne tien tot honderde millisekondes voltooi word. Oor die algemeen het ons 'n universele uitteltyd vir gebruikersversoeke - 30 sekondes - en dit werk baie selde.
 
Q kan net so maklik 'n in-geheue databasis wees. Nuwe data word so vinnig by in-geheue-tabelle gevoeg dat gebruikersversoeke die beperkende faktor is. Data in tabelle word in kolomme gestoor, wat beteken dat enige bewerking op 'n kolom die verwerkerkas teen volle kapasiteit sal gebruik. Daarbenewens het KX probeer om alle basiese bewerkings soos rekenkunde te implementeer deur vektorinstruksies van die verwerker, wat hul spoed maksimeer. Q kan ook take uitvoer wat nie tipies vir databasisse is nie - byvoorbeeld, verwerk stroomdata en bereken in "intydse" (met 'n vertraging van tien millisekondes tot 'n paar sekondes, afhangende van die taak) verskeie samevoegingsfunksies vir finansiële instrumente vir verskillende tyd intervalle of bou 'n model van die invloed van perfekte transaksies op die mark en voer sy profilering byna onmiddellik na die voltooiing daarvan uit. In sulke take is die belangrikste tydsvertraging meestal nie Q nie, maar die behoefte om data uit verskillende bronne te sinchroniseer. Hoë spoed word behaal as gevolg van die feit dat die data en die funksies wat dit verwerk in een proses is, en verwerking word verminder tot die uitvoering van verskeie QSQL-uitdrukkings en koppelings, wat nie geïnterpreteer word nie, maar deur binêre kode uitgevoer word.
 
Uiteindelik kan u enige diensprosesse in Q skryf. Byvoorbeeld, Gateway-prosesse wat outomaties gebruikersversoeke na die nodige databasisse en bedieners versprei. Die programmeerder het volle vryheid om enige algoritme vir balansering, prioritisering, foutverdraagsaamheid, toegangsregte, kwotas en basies enigiets anders te implementeer wat sy hart begeer. Die grootste probleem hier is dat jy dit alles self sal moet implementeer.
 
As voorbeeld sal ek lys watter tipe prosesse ons het. Almal van hulle word aktief gebruik en werk saam, wat dosyne verskillende databasisse in een kombineer, data van verskeie bronne verwerk en honderde gebruikers en toepassings bedien.

  • Koppelaars (voerhanteerder) na databronne. Hierdie prosesse gebruik gewoonlik eksterne biblioteke wat in Q gelaai word. Die C-koppelvlak in Q is uiters eenvoudig en laat jou toe om maklik instaanbedienerfunksies vir enige C/C++-biblioteek te skep. Q is vinnig genoeg om byvoorbeeld 'n vloed FIX-boodskappe van alle Europese aandelebeurse gelyktydig te verwerk.
  • Dataverspreiders (tikkerplant), wat dien as 'n tussenskakel tussen koppelaars en verbruikers. Terselfdertyd skryf hulle inkomende data na 'n spesiale binêre logboek, wat robuustheid bied vir verbruikers teen verbindingsverliese of herbegin.
  • In-geheue databasis (rdb). Hierdie databasisse bied die vinnigste moontlike toegang tot rou, vars data deur dit in die geheue te stoor. Tipies versamel hulle data in tabelle gedurende die dag en stel dit snags terug.
  • Volhard databasis (pdb). Hierdie databasisse verseker dat data vir vandag in 'n historiese databasis gestoor word. As 'n reël, anders as rdb, stoor hulle nie data in die geheue nie, maar gebruik 'n spesiale kas op skyf gedurende die dag en kopieer die data om middernag na die historiese databasis.
  • Historiese databasisse (hdb). Hierdie databasisse verskaf toegang tot data vir vorige dae, maande en jare. Hul grootte (in dae) word slegs beperk deur die grootte van die hardeskywe. Data kan enige plek gevind word, veral op verskillende skywe om toegang te bespoedig. Dit is moontlik om data saam te pers met behulp van verskeie algoritmes om van te kies. Die struktuur van die databasis is goed gedokumenteer en eenvoudig, die data word kolom vir kolom in gewone lêers gestoor, sodat dit verwerk kan word, ook deur middel van die bedryfstelsel.
  • Databasisse met saamgestelde inligting. Hulle stoor verskeie samevoegings, gewoonlik met, gegroepeer volgens instrumentnaam en tydinterval. In-geheue databasisse werk hul toestand op met elke inkomende boodskap, en historiese databasisse stoor vooraf berekende data om toegang tot historiese data te bespoedig.
  • uiteindelik, poortprosessedie diens van toepassings en gebruikers. Q laat jou toe om heeltemal asinchroniese verwerking van inkomende boodskappe te implementeer, dit oor databasisse te versprei, toegangsregte te kontroleer, ens. Let daarop dat boodskappe nie beperk is nie en meestal nie SQL-uitdrukkings is nie, soos in ander databasisse die geval is. Dikwels is die SQL-uitdrukking versteek in 'n spesiale funksie en word gekonstrueer op grond van die parameters wat deur die gebruiker versoek word - tyd word omgeskakel, gefiltreer, data word genormaliseer (byvoorbeeld, die aandeelprys word gelyk gemaak as dividende betaal is), ens.

Tipiese argitektuur vir een datatipe:

KDB+ databasis: van finansies tot Formule 1

Spoed

Alhoewel Q 'n geïnterpreteerde taal is, is dit ook 'n vektortaal. Dit beteken dat baie ingeboude funksies, veral rekenkundiges, argumente van enige vorm aanneem - getalle, vektore, matrikse, lyste - en daar word van die programmeerder verwag om die program as skikkingsbewerkings te implementeer. In so 'n taal, as jy twee vektore van 'n miljoen elemente byvoeg, maak dit nie meer saak dat die taal geïnterpreteer word nie; die optelling sal uitgevoer word deur 'n super-geoptimaliseerde binêre funksie. Aangesien die grootste deel van die tyd in Q-programme bestee word aan bewerkings met tabelle wat hierdie basiese gevektoriseerde funksies gebruik, is die uitset 'n baie ordentlike bedryfspoed, wat ons in staat stel om 'n groot hoeveelheid data selfs in een proses te verwerk. Dit is soortgelyk aan wiskundige biblioteke in Python - hoewel Python self 'n baie stadige taal is, het dit baie uitstekende biblioteke soos numpy wat jou toelaat om numeriese data te verwerk teen die spoed van 'n saamgestelde taal (terloops, numpy is ideologies naby Q ).
 
Daarbenewens het KX 'n baie versigtige benadering tot die ontwerp van tabelle en die optimalisering van werk daarmee. Eerstens word verskeie tipes indekse ondersteun, wat deur ingeboude funksies ondersteun word en nie net op tabelkolomme toegepas kan word nie, maar ook op enige vektore - groepering, sortering, uniekheidskenmerk en spesiale groepering vir historiese databasisse. Die indeks word eenvoudig toegepas en word outomaties aangepas wanneer elemente by die kolom/vektor gevoeg word. Indekse kan ewe suksesvol toegepas word op tabelkolomme beide in die geheue en op skyf. Wanneer 'n QSQL-navraag uitgevoer word, word indekse outomaties gebruik indien moontlik. Tweedens word gewerk met historiese data deur die meganisme vir die vertoon van OS-lêers (geheuekaart). Groot tabelle word nooit in die geheue gelaai nie; in plaas daarvan word die nodige kolomme direk in die geheue gekarteer en slegs daardie deel van hulle word werklik gelaai (indekse help ook hier) wat nodig is. Dit maak geen verskil aan die programmeerder of die data in die geheue is of nie; die meganisme om met mmap te werk is heeltemal versteek in die dieptes van Q.
 
KDB+ is nie 'n relasionele databasis nie; tabelle kan arbitrêre data bevat, terwyl die volgorde van rye in die tabel nie verander wanneer nuwe elemente bygevoeg word nie en kan en moet gebruik word wanneer navrae geskryf word. Hierdie kenmerk is dringend nodig om met tydreekse te werk (data van uitruilings, telemetrie, gebeurtenislogboeke), want as die data volgens tyd gesorteer word, hoef die gebruiker geen SQL-truuks te gebruik om die eerste of laaste ry of N te vind nie. rye in die tabel , bepaal watter lyn die Nde lyn volg, ens. Tabelverbindings word selfs verder vereenvoudig, byvoorbeeld om die laaste kwotasie vir 16000 500 VOD.L (Vodafone)-transaksies in 'n tabel van XNUMX miljoen elemente te vind, neem ongeveer 'n sekonde op skyf en tientalle millisekondes in geheue.
 
'n Voorbeeld van 'n tydverbinding - die aanhalingstabel word na die geheue gekarteer, so dit is nie nodig om VOD.L te spesifiseer waar nie, die indeks op die sim-kolom en die feit dat die data volgens tyd gesorteer is, word implisiet gebruik. Byna alle aansluitings in Q is gereelde funksies, nie deel van 'n uitgesoekte uitdrukking nie:

1. aj[`sym`time;select from trade where date=2019.03.26, sym=`VOD.L;select from quote where date=2019.03.26]  

Ten slotte is dit opmerklik dat die ingenieurs by KX, wat by Arthur Whitney self begin, werklik behep is met doeltreffendheid en baie moeite doen om die meeste uit die Q se standaardkenmerke te kry en die mees algemene gebruikspatrone te optimaliseer.
 

Totale

KDB+ is gewild onder besighede hoofsaaklik as gevolg van sy besonderse veelsydigheid - dit dien ewe goed as 'n databasis in die geheue, as 'n databasis vir die berging van teragrepe van historiese data, en as 'n platform vir data-analise. As gevolg van die feit dat dataverwerking direk in die databasis plaasvind, word hoë spoed van werk en hulpbronbesparing behaal. ’n Volwaardige programmeertaal wat met databasisfunksies geïntegreer is, laat jou toe om die hele stapel nodige prosesse op een platform te implementeer – van die ontvangs van data tot die verwerking van gebruikersversoeke.
 

Vir meer inligting,

Beperkings

'n Beduidende nadeel van KDB+/Q is die hoë toegangsdrempel. Die taal het 'n vreemde sintaksis, sommige funksies is erg oorlaai (waarde het byvoorbeeld ongeveer 11 gebruiksgevalle). Die belangrikste is dat dit 'n radikaal ander benadering tot die skryf van programme vereis. In 'n vektortaal moet jy altyd in terme van skikkingstransformasies dink, alle lusse deur verskeie variante van die kaart-/verminderingsfunksies (wat bywoorde in Q genoem word) implementeer en nooit probeer om geld te spaar deur vektorbewerkings met atooms te vervang nie. Byvoorbeeld, om die indeks van die Nde voorkoms van 'n element in 'n skikking te vind, moet jy skryf:

1. (where element=vector)[N]  

alhoewel dit verskriklik ondoeltreffend lyk volgens C/Java-standaarde (= skep 'n Boolese vektor, waar die ware indekse van die elemente daarin terugstuur). Maar hierdie notasie maak die betekenis van die uitdrukking duideliker en jy gebruik vinnige vektorbewerkings in plaas van stadige atoombewerkings. Die konseptuele verskil tussen 'n vektortaal en ander is vergelykbaar met die verskil tussen imperatiewe en funksionele benaderings tot programmering, en jy moet voorbereid wees hiervoor.
 
Sommige gebruikers is ook ontevrede met QSQL. Die punt is dat dit net soos regte SQL lyk. In werklikheid is dit net 'n tolk van SQL-agtige uitdrukkings wat nie navraagoptimalisering ondersteun nie. Die gebruiker moet self optimale navrae skryf, en in Q, waarvoor baie nie gereed is nie. Aan die ander kant kan jy natuurlik altyd self die optimale navraag skryf, eerder as om op 'n swartboks-optimaliseerder staat te maak.
 
As 'n pluspunt is 'n boek oor Q - Q For Mortals gratis beskikbaar by maatskappy webwerf, daar is ook baie ander nuttige materiaal daar versamel.
 
Nog 'n groot nadeel is die koste van die lisensie. Dit is tienduisende dollars per jaar per SVE. Slegs groot maatskappye kan sulke uitgawes bekostig. Onlangs het KX sy lisensiebeleid meer buigsaam gemaak en bied die geleentheid om slegs vir die tyd van gebruik te betaal of KDB+ in die Google- en Amazon-wolke te huur. KX bied ook vir aflaai gratis weergawe vir nie-kommersiële doeleindes (32-bis-weergawe of 64-bis op aanvraag).
 

mededingers

Daar is 'n hele paar gespesialiseerde databasisse wat op soortgelyke beginsels gebou is - kolomvormig, in die geheue, gefokus op baie groot hoeveelhede data. Die probleem is dat dit gespesialiseerde databasisse is. 'n Treffende voorbeeld is Clickhouse. Hierdie databasis het 'n baie soortgelyke beginsel as KDB+ vir die stoor van data op skyf en die bou van 'n indeks; dit voer sommige navrae vinniger uit as KDB+, hoewel nie beduidend nie. Maar selfs as 'n databasis is Clickhouse meer gespesialiseerd as KDB+ - webanalise vs arbitrêre tydreekse (hierdie verskil is baie belangrik - daarom is dit byvoorbeeld nie in Clickhouse moontlik om die ordening van rekords te gebruik nie). Maar die belangrikste is dat Clickhouse nie die veelsydigheid van KDB+ het nie, 'n taal wat data direk in die databasis kan verwerk, eerder as om dit eers in 'n aparte toepassing te laai, arbitrêre SQL-uitdrukkings te bou, arbitrêre funksies in 'n navraag toe te pas, prosesse te skep nie verband hou met die uitvoering van historiese databasisfunksies nie. Daarom is dit moeilik om KDB+ met ander databasisse te vergelyk; hulle kan beter wees in sekere gebruiksgevalle of bloot beter as dit by klassieke databasistake kom, maar ek weet nie van nog 'n ewe doeltreffende en veelsydige hulpmiddel vir die verwerking van tydelike data nie.
 

Python-integrasie

Om KDB+ makliker te maak om te gebruik vir mense wat nie vertroud is met die tegnologie nie, het KX biblioteke geskep om styf met Python binne 'n enkele proses te integreer. Jy kan óf enige Python-funksie vanaf Q noem, óf andersom - enige Q-funksie van Python oproep (veral QSQL-uitdrukkings). Biblioteke skakel, indien nodig (nie altyd ter wille van doeltreffendheid nie), data om van die formaat van een taal na die formaat van 'n ander. Gevolglik leef Q en Python in so 'n hegte simbiose dat die grense tussen hulle vervaag. Gevolglik het die programmeerder aan die een kant volle toegang tot talle nuttige Python-biblioteke, aan die ander kant ontvang hy 'n vinnige basis om met groot data geïntegreer in Python te werk, wat veral nuttig is vir diegene wat by masjienleer betrokke is. of modellering.
 
Werk met Q in Python:

1. >>> q()  
2.q)trade:([]date:();sym:();qty:())  
3. q)  
4. >>> q.insert('trade', (date(2006,10,6), 'IBM', 200))  
5. k(',0')  
6. >>> q.insert('trade', (date(2006,10,6), 'MSFT', 100))  
7. k(',1')  

verwysings

Die webwerf van die maatskappy - https://kx.com/
Webwerf vir ontwikkelaars - https://code.kx.com/v2/
Boek Q vir sterflinge (in Engels) - https://code.kx.com/q4m3/
Artikels oor KDB+/Q-toepassings van kx-werknemers - https://code.kx.com/v2/wp/

Bron: will.com

Voeg 'n opmerking