Link Search Menu Expand Document Documentation Menu

索引汇总

时间序列数据会随着时间的推移增加存储成本,给集群健康带来压力,并减慢聚合速度。索引汇总允许您通过将旧数据汇总到摘要索引中,定期降低数据粒度。

您可以选择您感兴趣的字段,并使用索引汇总创建一个新索引,该索引仅将这些字段聚合到更粗粒度的时间桶中。您可以以一小部分成本存储数月或数年的历史数据,同时保持相同的查询性能。

例如,假设您每五秒收集一次 CPU 消耗数据并将其存储在热节点上。您可以不将旧数据移动到只读温节点,而是汇总或压缩这些数据,只保留每天的平均 CPU 消耗量,或者每周将其间隔减少 10%。

您可以通过三种方式使用索引汇总

  1. 对于按需索引汇总作业,请使用索引汇总 API,该作业在未主动摄取的索引(例如已轮转的索引)上运行。例如,您可以执行索引汇总操作,将以五分钟间隔收集的数据缩减为每周平均值,用于趋势分析。
  2. 使用 OpenSearch Dashboards UI 创建按预定计划运行的索引汇总作业。您还可以将其设置为在索引主动摄取时进行汇总。例如,您可以将 Logstash 索引从五秒间隔连续汇总到一小时间隔。
  3. 将索引汇总作业指定为 ISM 操作以进行完整的索引管理。这允许您在特定事件(例如轮转、索引达到特定年龄、索引变为只读等)后汇总索引。您还可以让轮转和索引汇总作业按顺序运行,其中轮转首先将当前索引移动到温节点,然后索引汇总作业在热节点上使用最小化数据创建一个新索引。

创建索引汇总作业

要开始使用,请在 OpenSearch Dashboards 中选择 索引管理。选择 汇总作业,然后选择 创建汇总作业

步骤 1:设置索引

  1. 作业名称和描述部分,为索引汇总作业指定一个唯一的名称和可选的描述。
  2. 索引部分,选择源索引和目标索引。源索引是您要汇总的索引。源索引保持不变,索引汇总作业会创建一个新索引,称为目标索引。目标索引是保存索引汇总结果的地方。对于目标索引,您可以键入一个新索引的名称,也可以选择一个现有索引。
  3. 选择下一步

创建索引汇总作业后,您无法更改索引选择。

步骤 2:定义聚合和指标

选择您要汇总的具有聚合(术语和直方图)和指标(平均值、总和、最大值、最小值和值计数)的属性。确保不要添加太多高粒度属性,因为那样您将无法节省太多空间。

例如,考虑一个包含城市及其人口统计数据的数据集。您可以基于城市进行聚合,并将城市内的人口统计数据指定为指标。您选择属性的顺序至关重要。一个城市后跟一个人口统计数据与一个人口统计数据后跟一个城市是不同的。

  1. 时间聚合部分,选择一个时间戳字段。在固定日历间隔类型之间选择,并指定间隔和时区。索引汇总作业使用此信息为时间戳字段创建日期直方图。
  2. (可选)为每个字段添加额外的聚合。您可以为所有字段类型选择术语聚合,并且仅为数值字段选择直方图聚合。
  3. (可选)为每个字段添加额外的指标。您可以选择所有最小值最大值总和平均值值计数
  4. 选择下一步

步骤 3:指定计划

指定在索引摄取时汇总索引的计划。索引汇总作业默认启用。

  1. 指定数据是否连续。
  2. 对于汇总执行频率,选择按固定间隔定义并指定汇总间隔和时间单位,或按 cron 表达式定义并添加 cron 表达式以选择间隔。要了解如何定义 cron 表达式,请参阅警报
  3. 指定每个执行过程的页面数。数量越大意味着执行速度越快,但内存成本也越高。
  4. (可选)为汇总执行添加延迟。这是作业等待数据摄取以适应任何处理时间的时间量。例如,如果您将此值设置为 10 分钟,则一个在下午 2 点执行以汇总下午 1 点到下午 2 点数据的索引汇总将在下午 2:10 开始执行。
  5. 选择下一步

