Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Push conversion of cumulative timeseries into deltas into the database #6888

Open
bnaecker opened this issue Oct 16, 2024 · 6 comments
Open
Assignees
Labels
oxql Oximeter Query Langauge

Comments

@bnaecker
Copy link
Collaborator

Given a query like get <some_cumulative_timeseries> | ...., we automatically convert those cumulative values into deltas. That's to make the data easier to operate on, and is required for grouping, alignment, or joining. We currently do that outside the ClickHouse database, after selecting out the minimal set of raw data that matches the query's filtering predicates. That has been fine thus far, but to help with #6480, we'll need to figure out how to do that inside the database. That's needed so that we can push other operations, like alignment, into the database for cumulative timeseries.

This one will be pretty tricky, I think. ClickHouse has some methods for computing adjacent differences, but they're explicitly only valid within a single block. There might be a way to force ClickHouse to select the data into exactly one block, but I'm not sure that's possible. Other options might be grouping all the data into an array, and then using arrayDifference. That makes us subject to the 1 million-element array size limit, though. That might be fine for today's data. For example, given a cumulative counter sampled at 1Hz, that would enable queries selecting up to about 11.5 days of data, which is pretty good.

There might be smarter ways to do it though, such as using a window function or another method entirely. This will need a bit of research, but I think will bear lots of fruit.

@bnaecker bnaecker added the oxql Oximeter Query Langauge label Oct 16, 2024
@bnaecker bnaecker self-assigned this Oct 16, 2024
@bnaecker
Copy link
Collaborator Author

Well that sucks. From the reference on groupArray:

Creates an array of argument values. Values can be added to the array in any (indeterminate) order.

That is very frustrating, since it means we need to incur an additional sorting on the arrays as we group them. For example, doing some prototyping on data from the dogfood rack, we have this:

SELECT *
FROM
(
    SELECT
        timeseries_key,
        groupArray(start_time) AS start_time,
        groupArray(timestamp) AS t,
        arrayMap(x -> toFloat64(x), arrayDifference(t)) AS dt,
        arrayDifference(groupArray(datum)) AS diff
    FROM oximeter.measurements_cumulativeu64
    WHERE (timeseries_name = 'sled_data_link:bytes_sent') AND (timestamp > '2024-09-19 21:00:00')
    GROUP BY timeseries_key
)
ARRAY JOIN
    start_time,
    t,
    dt,
    diff
WHERE dt < 0

Query id: 217c929f-0d2d-4291-bcf4-400f86645d09

