하루 수백 TB의 로그를 처리하는 플랫폼을 운영하고 있다. 수집량이 늘어날 때 로그 유실을 막으면서 비용도 관리해야 했다.
수집과 조회
우리 플랫폼은 로그를 많이 수집하지만 조회하는 양은 상대적으로 적다. 수집한 로그 전체를 다시 읽는 경우는 드물다.
기존 Elasticsearch 기반 플랫폼은 로그 내용 전체를 색인했다. 수집량이 늘수록 색인 비용과 저장 용량도 늘었다. 보관 기간에 따라 저장 위치를 나눠 비용을 줄였지만 오래된 로그를 조회하려면 별도로 복원해야 했다.
이런 사용 패턴에 맞춰 Loki를 선택했다. Loki는 로그 내용 대신 레이블을 색인하고 로그는 압축해서 오브젝트 스토리지에 저장한다. 수집 경로(Write Path)와 조회 경로(Read Path)를 따로 확장할 수 있다는 점도 선택에 영향을 줬다.
대신 전체 내용을 검색하는 속도는 Elasticsearch보다 느릴 수 있었다. 엔지니어들은 조회 언어인 LogQL을 익혀야 했고 당시에는 대규모 운영 사례도 적었다. 이 제약을 받아들이고 비용과 확장성을 우선했다.
자동 확장
로그는 수집기를 거쳐 Loki에 들어오고 메모리와 디스크에 머문 뒤 오브젝트 스토리지에 저장된다. 중간에서 처리 속도가 느려지면 아직 처리하지 못한 로그가 앞단 버퍼에 쌓인다. 버퍼가 가득 차면 로그를 잃기 시작한다.
그래서 저장 용량뿐 아니라 버퍼가 차는 속도를 봐야 했다. 장애 분석에 필요한 로그를 장애가 발생한 순간에 잃을 수 있기 때문이다.
처음에는 Kubernetes의 수평형 Pod 오토스케일러(HPA)로 CPU와 메모리 평균 사용률을 보고 Pod를 늘렸다. 그런데 평균 사용률이 낮아져도 부하는 줄지 않는 상황이 있었다.
로그를 받아 처리하는 Ingester 일부가 메모리 부족(OOM)으로 재시작했다. 재시작한 Pod는 쌓인 데이터가 적어 메모리 사용률이 낮았다. 이 Pod들이 평균을 낮추자 HPA는 확장하지 않았다. 남아 있던 Pod는 계속 부하를 받았다.
확장 기준에 앞단 버퍼 사용률을 추가했다. 이벤트 기반 오토스케일러인 KEDA를 사용해 로그 처리가 밀리면 Pod를 늘리도록 했다.
이번에는 Pod가 과도하게 늘었다. Ingester가 준비되는 데 몇 분이 걸릴 수 있는데 그동안 버퍼는 계속 찼다. 오토스케일러는 늘어난 버퍼를 보고 Pod를 더 요청했다.
그래서 한 번에 늘릴 수 있는 Pod 수를 제한하고 메트릭에 맞게 안정화 시간을 조정했다. Pod 수가 줄어도 노드가 남으면 비용은 줄지 않으므로 노드 오토스케일링도 연결했다.
버퍼가 가득 차기 전에 새 Pod가 준비돼야 했다. 동시에 아직 준비 중인 Pod를 기다리지 않고 계속 늘리는 일도 막아야 했다.
비용
Loki로 전환한 뒤 로그 수집량은 이전의 1.6배가 됐다. 압축으로 로그 크기는 약 65% 줄었고 전체 비용은 기존 플랫폼보다 약 23% 줄었다.
로그를 덜 받는 방식으로 비용을 줄이지는 않았다. 수집과 조회를 따로 확장하고 오브젝트 스토리지를 쓰면서 필요한 기능을 유지했다.
현재는 하루 수백 TB의 원본 로그를 수집하고 있다. 일부 로그는 합의를 거쳐 보관 기간을 1년에서 6개월로 줄이는 중이다.
1년 보관 기준으로 일평균 인프라 비용을 같은 기간의 일평균 원본 로그 수집량으로 나누면 1GB당 5센트 이하다. 운영 인력 비용은 제외했고 보관과 조회 인프라 비용은 포함했다. 로그 1GB를 하루 보관하는 요금과는 다르다.
관리형 서비스의 공개 수집 단가는 다음과 같다.
- Amazon CloudWatch Logs: 미국 버지니아 북부 리전의 일반 로그 수집 단가는 1GB당 50센트다. 일부 Lambda 로그의 대용량 구간은 5센트까지 내려간다.
- Grafana Cloud Logs: 처리와 쓰기의 공개 시작 단가를 합하면 1GB당 45센트다.
- Elastic Logs Essentials: 대용량 수집 단가는 1GB당 최저 7센트다.
보관 기간과 조회량에 따라 비용이 더 붙을 수 있고 대용량 할인이나 계약 조건에 따라 실제 단가는 달라진다. 공개 단가만 보면 현재 인프라 비용이 더 낮지만 운영 인력이 빠져 있어 전체 운영 비용을 비교한 것은 아니다.
비용을 줄이려고 여유 용량을 없애면 로그가 몰릴 때 유실 위험이 커진다. 반대로 최대 부하에 맞춰 용량을 고정하면 평소에 쓰지 않는 리소스가 남는다.
Loki를 선택해 저장과 색인 비용을 줄였지만 로그 유실을 막으려면 확장 기준도 바꿔야 했다. 지금은 평균 사용률만 보고 용량을 정하지 않는다. 버퍼가 가득 차기 전에 새 Pod가 준비될 수 있는지를 함께 본다. 비용을 줄일 때도 그 시간을 확보할 수 있는지부터 확인한다.