步骤 4:审查和创建

审查您的配置并选择创建

步骤 5:搜索目标索引

您可以使用标准 _search API 搜索目标索引。确保查询与目标索引的约束条件匹配。例如,如果您没有在某个字段上设置术语聚合,则不会收到术语聚合的结果。如果您没有设置最大聚合,则不会收到最大聚合的结果。

您无法访问目标索引中数据的内部结构,因为插件会在后台自动重写查询以适应目标索引。这是为了确保您可以对源索引和目标索引使用相同的查询。

要查询目标索引,请将 size 设置为 0

GET target_index/_search
{
  "size": 0,
  "query": {
    "match_all": {}
  },
  "aggs": {
    "avg_cpu": {
      "avg": {
        "field": "cpu_usage"
      }
    }
  }
}

考虑这样一种情况:您收集下午 1 点到晚上 9 点按小时间隔汇总的数据,以及晚上 7 点到晚上 11 点按分钟间隔的实时数据。如果您在同一个查询中对这些数据执行聚合,那么在晚上 7 点到晚上 9 点期间,您会看到汇总数据和实时数据的重叠,因为它们在聚合中被计数了两次。

示例演练

本演练使用 OpenSearch Dashboards 示例电子商务数据。要添加该示例数据,请登录 OpenSearch Dashboards,选择主页尝试我们的示例数据。对于示例电子商务订单,选择添加数据

然后运行搜索

GET opensearch_dashboards_sample_data_ecommerce/_search

示例响应

{
  "took": 23,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 4675,
      "relation": "eq"
    },
    "max_score": 1,
    "hits": [
      {
        "_index": "opensearch_dashboards_sample_data_ecommerce",
        "_type": "_doc",
        "_id": "jlMlwXcBQVLeQPrkC_kQ",
        "_score": 1,
        "_source": {
          "category": [
            "Women's Clothing",
            "Women's Accessories"
          ],
          "currency": "EUR",
          "customer_first_name": "Selena",
          "customer_full_name": "Selena Mullins",
          "customer_gender": "FEMALE",
          "customer_id": 42,
          "customer_last_name": "Mullins",
          "customer_phone": "",
          "day_of_week": "Saturday",
          "day_of_week_i": 5,
          "email": "selena@mullins-family.zzz",
          "manufacturer": [
            "Tigress Enterprises"
          ],
          "order_date": "2021-02-27T03:56:10+00:00",
          "order_id": 581553,
          "products": [
            {
              "base_price": 24.99,
              "discount_percentage": 0,
              "quantity": 1,
              "manufacturer": "Tigress Enterprises",
              "tax_amount": 0,
              "product_id": 19240,
              "category": "Women's Clothing",
              "sku": "ZO0064500645",
              "taxless_price": 24.99,
              "unit_discount_amount": 0,
              "min_price": 12.99,
              "_id": "sold_product_581553_19240",
              "discount_amount": 0,
              "created_on": "2016-12-24T03:56:10+00:00",
              "product_name": "Blouse - port royal",
              "price": 24.99,
              "taxful_price": 24.99,
              "base_unit_price": 24.99
            },
            {
              "base_price": 10.99,
              "discount_percentage": 0,
              "quantity": 1,
              "manufacturer": "Tigress Enterprises",
              "tax_amount": 0,
              "product_id": 17221,
              "category": "Women's Accessories",
              "sku": "ZO0085200852",
              "taxless_price": 10.99,
              "unit_discount_amount": 0,
              "min_price": 5.06,
              "_id": "sold_product_581553_17221",
              "discount_amount": 0,
              "created_on": "2016-12-24T03:56:10+00:00",
              "product_name": "Snood - rose",
              "price": 10.99,
              "taxful_price": 10.99,
              "base_unit_price": 10.99
            }
          ],
          "sku": [
            "ZO0064500645",
            "ZO0085200852"
          ],
          "taxful_total_price": 35.98,
          "taxless_total_price": 35.98,
          "total_quantity": 2,
          "total_unique_products": 2,
          "type": "order",
          "user": "selena",
          "geoip": {
            "country_iso_code": "MA",
            "location": {
              "lon": -8,
              "lat": 31.6
            },
            "region_name": "Marrakech-Tensift-Al Haouz",
            "continent_name": "Africa",
            "city_name": "Marrakesh"
          },
          "event": {
            "dataset": "sample_ecommerce"
          }
        }
      }
    ]
  }
}
...