┌───────timeseries_key─┬────────────────────start_time─┬─────────────────────────────t─┬─────────────dt─┬────────diff─┐
│  3363465038672857733 │ 2024-09-18 22:56:28.034156764 │ 2024-09-19 21:00:08.869314782 │ -193.647586899 │        -298 │
│   460322870938857824 │ 2024-09-18 22:55:19.066707621 │ 2024-09-19 21:00:01.481147650 │  -190.54475953 │        -298 │
│  5001052893833390101 │ 2024-09-18 22:55:18.997506627 │ 2024-09-19 21:00:01.471760172 │ -190.545599616 │      -47046 │
│ 13077588349100346925 │ 2024-09-18 22:55:18.885903061 │ 2024-09-19 21:00:01.476864376 │ -190.545062973 │      -15634 │
│ 14616001835716390552 │ 2024-09-18 22:56:02.549134494 │ 2024-09-19 21:00:00.202860843 │ -182.348144985 │        -424 │
│  5386393882607352749 │ 2024-09-18 22:56:02.477391888 │ 2024-09-19 21:00:00.192233860 │  -182.34528169 │        -298 │
│ 13007899933608551837 │ 2024-09-18 22:56:28.241279204 │ 2024-09-19 21:00:08.846540939 │ -193.667984313 │        -298 │
│  7779868191731484988 │ 2024-09-18 22:56:02.623915283 │ 2024-09-19 21:00:00.195472056 │ -182.344761193 │       -3794 │
│ 15832069738186542669 │ 2024-09-18 22:56:28.403149730 │ 2024-09-19 21:00:08.876030391 │ -193.664008954 │       -3880 │
│ 15327245010700216906 │ 2024-09-19 00:32:31.311309544 │ 2024-09-19 21:00:01.477644701 │ -190.545055619 │           0 │
│ 13790310220921135113 │ 2024-09-18 22:56:02.406008569 │ 2024-09-19 21:00:00.199222030 │ -182.349118296 │        -424 │
│  8135000616753235831 │ 2024-09-18 22:56:02.661931318 │ 2024-09-19 21:00:00.201252491 │ -182.349109248 │        -424 │
│ 11617467799251268685 │ 2024-09-18 22:55:18.848982029 │ 2024-09-19 21:00:01.469159389 │ -190.545842826 │        -424 │
│  4102894546473463052 │ 2024-09-18 22:56:28.156523549 │ 2024-09-19 21:00:08.877453481 │ -193.664167364 │        -424 │
│ 13590351437573240573 │ 2024-09-19 20:04:40.175715817 │ 2024-09-19 21:00:01.482553627 │ -190.544623542 │        -424 │
│  3574870979683665573 │ 2024-09-18 22:56:27.995710474 │ 2024-09-19 21:00:08.876766878 │ -193.664069509 │  -484618467 │
│ 15524659641023140988 │ 2024-09-18 22:56:03.129250002 │ 2024-09-19 21:00:00.196263162 │  -182.34471689 │           0 │
│ 17654394455627625726 │ 2024-09-18 22:55:19.459702483 │ 2024-09-19 21:00:01.470775232 │ -190.545748286 │           0 │
│ 11326974237295412380 │ 2024-09-18 22:56:02.441288737 │ 2024-09-19 21:00:00.198493210 │ -182.349149586 │        -424 │
│  9697290744123984606 │ 2024-09-18 22:55:18.921976613 │ 2024-09-19 21:00:01.480478776 │ -190.544795508 │       -3754 │
│  7888320000011044216 │ 2024-09-18 22:44:28.203288885 │ 2024-09-19 21:00:00.196991490 │ -182.352682288 │   -15121794 │
│ 16243920800060468004 │ 2024-09-18 22:46:56.208130018 │ 2024-09-19 21:00:08.845648185 │ -193.687379758 │    -4509484 │
│  8935069020099268098 │ 2024-09-18 22:56:28.444499695 │ 2024-09-19 21:00:08.870080335 │ -193.647543536 │        -298 │
│ 11315210677247824878 │ 2024-09-18 22:56:02.585365823 │ 2024-09-19 21:00:00.203555887 │  -182.34909357 │      -15238 │
│ 12131315570667953735 │ 2024-09-18 22:56:03.152139693 │ 2024-09-19 21:00:00.204832273 │ -182.349075855 │    -7804612 │
│ 14862340117904951507 │ 2024-09-18 22:45:24.844530994 │ 2024-09-19 21:00:01.481805573 │ -190.544720526 │       -4737 │
│  7099898901494778453 │ 2024-09-18 22:48:09.968258332 │ 2024-09-19 21:00:00.206054154 │ -182.349080425 │           0 │
│  6158338936349689928 │ 2024-09-18 22:56:28.361930870 │ 2024-09-19 21:00:08.868114856 │ -193.648020882 │        -424 │
│  8588581828476444266 │ 2024-09-19 20:04:40.147313857 │ 2024-09-19 21:00:01.483817926 │ -190.544541167 │           0 │
│ 16202685905252528417 │ 2024-09-18 22:45:00.861412433 │ 2024-09-19 21:00:01.475221883 │ -190.554264219 │   -22362922 │
│ 11095310754376814238 │ 2024-09-18 22:56:28.322762113 │ 2024-09-19 21:00:08.844817449 │ -193.667959746 │        -424 │
│  1621116761302004751 │ 2024-09-18 22:48:09.992127978 │ 2024-09-19 21:00:00.193769726 │ -182.344821507 │      -14058 │
│  7329109609069119852 │ 2024-09-18 22:55:18.957972083 │ 2024-09-19 21:00:01.476054521 │ -190.545135605 │        -424 │
│ 12371539109148780542 │ 2024-09-18 22:55:19.031046218 │ 2024-09-19 21:00:01.474432673 │ -190.545334915 │     -171652 │
│ 18220381378192972667 │ 2024-09-18 22:56:28.114824660 │ 2024-09-19 21:00:08.874585159 │ -193.663705628 │        -424 │
│  8426056219709174209 │ 2024-09-18 22:56:28.197346493 │ 2024-09-19 21:00:08.843866415 │ -193.668010443 │       -4239 │
│ 14203150016620571245 │ 2024-09-18 22:55:18.808548255 │ 2024-09-19 21:00:01.473517123 │ -190.545474799 │        -424 │
│ 17567648572007546844 │ 2024-09-18 22:47:01.054013192 │ 2024-09-19 21:00:08.839071358 │ -193.666918824 │      -51496 │
│ 12468974222320493293 │ 2024-09-18 22:55:18.734315725 │ 2024-09-19 21:00:01.479065275 │ -190.544888543 │        -424 │
│ 12487835045721333289 │ 2024-09-18 22:55:19.494457712 │ 2024-09-19 21:00:01.479797539 │ -190.544815766 │   -13666210 │
│  1161068207174251536 │ 2024-09-18 22:55:18.771387340 │ 2024-09-19 21:00:01.484397120 │ -190.544520838 │        -424 │
│ 13318108223031485759 │ 2024-09-18 22:47:14.138277210 │ 2024-09-19 21:00:08.871905818 │ -193.646414844 │  -668841164 │
│  4927195514861313187 │ 2024-09-18 22:56:02.701542577 │ 2024-09-19 21:00:00.204201960 │ -182.349103168 │        -424 │
│  4878894661504443737 │ 2024-09-18 22:56:02.737329136 │ 2024-09-19 21:00:00.197769943 │  -182.34878715 │      -17814 │
│  5047169654026990074 │ 2024-09-18 22:46:56.208149365 │ 2024-09-19 21:00:08.873734385 │ -193.665394192 │ -1159793300 │
│  4381391176565769299 │ 2024-09-18 22:45:22.074779687 │ 2024-09-19 21:00:00.199893620 │ -182.349132002 │     -159111 │
│  8227466222941500945 │ 2024-09-18 22:44:28.203284305 │ 2024-09-19 21:00:00.194615525 │ -182.361080185 │    -1831464 │
│  7074541776916617857 │ 2024-09-18 22:56:28.281908261 │ 2024-09-19 21:00:08.840726929 │  -193.67002993 │        -424 │
│ 17855295327543934218 │ 2024-09-18 22:45:00.861372177 │ 2024-09-19 21:00:01.478304868 │ -190.549386964 │    -8067233 │
│ 18368268440791618906 │ 2024-09-18 22:47:34.036954076 │ 2024-09-19 21:00:08.849027286 │   -193.6662433 │       -4161 │
│ 11492523148210757507 │ 2024-09-18 22:56:28.073656433 │ 2024-09-19 21:00:08.878130395 │ -193.664285318 │        -298 │
│ 13339450937790515611 │ 2024-09-18 22:56:02.513634234 │ 2024-09-19 21:00:00.205442978 │ -182.349080435 │        -424 │
│  9135791571494743821 │ 2024-09-19 00:32:31.352580049 │ 2024-09-19 21:00:01.472704858 │ -190.545519203 │    -7233074 │
└──────────────────────┴───────────────────────────────┴───────────────────────────────┴────────────────┴─────────────┘

