지속적 폴링 덕분에 이제 Kibana 대시보드와 Discover의 로딩 속도가 최대 25% 빨라졌습니다. 주기적으로 확인 요청을 보낸 뒤 대기하던 방식에서 벗어나 이제 Kibana는 HTTP 연결을 열린 상태로 유지하고 Elasticsearch 쿼리 결과가 준비되는 즉시 전달합니다. HTTP/2+ 환경(Kibana 9.0부터 기본 적용)에서는 별도의 설정 없이도 이 기능이 자동으로 활성화됩니다. 반면 HTTP/1 환경에서는 커넥션 풀 고갈 현상을 방지하기 위해 기존의 전통적인 폴링 방식으로 자동 폴백됩니다.
대시보드 로딩 시 Kibana가 데이터를 가져오는 방법
대시보드가 열리면 대부분의 패널(내부적으로는 임베더블이라고 부릅니다)이 하나 이상의 Elasticsearch 쿼리를 실행합니다. 하지만 동기(Sync) 검색의 단순한 요청 및 응답 방식 대신 우리는 강력한 비동기(Async) 검색(문서)을 사용합니다.
비동기 검색을 이용하면 쿼리 결과가 특정 HTTP 요청 세션에 종속되지 않고, Elasticsearch 내에 안정적으로 유지됩니다. 이 방식은 다음과 같은 측면에서 중요한 역할을 합니다.
- 네트워크가 불안정한 상황에서도 데이터 로딩의 회복 탄력성을 보장합니다.
- 사용자가 오래 걸리는 대시보드나 Discover 세션을 기다리는 동안 Kibana에서 다른 작업을 할 수 있도록 백그라운드 검색 기능을 지원합니다.
최초 쿼리가 제출되면 Kibana는 해당 검색 프로세스를 모니터링하여 완료 시점을 감지하고 결과 집합을 가져옵니다.
전통적인 폴링 방식이 Kibana 대시보드 로딩 시간에 미치는 영향
전통적인 폴링 구조에서 Kibana는 쿼리를 제출한 뒤 초기 연결을 닫고, 이후 Elasticsearch를 주기적으로 조회하여 완료 여부를 확인합니다.

전통적 여론조사 전략
쿼리가 제출되면 Elasticsearch가 검색을 마친 후 결과를 반환할 수 있도록 잠시 시간을 둡니다. 검색이 그만큼 빠르게 완료된다면 단순한 요청과 응답으로 마무리됩니다. 반면 실행 시간이 더 긴 검색의 경우 초기 연결이 닫힌 후 Kibana가 완료 여부를 주기적으로 확인하기 시작합니다. 이러한 방식을 폴링이라고 합니다.
전통적인 폴링 방식의 성능 저하 요소
위 그림에서 볼 수 있듯이 이 방식에는 성능상 약점이 있습니다. 검색이 Kibana의 대기 시간 중에 완료될 가능성이 높아 그만큼 시간이 낭비됩니다.

전통적인 여론조사의 어두운 면
최악의 경우(대기 시간이 시작되자마자 검색이 완료될 때)에는 폴링 주기 전체가 고스란히 낭비됩니다.
백오프 전략의 영향
폴링을 수행할 때 백오프 전략을 적용하는 것은 일반적인 관행입니다. 즉, 검색 시간이 길어질수록 폴링 빈도를 낮추는 방식을 의미합니다.

폴링 주기 백오프 스케줄
하지만 이는 검색 시간이 길어질수록 잠재적인 시간 손실도 함께 늘어남을 의미합니다.
폴링 주기가 톱니형 지연 패턴을 유발하는 이유
이러한 요소들이 결합되면서 시간 손실은 계단식 톱니 함수 형태를 띠게 됩니다.

쿼리 실행 시간별 손실 시간
여기서 정점은 최악의 시나리오를, 저점은 최선의 시나리오를 나타냅니다. 즉, 전통적인 폴링 방식은 검색 시간과 네트워크 조건에 따라 시간 손실이 전혀 없을 수도, 혹은 전체 폴링 주기만큼 고스란히 발생할 수도 있음을 보여줍니다.
지속적 폴링: Kibana가 대기 시간을 제거하는 방법
전통적인 폴링 방식의 문제는 Kibana와 Elasticsearch 간의 상호 조율이 근본적으로 부족하다는 점입니다. 가장 이상적인 것은 결과가 준비되는 즉시 Kibana가 이를 바로 감지하는 것입니다. 그렇다면 폴링 패턴을 뒤집어, 대기 시간 없이 대부분의 시간을 Elasticsearch를 확인하는 데 사용하면 어떨까요?

