Vela → inteligentná vyrovnávacia pamäť pre časové rady a ďalšie

Vo fintech musíme často spracovávať pomerne masívne objemy údajov o výmenných kurzoch mien. Údaje získavame z rôznych zdrojov a každý z nich má vlastnú predstavu o tom, ako extrapolovať výmenné kurzy na zajtra, pozajtra, budúci mesiac a dokonca aj ďalšie tri roky. Keby niekto vedel predpovedať sadzby správne, bolo by načase zavrieť živnosť a len hlúpo meniť peniaze tam a späť. Niektoré zdroje sú spoľahlivejšie, niektoré dodávajú úplný odpad, so zriedkavými inklúziami takmer správnych hodnôt, ale pre exotické páry. Našou úlohou je preosiať tieto desiatky tisíc hodnôt za sekundu a určiť, čo presne ukázať zákazníkom. Potrebujeme odfiltrovať jednu správnu hodnotu z ton nečistôt a bahna, rovnako ako to robia plameniaky na obed.

Vela → inteligentná vyrovnávacia pamäť pre časové rady a ďalšie

Zvláštnym poznávacím znakom plameniakov je ich mohutný nadol zahnutý zobák, ktorým filtrujú potravu od vody či blata.
 - Vicki

Tak vznikla knižnica Vela, ktorý ukladá stavovú vyrovnávaciu pamäť pre viacero hodnôt v určených časových intervaloch. Pod kapotou za chodu filtruje zlé a neaktuálne údaje a poskytuje aj prístup k najnovším N overené hodnoty pre každý kľúč (v našom prípade menové páry).

Povedzme, že zbierame kurzy pre tri menové páry. Najjednoduchšia definícia Vela na uloženie aktuálneho stavu to bude vyzerať asi takto:

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

Aktualizácia hodnôt

Vela.put/3 Funkcia vykoná nasledujúce v poradí:

  • spôsobí validator na hodnote, ak je definovaná (pozri kapitolu Validácia nižšie);
  • pridá hodnotu buď do riadku dobrých hodnôt, ak bolo overenie úspešné, alebo do riadku služby :__errors__ inak;
  • spôsobí triedenie, ak sorter definované pre daný kľúč, alebo jednoducho umiestni hodnotu na začiatok zoznamu (LIFO, pozri kapitolu triedenie nižšie);
  • oreže riadok podľa parametra :limit odovzdaný stvorením;
  • vráti aktualizovanú štruktúru 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]}

Tiež Vela náradia Access, takže na aktualizáciu hodnôt môžete použiť ktorúkoľvek zo štandardných funkcií na hĺbkovú aktualizáciu štruktúr z arzenálu Kernel: Kernel.get_in/2, Kernel.put_in/3, Kernel.update_in/3, Kernel.pop_in/2a Kernel.get_and_update_in/3.

Validácia

Validátor môže byť definovaný ako:

  • externá funkcia s jedným argumentom (&MyMod.my_fun/1), dostane hodnotu len na overenie;
  • externá funkcia s dvoma argumentmi, &MyMod.my_fun/2, dostane pár serie, value na overenie;
  • implementácia modulu Vela.Validator;
  • konfiguračný parameter thresholda - voliteľne - compare_by, pozri kapitolu Porovnanie ниже.

Ak je validácia úspešná, hodnota sa pridá do zoznamu pod príslušný kľúč, v opačnom prípade n-tica {serie, value} ide :__errors_.

Сравнение

Hodnoty uložené v týchto riadkoch môžu byť akékoľvek. Učiť Vela na ich porovnanie je potrebné preniesť compare_by parameter v definícii série (pokiaľ hodnoty nemožno porovnať so štandardom Kernel.</2); tento parameter musí byť typu (Vela.value() -> number()). V predvolenom nastavení je to jednoduché & &1.

Tiež môžete zadať parameter do definície riadka comparator na výpočet hodnôt delta (min/max); napríklad vysielaním Date.diff/2 ako porovnávač môžete získať správne delty pre dátumy.

Ďalším pohodlným spôsobom práce je odovzdanie parametra threshold, ktorý definuje maximálny povolený pomer novej hodnoty k {min, max} interval. Keďže je zadaný v percentách, kontrola sa nepoužíva comparatorale stále používa compare_by. Ak chcete napríklad zadať prahovú hodnotu pre dátumy a časy, musíte zadať compare_by: &DateTime.to_unix/1 (na získanie celočíselnej hodnoty) a threshold: 1, čo spôsobí, že nové hodnoty budú povolené iba vtedy, ak sú v ±band interval od aktuálnych hodnôt.

Nakoniec môžete použiť Vela.equal?/2 na porovnanie dvoch skrýš. Ak hodnoty definujú funkciu equal?/2 alebo compare/2, potom budú tieto funkcie použité na porovnanie, inak hlúpo používame ==/2.

Získavanie hodnôt

Spracovanie aktuálneho stavu zvyčajne začína volaním Vela.purge/1, ktorý odstraňuje zastarané hodnoty (ak validator viazaný na timestamps). Potom môžete zavolať Vela.slice/1ktorý sa vráti keyword s názvami riadkov ako kľúčmi a prvými skutočnými hodnotami.

Môžete tiež použiť get_in/2/pop_in/2 pre nízkoúrovňový prístup k hodnotám v každom riadku.

Aplikácia

Vela môže byť mimoriadne užitočná ako vyrovnávacia pamäť časových radov v stave procesu, ako je GenServer/Agent. Nikdy nechceme používať zastarané hodnoty kurzu, a preto jednoducho udržiavame proces so stavom spracovaný Vela, s validátorom zobrazeným nižšie.

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

и Vela.purge/1 ticho odstráni všetky neaktuálne hodnoty vždy, keď potrebujeme údaje. Ak chcete získať prístup k skutočným hodnotám, jednoducho zavoláme Vela.slice/1, a keď je potrebná malá história kurzu (celá séria), jednoducho ju vrátime - už zoradenú - s overenými hodnotami.

Šťastné ukladanie časových radov do vyrovnávacej pamäte!

Zdroj: hab.com

Pridať komentár