Druid 쿼리 실행 문제 해결
Druid 쿼리 실행 문제 해결
Druid에서 쿼리 실행에 영향을 줄 수 있는 문제, 그 문제를 식별하는 방법, 그리고 해결 전략을 설명해요. 특히 내부 통신 타임아웃으로 쿼리가 실패하는 경우를 다뤄요.
출처: 문서
본문
이 주제에서는 Druid에서 쿼리 실행에 영향을 줄 수 있는 문제, 문제 식별 방법, 그리고 해결 전략을 설명해요.
내부 통신 타임아웃으로 인한 쿼리 실패
Druid의 쿼리 처리에서 Broker가 데이터 서버로 쿼리를 보내면, 데이터 서버가 쿼리를 처리하고 중간 결과를 Broker로 다시 밀어넣어요. Broker에서 데이터 서버로의 호출은 동기적이기 때문에, 특정 경우에 데이터 서버의 Jetty 서버가 타임아웃될 수 있어요:
- 데이터 서버가 최대 idle 시간까지 Broker에 어떤 결과도 밀어넣지 않는 경우.
- 데이터 서버가 데이터 전송을 시작했지만, Broker 백프레셔(backpressure) 등의 이유로 최대 idle 시간보다 길게 일시 중지된 경우.
이런 타임아웃이 발생하면 서버가 Broker와 데이터 서버 사이의 연결을 끊어서, 채널 연결 해제(channel disconnection) 오류로 쿼리가 실패해요. 예를 들어:
{ "error": { "error": "Unknown exception", "errorMessage": "Query[6eee73a6-a95f-4bdc-821d-981e99e39242] url[https://localhost:8283/druid/v2/] failed with exception msg [Channel disconnected] (through reference chain: org.apache.druid.query.scan.ScanResultValue[\"segmentId\"])", "errorClass": "com.fasterxml.jackson.databind.JsonMappingException", "host": "localhost:8283" }}
채널 연결 해제는 여러 이유로 발생할 수 있어요. 오류가 웹 서버 타임아웃 때문인지 확인하려면 Historical 로그에서 쿼리 ID를 검색해 보세요. 위 예시의 쿼리 ID는 6eee73a6-a95f-4bdc-821d-981e99e39242 예요. 위 오류 메시지의 "host" 필드는 문제가 있는 Historical의 IP 주소를 나타내요. Historical 로그에서 Idle timeout expired 를 나타내는 발생 예외를 볼 수 있어요:
2021-09-14T19:52:27,685 ERROR [qtp475526834-85[scan_[test_large_table]_6eee73a6-a95f-4bdc-821d-981e99e39242]] org.apache.druid.server.QueryResource - Unable to send query response. (java.io.IOException: java.util.concurrent.TimeoutException: Idle timeout expired: 300000/300000 ms)2021-09-14T19:52:27,685 ERROR [qtp475526834-85] org.apache.druid.server.QueryLifecycle - Exception while processing queryId [6eee73a6-a95f-4bdc-821d-981e99e39242] (java.io.IOException: java.util.concurrent.TimeoutException: Idle timeout expired: 300000/300000 ms)2021-09-14T19:52:27,686 WARN [qtp475526834-85] org.eclipse.jetty.server.HttpChannel - handleException /druid/v2/ java.io.IOException: java.util.concurrent.TimeoutException: Idle timeout expired: 300000/300000 ms
웹 서버 타임아웃으로 인한 쿼리 실패를 완화하려면:
- 웹 서버의 최대 idle 시간을 늘리세요. historical/runtime.properties 파일의 druid.server.http.maxIdleTime 속성에서 최대 idle 시간을 설정할 수 있어요. 이 변경을 적용하려면 Druid 클러스터를 다시 시작해야 해요. 서버 구성에 대한 자세한 내용은 Configuration reference 문서를 참고해요.
- 데이터 서버가 Broker에 어떤 결과도 밀어넣지 않아 타임아웃이 발생한다면, 데이터 서버 성능 최적화를 고려해 보세요. 데이터 서버의 상당한 느려짐은 groupBy 쿼리에서 디스크로 너무 많은 데이터를 spill하거나, 쿼리의 큰 IN 필터, 또는 과소 확장된(under scaled) 클러스터 때문일 수 있어요. Druid 쿼리 메트릭을 분석해 병목 지점을 파악해 보세요.
- 타임아웃이 Broker 백프레셔 때문이라면, Broker 성능 최적화를 고려해 보세요. Broker와 deep storage 사이의 연결이 충분히 빠른지 확인하세요.
더 알아보기 (Learn more)
- Query context reference — 쿼리 컨텍스트 파라미터
- groupBy 쿼리 — spill 동작 이해하기
- Configuration reference — 서버 구성 자세히 보기