53 rows in set. Elapsed: 0.362 sec. Processed 22.83 million rows, 187.52 MB (63.11 million rows/s., 518.43 MB/s.)
Peak memory usage: 16.97 MiB.

That group-array query is creating an array of all the start times, timestamps, and datapoints, along with the difference between adjacent array elements in those groups. We're then doing an ARRAY JOIN to "unravel" those arrays back into a table. But we can see that some of the timestamp deltas are negative, which means the arrays are not necessarily sorted in the same way as the underlying table data.

That means we'll need to do an explicit sort of the arrays, all of them, by timestamp. That will either mean an array zip + sort by timestamp + array unzip; or some other form of indirect sort. That's not awesome.

@bnaecker
Copy link
Collaborator Author

This monstrosity will I think do the trick, but it is pretty nauseating:

SELECT
    timeseries_key,
    sorted_timestamp,
    delta_t,
    sorted_datum,
    diff
FROM
(
    WITH
        groupArray((timestamp, ifNull(datum, 0))) AS timestamp_datum,
        arraySort(x -> (x.1), timestamp_datum) AS sorted_pairs,
        arrayMap(x -> (x.1), sorted_pairs) AS sorted_timestamp,
        arrayMap(x -> (x.2), sorted_pairs) AS sorted_datum,
        arrayDifference(sorted_timestamp) AS delta_t,
        arrayDifference(sorted_datum) AS diff
    SELECT
        timeseries_key,
        sorted_timestamp,
        delta_t,
        sorted_datum,
        diff
    FROM oximeter.measurements_cumulativeu64
    WHERE (timeseries_name = 'sled_data_link:bytes_sent') AND (timestamp > '2024-09-19 21:00:00')
    GROUP BY timeseries_key
)
ARRAY JOIN
    sorted_timestamp,
    delta_t,
    sorted_datum,
    diff

