2

私はelasticsearchドメインが初めてです。私はそれが私のニーズを満たしているかどうかを確認するためにそれを学び、試しています。

現在、私はelasticsearchで集計を学習しており、次のpythonスクリプトを作成して、時系列データをelasticsearchに取り込みました。

5 秒ごとに、次の新しいメッセージを作成します。

  1. タイムスタンプ (ISO8601 形式)
  2. カウンター
  3. 0 から 100 までの乱数

新しい日ごとにlogs_Y-m-D、インデックス名として新しいインデックスを作成します。

Counterメッセージをとして使用して、すべてのメッセージにインデックスを付けます_id。カウンターは、新しいインデックスごとに (毎日) リセットされます。


import csv
import time
import random
from datetime import datetime
from elasticsearch import Elasticsearch


class ElasticSearchDB:
    def __init__(self):
        self.es = Elasticsearch()

    def run(self):
        print("Started: {}".format(datetime.now().isoformat()))
        print("<Ctrl + c> for exit!")

        with open("..\\out\\logs.csv", "w", newline='') as f:
            writer = csv.writer(f)
            counter = 0
            try:
                while True:
                    i_name = "logs_" + time.strftime("%Y-%m-%d")
                    if not self.es.indices.exists([i_name]):
                        self.es.indices.create(i_name, ignore=400)
                        print("New index created: {}".format(i_name))
                        counter = 0

                    message = {"counter": counter, "@timestamp": datetime.now().isoformat(), "value": random.randint(0, 100)}
                    # Write to file
                    writer.writerow(message.values())
                    # Write to elasticsearch index
                    self.es.index(index=i_name, doc_type="logs", id=counter, body=message)
                    # Waste some time
                    time.sleep(5)
                    counter += 1

            except KeyboardInterrupt:
                print("Stopped: {}".format(datetime.now().isoformat()))


test_es = ElasticSearchDB()
test_es.run()

このスクリプトを30 分間実行しました。次に、Sense を使用して、次の集計クエリを使用して elasticsearch にクエリを実行します。

クエリ #1: すべて取得

クエリ #2: 過去 1 時間のログを集計し、それらの統計を生成します。これは正しい結果を示しています。

クエリ #3: 過去 1 分間のログを集計し、それらの統計を生成します。集約されるドキュメントの数は、1 時間の集約と同じです。理想的には、 12 ~ 13 個のログのみを集約する必要があります。

クエリ #4: 過去 15 秒間のログを集計し、それらの統計を生成します。集約されるドキュメントの数は、1 時間の集約と同じです。理想的には、3 ~ 4 個のログのみを集約する必要があります。

私の質問:

  1. Elasticsearch が 1 分 15 秒の範囲を認識できないのはなぜですか?
  2. マッピングは理解できますが、書き方がわからないので書いていません。それがこの問題の原因ですか?

助けてください!


クエリ #1: すべて取得

GET /_search

出力:

{
   "took": 3,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 314,
      "max_score": 1,
      "hits": [
         {
            "_index": "logs_2016-11-03",
            "_type": "logs",
            "_id": "19",
            "_score": 1,
            "_source": {
               "counter": 19,
               "value": 62,
               "@timestamp": "2016-11-03T07:40:35.981395"
            }
         },
         {
            "_index": "logs_2016-11-03",
            "_type": "logs",
            "_id": "22",
            "_score": 1,
            "_source": {
               "counter": 22,
               "value": 95,
               "@timestamp": "2016-11-03T07:40:51.066395"
            }
         },
         {
            "_index": "logs_2016-11-03",
            "_type": "logs",
            "_id": "25",
            "_score": 1,
            "_source": {
               "counter": 25,
               "value": 18,
               "@timestamp": "2016-11-03T07:41:06.140395"
            }
         },
         {
            "_index": "logs_2016-11-03",
            "_type": "logs",
            "_id": "26",
            "_score": 1,
            "_source": {
               "counter": 26,
               "value": 58,
               "@timestamp": "2016-11-03T07:41:11.164395"
            }
         },
         {
            "_index": "logs_2016-11-03",
            "_type": "logs",
            "_id": "29",
            "_score": 1,
            "_source": {
               "counter": 29,
               "value": 73,
               "@timestamp": "2016-11-03T07:41:26.214395"
            }
         },
         {
            "_index": "logs_2016-11-03",
            "_type": "logs",
            "_id": "41",
            "_score": 1,
            "_source": {
               "counter": 41,
               "value": 59,
               "@timestamp": "2016-11-03T07:42:26.517395"
            }
         },
         {
            "_index": "logs_2016-11-03",
            "_type": "logs",
            "_id": "14",
            "_score": 1,
            "_source": {
               "counter": 14,
               "value": 9,
               "@timestamp": "2016-11-03T07:40:10.857395"
            }
         },
         {
            "_index": "logs_2016-11-03",
            "_type": "logs",
            "_id": "40",
            "_score": 1,
            "_source": {
               "counter": 40,
               "value": 9,
               "@timestamp": "2016-11-03T07:42:21.498395"
            }
         },
         {
            "_index": "logs_2016-11-03",
            "_type": "logs",
            "_id": "24",
            "_score": 1,
            "_source": {
               "counter": 24,
               "value": 41,
               "@timestamp": "2016-11-03T07:41:01.115395"
            }
         },
         {
            "_index": "logs_2016-11-03",
            "_type": "logs",
            "_id": "0",
            "_score": 1,
            "_source": {
               "counter": 0,
               "value": 79,
               "@timestamp": "2016-11-03T07:39:00.302395"
            }
         }
      ]
   }
}

