Vela → έξυπνη κρυφή μνήμη για χρονοσειρές και πολλά άλλα

Στο fintech, συχνά πρέπει να επεξεργαζόμαστε τεράστιους όγκους δεδομένων συναλλαγματικών ισοτιμιών. Λαμβάνουμε δεδομένα από διαφορετικές πηγές και καθεμία από αυτές έχει τη δική της ιδέα για το πώς να υπολογίσουμε τις συναλλαγματικές ισοτιμίες για αύριο, μεθαύριο, τον επόμενο μήνα και ακόμη και τα επόμενα τρία χρόνια. Αν κάποιος μπορούσε να προβλέψει τα ποσοστά σωστά, θα ήταν καιρός να κλείσουμε την επιχείρηση και να αλλάξουμε ανόητα χρήματα πέρα ​​δώθε. Κάποιες πηγές είναι πιο αξιόπιστες, κάποιες προμηθεύουν πλήρη σκουπίδια, με σπάνιες συμπεριλήψεις σχεδόν σωστών τιμών, αλλά για εξωτικά ζευγάρια. Η δουλειά μας είναι να διερευνήσουμε αυτές τις δεκάδες χιλιάδες τιμές ανά δευτερόλεπτο και να καθορίσουμε τι ακριβώς θα δείξουμε στους πελάτες. Πρέπει να φιλτράρουμε τη μία σωστή τιμή από τόνους βρωμιάς και λάσπης, όπως ακριβώς κάνουν τα φλαμίνγκο στο μεσημεριανό γεύμα.

Vela → έξυπνη κρυφή μνήμη για χρονοσειρές και πολλά άλλα

Ένα ιδιαίτερο χαρακτηριστικό των φλαμίνγκο είναι το ογκώδες κυρτό ράμφος τους, με το οποίο φιλτράρουν τα τρόφιμα από το νερό ή τη λάσπη.
 - Wiki

Έτσι γεννήθηκε η βιβλιοθήκη Vela, το οποίο αποθηκεύει μια κρυφή μνήμη κατάστασης για πολλαπλές τιμές σε καθορισμένα χρονικά διαστήματα. Κάτω από την κουκούλα, φιλτράρει τα κακά και ξεπερασμένα δεδομένα εν κινήσει και παρέχει επίσης πρόσβαση στα πιο πρόσφατα N επικυρωμένες τιμές για κάθε κλειδί (ζεύγη νομισμάτων, στην περίπτωσή μας).

Ας υποθέσουμε ότι συλλέγουμε επιτόκια για τρία ζεύγη νομισμάτων. Ο απλούστερος ορισμός Vela για να αποθηκεύσετε την τρέχουσα κατάσταση θα μοιάζει κάπως έτσι:

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

Ενημέρωση τιμών

Vela.put/3 Η συνάρτηση θα κάνει τα εξής με τη σειρά:

  • θα προκαλέσει validator στην τιμή, εάν έχει οριστεί κάποια (βλ. κεφάλαιο Επικύρωση παρακάτω);
  • θα προσθέσει την τιμή είτε στη σειρά καλών τιμών, εάν η επικύρωση ήταν επιτυχής, είτε στη γραμμή εξυπηρέτησης :__errors__ σε διαφορετική περίπτωση;
  • θα προκαλέσει ταξινόμηση εάν sorter ορίζεται για ένα δεδομένο κλειδί ή απλώς θα βάλει την τιμή στην κορυφή της λίστας (LIFO, βλέπε κεφάλαιο Ταξινόμηση παρακάτω);
  • θα κόψει τη σειρά σύμφωνα με την παράμετρο :limit πέρασε κατά τη δημιουργία?
  • θα επιστρέψει την ενημερωμένη δομή 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]}

Επίσης Vela υλοποιεί Access, ώστε να μπορείτε να χρησιμοποιήσετε οποιαδήποτε από τις τυπικές συναρτήσεις για βαθιά ενημέρωση δομών από το οπλοστάσιο για ενημέρωση τιμών Kernel: Kernel.get_in/2, Kernel.put_in/3, Kernel.update_in/3, Kernel.pop_in/2, να Kernel.get_and_update_in/3.

Επικύρωση

Ένας επικυρωτής μπορεί να οριστεί ως:

  • εξωτερική συνάρτηση με ένα όρισμα (&MyMod.my_fun/1), θα λάβει μόνο την τιμή για επικύρωση.
  • εξωτερική συνάρτηση με δύο ορίσματα, &MyMod.my_fun/2, θα πάρει ένα ζευγάρι serie, value για την επικύρωση;
  • υλοποίηση της ενότητας Vela.Validator;
  • παράμετρος διαμόρφωσης thresholdκαι - προαιρετικά - compare_by, βλέπε κεφάλαιο Σύγκριση παρακάτω.