Query id: a443243d-f9f7-40bd-8600-2b47ea8f85e3

┌───────timeseries_key─┬──────────────sorted_timestamp─┬──────delta_t─┬──sorted_datum─┬──────diff─┐
│  3991458777114752129 │ 2024-09-19 21:00:09.154532381 │            0 │        387013 │         0 │
│  3991458777114752129 │ 2024-09-19 21:00:19.160171876 │ 10.005639495 │        387013 │         0 │
│  3991458777114752129 │ 2024-09-19 21:00:29.164643200 │ 10.004471324 │        387013 │         0 │
│  3991458777114752129 │ 2024-09-19 21:00:39.167290263 │ 10.002647063 │        387013 │         0 │
│  3991458777114752129 │ 2024-09-19 21:00:49.173166599 │ 10.005876336 │        387013 │         0 │
│  3991458777114752129 │ 2024-09-19 21:00:59.177771387 │ 10.004604788 │        387013 │         0 │
│  3991458777114752129 │ 2024-09-19 21:01:09.179517084 │ 10.001745697 │        387013 │         0 │
│  3991458777114752129 │ 2024-09-19 21:01:19.186833340 │ 10.007316256 │        387013 │         0 │
│  3991458777114752129 │ 2024-09-19 21:01:29.191291776 │ 10.004458436 │        387185 │       172 │
│  3991458777114752129 │ 2024-09-19 21:01:39.193108984 │ 10.001817208 │        387185 │         0 │
│  3991458777114752129 │ 2024-09-19 21:01:49.199350530 │ 10.006241546 │        387311 │       126 │
│  3991458777114752129 │ 2024-09-19 21:01:59.203943470 │  10.00459294 │        387311 │         0 │
│  3991458777114752129 │ 2024-09-19 21:02:09.206289551 │ 10.002346081 │        387311 │         0 │
│  3991458777114752129 │ 2024-09-19 21:02:19.213602968 │ 10.007313417 │        387311 │         0 │
│  3991458777114752129 │ 2024-09-19 21:02:29.219602338 │  10.00599937 │        387311 │         0 │
│  3991458777114752129 │ 2024-09-19 21:02:39.223883731 │ 10.004281393 │        387311 │         0 │
│  3991458777114752129 │ 2024-09-19 21:02:50.319978366 │ 11.096094635 │        387311 │         0 │
│  3991458777114752129 │ 2024-09-19 21:03:00.462557638 │ 10.142579272 │        387311 │         0 │
│   137928658446570774 │ 2024-09-19 21:00:02.694424919 │            0 │        309219 │         0 │
│   137928658446570774 │ 2024-09-19 21:00:12.698725339 │  10.00430042 │        309345 │       126 │
│   137928658446570774 │ 2024-09-19 21:00:22.703988355 │ 10.005263016 │        309345 │         0 │
│   137928658446570774 │ 2024-09-19 21:00:32.727521562 │ 10.023533207 │        309345 │         0 │
│   137928658446570774 │ 2024-09-19 21:00:42.730698897 │ 10.003177335 │        309517 │       172 │
│   137928658446570774 │ 2024-09-19 21:00:52.733588582 │ 10.002889685 │        309517 │         0 │
│   137928658446570774 │ 2024-09-19 21:01:02.736583313 │ 10.002994731 │        309517 │         0 │
│   137928658446570774 │ 2024-09-19 21:01:13.007079790 │ 10.270496477 │        309517 │         0 │
│   137928658446570774 │ 2024-09-19 21:01:23.012277121 │ 10.005197331 │        309517 │         0 │
│   137928658446570774 │ 2024-09-19 21:01:33.014617503 │ 10.002340382 │        309517 │         0 │
│   137928658446570774 │ 2024-09-19 21:01:43.928750296 │ 10.914132793 │        309517 │         0 │
│   137928658446570774 │ 2024-09-19 21:01:53.930675972 │ 10.001925676 │        309517 │         0 │
│   137928658446570774 │ 2024-09-19 21:02:04.633858568 │ 10.703182596 │        309643 │       126 │
│   137928658446570774 │ 2024-09-19 21:02:14.636749918 │  10.00289135 │        309643 │         0 │
│   137928658446570774 │ 2024-09-19 21:02:24.639449057 │ 10.002699139 │        309643 │         0 │
│   137928658446570774 │ 2024-09-19 21:02:35.564506996 │ 10.925057939 │        309643 │         0 │
│   137928658446570774 │ 2024-09-19 21:02:45.567445959 │ 10.002938963 │        309643 │         0 │
│   137928658446570774 │ 2024-09-19 21:02:55.570423484 │ 10.002977525 │        309643 │         0 │
│  3363465038672857733 │ 2024-09-19 21:00:08.869314782 │            0 │        397191 │         0 │
│  3363465038672857733 │ 2024-09-19 21:00:18.923944060 │ 10.054629278 │        397191 │         0 │
│  3363465038672857733 │ 2024-09-19 21:00:28.929677447 │ 10.005733387 │        397191 │         0 │
│  3363465038672857733 │ 2024-09-19 21:00:39.721394194 │ 10.791716747 │        397191 │         0 │
│  3363465038672857733 │ 2024-09-19 21:00:49.726304775 │ 10.004910581 │        397191 │         0 │
│  3363465038672857733 │ 2024-09-19 21:00:59.731694179 │ 10.005389404 │        397191 │         0 │
│  3363465038672857733 │ 2024-09-19 21:01:10.638338911 │ 10.906644732 │        397191 │         0 │
│  3363465038672857733 │ 2024-09-19 21:01:20.641761997 │ 10.003423086 │        397191 │         0 │
│  3363465038672857733 │ 2024-09-19 21:01:30.644498239 │ 10.002736242 │        397191 │         0 │
│  3363465038672857733 │ 2024-09-19 21:01:41.558058654 │ 10.913560415 │        397317 │       126 │
│  3363465038672857733 │ 2024-09-19 21:01:51.563379440 │ 10.005320786 │        397489 │       172 │
...

