滚动历史数据
edit滚动历史数据
edit保留用于分析的历史数据非常有用,但由于存档大量数据的财务成本,通常会被避免。因此,保留期限是由财务现实驱动的,而不是由广泛历史数据的实用性驱动的。
Elastic Stack 数据汇总功能提供了一种方法来汇总和存储历史数据,以便它仍然可以用于分析,但存储成本仅为原始数据的一小部分。
Rollup 概述
edit基于时间的数据(主要通过时间戳标识的文档)通常有相关的保留策略来管理数据增长。例如,您的系统可能每秒生成500个文档。这将每天生成4300万份文档,每年接近160亿份文档。
虽然您的分析师和数据科学家可能希望您无限期地存储这些数据以供分析,但时间是无止境的,因此您的存储需求将继续无限制地增长。因此,保留策略通常由存储成本随时间的简单计算决定,以及组织愿意为保留历史数据支付的费用。通常,这些策略会在几个月或几年后开始删除数据。
存储成本是一个固定的量。存储Y数据需要X金钱。但数据的价值通常会随时间变化。以毫秒粒度收集的传感器数据现在非常有用,如果是几周前的数据则还算有用,而如果是几个月前的数据则只有边际价值。
因此,尽管存储十年前一毫秒传感器数据的成本是固定的,但该个别传感器读数的价值通常会随着时间的推移而降低。它并非毫无用处——它可能很容易为有用的分析做出贡献——但其价值的降低通常导致删除而不是支付固定的存储成本。
Rollup 以降低的粒度存储历史数据
edit这就是Rollup发挥作用的地方。Rollup功能将旧的、高粒度数据汇总为减少粒度的格式,以便长期存储。通过将数据“汇总”到一个汇总文档中,历史数据可以比原始数据大大压缩。
例如,考虑一个每天生成4300万份文档的系统。每秒的数据对于实时分析是有用的,但对于查看十年数据的历史分析,可能会在更大的时间间隔上进行,例如每小时或每日的趋势。
如果我们把4300万份文档压缩成每小时的摘要,我们可以节省大量的空间。Rollup功能自动执行汇总历史数据的过程。
关于设置和配置Rollup的详细信息,请参阅创建任务API。
Rollup 使用标准查询DSL
editRollup 功能提供了一个新的搜索端点(/_rollup_search 与标准的 /_search 相对),该端点知道如何搜索汇总数据。重要的是,此端点接受 100% 标准的 Elasticsearch 查询 DSL。您的应用程序不需要学习新的 DSL 来检查历史数据,它可以简单地重用现有的查询和仪表板。
功能上存在一些限制;并非所有查询和聚合都受支持,某些搜索功能(如高亮显示等)被禁用,可用字段取决于汇总配置的方式。这些限制在汇总搜索限制中有更详细的介绍。
但如果您的查询、聚合和仪表板仅使用可用功能,将它们重定向到历史数据是非常简单的。
汇总合并“实时”和“汇总”数据
editRollup 的一个有用功能是能够在单个查询中同时查询“实时”的实时数据和历史的“汇总”数据。
例如,您的系统可能会保留一个月的原始数据。一个月后,使用Rollup将其汇总为历史摘要,并删除原始数据。
如果您查询原始数据,您只会看到最近一个月的数据。而如果您查询汇总数据,您只会看到一个月前的数据。然而,RollupSearch 端点支持同时查询两者。它将获取两个数据源的结果并将它们合并在一起。如果“实时”数据和“汇总”数据之间存在重叠,则优先选择实时数据以提高准确性。
Rollup 支持多区间感知
edit最后,Rollup 能够智能地利用可用的最佳时间间隔。如果你曾经使用过其他产品的汇总功能,你会发现它们可能会有所限制。如果你以每日间隔配置汇总…你的查询和图表只能使用每日间隔。如果你需要每月间隔,你必须创建另一个明确存储每月平均值等的汇总。
Rollup 功能以一种方式存储数据,使得查询可以识别最小的可用间隔并使用它进行处理。如果你以每日间隔存储汇总数据,查询可以在每日或更长的时间间隔(每周、每月等)上执行,而无需显式配置新的汇总作业。这有助于缓解汇总系统的一个主要缺点;相对于原始数据的灵活性降低。
Rollup API 快速参考
edit大多数汇总端点具有以下基础:
/_rollup/
/作业/
edit-
PUT /_rollup/job/
: 创建一个汇总任务 - GET /_rollup/job: 列出汇总任务
-
GET /_rollup/job/
: 获取汇总任务详情 -
POST /_rollup/job/
/_start : 启动一个汇总任务 -
POST /_rollup/job/
/_stop : 停止一个汇总任务 -
DELETE /_rollup/job/
: 删除一个汇总任务
/数据/
edit-
GET /_rollup/data/
/_rollup_caps : 获取汇总功能 -
GET /
/_rollup/data/ : 获取汇总索引功能
//
edit-
GET /
/_rollup_search : 搜索汇总数据
开始使用rollups
edit从8.15.0版本开始,在没有汇总使用的集群中调用put job API将会失败,并显示关于汇总的弃用和计划移除的消息。集群需要包含一个汇总作业或汇总索引,才能允许执行put job API。
要使用汇总功能,您需要创建一个或多个“汇总作业”。这些作业在后台持续运行,并对您指定的索引进行汇总,将汇总后的文档放置在您选择的二级索引中。
假设你有一系列包含传感器数据的每日索引(sensor-2017-01-01、sensor-2017-01-02等)。一个示例文档可能看起来像这样:
{
"timestamp": 1516729294000,
"temperature": 200,
"voltage": 5.2,
"node": "a"
}
创建一个汇总任务
edit我们希望将这些文档汇总为每小时的摘要,这将使我们能够生成报告和仪表板,时间间隔为一小时或更长。汇总作业可能如下所示:
PUT _rollup/job/sensor
{
"index_pattern": "sensor-*",
"rollup_index": "sensor_rollup",
"cron": "*/30 * * * * ?",
"page_size": 1000,
"groups": {
"date_histogram": {
"field": "timestamp",
"fixed_interval": "60m"
},
"terms": {
"fields": [ "node" ]
}
},
"metrics": [
{
"field": "temperature",
"metrics": [ "min", "max", "sum" ]
},
{
"field": "voltage",
"metrics": [ "avg" ]
}
]
}
我们将任务的ID设置为“sensor”(在URL中:PUT _rollup/job/sensor),并告诉它汇总索引模式 "sensor-*"。
此任务将查找并汇总任何匹配该模式的索引。汇总摘要随后存储在 "sensor_rollup" 索引中。
参数 cron 控制作业何时以及多久激活一次。当滚动作业的 cron 计划触发时,它将从上次激活后的停止位置开始滚动。因此,如果您将 cron 配置为每 30 秒运行一次,作业将处理索引到 sensor-* 索引中的最近 30 秒的数据。
如果cron配置为每天午夜运行一次,该作业将处理过去24小时的数据。选择主要取决于您希望汇总数据的“实时性”,以及您是否希望连续处理或将处理时间移至非高峰时段。
接下来,我们定义一组groups。本质上,我们是在定义我们希望在将来查询数据时进行透视的维度。在这个作业中的分组允许我们对timestamp字段使用date_histogram聚合,按每小时间隔进行汇总。它还允许我们对node字段运行术语聚合。
在定义了应该为数据生成哪些组之后,接下来配置应该收集哪些指标。默认情况下,仅为每个组收集doc_counts。为了使汇总功能有用,您通常会添加诸如平均值、最小值、最大值等指标。在这个例子中,指标相当简单:我们希望保存temperature字段的最小值/最大值/总和,以及voltage字段的平均值。
有关作业语法的更多详细信息,请参阅创建汇总作业。
执行上述命令并创建作业后,您将收到以下响应:
{
"acknowledged": true
}
启动任务
edit作业创建后,它将处于非活动状态。作业需要启动后才能开始处理数据(这允许您稍后停止它们作为一种临时暂停的方式,而无需删除配置)。
要启动任务,请执行此命令:
POST _rollup/job/sensor/_start
搜索滚动结果
edit在作业运行并处理了一些数据后,我们可以使用Rollup search端点进行一些搜索。Rollup功能的设计目的是让您可以使用您习惯的相同Query DSL语法……它只是恰好运行在汇总的数据上。
例如,考虑这个查询:
GET /sensor_rollup/_rollup_search
{
"size": 0,
"aggregations": {
"max_temperature": {
"max": {
"field": "temperature"
}
}
}
}
这是一个简单的聚合,用于计算temperature字段的最大值。但你会注意到,它被发送到sensor_rollup索引,而不是原始的sensor-*索引。你还会注意到,它使用了_rollup_search端点。否则,语法与你预期的一样。
如果您执行该查询,您将收到一个看起来像正常聚合响应的结果:
{
"took" : 102,
"timed_out" : false,
"terminated_early" : false,
"_shards" : ... ,
"hits" : {
"total" : {
"value": 0,
"relation": "eq"
},
"max_score" : 0.0,
"hits" : [ ]
},
"aggregations" : {
"max_temperature" : {
"value" : 202.0
}
}
}
唯一显著的区别是,Rollup 搜索结果的 hits 为零,因为我们不再真正搜索原始的实时数据。否则语法是相同的。
这里有几个有趣的要点。首先,尽管数据是以每小时的时间间隔汇总并按节点名称分区的,但我们运行的查询只是计算所有文档中的最高温度。在作业中配置的groups并不是查询的强制元素,它们只是你可以分区的额外维度。其次,请求和响应的语法几乎与普通的DSL相同,这使得它很容易集成到仪表板和应用程序中。
最后,我们可以使用我们定义的分组字段来构建一个更复杂的查询:
GET /sensor_rollup/_rollup_search
{
"size": 0,
"aggregations": {
"timeline": {
"date_histogram": {
"field": "timestamp",
"fixed_interval": "7d"
},
"aggs": {
"nodes": {
"terms": {
"field": "node"
},
"aggs": {
"max_temperature": {
"max": {
"field": "temperature"
}
},
"avg_voltage": {
"avg": {
"field": "voltage"
}
}
}
}
}
}
}
}
返回相应的响应:
{
"took" : 93,
"timed_out" : false,
"terminated_early" : false,
"_shards" : ... ,
"hits" : {
"total" : {
"value": 0,
"relation": "eq"
},
"max_score" : 0.0,
"hits" : [ ]
},
"aggregations" : {
"timeline" : {
"buckets" : [
{
"key_as_string" : "2018-01-18T00:00:00.000Z",
"key" : 1516233600000,
"doc_count" : 6,
"nodes" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "a",
"doc_count" : 2,
"max_temperature" : {
"value" : 202.0
},
"avg_voltage" : {
"value" : 5.1499998569488525
}
},
{
"key" : "b",
"doc_count" : 2,
"max_temperature" : {
"value" : 201.0
},
"avg_voltage" : {
"value" : 5.700000047683716
}
},
{
"key" : "c",
"doc_count" : 2,
"max_temperature" : {
"value" : 202.0
},
"avg_voltage" : {
"value" : 4.099999904632568
}
}
]
}
}
]
}
}
}
除了更复杂(日期直方图和术语聚合,加上一个额外的平均指标)之外,您还会注意到date_histogram使用了7d间隔,而不是60m。
结论
edit本快速入门应已提供对Rollup所暴露的核心功能的简明概述。在设置Rollups时,还有更多提示和事项需要考虑,您可以在本节的其余部分找到这些内容。您还可以探索REST API,以了解可用的内容概述。
理解组
edit为了保持灵活性,Rollup Jobs 是基于未来查询可能需要如何使用数据来定义的。传统上,系统会强制管理员做出关于要汇总哪些指标以及在什么时间间隔内进行汇总的决定。例如,按小时计算的 cpu_time 的平均值。这是有局限性的;如果将来管理员希望按小时查看 cpu_time 的平均值 并且 按 host_name 进行分区,他们就无能为力了。
当然,管理员可以决定按小时为基础对[小时, 主机]元组进行汇总,但随着分组键数量的增加,管理员需要配置的元组数量也随之增加。此外,这些[小时, 主机]元组仅对每小时汇总有用……每日、每周或每月的汇总都需要新的配置。
与其强迫管理员提前决定哪些单独的元组应该被汇总,Elasticsearch 的汇总作业是根据哪些组可能对未来的查询有用而配置的。例如,这个配置:
"groups" : {
"date_histogram": {
"field": "timestamp",
"fixed_interval": "1h",
"delay": "7d"
},
"terms": {
"fields": ["hostname", "datacenter"]
},
"histogram": {
"fields": ["load", "net_in", "net_out"],
"interval": 5
}
}
允许在"timestamp"字段上使用date_histogram,在"hostname"和"datacenter"字段上使用terms聚合,并在"load"、"net_in"、"net_out"字段上使用histograms。
重要的是,这些聚合/字段可以以任何组合方式使用。这个聚合:
"aggs" : {
"hourly": {
"date_histogram": {
"field": "timestamp",
"fixed_interval": "1h"
},
"aggs": {
"host_names": {
"terms": {
"field": "hostname"
}
}
}
}
}
与以下聚合同样有效:
"aggs" : {
"hourly": {
"date_histogram": {
"field": "timestamp",
"fixed_interval": "1h"
},
"aggs": {
"data_center": {
"terms": {
"field": "datacenter"
}
},
"aggs": {
"host_names": {
"terms": {
"field": "hostname"
}
},
"aggs": {
"load_values": {
"histogram": {
"field": "load",
"interval": 5
}
}
}
}
}
}
}
你会注意到,第二个聚合不仅明显更大,而且还将术语聚合的位置交换到了"hostname"上,说明了聚合的顺序对汇总没有影响。同样,虽然date_histogram在汇总数据时是必需的,但在查询时并不需要(尽管经常使用)。例如,这是一个有效的聚合,供Rollup Search执行:
"aggs" : {
"host_names": {
"terms": {
"field": "hostname"
}
}
}
最终,在为作业配置groups时,请考虑您可能希望在未来某个日期在查询中如何分区数据……
然后在配置中包含这些内容。因为Rollup Search允许任何顺序或组合的分组字段,您只需要决定
一个字段是否对以后的聚合有用,以及您可能希望如何使用它(术语、直方图等)。
日历与固定时间间隔
edit每个rollup-job必须有一个定义了间隔的日期直方图组。Elasticsearch理解日历和固定时间间隔。固定时间间隔相当容易理解;60s表示六十秒。但1M是什么意思呢?一个月的时间取决于我们谈论的是哪个月,有些月份比其他月份长或短。这是日历时间的例子,该单位的时间长度取决于上下文。日历单位也受到闰秒、闰年等的影响。
这一点很重要,因为由rollup生成的桶要么是日历间隔,要么是固定间隔,这限制了你以后如何查询它们。请参阅 请求必须是配置的倍数。
我们建议坚持使用固定的时间间隔,因为它们更容易理解和在查询时更具灵活性。在闰年事件期间,它会在您的数据中引入一些漂移,并且您必须以固定数量(30天)来考虑月份,而不是实际的日历长度。然而,这通常比在查询时处理日历单位更容易。
单位的倍数总是“固定的”。例如,2h 总是固定数量 7200 秒。单个单位可以是固定的或日历的,具体取决于单位:
| Unit | Calendar | Fixed |
|---|---|---|
毫秒 |
NA |
|
第二 |
NA |
|
分钟 |
|
|
小时 |
|
|
天 |
|
|
周 |
|
NA |
月份 |
|
NA |
季度 |
|
NA |
年 |
|
NA |
对于某些既有固定时间又有日历时间的单位,您可能需要用下一个较小的单位来表示数量。例如,如果您想要一个固定的天(而不是日历天),您应该指定 24h 而不是 1d。同样,如果您想要固定的小时,请指定 60m 而不是 1h。这是因为单个数量涉及日历时间,并且限制了您在未来只能通过日历时间进行查询。
具有异构索引的分组限制
edit之前,Rollup 在处理具有异构映射(多个不相关/不重叠的映射)的索引时存在限制。当时的建议是为每种数据“类型”配置一个单独的作业。例如,您可能为每个已启用的 Beats 模块配置一个单独的作业(一个用于 process,另一个用于 filesystem,等等)。
这一建议是由于内部实现细节导致的,如果使用单个“合并”作业,可能会导致文档计数不准确。
这一限制自那时起已被缓解。自6.4.0版本起,现在被认为是最佳实践,将所有汇总配置合并到一个作业中。
例如,如果你的索引有两种类型的文档:
{
"timestamp": 1516729294000,
"temperature": 200,
"voltage": 5.2,
"node": "a"
}
和
{
"timestamp": 1516729294000,
"price": 123,
"title": "Foo"
}
最佳实践是将它们合并到一个涵盖这两种文档类型的汇总作业中,如下所示:
PUT _rollup/job/combined
{
"index_pattern": "data-*",
"rollup_index": "data_rollup",
"cron": "*/30 * * * * ?",
"page_size": 1000,
"groups": {
"date_histogram": {
"field": "timestamp",
"fixed_interval": "1h",
"delay": "7d"
},
"terms": {
"fields": [ "node", "title" ]
}
},
"metrics": [
{
"field": "temperature",
"metrics": [ "min", "max", "sum" ]
},
{
"field": "price",
"metrics": [ "avg" ]
}
]
}
文档计数和重叠作业
edit之前在“重叠”作业配置的文档计数上存在一个问题,这是由相同的内部实现细节驱动的。如果两个汇总作业保存到同一个索引中,其中一个作业是另一个作业的“子集”,那么在某些聚合排列下,文档计数可能会不正确。
此问题在6.4.0版本中也已被消除。
汇总聚合限制
edit字段在汇总/聚合时存在一些限制。本页面重点介绍了主要的限制,以便您了解这些限制。
有限的聚合组件
edit汇总功能允许字段按以下聚合方式进行分组:
- 日期直方图聚合
- 直方图聚合
- 词条聚合
以下指标允许为数值字段指定:
- 最小值聚合
- 最大值聚合
- 求和聚合
- 平均值聚合
- 值计数聚合
汇总搜索限制
edit虽然我们认为Rollup函数非常灵活,但汇总数据的性质意味着会有一些限制。一旦实时数据被丢弃,您将始终失去一些灵活性。
本页面重点介绍了主要限制,以便您了解这些限制。
每个搜索仅一个汇总索引
edit在使用Rollup search端点时,index参数接受一个或多个索引。这些可以是常规的、非汇总索引和汇总索引的混合。但是,只能指定一个汇总索引。index参数的确切规则列表如下:
-
必须指定至少一个索引/索引模式。这可以是滚动索引或非滚动索引。省略索引参数,或使用
_all,是不允许的 - 可以指定多个非滚动索引
- 只能指定一个滚动索引。如果提供了多个,将抛出异常
- 可以使用索引模式,但如果它们匹配多个滚动索引,将抛出异常。
这一限制是由决定哪些作业是任何给定查询的“最佳”作业的逻辑驱动的。如果你在一个索引中存储了十个作业,这些作业以不同程度的完整性和不同的时间间隔覆盖了源数据,查询需要确定实际搜索哪些作业集合。错误的决定可能导致不准确的聚合结果(例如,文档计数过多,或指标不佳)。不用说,这是一段技术上具有挑战性的代码。
为了简化问题,我们已将搜索限制为一次仅一个汇总索引(其中可能包含多个作业)。未来我们可能会开放到多个汇总作业。
只能聚合已存储的内容
edit一个或许显而易见的限制,但rollups只能对已经存储在rollups中的数据进行聚合。如果你没有配置rollup作业来存储关于price字段的指标,你将无法在任何查询或聚合中使用price字段。
例如,以下查询中的 temperature 字段已存储在汇总作业中……但没有使用 avg 指标。这意味着在此处使用 avg 是不允许的:
GET sensor_rollup/_rollup_search
{
"size": 0,
"aggregations": {
"avg_temperature": {
"avg": {
"field": "temperature"
}
}
}
}
响应将告知您该字段和聚合是不可能的,因为没有找到包含它们的汇总作业:
{
"error": {
"root_cause": [
{
"type": "illegal_argument_exception",
"reason": "There is not a rollup job that has a [avg] agg with name [avg_temperature] which also satisfies all requirements of query.",
"stack_trace": ...
}
],
"type": "illegal_argument_exception",
"reason": "There is not a rollup job that has a [avg] agg with name [avg_temperature] which also satisfies all requirements of query.",
"stack_trace": ...
},
"status": 400
}
间隔粒度
edit汇总数据以配置中date_histogram组定义的特定粒度存储。这意味着您只能以大于或等于配置的汇总间隔的间隔来搜索/聚合汇总数据。
例如,如果数据是以每小时为间隔进行汇总,汇总搜索 API 可以在任何时间间隔(每小时或更长)上进行聚合。小于一小时的间隔将会抛出异常,因为数据在更细粒度上根本不存在。
由于RollupSearch端点可以“上采样”间隔,因此无需配置具有多个间隔(每小时、每天等)的任务。 建议仅配置一个具有所需最小粒度的任务,并允许搜索端点根据需要进行上采样。
也就是说,如果在一个汇总索引中存在多个具有不同间隔的任务,搜索端点将识别并使用具有最大间隔的任务来满足搜索请求。
有限的查询组件
editRollup 功能允许在搜索请求中使用 query,但仅限于部分组件。目前允许的查询包括:
- 术语查询
- 术语查询
- 范围查询
- 匹配所有查询
- 任何复合查询(布尔、提升、常数分数等)
此外,这些查询只能使用在汇总作业中作为group保存的字段。
如果您希望对关键字hostname字段进行过滤,则该字段必须在terms分组下的汇总作业中进行配置。
如果你尝试使用一个不支持的查询,或者查询引用了在汇总作业中未配置的字段,将会抛出一个异常。我们预计随着更多查询的实现,支持的查询列表将会逐渐增加。
时区
edit汇总文档存储在作业中date_histogram组配置的时区中。如果未指定时区,默认情况下会在UTC时区汇总时间戳。
从 Rollup 迁移到降采样
editRollup和下采样是两种不同的功能,允许对历史指标进行汇总。 从高层次来看,Rollup比下采样更灵活,但下采样是一个更稳健且更容易实现指标下采样的功能。
以下降采样的方面更容易或更稳健:
- 无需安排作业。下采样与索引生命周期管理(ILM)和数据流生命周期(DSL)集成。
- 没有单独的搜索API。可以通过搜索API和es|ql访问下采样索引。
- 没有单独的汇总配置。下采样使用映射中的时间序列维度和度量配置。
并非所有汇总使用场景都可以迁移到降采样。主要要求是数据应存储在Elasticsearch中作为时间序列数据流 (TSDS)。基本上通过时间和所有维度汇总数据的汇总使用场景可以迁移到降采样。
一个可以迁移到下采样的汇总使用示例:
PUT _rollup/job/sensor
{
"index_pattern": "sensor-*",
"rollup_index": "sensor_rollup",
"cron": "0 0 * * * *",
"page_size": 1000,
"groups": {
"date_histogram": {
"field": "timestamp",
"fixed_interval": "60m"
},
"terms": {
"fields": [ "node" ]
}
},
"metrics": [
{
"field": "temperature",
"metrics": [ "min", "max", "sum" ]
},
{
"field": "voltage",
"metrics": [ "avg" ]
}
]
}
使用通过DSL进行下采样的等效时间序列数据流 (TSDS)设置:
PUT _index_template/sensor-template
{
"index_patterns": ["sensor-*"],
"data_stream": { },
"template": {
"lifecycle": {
"downsampling": [
{
"after": "1d",
"fixed_interval": "1h"
}
]
},
"settings": {
"index.mode": "time_series"
},
"mappings": {
"properties": {
"node": {
"type": "keyword",
"time_series_dimension": true
},
"temperature": {
"type": "half_float",
"time_series_metric": "gauge"
},
"voltage": {
"type": "half_float",
"time_series_metric": "gauge"
},
"@timestamp": {
"type": "date"
}
}
}
}
}
降采样配置包含在上述模板中,用于时间序列数据流 (TSDS)。
仅需要downsampling部分来启用降采样,该部分指示何时将数据降采样到固定的时间间隔。
|
在汇总作业中, |
|
|
在汇总作业中, |
|
|
在汇总作业中, |
|
|
在汇总作业中, |