创建一个索引汇总作业。此示例选取 order_datecustomer_gendergeoip.city_namegeoip.region_nameday_of_week 字段,并将它们汇总到 example_rollup 目标索引中。

PUT _plugins/_rollup/jobs/example
{
  "rollup": {
    "enabled": true,
    "schedule": {
      "interval": {
        "period": 1,
        "unit": "Minutes",
        "start_time": 1602100553
      }
    },
    "last_updated_time": 1602100553,
    "description": "An example policy that rolls up the sample ecommerce data",
    "source_index": "opensearch_dashboards_sample_data_ecommerce",
    "target_index": "example_rollup",
    "page_size": 1000,
    "delay": 0,
    "continuous": false,
    "dimensions": [
      {
        "date_histogram": {
          "source_field": "order_date",
          "fixed_interval": "60m",
          "timezone": "America/Los_Angeles"
        }
      },
      {
        "terms": {
          "source_field": "customer_gender"
        }
      },
      {
        "terms": {
          "source_field": "geoip.city_name"
        }
      },
      {
        "terms": {
          "source_field": "geoip.region_name"
        }
      },
      {
        "terms": {
          "source_field": "day_of_week"
        }
      }
    ],
    "metrics": [
      {
        "source_field": "taxless_total_price",
        "metrics": [
          {
            "avg": {}
          },
          {
            "sum": {}
          },
          {
            "max": {}
          },
          {
            "min": {}
          },
          {
            "value_count": {}
          }
        ]
      },
      {
        "source_field": "total_quantity",
        "metrics": [
          {
            "avg": {}
          },
          {
            "max": {}
          }
        ]
      }
    ]
  }
}

您可以查询 example_rollup 索引,获取在汇总作业中设置的字段的术语聚合。您将获得与原始 opensearch_dashboards_sample_data_ecommerce 源索引相同的响应。

POST example_rollup/_search
{
  "size": 0,
  "query": {
    "bool": {
      "must": {"term": { "geoip.region_name": "California" } }
    }
  },
  "aggregations": {
    "daily_numbers": {
      "terms": {
        "field": "day_of_week"
      },
      "aggs": {
        "per_city": {
          "terms": {
            "field": "geoip.city_name"
          },
          "aggregations": {
            "average quantity": {
               "avg": {
                  "field": "total_quantity"
                }
              }
            }
          },
          "total_revenue": {
            "sum": {
              "field": "taxless_total_price"
          }
        }
      }
    }
  }
}

示例响应

{
  "took" : 14,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 281,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "daily_numbers" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "Friday",
          "doc_count" : 59,
          "total_revenue" : {
            "value" : 4858.84375
          },
          "per_city" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "Los Angeles",
                "doc_count" : 59,
                "average quantity" : {
                  "value" : 2.305084745762712
                }
              }
            ]
          }
        },
        {
          "key" : "Saturday",
          "doc_count" : 46,
          "total_revenue" : {
            "value" : 3547.203125
          },
          "per_city" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "Los Angeles",
                "doc_count" : 46,
                "average quantity" : {
                  "value" : 2.260869565217391
                }
              }
            ]
          }
        },
        {
          "key" : "Tuesday",
          "doc_count" : 45,
          "total_revenue" : {
            "value" : 3983.28125
          },
          "per_city" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "Los Angeles",
                "doc_count" : 45,
                "average quantity" : {
                  "value" : 2.2888888888888888
                }
              }
            ]
          }
        },
        {
          "key" : "Sunday",
          "doc_count" : 44,
          "total_revenue" : {
            "value" : 3308.1640625
          },
          "per_city" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "Los Angeles",
                "doc_count" : 44,
                "average quantity" : {
                  "value" : 2.090909090909091
                }
              }
            ]
          }
        },
        {
          "key" : "Thursday",
          "doc_count" : 40,
          "total_revenue" : {
            "value" : 2876.125
          },
          "per_city" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "Los Angeles",
                "doc_count" : 40,
                "average quantity" : {
                  "value" : 2.3
                }
              }
            ]
          }
        },
        {
          "key" : "Monday",
          "doc_count" : 38,
          "total_revenue" : {
            "value" : 2673.453125
          },
          "per_city" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "Los Angeles",
                "doc_count" : 38,
                "average quantity" : {
                  "value" : 2.1578947368421053
                }
              }
            ]
          }
        },
        {
          "key" : "Wednesday",
          "doc_count" : 38,
          "total_revenue" : {
            "value" : 3202.453125
          },
          "per_city" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "Los Angeles",
                "doc_count" : 38,
                "average quantity" : {
                  "value" : 2.236842105263158
                }
              }
            ]
          }
        }
      ]
    }
  }
}