Let's check if any of the timestamp deltas are negative:

SELECT
    timeseries_key,
    sorted_timestamp,
    delta_t,
    sorted_datum,
    diff
FROM
(
    WITH
        groupArray((timestamp, ifNull(datum, 0))) AS timestamp_datum,
        arraySort(x -> (x.1), timestamp_datum) AS sorted_pairs,
        arrayMap(x -> (x.1), sorted_pairs) AS sorted_timestamp,
        arrayMap(x -> (x.2), sorted_pairs) AS sorted_datum,
        arrayDifference(sorted_timestamp) AS delta_t,
        arrayDifference(sorted_datum) AS diff
    SELECT
        timeseries_key,
        sorted_timestamp,
        delta_t,
        sorted_datum,
        diff
    FROM oximeter.measurements_cumulativeu64
    WHERE (timeseries_name = 'sled_data_link:bytes_sent') AND (timestamp > '2024-09-19 21:00:00')
    GROUP BY timeseries_key
)
ARRAY JOIN
    sorted_timestamp,
    delta_t,
    sorted_datum,
    diff
WHERE delta_t < 0

Query id: 3d148a4f-eb8d-4c23-9077-2d0948f38414

Ok.

0 rows in set. Elapsed: 0.267 sec. Processed 22.83 million rows, 187.07 MB (85.59 million rows/s., 701.46 MB/s.)
Peak memory usage: 17.33 MiB.

Whew, at least it seems to work.

@bnaecker
Copy link
Collaborator Author

bnaecker commented Oct 17, 2024

I think we should seriously consider just storing deltas in ClickHouse directly, moving this complexity to insertion time where we care much less about the latency (and are operating on much less data in each query). If we do the above query on the last 24 hours of data (from all 205 timeseries with data in that time range), here's the resource usage:

1702390 rows in set. Elapsed: 2.056 sec. Processed 22.98 million rows, 352.49 MB (11.18 million rows/s., 171.43 MB/s.)
Peak memory usage: 197.41 MiB.

That efficiency is pretty incredible, but we could still avoid almost all of that if stored deltas, since we could just select the data directly from the table as-is.

Another reason to do that is the above query is not actually correct. What I want to return is the adjacent difference between successive array elements, using the actual value for the first element. The arrayDifference function returns zero for the first array element. We would need to have a conditional or add the first value to each element of the array, which makes this even more insane.