Εάν η επικύρωση είναι επιτυχής, η τιμή προστίθεται στη λίστα κάτω από το αντίστοιχο κλειδί, διαφορετικά, η πλειάδα {serie, value} πηγαίνει στο :__errors_.

Σύγκριση

Οι τιμές που αποθηκεύονται σε αυτές τις σειρές μπορεί να είναι οτιδήποτε. Να διδάξει Vela για να τα συγκρίνετε, είναι απαραίτητο να μεταφέρετε compare_by παράμετρος στον ορισμό της σειράς (εκτός εάν οι τιμές δεν μπορούν να συγκριθούν με το πρότυπο Kernel.</2) αυτή η παράμετρος πρέπει να είναι του τύπου (Vela.value() -> number()). Από προεπιλογή είναι απλό & &1.

Επίσης, μπορείτε να μεταβιβάσετε μια παράμετρο στον ορισμό της γραμμής comparator για να υπολογίσετε τις τιμές δέλτα (min/max) για παράδειγμα, με τη μετάδοση Date.diff/2 Ως σύγκριση, μπορείτε να βρείτε τα σωστά δέλτα για ημερομηνίες.

Ένας άλλος βολικός τρόπος εργασίας είναι να περάσετε μια παράμετρο threshold, το οποίο ορίζει τη μέγιστη επιτρεπόμενη αναλογία της νέας τιμής προς {min, max} διάστημα. Δεδομένου ότι προσδιορίζεται ως ποσοστό, η επιταγή δεν χρησιμοποιείται comparatorαλλά εξακολουθεί να χρησιμοποιεί compare_by. Για παράδειγμα, για να καθορίσετε μια τιμή κατωφλίου για ώρες ημερομηνίας, πρέπει να καθορίσετε compare_by: &DateTime.to_unix/1 (για να πάρετε μια ακέραια τιμή) και threshold: 1, με αποτέλεσμα να επιτρέπονται νέες τιμές μόνο εάν είναι μέσα ±band διάστημα από τις τρέχουσες τιμές.

Τέλος, μπορείτε να χρησιμοποιήσετε Vela.equal?/2 να συγκρίνετε δύο κρυφές μνήμες. Εάν οι τιμές ορίζουν μια συνάρτηση equal?/2 ή compare/2, τότε αυτές οι συναρτήσεις θα χρησιμοποιηθούν για σύγκριση, διαφορετικά χρησιμοποιούμε ανόητα ==/2.

Λήψη αξιών

Η επεξεργασία της τρέχουσας κατάστασης ξεκινά συνήθως με την κλήση Vela.purge/1, το οποίο αφαιρεί τις παρωχημένες τιμές (αν validator δεμένος σε timestamps). Στη συνέχεια, μπορείτε να καλέσετε Vela.slice/1που θα επιστρέψει keyword με τα ονόματα σειρών ως κλειδιά και τις πρώτες, πραγματικές τιμές.

Μπορείτε επίσης να χρησιμοποιήσετε get_in/2/pop_in/2 για πρόσβαση χαμηλού επιπέδου στις τιμές σε κάθε σειρά.

App

Vela μπορεί να είναι εξαιρετικά χρήσιμο ως προσωρινή μνήμη χρονοσειράς σε μια κατάσταση διεργασίας όπως GenServer/Agent. Θέλουμε να μην χρησιμοποιούμε ποτέ μπαγιάτικες τιμές μαθημάτων και για να το κάνουμε αυτό απλώς κρατάμε τη διαδικασία με την κατάσταση επεξεργασμένη Vela, με τον επικυρωτή που φαίνεται παρακάτω.

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

и Vela.purge/1 αφαιρεί αθόρυβα όλες τις παλιές τιμές κάθε φορά που χρειαζόμαστε τα δεδομένα. Για να αποκτήσουμε πρόσβαση στις πραγματικές τιμές, απλώς καλούμε Vela.slice/1, και όταν απαιτείται ένα μικρό ιστορικό του μαθήματος (όλη η σειρά), απλά το επιστρέφουμε - ήδη ταξινομημένο - με επικυρωμένες τιμές.

Χαρούμενη προσωρινή αποθήκευση χρονολογικών σειρών!

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο