2015-05-30 5 views
5

Ich habe viele Analysedaten, die ich immer wieder sammeln möchte (sagen wir mal eine Minute). Die Daten werden an einen Prozess gesendet, der sie in einer ETS-Tabelle speichert und von Zeit zu Zeit von einem Timer gesendet wird eine Nachricht, um die Tabelle zu verarbeiten und alte Daten zu entfernen.Wie sollte ich ganze ETS-Tabellen automatisch ablaufen lassen und gleichzeitig die Gesamtgröße begrenzen?

Das Problem ist, dass die Datenmenge, die in wild kommt variiert, und ich brauche im Grunde genommen, um es zwei Dinge zu tun:

  • Wenn die Datenmenge in den kommenden zu groß ist, die ältesten Daten fallen und schieben Sie die neuen Daten ein. Dies könnte als eine Warteschlange mit fester Größe angesehen werden. Wenn die Datenmenge das Limit erreicht, würde die Warteschlange beginnen, Dinge von vorne fallen zu lassen, wenn neue Daten in den Hintergrund treten.
  • Wenn die Warteschlange nicht voll ist, aber die Daten für eine Weile dort sitzen wurden, wird es automatisch verwerfen (nach einer festgelegten Timeout.)

Wenn diese beiden Bedingungen gehalten werden, könnte ich im Grunde Angenommen, die Tabelle hat eine konstante Größe und alles darin ist neuer als X.

Das Problem ist, dass ich keinen effizienten Weg gefunden habe, diese beiden Dinge zusammen zu tun. Ich weiß, dass ich Matchspezifikationen verwenden könnte, um alle Ganzzahlen zu löschen, die älter als X sind, was ziemlich schnell sein sollte, wenn der Index der Zeitstempel ist. Obwohl ich nicht sicher bin, ob dies der beste Weg ist, den Tisch regelmäßig zu beschneiden.

Das zweite Problem ist, die Gesamttabellengröße unter einer bestimmten Grenze zu halten, was ich nicht so genau weiß. Eine Lösung besteht darin, ein Auto-Inkrement-Feld zu verwenden, das jedes Einfügen und wenn die Tabelle getrimmt wird, den ersten und letzten Index zu betrachten, den Unterschied zu berechnen und wiederum mit Match-Spezifikationen alles unter dem Schwellenwert zu löschen.

Nachdem dies alles gesagt wurde, habe ich das Gefühl, dass ich die ETS-Tabelle für etwas verwenden könnte, für das sie nicht vorgesehen war. Gibt es eine bessere Möglichkeit, Daten wie diese zu speichern, oder nähere ich mich dem Problem richtig?

+0

Wie wird normalerweise auf die Daten zugegriffen? Verwenden Sie Ets, weil Sie normalerweise eine Datensuche nach Schlüssel benötigen? –

+0

@SteveVinoski Nein, ich benutze ETS einfach, weil das Speichern einer Menge von Daten im Prozesszustand nicht als eine vernünftige Idee schien. –

Antwort

1

Ich habe ETS für so etwas nicht verwendet, aber in anderen NoSQL DBs (DynamoDB) ist eine einfache Lösung, mehrere Tabellen zu verwenden: Wenn Sie 24 Stunden Daten speichern, dann behalten Sie 24 Tabellen, eins für jedes Stunde des Tages. Wenn Sie Daten löschen möchten, löschen Sie eine ganze Tabelle.

2

Sie können die Anzahl der belegten Daten mit ets:info(Tab, memory) ermitteln. Das Ergebnis ist die Anzahl der Wörter. Aber da ist ein Haken. Wenn Sie Binärdateien speichern, sind nur die Heap-Binärdateien enthalten. Wenn Sie also hauptsächlich normale Erlang-Begriffe speichern, können Sie sie verwenden und mit einem Zeitstempel, wie Sie es beschrieben haben, ist es ein Weg zu gehen. Für die Größe in Bytes multiplizieren Sie einfach mit erlang:system_info(wordsize).

0

würde ich Folgendes tun: Erstellen Sie einen Server verantwortlich für

  • alle Datenspeicher Nachrichten zu empfangen. Diese Nachrichten sollten vom Client-Prozess mit Zeitstempel versehen werden (es spielt also keine Rolle, ob sie in der Nachrichtenwarteschlange etwas warten). Der Server speichert dann dann in der ETS, konfiguriert als order_set und unter Verwendung des Zeitstempels, konvertiert in einer Ganzzahl, als Schlüssel (wenn die Zeitstempel von der Funktion erlang geliefert werden: jetzt in einer einzigen VM werden sie anders sein, wenn Sie verwenden mehrere Knoten, dann müssen Sie einige Informationen wie den Knotennamen hinzufügen, um die Eindeutigkeit zu gewährleisten).
  • empfängt ein Häkchen (unter Verwendung von zum Beispiel timer: send_interval) und verarbeitet dann die in den letzten N μs empfangene Nachricht (unter Verwendung des Schlüssels = aktuelle Zeit - N) und sucht nach ets: next (Table, Key) und fährt mit die letzte NachrichtSchließlich können Sie alle Nachrichten über ets verwerfen: delete_all_objects (Table). Wenn Sie eine Information wie einen Knotennamen hinzufügen mussten, ist es immer noch möglich, die nächste Funktion zu verwenden (zum Beispiel die Schlüssel sind {TimeStamp: int(), Node: atom()}, die Sie mit {Time: int (), 0}, da eine Zahl kleiner ist als jedes Atom)
Verwandte Themen