Vela → pametna predmemorija za vremenske serije i još mnogo toga

U fintech-u često moramo da obrađujemo prilično velike količine podataka o kursu valuta. Podatke dobijamo iz različitih izvora, a svaki od njih ima svoju ideju ​​kako ekstrapolirati kurseve za sutra, prekosutra, naredni mesec, pa čak i za naredne tri godine. Kad bi neko mogao predvidjeti stope desno, bilo bi vrijeme da zatvorite posao i samo glupo mijenjate novac naprijed-natrag. Neki izvori su pouzdaniji, neki isporučuju potpuno smeće, sa rijetkim uključcima gotovo tačnih vrijednosti, ali za egzotične parove. Naš posao je da procijedimo ove desetine hiljada vrijednosti u sekundi i odredimo šta tačno pokazati kupcima. Moramo filtrirati jednu tačnu vrijednost iz tona prljavštine i mulja, baš kao što flamingosi rade za ručkom.

Vela → pametna predmemorija za vremenske serije i još mnogo toga

Posebna karakteristika flamingosa je njihov masivni prema dolje zakrivljen kljun, kojim filtriraju hranu iz vode ili blata.
 - Wiki

Tako je nastala biblioteka Vela, koji pohranjuje keš stanja za više vrijednosti u određenim vremenskim intervalima. Ispod haube, filtrira loše i zastarjele podatke u hodu, a također pruža pristup najnovijim N provjerene vrijednosti za svaki ključ (valutni parovi, u našem slučaju).

Recimo da prikupljamo stope za tri valutna para. Najjednostavnija definicija Vela za pohranjivanje trenutnog stanja izgledat će otprilike ovako:

defmodule Pairs do
  use Vela,
    eurusd: [sorter: &Kernel.<=/2],
    eurgbp: [limit: 3, errors: 1],
    eurcad: [validator: Pairs]

  @behaviour Vela.Validator

  @impl Vela.Validator
  def valid?(:eurcad, rate), do: rate > 0
end

Ažuriranje vrijednosti

Vela.put/3 Funkcija će raditi sljedeće u nizu:

  • će uzrokovati validator na vrijednost, ako je ona definirana (vidi pogl Validacija ispod);
  • će dodati vrijednost ili u red dobrih vrijednosti ako je provjera valjanosti bila uspješna, ili u red usluge :__errors__ inače;
  • će uzrokovati sortiranje ako sorter definisano za dati ključ, ili će jednostavno staviti vrijednost na čelo liste (LIFO, vidi poglavlje Sortiranje ispod);
  • će skratiti red prema parametru :limit preneo na stvaranje;
  • će vratiti ažuriranu strukturu Vela.

iex|1 > pairs = %Pairs{}
iex|2 > Vela.put(pairs, :eurcad, 1.0)
#⇒ %Pairs{..., eurcad: [1.0], ...}
iex|3 > Vela.put(pairs, :eurcad, -1.0)
#⇒ %Pairs{__errors__: [eurcad: -1.0], ...}
iex|4 > pairs |> Vela.put(:eurusd, 2.0) |> Vela.put(:eurusd, 1.0)
#⇒ %Pairs{... eurusd: [1.0, 2.0]}

Takođe Vela pribor Access, tako da možete koristiti bilo koju od standardnih funkcija za dubinsko ažuriranje struktura iz arsenala za ažuriranje vrijednosti Kernel: Kernel.get_in/2, Kernel.put_in/3, Kernel.update_in/3, Kernel.pop_in/2, I Kernel.get_and_update_in/3.

Validacija

Validator se može definirati kao:

  • vanjska funkcija s jednim argumentom (&MyMod.my_fun/1), prima samo vrijednost za validaciju;
  • eksterna funkcija sa dva argumenta, &MyMod.my_fun/2, ona će dobiti par serie, value za validaciju;
  • implementacija modula Vela.Validator;
  • konfiguracijski parametar thresholdi - opciono - compare_by, vidi poglavlje poređenje ispod.

Ako je provjera valjanosti uspješna, vrijednost se dodaje na listu pod odgovarajućim ključem; {serie, value} ide u :__errors_.

Upoređivanje

Vrijednosti pohranjene u ovim redovima mogu biti bilo koje. Učiti Vela da bismo ih uporedili, potrebno je prenijeti compare_by parametar u definiciji serije (osim ako se vrijednosti ne mogu porediti sa standardom Kernel.</2); ovaj parametar mora biti tipa (Vela.value() -> number()). Podrazumevano je jednostavno & &1.

Također, možete prenijeti parametar u definiciju reda comparator za izračunavanje delta vrijednosti (min/max); na primjer, prenošenjem Date.diff/2 kao komparator, možete dobiti ispravne delte za datume.

Još jedan zgodan način rada je prosljeđivanje parametra threshold, koji definira maksimalni dozvoljeni omjer nove vrijednosti prema {min, max} interval. Pošto je naveden kao procenat, ček se ne koristi comparatorali i dalje koristi compare_by. Na primjer, da navedete vrijednost praga za datum vremena, morate navesti compare_by: &DateTime.to_unix/1 (da biste dobili cjelobrojnu vrijednost) i threshold: 1, što dovodi do toga da nove vrijednosti budu dozvoljene samo ako su u ±band interval od trenutnih vrijednosti.

Konačno, možete koristiti Vela.equal?/2 da uporedimo dva keša. Ako vrijednosti definiraju funkciju equal?/2 ili compare/2, tada će se ove funkcije koristiti za usporedbu, inače ćemo glupo koristiti ==/2.

Dobivanje vrijednosti

Obrada trenutnog stanja obično počinje pozivom Vela.purge/1, koji uklanja zastarjele vrijednosti (if validator vezan za timestamps). Tada možete nazvati Vela.slice/1koji će se vratiti keyword sa imenima redova kao ključevima i prvim, stvarnim vrijednostima.

Takođe možete koristiti get_in/2/pop_in/2 za pristup na niskom nivou vrijednostima u svakom redu.

Aplikacija

Vela može biti izuzetno korisno kao keš vremenske serije u stanju procesa kao što je GenServer/Agent. Ne želimo nikada koristiti zastarjele vrijednosti kursa, a da bismo to učinili, jednostavno održavamo proces sa stanjem obrađenim Vela, sa validatorom prikazanim ispod.

@impl Vela.Validator
def valid?(_key, %Rate{} = rate),
  do: Rate.age(rate) < @death_age

и Vela.purge/1 tiho uklanja sve zastarjele vrijednosti svaki put kada nam zatrebaju podaci. Za pristup stvarnim vrijednostima jednostavno pozovemo Vela.slice/1, a kada je potrebna mala historija kursa (cijela serija), jednostavno je vraćamo - već sortiranu - s validiranim vrijednostima.

Sretno keširanje vremenskih serija!

izvor: www.habr.com

Dodajte komentar