Vela → intelligenter Cache für Zeitreihen und mehr

Im FinTech-Sektor müssen wir häufig ziemlich große Datenmengen zu Wechselkursen verarbeiten. Wir beziehen unsere Daten aus verschiedenen Quellen, und jede von ihnen hat ihre eigene Methode, um die Wechselkurse für morgen, übermorgen, den nächsten Monat und sogar die nächsten drei Jahre zu extrapolieren. Würde jemand die Wechselkurse vorhersagen können, könnte man das Geschäft einstellen und einfach nur Geld hin- und herschieben. der richtigeEinige Quellen genießen mehr Vertrauen, während andere nur Müll liefern, abgesehen von gelegentlich fast korrekten Werten, insbesondere bei exotischen Währungspaaren. Unsere Aufgabe besteht darin, diese Zehntausenden von Werten pro Sekunde zu filtern und herauszufinden, was wir unseren Kunden präsentieren. Wir müssen den einen richtigen Wert aus einer Tonne von Schmutz und Schlamm herausfiltern, ähnlich wie Flamingos beim Fressen.

Vela → intelligenter Cache für Zeitreihen und mehr

Das auffälligste Merkmal von Flamingos ist der massive, nach unten gebogene Schnabel, mit dem sie ihre Nahrung aus Wasser oder Schlamm filtern.
 — Wiki

So entstand die Bibliothek Vela, die den Status-Cache für mehrere Werte in bestimmten Zeitintervallen speichert. Im Hintergrund filtert sie auf der Fl fly schlechte und veraltete Daten und bietet Zugriff auf die neuesten N validierten Werte für jeden Schlüssel (Währungspaare in unserem Fall).

Angenommen, wir sammeln die Kurse für drei Währungspaare. Eine einfache Definition Vela zum Speichern des aktuellen Status könnte so aussehen:

defmodule Pairs do
  use Vela,
    eurusd: [sorter: &Kernel. 0
end

Aktualisierung der Werte

Vela.put/3 Die Funktion wird dann nacheinander Folgendes tun:

  • validator auf den Wert aufrufen, falls einer definiert ist (siehe Kapitel Validierung unten); Den Wert entweder in die Reihe der guten Werte hinzufügen, falls die Validierung erfolgreich war, oder in die Hilfsreihe
  • :__errors__ ansonsten; Sortierung aufrufen, wenn
  • sorter für diesen Schlüssel definiert ist, oder einfach den Wert an den Kopf der Liste legen ( LIFO, siehe Kapiteldie Reihe entsprechend dem Parameter Sortierung Den Wert entweder in die Reihe der guten Werte hinzufügen, falls die Validierung erfolgreich war, oder in die Hilfsreihe
  • :limit der bei der Erstellung übergeben wurde; gibt die aktualisierte Struktur zurück
  • вернет обновленную структуру 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]}

Außerdem Vela implementiert Zugriff, sodass zur Aktualisierung der Werte eine der Standardfunktionen zur tiefen Aktualisierung von Strukturen verwendet werden kann Kernel: Kernel.get_in/2, Kernel.put_in/3, Kernel.update_in/3, Kernel.pop_in/2, und Kernel.get_and_update_in/3.

unten);

Der Validator kann definiert werden als:

  • eine externe Funktion mit einem Argument (&MyMod.my_fun/1), die nur den zu validierenden Wert erhält;
  • eine externe Funktion mit zwei Argumenten, &MyMod.my_fun/2, die ein Paar serie, value zur Validierung erhält;
  • Modul, das Vela.Validator;
  • Konfigurationsparameter Schwellenwert, und – optional – compare_bydie Reihe entsprechend dem Parameter Vergleich unten.

Wenn die Validierung erfolgreich war, wird der Wert unter dem entsprechenden Schlüssel zur Liste hinzugefügt, andernfalls wird das Tupel {serie, value} in :__errors_.

Der Vergleich

Die in diesen Reihen gespeicherten Werte können beliebig sein. Um zu lehren, Vela sie zu vergleichen, muss compare_by ein Parameter in die Definition der Reihe übergeben werden (es sei denn, die Werte können mit den Standard Kernel.</2); dieser Parameter sollte den Typ haben (Vela.value() -> number()). Standardmäßig ist das einfach &&1.

Außerdem kann man beim Festlegen einer Reihe einen Parameter übergeben Comparator zur Berechnung der Delta-Werte (min/max); beispielsweise durch die Übergabe von Date.diff/2 als Comparator erhält man die korrekten Deltas für Daten.

Eine weitere praktische Methode besteht darin, einen Parameter zu übergeben Schwellenwert, der das maximal zulässige Verhältnis des neuen Wertes zu {min, max} dem Intervall definiert. Da er in Prozent angegeben wird, erfolgt die Prüfung nicht über Comparator, nutzt aber weiterhin compare_by. Zum Beispiel, um einen Schwellenwert für Zeitstempel anzugeben, sollte man compare_by: &DateTime.to_unix/1 verwenden (um einen ganzzahligen Wert zu erhalten) und threshold: 1, wodurch neue Werte nur akzeptiert werden, wenn sie innerhalb von ±band dem Bereich der aktuellen Werte liegen.

Schließlich kann man Vela.equal?/2 verwenden, um zwei Caches zu vergleichen. Wenn Werte die Funktion definieren equal?/2 oder compare/2, werden diese Funktionen zum Vergleich verwendet, andernfalls verwenden wir einfach ==/2.

Das Abrufen von Werten

Die Verarbeitung des aktuellen Zustands beginnt in der Regel mit dem Aufruf Vela.purge/1, der veraltete Werte entfernt (wenn auf den Wert aufrufen, falls einer definiert ist (siehe Kapitel abhängig von timestamps). Danach kann man Vela.slice/1, die zurückgibt keyword mit den Namen der Reihen als Schlüsseln und der ersten aktuellen Werte.

Außerdem kann man get_in/2/pop_in/2 für den niedrigstufigen Zugriff auf die Werte in jeder Reihe.

generierten Wortliste wurde sichergestellt.

Vela kann sich als äußerst nützlich als Cache für Zeitreihen im Zustand des GenServer/Agent. Wir wollen niemals veraltete Wechselkurswerte verwenden, und dafür halten wir einfach den Prozess mit einem Zustand, der bearbeitet wird Vela, mit dem Validator, der unten gezeigt wird.

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

und Vela.purge/1 entfernt alle veralteten Werte jedes Mal ruhig, wenn wir Daten benötigen. Um auf die aktuellen Werte zuzugreifen, rufen wir einfach Vela.slice/1auf, und wenn eine kleine Historie des Kurses benötigt wird (die gesamte Reihe), geben wir sie einfach zurück – bereits sortiert – mit validierten Werten.

Viel Erfolg beim Caching von Zeitreihen!

Quelle: habr.com

Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen 🔥 Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen | ProHoster