@bnaecker
Copy link
Collaborator Author

bnaecker commented Oct 17, 2024

This works, and is also terrible:

SELECT
    timeseries_key,
    sorted_start_time,
    sorted_timestamp,
    delta_t,
    sorted_datum,
    diff
FROM
(
    WITH
        groupArray((start_time, timestamp, ifNull(datum, 0))) AS tuples,
        arraySort(x -> (x.2), tuples) AS sorted_tuples,
        arrayPushFront(arrayPopBack(sorted_timestamp), (sorted_tuples[1]).1) AS sorted_start_time,
        arrayMap(x -> (x.2), sorted_tuples) AS sorted_timestamp,
        arrayMap(x -> (x.3), sorted_tuples) AS sorted_datum,
        arrayMap((x, y) -> (toFloat64(y) - toFloat64(x)), sorted_start_time, sorted_timestamp) AS delta_t,
        arrayPushFront(arrayPopFront(arrayDifference(sorted_datum)), toInt64((sorted_tuples[1]).3)) AS diff
    SELECT
        timeseries_key,
        sorted_start_time,
        sorted_timestamp,
        delta_t,
        sorted_datum,
        diff
    FROM oximeter.measurements_cumulativeu64
    WHERE (timeseries_name = 'sled_data_link:bytes_sent') AND (timestamp > '2024-09-19 21:00:00')
    GROUP BY timeseries_key
)
ARRAY JOIN
    sorted_start_time,
    sorted_timestamp,
    delta_t,
    sorted_datum,
    diff

The trickery around the pushing / popping on the arrays is for two things:

  • To create the start time for the deltas, we take the first start timestamp, and then push the slice of the actual sample timestamps from elements 1..
  • To create the diffs, we do a similar thing: take the array of differences, and replace the first value with the raw (non-diff) data.

We get things like this:

