dcrck

dcrck

Persistent real-time statistics for time series data

I’m working on a high-availability real-time application. Currently, it’s composed of a number of “bots”, each of which listens on WebSocket endpoints for data, responds to the data in various ways, and stores important events in CSV files. The system works great so far, and is able to run all day without problems.

I’d like to add the ability to compute statistics for these events, as they come in, to determine the performance of each “bot”.

I also have another, totally unrelated Phoenix web application which relies on very similar statistics. It stores the time series events in a Postgres database and re-calculates the needed statistics whenever someone visits a page. There aren’t any performance issues there – yet.

Ideally I’d like both of these applications to rely on the same solution. I don’t believe the re-calculation is the most appropriate solution for the real-time app, though…please correct me if I’m wrong!

I’ve read through the post on Creating Persistent Real-Time Analytics of Time Series Data, but that post is a few years old, plus my use case is much less intense – for now.

Here are the important data points for the real-time app:

  • fewer than 100 events per day
  • fewer than 20 bots running at a given time
  • the calculations themselves aren’t computationally intense (for now)

Here are the features I’d like the statistics-tracking application to have:

  • persistent: if the system crashes, I should be able to load in the last known stats or compute the stats from events generated so far.
  • lightweight: I’d like this to be easy to include in other projects that deal with similar data, so I’d like to keep dependencies to a minimum. I’m not opposed to using a database, though, if it proves to be the most appropriate solution.
  • configurable: I’d like it to be relatively easy to support new statistics for the system as needed. I’d also like to be able to choose a subset of the statistics to track if I want.

Right now, my idea is to use a Supervisor with an Agent for each statistic I want to calculate and track. I’m a bit lost when it comes to the persistence part, though. I’m also new to time-series calculations and tools in general.

Do you have any suggestions for libraries or built-in tools I can use to solve my problem without too much overkill? Am I overthinking this? Thanks in advance!

Marked As Solved

lucaong

lucaong

I don’t know enough about your case to determine whether you are looking for a centralized store like Postgres (where multiple app instances would use the same database) or a local one (each app instance having its own storage). If you need a centralized one, you can discard the rest of my post :slight_smile:

If you are looking for a local storage, you could check out CubDB (disclaimer: I am the author of the library). It is an embedded persistent storage written in Elixir, supporting key/value access and sorted ranges, kind of like a durable Map where you can select range of entries sorted by key. Storing time series and selecting ranges is quite easy and performant, you could follow the approach explained here but using timestamps instead of integer IDs):

{:ok, db} = CubDB.start_link(data_dir: "some/dir")

# Save a measurement (temperature for the
# sake of the example):
key = {:temperature, :os.system_time(:millisecond)}
value = measure_temperatue()
:ok = CubDB.put(key, value)

# Get measurements for a time range:
start_time = ...
end_time = ...
{:ok, measurements} = CubDB.select(db,
  min_key: {:temperature, start_time},
  max_key: {:temperature, end_time}
)

Of course, there are several other possible solutions out there, like DETS (but it does not support sorted collections, so it makes the time series case tricky), Mnesia, or embedded databases like LevelDB, LMDB, SQLite, etc. Here you can find a quick comparison with CubDB. I think CubDB would be a good choice if you are looking for something lightweight and idiomatic from Elixir.

Also Liked

hauleth

hauleth

As you are already using PostgreSQL then maybe TimescaleDB will be something that will fit your needs (it is PostgreSQL extension).

dcrck

dcrck

Thanks for the suggestions. CubDB is pretty close to what I was looking for. I may decide to move to something more centralized like Timescale with Postgres at some point, but this should work for now. Thanks @lucaong!

Where Next?

Popular in Questions Top

_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
JulienCorb
I am trying to implement my new.html.eex file to create new posts on my website. new.html.eex: <h1>Create Post</h1> <%= ...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call t...
New

Other popular topics Top

aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 53690 245
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 52341 488
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New

We're in Beta

About us Mission Statement