doc_count 字段

桶聚合中的 doc_count 字段包含每个桶中收集的文档数量。在计算桶的 doc_count 时,文档数量会根据每个摘要文档中预聚合文档的数量进行递增。从汇总搜索返回的 doc_count 表示源索引中匹配文档的总数。无论您搜索源索引还是汇总目标索引,每个桶的文档计数都是相同的。

查询字符串查询

为了利用 Query DSL 中更短、更容易编写的字符串,您可以使用查询字符串来简化汇总索引中的搜索查询。要使用查询字符串,请将以下字段添加到您的汇总搜索请求中。

"query": {
      "query_string": {
          "query": "field_name:field_value"
      }
  }

以下示例使用带有 * 通配符运算符的查询字符串,在名为 my_server_logs_rollup 的汇总索引中进行搜索。

GET my_server_logs_rollup/_search
{
  "size": 0,
  "query": {
      "query_string": {
          "query": "email* OR inventory",
          "default_field": "service_name"
      }
  },  
  
  "aggs": {
    "service_name": {
      "terms": {
        "field": "service_name"
      },
      "aggs": {
        "region": {
          "terms": {
            "field": "region"
          },
          "aggs": {
            "average quantity": {
               "avg": {
                  "field": "cpu_usage"
                }
              }
            }
          }
        }
      }
    }
}

有关查询字符串查询参数的更多信息,请参阅查询字符串查询

动态目标索引

在 ISM 汇总中,target_index 字段可能包含一个在每次汇总索引时编译的模板。例如,如果您将 target_index 字段指定为 rollup_ndx-{{ctx.source_index}}则源索引 log-000001 将汇总到目标索引 rollup_ndx-log-000001 中。这允许您将数据汇总到多个基于时间的索引中,为每个源索引创建一个汇总作业。

{{ctx.source_index}} 中的 source_index 参数不能包含通配符。

搜索多个汇总索引

当数据汇总到多个目标索引中时,您可以对所有汇总索引运行一次搜索。要搜索具有相同汇总的多个目标索引,请将索引名称指定为逗号分隔列表或通配符模式。例如,当 target_indexrollup_ndx-{{ctx.source_index}} 且源索引以 log 开头时,请指定 rollup_ndx-log* 模式。或者,要搜索汇总的 log-000001 和 log-000002 索引,请指定 rollup_ndx-log-000001,rollup_ndx-log-000002 列表。

您不能使用相同的查询同时搜索汇总索引和非汇总索引。

示例

以下示例演示了 doc_count 字段、动态索引名称以及搜索具有相同汇总的多个汇总索引。

步骤 1: 添加 ISM 索引模板,以管理通过 log 别名引用的索引的轮转。

PUT _index_template/ism_rollover
{
  "index_patterns": ["log*"],
  "template": {
   "settings": {
    "plugins.index_state_management.rollover_alias": "log"
   }
 }
}