┌──────timeseries_key─┬─────────────sorted_start_time─┬──────────────sorted_timestamp─┬────────────delta_t─┬─sorted_datum─┬───diff─┐
│ 3991458777114752129 │ 2024-09-18 22:56:06.400206845 │ 2024-09-19 21:00:09.154532381 │  79442.75432562828 │       387013 │ 387013 │
│ 3991458777114752129 │ 2024-09-19 21:00:09.154532381 │ 2024-09-19 21:00:19.160171876 │  10.00563931465149 │       387013 │      0 │
│ 3991458777114752129 │ 2024-09-19 21:00:19.160171876 │ 2024-09-19 21:00:29.164643200 │  10.00447154045105 │       387013 │      0 │
│ 3991458777114752129 │ 2024-09-19 21:00:29.164643200 │ 2024-09-19 21:00:39.167290263 │ 10.002647161483765 │       387013 │      0 │
│ 3991458777114752129 │ 2024-09-19 21:00:39.167290263 │ 2024-09-19 21:00:49.173166599 │ 10.005876064300537 │       387013 │      0 │
│ 3991458777114752129 │ 2024-09-19 21:00:49.173166599 │ 2024-09-19 21:00:59.177771387 │ 10.004604816436768 │       387013 │      0 │
│ 3991458777114752129 │ 2024-09-19 21:00:59.177771387 │ 2024-09-19 21:01:09.179517084 │  10.00174593925476 │       387013 │      0 │
│ 3991458777114752129 │ 2024-09-19 21:01:09.179517084 │ 2024-09-19 21:01:19.186833340 │  10.00731611251831 │       387013 │      0 │
│ 3991458777114752129 │ 2024-09-19 21:01:19.186833340 │ 2024-09-19 21:01:29.191291776 │   10.0044584274292 │       387185 │    172 │
│ 3991458777114752129 │ 2024-09-19 21:01:29.191291776 │ 2024-09-19 21:01:39.193108984 │ 10.001817226409912 │       387185 │      0 │
│ 3991458777114752129 │ 2024-09-19 21:01:39.193108984 │ 2024-09-19 21:01:49.199350530 │   10.0062415599823 │       387311 │    126 │
│ 3991458777114752129 │ 2024-09-19 21:01:49.199350530 │ 2024-09-19 21:01:59.203943470 │ 10.004592895507812 │       387311 │      0 │
│ 3991458777114752129 │ 2024-09-19 21:01:59.203943470 │ 2024-09-19 21:02:09.206289551 │ 10.002346277236938 │       387311 │      0 │
│ 3991458777114752129 │ 2024-09-19 21:02:09.206289551 │ 2024-09-19 21:02:19.213602968 │ 10.007313251495361 │       387311 │      0 │
│ 3991458777114752129 │ 2024-09-19 21:02:19.213602968 │ 2024-09-19 21:02:29.219602338 │ 10.005999326705933 │       387311 │      0 │
│ 3991458777114752129 │ 2024-09-19 21:02:29.219602338 │ 2024-09-19 21:02:39.223883731 │ 10.004281520843506 │       387311 │      0 │
│ 3991458777114752129 │ 2024-09-19 21:02:39.223883731 │ 2024-09-19 21:02:50.319978366 │ 11.096094369888306 │       387311 │      0 │
│ 3991458777114752129 │ 2024-09-19 21:02:50.319978366 │ 2024-09-19 21:03:00.462557638 │ 10.142579555511475 │       387311 │      0 │
│  137928658446570774 │ 2024-09-18 22:55:18.800448757 │ 2024-09-19 21:00:02.694424919 │  79483.89397621155 │       309219 │ 309219 │
│  137928658446570774 │ 2024-09-19 21:00:02.694424919 │ 2024-09-19 21:00:12.698725339 │ 10.004300594329834 │       309345 │    126 │
│  137928658446570774 │ 2024-09-19 21:00:12.698725339 │ 2024-09-19 21:00:22.703988355 │ 10.005263090133667 │       309345 │      0 │
│  137928658446570774 │ 2024-09-19 21:00:22.703988355 │ 2024-09-19 21:00:32.727521562 │  10.02353286743164 │       309345 │      0 │
│  137928658446570774 │ 2024-09-19 21:00:32.727521562 │ 2024-09-19 21:00:42.730698897 │ 10.003177642822266 │       309517 │    172 │
│  137928658446570774 │ 2024-09-19 21:00:42.730698897 │ 2024-09-19 21:00:52.733588582 │ 10.002889394760132 │       309517 │      0 │
│  137928658446570774 │ 2024-09-19 21:00:52.733588582 │ 2024-09-19 21:01:02.736583313 │ 10.002995014190674 │       309517 │      0 │
│  137928658446570774 │ 2024-09-19 21:01:02.736583313 │ 2024-09-19 21:01:13.007079790 │ 10.270496129989624 │       309517 │      0 │
│  137928658446570774 │ 2024-09-19 21:01:13.007079790 │ 2024-09-19 21:01:23.012277121 │ 10.005197763442993 │       309517 │      0 │
│  137928658446570774 │ 2024-09-19 21:01:23.012277121 │ 2024-09-19 21:01:33.014617503 │ 10.002340316772461 │       309517 │      0 │
│  137928658446570774 │ 2024-09-19 21:01:33.014617503 │ 2024-09-19 21:01:43.928750296 │ 10.914132595062256 │       309517 │      0 │
│  137928658446570774 │ 2024-09-19 21:01:43.928750296 │ 2024-09-19 21:01:53.930675972 │ 10.001925706863403 │       309517 │      0 │
│  137928658446570774 │ 2024-09-19 21:01:53.930675972 │ 2024-09-19 21:02:04.633858568 │ 10.703182458877563 │       309643 │    126 │
│  137928658446570774 │ 2024-09-19 21:02:04.633858568 │ 2024-09-19 21:02:14.636749918 │ 10.002891302108765 │       309643 │      0 │
│  137928658446570774 │ 2024-09-19 21:02:14.636749918 │ 2024-09-19 21:02:24.639449057 │ 10.002699375152588 │       309643 │      0 │
│  137928658446570774 │ 2024-09-19 21:02:24.639449057 │ 2024-09-19 21:02:35.564506996 │ 10.925057649612427 │       309643 │      0 │
│  137928658446570774 │ 2024-09-19 21:02:35.564506996 │ 2024-09-19 21:02:45.567445959 │ 10.002939224243164 │       309643 │      0 │
│  137928658446570774 │ 2024-09-19 21:02:45.567445959 │ 2024-09-19 21:02:55.570423484 │   10.0029776096344 │       309643 │      0 │
│ 3363465038672857733 │ 2024-09-18 22:56:28.034156764 │ 2024-09-19 21:00:08.869314782 │  79420.83515810966 │       397191 │ 397191 │
│ 3363465038672857733 │ 2024-09-19 21:00:08.869314782 │ 2024-09-19 21:00:18.923944060 │  10.05462908744812 │       397191 │      0 │
│ 3363465038672857733 │ 2024-09-19 21:00:18.923944060 │ 2024-09-19 21:00:28.929677447 │ 10.005733489990234 │       397191 │      0 │
│ 3363465038672857733 │ 2024-09-19 21:00:28.929677447 │ 2024-09-19 21:00:39.721394194 │ 10.791716575622559 │       397191 │      0 │
│ 3363465038672857733 │ 2024-09-19 21:00:39.721394194 │ 2024-09-19 21:00:49.726304775 │ 10.004910707473755 │       397191 │      0 │
│ 3363465038672857733 │ 2024-09-19 21:00:49.726304775 │ 2024-09-19 21:00:59.731694179 │ 10.005389213562012 │       397191 │      0 │
│ 3363465038672857733 │ 2024-09-19 21:00:59.731694179 │ 2024-09-19 21:01:10.638338911 │ 10.906644821166992 │       397191 │      0 │
│ 3363465038672857733 │ 2024-09-19 21:01:10.638338911 │ 2024-09-19 21:01:20.641761997 │  10.00342321395874 │       397191 │      0 │
│ 3363465038672857733 │ 2024-09-19 21:01:20.641761997 │ 2024-09-19 21:01:30.644498239 │  10.00273609161377 │       397191 │      0 │
│ 3363465038672857733 │ 2024-09-19 21:01:30.644498239 │ 2024-09-19 21:01:41.558058654 │ 10.913560628890991 │       397317 │    126 │
│ 3363465038672857733 │ 2024-09-19 21:01:41.558058654 │ 2024-09-19 21:01:51.563379440 │  10.00532078742981 │       397489 │    172 │
│ 3363465038672857733 │ 2024-09-19 21:01:51.563379440 │ 2024-09-19 21:02:01.566998788 │ 10.003619194030762 │       397489 │      0 │
│ 3363465038672857733 │ 2024-09-19 21:02:01.566998788 │ 2024-09-19 21:02:12.478091103 │ 10.911092281341553 │       397489 │      0 │
│ 3363465038672857733 │ 2024-09-19 21:02:12.478091103 │ 2024-09-19 21:02:22.480984649 │ 10.002893686294556 │       397489 │      0 │
...

