기존 서버 환경 및 구성과 ELK stack을 위한 구성 종류
주의!
이 글은 스타트업에 다닐 적, elk stack을 통하여 구축하라는 명령 하달로 인하여 급하게 준비한 내용이다.
금액적 측면에 대한 제한과.. 시간의 제한이 있었으므로 단순히 이런 생각을 했구나~! 라고 보고 넘기면 되겠다.
Elasticsearch는 아파치 루신을 기반으로 개발된 오픈소스 분산 검색 서버(엔진)이다. 이번에는 기존에 구축되었던 ELK를 재구축하는 내용을 다룬다.
회사 내 서버를 운용하는 과정에서 클라이언트 측이 서버 쪽으로 로그를 전송하다 Time out이 발생하는 문제점이 발생하였다. 왜 이런 문제가 발생했을까?
우선, 기존 서버의 구성도를 살펴보도록 하자.
Elasticsearch의 노드 상태는 아래와 같다.
위와 같이 앞단에 위치한 단일 Logstash가 shipper이자 indexer의 역할을 모두 수행하고 있으며, 뒷단에는 두 개의 ES 노드가 구성되어있다.
왜 이렇게 구성했나?
해당 로그 서버는 필자가 구축한 서버는 아니다. 재작년쯤, 회사에서 급하게 로그 수집 서버가 필요하게 되었고 그때 당시의 담당자분께서 아주 짧은 시간 안에 구성하신 서버이다. 그때 당시에는 요구조건도 매우 낮았으며 많은 트래픽이 쌓일 거라는 기대도 안 하셨다고 했다. 이 서버는 그간 요구사항에 걸맞은 역할을 아주 잘 수행해주었지만, 대규모 트래픽을 감당하기 위해 이제 다시 재구축이 필요한 시점이다.
문제 발생 원인과 해결(임시방편)
문제 발생 상황을 직접 보지 않고 임시방편까지 설정되어 있는 상태에서 해당 프로젝트를 인계받게 되었다. 따라서 문제가 한참 발생할 때의 상황을 기록하진 못했다(담았으면 더 좋았을 텐데). 하지만 담당자분께서 임시방편 책을 새우신 방법을 들어보니 원인은 어느 정도 추측이 되었다.
1. 서버 하드웨어적 사양을 높였다(RAM 증설)
2. Logstash worker를 늘렸다.
기존 Logstash는 filter 기능도 추가되어 있었는데, 단일 프로세스가 shipper의 역할도 진행하면서 indexer의 역할도 진행하는 과정에서 인입의 양을 처리 량이 못 따라줘서 발생한 문제로 보였다. 즉 다음과 같이 발생한 것으로 보인다.
1. 클라이언트가 발생한 이슈에 대하여 로그를 http 통신으로 전달한다.
2. logstash는 8088 포트로 해당 패킷을 전달받는다.
3. 패킷을 정해진 규칙에 맞게 filter-grok 작업을 수행 후 ES 서버로 전달한다.
4. 수많은 로그가 logstash로 몰린다.
5. logstash는 많은 로그 중 일부를 열심히 처리한다. (이 와중에 8088로 로그는 계속해서 쌓인다)
6. 작업을 대기하는 패킷들은 결국 timeout 이 발생한다.
임시방편 책은 어디까지나 일시적이기에, 전체적인 로그 수집 서버를 새로 구축하라는 프로젝트를 진행하게 되었다.
어떻게 진행할 것인가?
우선, 진행하기에 앞서 전제조건을 할당받게 되었다.
1. 인스턴스는 3개 이하로 구성할 것(비용 절감을 위함)
2. 사양은 될 수 있으면 낮게 할 것
3. json 형태로도 받을 수 있어야 할 것(기존엔 그냥 text 형태)
위 조건 하에 이제 구성을 위하여 ELK와 관련된 내용을 수집해보자.
로그 수집 및 Visualization은 여러 종류의 시스템을 통하여 구성이 가능하다.
Filebeat : 데이터 수집기
ElasticSearch : 분산형 RESTful 검색 및 분석 엔진
Logstash : 다양한 소스에서 동시에 데이터를 수집하여 변환한 후 자주 사용하는 저장소로 전달
Kibana : Elasticsearch 데이터의 시각화와 Elastic Stack의 탐색
Redis : "키-값" 구조의 비정형 데이터를 저장하고 관리하기 위한 오픈 소스 기반의 비 관계형 데이터베이스 관리 시스템(DBMS)
Kafka : 카프카는 비동기 처리를 위한 메시징 큐의 한 종류
RabbitMQ : AMQP (Advanced Message Queueing Protocol) 메시지 중개인 소프트웨어
1. Filebeat
특정 파일의 박동(beat)을 감지하며, 이를 감지하게 될 경우 logstash에게 보내는 구조이다. 주로 로그 등의 데이터를 Logstash, ElasticSearch 등으로 전달할 때 사용. 하지만 Logstash와 달리 전처리 기능이 없다. 그러므로 log 데이터가 전 처리된 형태라면 바로 ElasticSearch로 보내고, 그렇지 않다면 Logstash로 보내서 전 처리하는 게 일반적이다.
2. Redis
다량의 로그가 빠르게 쌓일 경우를 대비해 Redis를 중간 데이터 수집 Queue로 사용한다. 만약 Queue가 없고, 수십 개의 서비스가 돌고 있는 채로 직접 ElasticSearch에 모든 서비스의 log 데이터를 주면 ES에 엄청난 부하가 걸려 ES가 마비가 될 것. 이를 우리는 Queue를 통하여 순차적으로 처리함으로써 부하를 줄일 수 있다. 물론 Queue도 부하가 많으면 문제가 생길 수 있지만, Redis는 이를 간단하게 Scale out을 통하여 해결할 수 있다.
3. Kafka
Kafka는 LinkedIn에서 개발된 메시 지큐 시스템이다. 아파치 재단의 카프카는 pub-sub모델의 메시지 큐이고, 분산 환경에 특화되어 설계되어 있다는 특징을 가진다. 기존의 RabbitMQ와 같은 다른 메세 지큐와의 성능 차이가 난다(훨씬 빠르게 처리한다). 그 외에도 클러스터 구성, fail-over, replication와 같은 여러 가지 특징들을 가지고 있다. 보통 카프카는 엄청 큰 메시지를 처리하는 분산된 환경에서 많이 사용하고, 그 외에도 여러 분야에서 아키텍처의 구조적인 복잡도를 줄이고자도 사용한다.
전체적인 그림은 다음과 같겠다.