クエリ #2: 過去 1 時間の統計を取得します。

GET /logs_2016-11-03/logs/_search?search_type=count
{
    "aggs": {
        "time_range": {
            "filter": {
                "range": {
                    "@timestamp": {
                        "from": "now-1h"
                    }
                }
            },
            "aggs": {
                "just_stats": {
                    "stats": {
                        "field": "value"
                    }
                }
            }
        }
    }
}

出力:

{
   "took": 5,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 366,
      "max_score": 0,
      "hits": []
   },
   "aggregations": {
      "time_range": {
         "doc_count": 366,
         "just_stats": {
            "count": 366,
            "min": 0,
            "max": 100,
            "avg": 53.17213114754098,
            "sum": 19461
         }
      }
   }
}

366 エントリを取得しましたが、これは正しいです。

クエリ #3: 過去 1 分間の統計を取得します。

GET /logs_2016-11-03/logs/_search?search_type=count
{
    "aggs": {
        "time_range": {
            "filter": {
                "range": {
                    "@timestamp": {
                        "from": "now-1m"
                    }
                }
            },
            "aggs": {
                "just_stats": {
                    "stats": {
                        "field": "value"
                    }
                }
            }
        }
    }
}

出力:

{
   "took": 15,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 407,
      "max_score": 0,
      "hits": []
   },
   "aggregations": {
      "time_range": {
         "doc_count": 407,
         "just_stats": {
            "count": 407,
            "min": 0,
            "max": 100,
            "avg": 53.152334152334156,
            "sum": 21633
         }
      }
   }
}

これは誤りです。過去 1 分間で 407 エントリになることはできません。12 ~ 13 個のログのみである必要があります。

クエリ #4: 過去 15 秒間の統計を取得します。

GET /logs_2016-11-03/logs/_search?search_type=count
{
    "aggs": {
        "time_range": {
            "filter": {
                "range": {
                    "@timestamp": {
                        "from": "now-15s"
                    }
                }
            },
            "aggs": {
                "just_stats": {
                    "stats": {
                        "field": "value"
                    }
                }
            }
        }
    }
}

出力:

{
   "took": 15,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 407,
      "max_score": 0,
      "hits": []
   },
   "aggregations": {
      "time_range": {
         "doc_count": 407,
         "just_stats": {
            "count": 407,
            "min": 0,
            "max": 100,
            "avg": 53.152334152334156,
            "sum": 21633
         }
      }
   }
}

これも間違っています。最後の 15 秒間で 407 エントリになることはできません。3 ~ 4 個のログのみである必要があります。

4

1 に答える 1

2

クエリは正しいですが、ES は日付を UTC で保存するため、すべてが返されます。ドキュメントから

JSON ドキュメントでは、日付は文字列として表されます。Elasticsearch は、一連の事前構成された形式を使用して、これらの文字列を認識し、解析して、 UTCでのエポックからのミリ秒を表す long 値に変換します 。

モジュールを使用して、pytz日付を ES の UTC に保存できます。このSOの質問を参照してください。

また、範囲クエリで param を使用することもできtime_zoneます。また、すべての結果を取得してからそれらすべてをフィルター処理するよりも、フィルター処理された結果を集計することをお勧めします。

GET /logs_2016-11-03/logs/_search
{
  "query": {
    "bool": {
      "filter": {
        "range": {
          "@timestamp": {
            "gte": "2016-11-03T07:15:35",         <----- You would need absolute value
            "time_zone": "-01:00"              <---- timezone setting
          }
        }
      }
    }
  },
  "aggs": {
    "just_stats": {
      "stats": {
        "field": "value"
      }
    }
  },
  "size": 0
}

time_zone パラメータが影響を受けないため、目的の時間 ( now-1m, now-15s ) をフォーマットに変換する必要があるため、日付を UTC に変換して保存することをお勧めします。yyyy-MM-dd'T'HH:mm:ssnowtime_zone

于 2016-11-03T05:32:42.400 に答える