It's also important to note that this does not handle histograms at all. I don't have any idea what that would look like yet, but to do this correctly, you'd need to compute the difference between corresponding array elements of each histogram. That sounds like another array map / zip / reduce of some kind.

@bnaecker
Copy link
Collaborator Author

One more thing to consider on this front -- we actually don't need the ARRAY JOIN. That's to make it easy to see what's happening, but it's not needed, since OxQL queries will ultimately create an array from the timestamps / datapoints anyway. So the array join means the server needs to do work to blow all that back up, and then we also pay unnecessary serialization costs for things like the timeseries keys which are constant for each group. That's the only duplicated column in this case, so it's not huge, but it's still not required.

@bnaecker
Copy link
Collaborator Author

I talked with @ahl about this a bit. There is one huge benefit of storing the raw cumulative values in the database, which is that we can always select any time range of data, and have the full picture. If you don't store those, then we need to sum all the values before the start time of the query to correctly compute the values within the time range specified by the query.

We could also entertain two other options:

  • store both the cumulative values and deltas
  • create a non-materialized view onto the cumulative tables that computes the deltas on demand

Both of these have their own tradeoffs. The first obviously plays fast and loose with storage space. It's 100% redundant data, so while it might compress very well, we are definitely using customer space to store something we could otherwise get. In the second, we don't pay any storage costs since the view isn't materialized, but it might not be possible to actually do that. Specifically, the materialized view would need to collect the entire time history of a timeseries into an array in the groupArray() call. Arrays have a limit of 1 million elements today, which we might feasibly hit in that case. We could use a parametrized view to help limit the data that query accessed, but I'm not sure how much that would help.

As Adam pointed out, either of these basically make clear that what we're trading off is query latency vs storage space. In the absence of some compelling data that the query is "too slow", we should probably not use more disk at this point. The OxQL queries that prompted this investigation do time out on the client side, to be clear, but that can probably be improved by lengthening timeouts at this point. We should keep an eye on it, but it's still probably worth it to be more parsimonious with customer disk space at this point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
oxql Oximeter Query Langauge
Projects
None yet
Development

No branches or pull requests

1 participant