지속적 폴링: 시간 손실을 해결하기 위한 솔루션
이처럼 롱 폴링과 대기 시간이 없는 구조가 결합되어 결과는 준비되는 즉시 제공됩니다.
HTTP/1 성능 저하
이론은 확실합니다. 그렇다면 왜 이 Kibana 배포 환경에서는 지속적 폴링을 켰을 때 오히려 성능이 크게 떨어지는 것처럼 보일까요?

지속적 폴링이 HTTP/1로 연결된 클라이언트에서 유발하는 성능 저하
핵심은 이 배포 환경이 HTTP/1 기반으로 구동되고 있다는 점입니다. HTTP/1에서는 HTTP 요청이 TCP 커넥션과 1:1로 매핑됩니다. 따라서 몇 개의 오래 지속되는 폴링 요청이 브라우저의 제한된 커넥션 풀을 독점하게 되고, 이로 인해 다른 요청들이 대기열에 쌓이게 됩니다.
반면 HTTP/2+에서는 멀티플렉싱을 통해 네트워크 요청이 TCP 커넥션을 공유할 수 있으므로 이러한 문제가 발생하지 않습니다.

HTTP/1과 HTTP/2+ 간의 HTTP-TCP 매핑 차이
결론적으로 지속적 폴링은 HTTP/2+ 환경에서는 큰 장점이 되지만 HTTP/1 환경에서는 오히려 악영향을 미치게 됩니다.
| HTTP/1 | HTTP/2+ | |
|---|---|---|
| TCP 연결 | HTTP 요청당 하나 | 멀티플렉싱(다수의 요청이 연결 공유) |
| 지속적 폴링 동작 방식 | 성능 저하(연결 풀 고갈) | 이점 극대화(결과 즉시 전달) |
최적의 폴링을 위한 Kibana의 HTTP 프로토콜 감지 방법
HTTP/2는 권장 프로토콜이자 Kibana 9.0부터의 기본값입니다. 따라서 이러한 성능 향상 기능을 릴리스하지 않을 이유가 없었습니다. 반면 HTTP/1에서의 사용자 경험은 저하가 너무 심해 아직 프로토콜을 업그레이드하지 않은 온프레미스 배포 환경에 위험을 감수하고 적용할 수는 없었습니다. 답은 명확했습니다. 현재 어떤 프로토콜이 사용 중인지 감지하고, 그에 맞는 최적의 폴링 전략을 적용하는 것입니다.
물론 Kibana 서버가 자체적으로 어떤 프로토콜로 통신하고 있는지는 충분히 파악할 수 있습니다. 하지만 걸림돌이 하나 있습니다. 병목을 유발하는 결정적 요인은 브라우저의 커넥션 풀이라는 점입니다. 즉, 진짜 중요한 것은 브라우저가 어떤 프로토콜로 통신하는가입니다.
프록시로 인해 이러한 구간의 프로토콜이 항상 일치하지는 않기 때문입니다.

프로토콜은 각 네트워크 홉마다 달라질 수 있습니다
만약 서버 프로토콜을 기준으로 최적화를 진행한다면 다음과 같은 두 가지 오류가 발생할 수 있습니다.
- 지속적 폴링을 적용해서는 안 되는 상황에 적용하여 사용자 경험을 저하시키거나,
- 반대로 적용해야 하는 상황에 적용하지 못해 최적화 기회를 놓치는 것입니다.
다행히 최신 브라우저에서는 PerformanceObserver를 활용해 완료된 요청의 최종 네트워크 홉 프로토콜을 감지하는 방법을 제공합니다. 따라서 첫 번째 쿼리가 제출될 때의 프로토콜을 모니터링하고 이를 기준으로 최적화를 수행합니다.
실험 결과: Kibana의 지속적 폴링과 전통적 폴링 비교
지속적 폴링을 검증하기 위해 1초에서 23초 사이의 쿼리 지연 시간이 있는 대시보드를 생성한 후, 최적화 기능을 켰을 때와 껐을 때의 로딩 시간을 각각 측정했습니다. 이어서 성능 향상 폭을 측정하고자 지속적 폴링 적용 여부에 따라 대시보드를 로드해 보았습니다. 어느 쪽이 먼저 도달하는지 시합하며 테스트를 진행하는 과정은 꽤 흥미진진했습니다.

