コンテンツにスキップ

DataKit ログコレクターの性能テスト

環境とツール

  • オペレーティング システム: Ubuntu 20.04.2 LTS
  • CPU:Intel(R) Core(TM) i5-7500 CPU @ 3.40GHz
  • メモリ: 16GB 速度 2133 MT/秒
  • DataKit:1.1.8-rc1
  • ログテキスト (nginx アクセスログ):
172.17.0.1 - - [06/Jan/2017:16:16:37 +0000] "GET /datadoghq/company?test=var1%20Pl HTTP/1.1" 401 612 "http://www.perdu.com/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36" "-"
  • ログ数:100,000行
  • Pipelineの使用: 以下を参照

テスト結果

試験条件 時間がかかる
Pipelineなし、純粋なログ テキスト処理 (エンコード、複数行およびフィールドの検出などを含む) 3秒63
Pipeline のフルバージョンを使用します (付録 1 を参照) 43秒70
access.log の場合のみ、NGINX エラー ログなどの完全バージョンと比較して複数の一致する形式を破棄し、単一の一致するPipelineを使用します (付録 2 を参照)。 16秒91
最適化された単一の一致するPipelineを使用して、パフォーマンスを大量に消費するパターンを置き換えます (付録 3 を参照) 4秒40
Info

Pipelineの時間がかかる間、CPU の単一コアが全負荷で実行され、使用率は約 100% でした。 100,000 ログの処理が完了すると、CPU が低下しました。テスト中、メモリ消費量は安定しており、使用量の明らかな増加はありませんでした。消費時間は DataKit プログラムによって計算されており、環境によっては差異が生じる可能性があります。

比較

Fluentd を使用して同じ 100,000 行のログを収集すると、CPU 使用率は 3 秒以内に 43% から 77% に上昇し、その後低下しました。この時点で処理が終了していることが予想されます。

Fluentd はメタデータのキャッシュ機構を備えており、結果をバッチで出力するため、どのくらいの時間がかかるかを正確に計算することはできません。

Fluentd のPipeline マッチング モードは単一であり、同じデータ ソースからの複数形式のPipelineはありません (たとえば、nginx はアクセス ログのみをサポートし、エラー ログはサポートしません)。

結論

DataKit のログ収集、Pipeline シングルマッチングモードでは、Fluentd と比べて処理時間が 30% 程度異なります。

ただし、完全に一致するPipelineの完全バージョンを使用すると、消費時間は大幅に増加します。

付録(Pipeline)

完全版・すべてのパターンを照合する Pipeline

add_pattern("date2", "%{YEAR}[./]%{MONTHNUM}[./]%{MONTHDAY} %{TIME}")

# access log
grok(_, "%{IPORHOST:client_ip} %{NOTSPACE:http_ident} %{NOTSPACE:http_auth} \\[%{HTTPDATE:time}\\] \"%{DATA:http_method} %{GREEDYDATA:http_url} HTTP/%{NUMBER:http_version}\" %{INT:status_code} %{INT:bytes}")

# access log
add_pattern("access_common", "%{IPORHOST:client_ip} %{NOTSPACE:http_ident} %{NOTSPACE:http_auth} \\[%{HTTPDATE:time}\\] \"%{DATA:http_method} %{GREEDYDATA:http_url} HTTP/%{NUMBER:http_version}\" %{INT:status_code} %{INT:bytes}")
grok(_, '%{access_common} "%{NOTSPACE:referrer}" "%{GREEDYDATA:agent}')
user_agent(agent)

# error log
grok(_, "%{date2:time} \\[%{LOGLEVEL:status}\\] %{GREEDYDATA:msg}, client: %{IPORHOST:client_ip}, server: %{IPORHOST:server}, request: \"%{DATA:http_method} %{GREEDYDATA:http_url} HTTP/%{NUMBER:http_version}\", (upstream: \"%{GREEDYDATA:upstream}\", )?host: \"%{IPORHOST:ip_or_host}\"")
grok(_, "%{date2:time} \\[%{LOGLEVEL:status}\\] %{GREEDYDATA:msg}, client: %{IPORHOST:client_ip}, server: %{IPORHOST:server}, request: \"%{GREEDYDATA:http_method} %{GREEDYDATA:http_url} HTTP/%{NUMBER:http_version}\", host: \"%{IPORHOST:ip_or_host}\"")
grok(_,"%{date2:time} \\[%{LOGLEVEL:status}\\] %{GREEDYDATA:msg}")

group_in(status, ["warn", "notice"], "warning")
group_in(status, ["error", "crit", "alert", "emerg"], "error")

cast(status_code, "int")
cast(bytes, "int")

group_between(status_code, [200,299], "OK", status)
group_between(status_code, [300,399], "notice", status)
group_between(status_code, [400,499], "warning", status)
group_between(status_code, [500,599], "error", status)


nullif(http_ident, "-")
nullif(http_auth, "-")
nullif(upstream, "")
default_time(time)

単一パターンを照合する Pipeline

# access log
grok(_, "%{IPORHOST:client_ip} %{NOTSPACE:http_ident} %{NOTSPACE:http_auth} \\[%{HTTPDATE:time}\\] \"%{DATA:http_method} %{GREEDYDATA:http_url} HTTP/%{NUMBER:http_version}\" %{INT:status_code} %{INT:bytes}")

cast(status_code, "int")
cast(bytes, "int")

default_time(time)

最適化した単一パターン照合 Pipeline

この例では、パフォーマンスを大量に消費する IPORHOST が NOTSPACE に変更されます。

# access log
grok(_, "%{NOTSPACE:client_ip} %{NOTSPACE:http_ident} %{NOTSPACE:http_auth} \\[%{HTTPDATE:time}\\] \"%{DATA:http_method} %{GREEDYDATA:http_url} HTTP/%{NUMBER:http_version}\" %{INT:status_code} %{INT:bytes}")

cast(status_code, "int")
cast(bytes, "int")

default_time(time)

フィードバック

このページは役に立ちましたか?