콘텐츠로 이동

DataKit 로그 수집기 성능 테스트

환경 및 도구

  • 운영 체제: 우분투 20.04.2 LTS
  • CPU:Intel(R) Core(TM) i5-7500 CPU @ 3.40GHz
  • 메모리: 16GB 속도 2133MT/s
  • 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
단일 일치 Pipeline을 사용하여 정식 버전과 비교하여 NGINX 오류 로그와 같은 여러 일치 형식을 폐기합니다. access.log에 대해서만(부록 2 참조) 16초 91
최적화된 단일 매칭 Pipeline을 사용하여 성능을 많이 소모하는 패턴 대체(부록 3 참조) 4초 40
Info

Pipeline의 시간이 많이 소요되는 기간 동안 CPU의 단일 코어는 전체 로드로 실행되었으며 사용률은 계속해서 100% 정도였습니다. 100,000개의 로그 처리가 완료되면 CPU가 다시 떨어졌습니다. 테스트하는 동안 메모리 소비는 안정적이었고 사용량이 눈에 띄게 증가하지 않았습니다. 소요 시간은 DataKit 프로그램으로 계산한 것으로, 환경에 따라 차이가 있을 수 있습니다.

비교

Fluentd를 사용하여 동일한 100,000줄의 로그를 수집한 결과, CPU 사용량은 3초 이내에 43%에서 77%로 증가한 후 다시 감소했습니다. 현재 처리가 종료된 것으로 예상할 수 있습니다.

Fluentd에는 Meta-Data 캐싱 메커니즘이 있고 결과를 일괄적으로 출력하기 때문에 시간이 얼마나 걸리는지 정확하게 계산하는 것은 불가능합니다.

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)

문서 평가

이 페이지가 도움이 되었나요?