쿼리 실행 시간별 대시보드 로딩 시간
이 패턴은 앞서 보았던 톱니형 다이어그램과 일치합니다. 특정 쿼리 실행 시간대에서는 성능 향상 폭이 미미했지만 다른 시간대에서는 수 초의 시간을 단축하는 결과를 보였습니다.
결론
이번 최적화는 전통적인 폴링 방식에 내재된 고유의 지연 시간을 더 효율적인 지속적 폴링 전략으로 성공적으로 대체합니다. 가장 큰 과제는 HTTP/1 배포 환경에서의 성능 저하를 막기 위해 이 최적화 기능을 조건부로 적용하는 것이었습니다. 우리는 브라우저의 PerformanceObserver를 이용해 최종 네트워크 홉에서 사용 중인 프로토콜을 안정적으로 감지함으로써 이 문제를 해결했습니다.
실험실 테스트 결과 역시 이 이론을 뒷받침하며 지속적 폴링이 결과가 준비되는 즉시 데이터를 전달함을 보여줍니다. 이는 결과적으로 사용자 경험의 확연한 개선으로 이어져 데이터 로딩 속도를 최대 25%까지 단축합니다.
이번 작업은 사용자의 인사이트 확보 시간을 줄이기 위한 우리의 지속적인 노력의 최신 성과입니다. Kibana를 Elasticsearch 데이터에 대한 더 투명한 프록시로 기능하게 함으로써 우리가 혁신을 이끌어낼 수 있는 영역 내에서 성능의 한계를 한 단계 더 끌어올렸습니다. 앞으로의 행보도 기대해 주세요!
(지난 2025년, Thomas Neirynk가 Kibana 대시보드 성능 개선의 목적과 방법론에 대해 훌륭하게 정리해 준 바 있습니다. 본 글은 해당 이니셔티브의 후속 업데이트입니다.)
자주 묻는 질문
지속적 폴링은 Kibana의 대시보드 로딩 속도를 어떻게 향상시키나요?
대시보드 로드 속도는 Kibana가 Elasticsearch로부터 쿼리 결과를 얼마나 빨리 가져오느냐에 달려 있습니다. 전통적인 폴링은 완료 여부를 주기적으로 확인하기 때문에 결과를 가져오는 과정에서 지연이 발생할 수 있습니다. 반면 HTTP/2+에서는 Kibana가 지속적 폴링을 자동으로 활성화하여 연결을 열린 상태로 유지하고 결과가 준비되는 즉시 전달함으로써 지연을 완전히 제거합니다.
지속적 폴링이란 무엇이며 Kibana 성능을 어떻게 향상시키나요?
지속적 폴링은 주기적인 확인 사이에 대기하는 대신 Elasticsearch 쿼리 결과를 기다리는 동안 HTTP 연결을 열린 상태로 유지하여 기존 패턴을 뒤집은 방식입니다. 이를 통해 낭비되는 시간을 없애고 결과가 준비되는 즉시 전달하므로 대시보드와 Discover의 속도가 빨라집니다.
지속적 폴링이 HTTP/1 연결에서도 작동하나요?
아닙니다. 지속적 폴링은 멀티플렉싱을 통해 오래 지속되는 요청이 다른 트래픽을 차단하지 않도록 해주는 HTTP/2+ 연결에만 적용됩니다. Kibana는 브라우저의 PerformanceObserver API를 이용해 프로토콜을 자동으로 감지하며, 성능 저하를 막기 위해 HTTP/1에서는 전통적인 폴링 방식을 적용합니다.
지속적 폴링을 사용하면 Kibana 대시보드가 얼마나 빨라지나요?
실험실 테스트 결과, 쿼리 지속 시간에 따라 대시보드 로딩 시간이 최대 25%까지 개선되는 것으로 나타났습니다. 쿼리가 길수록 절대 시간이 더 많이 절약되는 반면, 쿼리가 매우 짧을수록 그 차이는 미미합니다.
Kibana는 지속적 폴링과 전통적 폴링 중 어떤 방식을 사용할지 어떻게 감지하나요?
Kibana는 브라우저의 PerformanceObserver API를 사용하여 첫 번째 쿼리 요청의 HTTP 프로토콜을 감지합니다. 프로토콜이 멀티플렉싱을 지원하는 HTTP/2 또는 HTTP/3이면 지속적 폴링을 활성화하고, HTTP/1이 감지되면 커넥션 풀 소진을 막기 위해 전통적 폴링을 적용합니다.
지속적 폴링이 네트워크 프록시나 로드 밸런서에 문제를 일으킬 수 있나요?
지속적 폴링은 브라우저의 커넥션 풀 소진을 방지하기 위해 HTTP/2+ 멀티플렉싱에 의존합니다. 만약 프록시와 브라우저 구간에서 프록시가 연결을 HTTP/1로 다운그레이드하는 경우 Kibana는 이를 감지하여 대신 전통적 폴링을 사용합니다. 즉, 최적화는 브라우저가 실제로 통신하는 프로토콜을 기준으로 조건부 적용됩니다.
타임아웃이 발생합니다. 어떻게 해야 하나요?
프록시가 HTTP/2+를 사용하더라도 30초 미만의 타임아웃을 강제하는 경우 검색 제한 시간 초과가 발생할 수 있습니다. 이를 해결하려면 프록시의 타임아웃 설정을 늘리거나, kibana.yml 파일에서 data.search.asyncSearch.pollLength 값을 해당 타임아웃보다 낮은 값으로 설정해 주세요.




