Skip to content

Commit de05991

Browse files
committed
[Rollup] Log deprecation if config and request intervals are mixed
Backport of elastic#32052, with some changes. In 6.5, we forbid mixed intervals (one fixed, one calendar). But for a 6.4.x bugfix release this would be a pretty extreme break. So we continue to allow mixed intervals in 6.4, but log a deprecation warning. 6.4 also doesn't enforce that the request is a multiple of the config. We also log a deprecation if that is not the case, but don't prevent the query. Finally, mixed intervals are only used if a better job cap can't be found. To support the case where we have to compare fixed and calendar, there is a table of rough conversions (e.g. 1 day == 86400000ms). This lets us crudely ensure the user doesn't try to query `2d` on an index that is set for `1w`.
1 parent 4a548b0 commit de05991

File tree

8 files changed

+583
-84
lines changed

8 files changed

+583
-84
lines changed

x-pack/docs/build.gradle

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -685,9 +685,8 @@ setups['sensor_prefab_data'] = '''
685685
page_size: 1000
686686
groups:
687687
date_histogram:
688-
delay: "7d"
689688
field: "timestamp"
690-
interval: "1h"
689+
interval: "7d"
691690
time_zone: "UTC"
692691
terms:
693692
fields:

x-pack/docs/en/rest-api/rollup/put-job.asciidoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ started with the <<rollup-start-job,Start Job API>>.
4343
`metrics`::
4444
(object) Defines the metrics that should be collected for each grouping tuple. See <<rollup-job-config,rollup job config>>.
4545

46+
For more details about the job configuration, see <<rollup-job-config>>.
47+
4648
==== Authorization
4749

4850
You must have `manage` or `manage_rollup` cluster privileges to use this API.

x-pack/docs/en/rest-api/rollup/rollup-job-config.asciidoc

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ PUT _xpack/rollup/job/sensor
2323
"groups" : {
2424
"date_histogram": {
2525
"field": "timestamp",
26-
"interval": "1h",
26+
"interval": "60m",
2727
"delay": "7d"
2828
},
2929
"terms": {
@@ -93,7 +93,7 @@ fields will then be available later for aggregating into buckets. For example,
9393
"groups" : {
9494
"date_histogram": {
9595
"field": "timestamp",
96-
"interval": "1h",
96+
"interval": "60m",
9797
"delay": "7d"
9898
},
9999
"terms": {
@@ -127,9 +127,9 @@ The `date_histogram` group has several parameters:
127127
The date field that is to be rolled up.
128128

129129
`interval` (required)::
130-
The interval of time buckets to be generated when rolling up. E.g. `"1h"` will produce hourly rollups. This follows standard time formatting
131-
syntax as used elsewhere in Elasticsearch. The `interval` defines the _minimum_ interval that can be aggregated only. If hourly (`"1h"`)
132-
intervals are configured, <<rollup-search,Rollup Search>> can execute aggregations with 1hr or greater (weekly, monthly, etc) intervals.
130+
The interval of time buckets to be generated when rolling up. E.g. `"60m"` will produce 60 minute (hourly) rollups. This follows standard time formatting
131+
syntax as used elsewhere in Elasticsearch. The `interval` defines the _minimum_ interval that can be aggregated only. If hourly (`"60m"`)
132+
intervals are configured, <<rollup-search,Rollup Search>> can execute aggregations with 60m or greater (weekly, monthly, etc) intervals.
133133
So define the interval as the smallest unit that you wish to later query.
134134

135135
Note: smaller, more granular intervals take up proportionally more space.
@@ -148,6 +148,46 @@ The `date_histogram` group has several parameters:
148148
to be stored with a specific timezone. By default, rollup documents are stored in `UTC`, but this can be changed with the `time_zone`
149149
parameter.
150150

151+
.Calendar vs Fixed time intervals
152+
**********************************
153+
Elasticsearch understands both "calendar" and "fixed" time intervals. Fixed time intervals are fairly easy to understand;
154+
`"60s"` means sixty seconds. But what does `"1M` mean? One month of time depends on which month we are talking about,
155+
some months are longer or shorter than others. This is an example of "calendar" time, and the duration of that unit
156+
depends on context. Calendar units are also affected by leap-seconds, leap-years, etc.
157+
158+
This is important because the buckets generated by Rollup will be in either calendar or fixed intervals, and will limit
159+
how you can query them later (see <<rollup-search-limitations-intervals, Requests must be multiples of the config>>.
160+
161+
We recommend sticking with "fixed" time intervals, since they are easier to understand and are more flexible at query
162+
time. It will introduce some drift in your data during leap-events, and you will have to think about months in a fixed
163+
quantity (30 days) instead of the actual calendar length... but it is often easier than dealing with calendar units
164+
at query time.
165+
166+
Multiples of units are always "fixed" (e.g. `"2h"` is always the fixed quantity `7200` seconds. Single units can be
167+
fixed or calendar depending on the unit:
168+
169+
[options="header"]
170+
|=======
171+
|Unit |Calendar |Fixed
172+
|millisecond |NA |`1ms`, `10ms`, etc
173+
|second |NA |`1s`, `10s`, etc
174+
|minute |`1m` |`2m`, `10m`, etc
175+
|hour |`1h` |`2h`, `10h`, etc
176+
|day |`1d` |`2d`, `10d`, etc
177+
|week |`1w` |NA
178+
|month |`1M` |NA
179+
|quarter |`1q` |NA
180+
|year |`1y` |NA
181+
|=======
182+
183+
For some units where there are both fixed and calendar, you may need to express the quantity in terms of the next
184+
smaller unit. For example, if you want a fixed day (not a calendar day), you should specify `24h` instead of `1d`.
185+
Similarly, if you want fixed hours, specify `60m` instead of `1h`. This is because the single quantity entails
186+
calendar time, and limits you to querying by calendar time in the future.
187+
188+
189+
**********************************
190+
151191
===== Terms
152192

153193
The `terms` group can be used on `keyword` or numeric fields, to allow bucketing via the `terms` aggregation at a later point. The `terms`

x-pack/docs/en/rollup/rollup-getting-started.asciidoc

Lines changed: 62 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ PUT _xpack/rollup/job/sensor
3737
"groups" : {
3838
"date_histogram": {
3939
"field": "timestamp",
40-
"interval": "1h",
41-
"delay": "7d"
40+
"interval": "60m"
4241
},
4342
"terms": {
4443
"fields": ["node"]
@@ -66,7 +65,7 @@ The `cron` parameter controls when and how often the job activates. When a roll
6665
from where it left off after the last activation. So if you configure the cron to run every 30 seconds, the job will process the last 30
6766
seconds worth of data that was indexed into the `sensor-*` indices.
6867

69-
If instead the cron was configured to run once a day at midnight, the job would process the last 24hours worth of data. The choice is largely
68+
If instead the cron was configured to run once a day at midnight, the job would process the last 24 hours worth of data. The choice is largely
7069
preference, based on how "realtime" you want the rollups, and if you wish to process continuously or move it to off-peak hours.
7170

7271
Next, we define a set of `groups` and `metrics`. The metrics are fairly straightforward: we want to save the min/max/sum of the `temperature`
@@ -79,7 +78,7 @@ It also allows us to run terms aggregations on the `node` field.
7978
.Date histogram interval vs cron schedule
8079
**********************************
8180
You'll note that the job's cron is configured to run every 30 seconds, but the date_histogram is configured to
82-
rollup at hourly intervals. How do these relate?
81+
rollup at 60 minute intervals. How do these relate?
8382
8483
The date_histogram controls the granularity of the saved data. Data will be rolled up into hourly intervals, and you will be unable
8584
to query with finer granularity. The cron simply controls when the process looks for new data to rollup. Every 30 seconds it will see
@@ -223,70 +222,71 @@ Which returns a corresponding response:
223222
[source,js]
224223
----
225224
{
226-
"took" : 93,
227-
"timed_out" : false,
228-
"terminated_early" : false,
229-
"_shards" : ... ,
230-
"hits" : {
231-
"total" : 0,
232-
"max_score" : 0.0,
233-
"hits" : [ ]
234-
},
235-
"aggregations" : {
236-
"timeline" : {
237-
"meta" : { },
238-
"buckets" : [
239-
{
240-
"key_as_string" : "2018-01-18T00:00:00.000Z",
241-
"key" : 1516233600000,
242-
"doc_count" : 6,
243-
"nodes" : {
244-
"doc_count_error_upper_bound" : 0,
245-
"sum_other_doc_count" : 0,
246-
"buckets" : [
247-
{
248-
"key" : "a",
249-
"doc_count" : 2,
250-
"max_temperature" : {
251-
"value" : 202.0
252-
},
253-
"avg_voltage" : {
254-
"value" : 5.1499998569488525
255-
}
256-
},
257-
{
258-
"key" : "b",
259-
"doc_count" : 2,
260-
"max_temperature" : {
261-
"value" : 201.0
262-
},
263-
"avg_voltage" : {
264-
"value" : 5.700000047683716
265-
}
266-
},
267-
{
268-
"key" : "c",
269-
"doc_count" : 2,
270-
"max_temperature" : {
271-
"value" : 202.0
272-
},
273-
"avg_voltage" : {
274-
"value" : 4.099999904632568
275-
}
276-
}
277-
]
278-
}
279-
}
280-
]
281-
}
282-
}
225+
"took" : 93,
226+
"timed_out" : false,
227+
"terminated_early" : false,
228+
"_shards" : ... ,
229+
"hits" : {
230+
"total" : 0,
231+
"max_score" : 0.0,
232+
"hits" : [ ]
233+
},
234+
"aggregations" : {
235+
"timeline" : {
236+
"meta" : { },
237+
"buckets" : [
238+
{
239+
"key_as_string" : "2018-01-18T00:00:00.000Z",
240+
"key" : 1516233600000,
241+
"doc_count" : 6,
242+
"nodes" : {
243+
"doc_count_error_upper_bound" : 0,
244+
"sum_other_doc_count" : 0,
245+
"buckets" : [
246+
{
247+
"key" : "a",
248+
"doc_count" : 2,
249+
"max_temperature" : {
250+
"value" : 202.0
251+
},
252+
"avg_voltage" : {
253+
"value" : 5.1499998569488525
254+
}
255+
},
256+
{
257+
"key" : "b",
258+
"doc_count" : 2,
259+
"max_temperature" : {
260+
"value" : 201.0
261+
},
262+
"avg_voltage" : {
263+
"value" : 5.700000047683716
264+
}
265+
},
266+
{
267+
"key" : "c",
268+
"doc_count" : 2,
269+
"max_temperature" : {
270+
"value" : 202.0
271+
},
272+
"avg_voltage" : {
273+
"value" : 4.099999904632568
274+
}
275+
}
276+
]
277+
}
278+
}
279+
]
280+
}
281+
}
283282
}
283+
284284
----
285285
// TESTRESPONSE[s/"took" : 93/"took" : $body.$_path/]
286286
// TESTRESPONSE[s/"_shards" : \.\.\. /"_shards" : $body.$_path/]
287287

288288
In addition to being more complicated (date histogram and a terms aggregation, plus an additional average metric), you'll notice
289-
the date_histogram uses a `7d` interval instead of `1h`.
289+
the date_histogram uses a `7d` interval instead of `60m`.
290290

291291
[float]
292292
=== Conclusion

x-pack/docs/en/rollup/rollup-search-limitations.asciidoc

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,25 @@ The response will tell you that the field and aggregation were not possible, bec
8080
[float]
8181
=== Interval Granularity
8282

83-
Rollups are stored at a certain granularity, as defined by the `date_histogram` group in the configuration. If data is rolled up at hourly
84-
intervals, the <<rollup-search>> API can aggregate on any time interval hourly or greater. Intervals that are less than an hour will throw
85-
an exception, since the data simply doesn't exist for finer granularities.
83+
Rollups are stored at a certain granularity, as defined by the `date_histogram` group in the configuration. This means you
84+
can only search/aggregate the rollup data with an interval that is greater-than or equal to the configured rollup interval.
85+
86+
For example, if data is rolled up at hourly intervals, the <<rollup-search>> API can aggregate on any time interval
87+
hourly or greater. Intervals that are less than an hour will throw an exception, since the data simply doesn't
88+
exist for finer granularities.
89+
90+
[[rollup-search-limitations-intervals]]
91+
.Requests must be multiples of the config
92+
**********************************
93+
Perhaps not immediately apparent, but the interval specified in an aggregation request must be a whole
94+
multiple of the configured interval. If the job was configured to rollup on `3d` intervals, you can only
95+
query and aggregate on multiples of three (`3d`, `6d`, `9d`, etc).
96+
97+
A non-multiple wouldn't work, since the rolled up data wouldn't cleanly "overlap" with the buckets generated
98+
by the aggregation, leading to incorrect results.
99+
100+
For that reason, an error is thrown if a whole multiple of the configured interval isn't found.
101+
**********************************
86102

87103
Because the RollupSearch endpoint can "upsample" intervals, there is no need to configure jobs with multiple intervals (hourly, daily, etc).
88104
It's recommended to just configure a single job with the smallest granularity that is needed, and allow the search endpoint to upsample

0 commit comments

Comments
 (0)