步骤 2: 设置 ISM 轮转策略,以便在上传一个文档后轮转任何名称以 log* 开头的索引,然后汇总各个后端索引。目标索引名称通过在源索引名称前加上字符串 rollup_ndx- 从源索引名称动态生成。

PUT _plugins/_ism/policies/rollover_policy 
{ 
  "policy": { 
    "description": "Example rollover policy.", 
    "default_state": "rollover", 
    "states": [ 
      { 
        "name": "rollover", 
        "actions": [ 
          { 
            "rollover": { 
              "min_doc_count": 1 
            } 
          } 
        ], 
        "transitions": [ 
          { 
            "state_name": "rp" 
          } 
        ] 
      }, 
      { 
        "name": "rp", 
        "actions": [
          { 
            "rollup": { 
              "ism_rollup": { 
                "target_index": "rollup_ndx-{{ctx.source_index}}", 
                "description": "Example rollup job", 
                "page_size": 200, 
                "dimensions": [ 
                  { 
                    "date_histogram": { 
                      "source_field": "ts", 
                      "fixed_interval": "60m", 
                      "timezone": "America/Los_Angeles" 
                    } 
                  }, 
                  { 
                    "terms": { 
                      "source_field": "message.keyword" 
                    } 
                  } 
                ], 
                "metrics": [ 
                  { 
                    "source_field": "msg_size", 
                    "metrics": [ 
                      { 
                        "sum": {} 
                      } 
                    ]
                  } 
                ]
              } 
            } 
          } 
        ], 
        "transitions": [] 
      } 
    ], 
    "ism_template": { 
      "index_patterns": ["log*"], 
      "priority": 100 
    } 
  } 
}

步骤 3: 创建一个名为 log-000001 的索引,并为其设置别名 log

PUT log-000001
{
  "aliases": {
    "log": {
      "is_write_index": true
    }
  }
}

步骤 4: 将四个文档索引到上面创建的索引中。其中两个文档的消息为“Success”,另外两个的消息为“Error”。

POST log/_doc?refresh=true 
{ 
  "ts" : "2022-08-26T09:28:48-04:00", 
  "message": "Success", 
  "msg_size": 10 
}
POST log/_doc?refresh=true 
{ 
  "ts" : "2022-08-26T10:06:25-04:00", 
  "message": "Error", 
  "msg_size": 20 
}
POST log/_doc?refresh=true 
{ 
  "ts" : "2022-08-26T10:23:54-04:00", 
  "message": "Error", 
  "msg_size": 30 
}
POST log/_doc?refresh=true 
{ 
  "ts" : "2022-08-26T10:53:41-04:00", 
  "message": "Success", 
  "msg_size": 40 
}

索引第一个文档后,将执行轮转操作。此操作将创建索引 log-000002 并附加 rollover_policy。然后执行汇总操作,这将创建汇总索引 rollup_ndx-log-000001

要监控轮转和汇总索引创建的状态,您可以使用 ISM explain API:GET _plugins/_ism/explain

步骤 5: 搜索汇总索引。

GET rollup_ndx-log-*/_search
{
  "size": 0,
  "query": {
    "match_all": {}
  },
  "aggregations": {
    "message_numbers": {
      "terms": {
        "field": "message.keyword"
      },
      "aggs": {
        "per_message": {
          "terms": {
            "field": "message.keyword"
          },
          "aggregations": {
            "sum_message": {
              "sum": {
                "field": "msg_size"
              }
            }
          }
        }
      }
    }
  }
}

响应包含两个桶,“Error”和“Success”,每个桶的文档计数均为 2。

{
  "took" : 30,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "message_numbers" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "Success",
          "doc_count" : 2,
          "per_message" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "Success",
                "doc_count" : 2,
                "sum_message" : {
                  "value" : 50.0
                }
              }
            ]
          }
        },
        {
          "key" : "Error",
          "doc_count" : 2,
          "per_message" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "Error",
                "doc_count" : 2,
                "sum_message" : {
                  "value" : 50.0
                }
              }
            ]
          }
        }
      ]
    }
  }
}

索引编解码器注意事项

有关索引编解码器注意事项,请参阅索引编解码器


相关文章