logo
logo
언어
Go
StackOverflow 질문 수: 74811
Github Stars : ★ 126849
사용 기업
인공지능
이커머스
소셜/컨텐츠
부동산/인테리어
기타
푸드테크
헬스케어
금융/보험
패션
모빌리티
직장
여행
종합
블록체인
교육
techstack-logo
슈퍼브에이아이
techstack-logo
식스샵
techstack-logo
드림어스컴퍼니
techstack-logo
스푼
techstack-logo
당근
techstack-logo
버킷플레이스
techstack-logo
버즈빌
techstack-logo
마켓컬리
techstack-logo
에이비일팔공
techstack-logo
왓챠
techstack-logo
버드뷰
techstack-logo
채널코퍼레이션
techstack-logo
카카오페이
techstack-logo
카카오스타일
techstack-logo
42dot
techstack-logo
카카오엔터테인먼트
techstack-logo
의식주컴퍼니
techstack-logo
카카오엔터프라이즈
더 보기
기술 블로그 글
네이버
Go GC를 너무 믿지 마세요 - 메모리 누수 탐지와 GC 주기 조절
Noir는 Go로 작성한 개별 데이터 특화 검색 엔진으로, 메일처럼 사용자마다 데이터가 분리된 서비스에 효과적입니다. 대표적으로 네이버 메일, 메시지 검색 서비스 등이 Noir를 사용하고 있습니다.수년간 Noir를 개발 및 운영하는 동안 Noir 서버 메모리 사용량이 시간이 갈수록 천천히 증가하는 현상이 자주 관찰되었고 이를 해결하기 위해 큰 노력을 기울였습니다.Go는 가비지 컬렉터(GC)가 있는 언어로, 개발자가 메모리 관리에 크게 신경 쓰지 않아도 된다는 장점이 있습니다. 하지만 개발자가 메모리 관리에 개입할 수 있는 여지가 적기에, Noir에서 발생한 메모리 사용량 증가 현상은 해결하기 까다로운 이슈였습니다.다음 그래프는 실제 프로덕션에 배포된 Noir 서버 일부의 메모리 사용량 그래프입니다.시간이 갈수록 애플리케이션의 메모리 사용량이 늘어납니다. 사용량이 줄어드는 부분은 운영자가 배포 등의 이유로 검색 서버를 재시작하여 메모리 할당이 해제된 경우입니다.해당 문제의 원인을 파악하기 위해 여러 실험을 해본 결과 원인은 크게 두 가지로 나눌 수 있었습니다.cgo를 사용하는 경우 Go가 아닌 C 언어가 관리하는 메모리가 생기기 때문에 메모리 누수 발생 가능애플리케이션이 메모리를 많이 사용한다면 GC에 의해 메모리가 할당 해제되는 속도보다 할당되는 속도가 빠를 수 있음이번 글에서는 Noir의 메모리 사용량 증가 현상을 해결하기 위해 사용한 방법 중 일부를 소개합니다.RES와 heap해결 방법을 살펴보기 전에 애플리케이션 프로세스의 RES와 heap에 대해서 알아보겠습니다.출처: Memory - HPC @ QMULRES(Resident Memory Size, Resident Set Size, RSS)는 프로세스가 실제로 사용하고 있는 물리 메모리의 크기입니다. OS는 프로세스가 요청한 메모리를 실제로 사용하기 전까지 물리 메모리를 할당하지 않습니다. 따라서 프로세스가 사용하는 메모리(virtual memory) 크기와 실제로 사용하는 물리 메모리 크기(RES)에는 차이가 있습니다. RES는 여러 프로세스와 함께 사용하는 공유 라이브러리(shared libraries)와 프로세스가 요청하여 사용하는 메모리(actual ram usage)로 나뉩니다.RES는 top 명령어로 확인할 수 있습니다.heap은 프로세스가 런타임에 데이터를 저장하기 위해 OS로부터 할당받는 메모리입니다. 프로세스는 런타임에 저장하는 데이터가 많아지면 OS로부터 메모리를 할당받고 할당받은 메모리가 필요 없어지면 할당 해제합니다. heap의 구현은 언어마다 다르며 Go의 경우 TCmalloc에 영향을 받은 런타임 메모리 할당 알고리즘을 사용하고 있습니다.Go 애플리케이션의 heap 크기는 runtime 패키지를 사용하거나 GODEBUG=gctrace=1 환경 변수를 설정해서 확인할 수 있습니다.간단히 말해, RES는 OS가 관리하는 메모리와 관련된 개념이고 heap은 Go가 관리하는 메모리입니다. 그리고 RES는 heap뿐만 아니라 프로세스가 동작하는 데 필요한 모든 메모
go
카카오
Ingress Nginx Controller의 Prometheus Metric 병목 현상: 원인 분석과 해결 (2부)
광고추천 조직에서 타게팅 광고 서빙 시스템을 담당하고 있는 에이든입니다.안녕하세요. 카카오 광고추천팀에서 광고 추천 개발 업무를 담당하고 있는 aiden.song입니다. 이번 글은 ingress nginx controller의 대용량 트래픽 환경에서의 병목 현상 분석의 두 번째 글로 1부에서 문제 발생의 배경과 ingress-nginx-controller의 구조적인 측면에서 발생했던 원인에 대해 파악 했다면, 2부에서는 controller에서 병목이 발생한 근본적인 원인을 찾는 과정과 이를 해결하는 방법에 대해 정리해보겠습니다.본론에 들어가기에 앞서 본 글은 golang과 kubernetes 그리고 prometheus에 대한 기본적인 이해가 필요합니다. golang은 자체적인 문법이 간단해서 초보자가 코드를 봐도 이해하기 어렵지 않으나 kubernetes와 prometheus에 대해서는 사용해본 경험이 있는 수준의 배경 지식이 있어야 본론을 이해하기 수월합니다. 각 기술셋에 대한 자세한 내용을 모두 설명하기는 어려우나 설명 중간중간에 최대한 이해를 도울 수 있게 설명을 해보도록 해보겠습니다.1부에서 간단하게 설명했던 Ingress Nginx Controller(이하 IC)에 대해 조금 더 설명을 해보겠습니다. IC는 kubernetes에서 Pod 형태로 실행됩니다. IC Pod 내부에는 크게 세 종류의 프로세스가 실행되며 IC, Nginx master, Nginx worker가 이에 해당합니다. 이 세 종류의 프로세스는 Pod의 리소스를 공유합니다. 이런 구조 때문에 Nginx Master나 Worker 프로세스 뿐만 아니라 IC 프로세스 메모리 사용량이 늘어나게 되면 IC Pod의 메모리 사용량이 증가하게됩니다. 마지막으로 IC 프로세스의 주요 역할은 아래와 같습니다• Nginx의 master, worker 프로세스를 실행하고 관리• kubernetes 리소스로 관리되는 Nginx 관련 설정들을 Nginx 프로세스와 동기화이번 트러블 슈팅 과정에서 중심적으로 살펴볼 IC 프로세스의 동작은 마지막 항목인 메트릭 수집 부분입니다.1부에서 nginx worker가 생성하는 메트릭들을 소켓 통신을 통해 IC 프로세스로 전달되고, 이 메트릭들을 처리하는 과정에서 병목이 발생할것으로 추정하며 마무리 했었습니다. 이번에는 해당 추정이 맞았는지 확인하는 과정, 그리고 병목 현상을 해결하는 방법을 찾는 과정을 자세히 정리해보겠습니다.go는 자체적으로 프로세스를 진단할 수 있는 프로파일 기능을 풍부하게 지원하고 있고 간단한 설정 및 CLI을 활용해 모니터링이 가능합니다. 관련해서 프로파일 설정 및 자세한 활용 방법에 대해서는 카카오 테크 블로그의 “Golang GC 튜닝 가이드 포스트”(https://tech.kakao.com/posts/618)를 참고하시면 좋습니다. 앞서 안에 고루틴 영역을 병목지점으로 추정했으니, 실제로 해당 지점에 병목이 있는지를 goroutin 프로파일을 통해서 확인해 봤습니다.goroutine 프로파일에서 가장 많은(4309개
go
kubernetes
prometheus
카카오
Ingress Nginx Controller의 Prometheus Metric 병목 현상: 원인 분석과 해결 (1부)
안녕하세요 광고추천 조직에서 타게팅 광고 서빙 시스템을 당당하고 있는 푸입니다.안녕하세요. 카카오 광고 추천팀에서 광고 추천 개발 업무를 담당하는 pooh.duck입니다. 이 글에서는 Ingress Nginx Controller에서 발생한 Prometheus metric 병목 현상에 대한 원인 분석과 해결 방법을 소개합니다. 본 글은 1부와 2부로 구성되어 있으며, 실무에서 Trouble Shooting을 어떻게 하는지, Ingress Nginx Controller, Go 프로파일링에 관한 내용을 담고 있습니다. 1부에서는 문제 발생의 배경과 원인 분석 과정을 상세히 설명하고, 2부에서는 이를 바탕으로 한 해결 방법을 소개합니다. 단계별로 우리 팀이 겪었던 실제 사례와 적용했던 방법들을 공유하며, 비슷한 문제를 겪고 있는 다른 분들께 도움이 되기를 기대합니다.우리는 웹사이트를 방문할 때마다 다양한 광고를 접하게 됩니다. 이러한 광고가 사용자에게 노출되기까지 여러 카카오 광고 API 서버들이 상호작용을 하게 되고, 이에 따라 대부분의 광고 API 서버들은 평균적으로 매우 높은 트래픽을 받게 됩니다. 제가 담당하는 API 서버 중 하나는 피크 시간대에 최대 약 16만 req/sec의 요청을 처리하고 있습니다.대용량 트래픽을 처리하기 위해서, 저희 API 서버는 Kubernetes 위에서 다수 Pod를 실행 중입니다. 이 서버들에 HTTP(S) 트래픽을 라우팅하기 위해 Ingress를 사용하고 있으며, 구현체로는 가장 범용적으로 사용되는 Ingress Nginx Controller를 채택하고 있습니다.현재 저희는 재해 복구(Disaster Recovery)와 부하 분산을 위해 두 개의 Region에 걸쳐 다수의 Ingress Nginx Controller를 구성해 운영하고 있습니다.저희는 서비스 모니터링을 위해 서버에서 발생하는 Metric들을 Prometheus로 수집하고, Grafana를 통해 모니터링하고 있습니다. 그러던 어느 날 모든 Nginx 'request volume’이 No Data라는 알람이 발생했습니다. 또한, 간헐적으로 기록되는 Metric도 정상치에 비해 매우 낮게 기록되는 것을 확인할 수 있었습니다.Request Volume은 Nginx의 Prometheus Metric 중 하나로, 현재 Nginx가 처리하는 Request Count를 뜻합니다. 이 값이 Null이라는 것은 현재 Nginx 자체에 문제가 발생해 트래픽을 제대로 처리하지 못하고 있거나, Nginx가 처리하는 요청에 대한 metric이 정상적으로 수집되지 않는 상태임을 뜻합니다. 이에, 서비스를 점검해 보니 서버는 요청을 정상적으로 처리하고 있었습니다. 만약 Nginx에 문제가 생겼다면 이는 불가능한 일입니다.이러한 현상은 트래픽이 일정 기준치를 상회하면 재현된다는 것을 확인할 수 있었습니다. 아래와 그래프와 같이 Metric이 요동치다, Metric이 유실되고 이후 트래픽이 감소하면 Metric이 복구되는 것을 관찰할 수 있었습니다. 아래 그래프는 Ing
go
네이버
Kubernetes Job과 커스텀 컨트롤러를 활용한 배치 처리 경험기
배치 작업을 VM 서버에서 실행해 동시 실행에 어려움을 겪은 적이 있나요?이 글에서는 Kubernetes Job을 활용해, 기존에는 VM 서버에서 실행되던 배치 작업이 클러스터에서 실행되도록 아키텍처를 변경해 작업의 효율성을 높이고, Kubernetes 커스텀 컨트롤러로 Job 스케줄러를 구현해 Job 실행을 더 유연하게 관리한 방법을 공유하고자 합니다.동시에 실행하고 싶은 배치가 너무 많다프로젝트 초기에는 실행해야 하는 배치 수가 적기 때문에 간편하게 VM 서버 한 대에서 모든 작업을 처리할 수 있습니다. 하지만 프로젝트를 운영해 갈수록 실행해야 하는 배치 수는 점점 늘어나고 VM 서버 한 대로는 해결하기 힘든 상황이 옵니다.예를 들어보겠습니다. VM 서버 한 대로 특정 시간에 사용자에게 다양한 알림을 보내고 싶다면 어떻게 해야 할까요?일반적인 운영 환경에서는 VM 장비 한 대로는 CPU, 메모리 등 자원 할당의 문제로 여러 배치 작업을 동시에 실행하기 힘들기 때문에 서로 연관이 없는 독립적인 배치 작업이라도 동시에 실행하지 못하고 하나의 작업이 끝날 때까지 기다렸다가 다른 작업을 시작해야 합니다.만약 동시에 여러 작업을 실행하고 싶다면 서버를 추가해서 각각 실행해야 합니다. 하지만 서버를 추가하면 비용이 증가할 뿐 아니라 관리 포인트가 늘어나고, 이 경우 특정 시간에만 작업을 실행하기 때문에 대부분의 시간에 서버가 사용되지 않아서 자원을 효율적으로 사용할 수 없습니다. 그렇다고 해서 이 작업을 위해 특정 시간에만 새로운 서버를 설정하는 방법은 확장성이 떨어집니다.그래서 이런 문제점을 해결하기 위해 Kubernetes Job을 활용해 배치 작업을 클러스터에서 실행할 수 있게 했습니다.클러스터에서 일회성 작업을 실행할 수 있는 Kubernetes Job 오브젝트Kubernetes Job은 Kubernetes 클러스터에서 일회성 작업을 실행하기 위한 오브젝트입니다.의존성 없는 다수의 배치 작업을 각각 Job으로 실행하면 하나 이상의 컨테이너에서 배치 작업을 독립적으로 수행할 수 있어 전체 배치 작업의 실행 시간이 단축되고 시스템 전체의 효율이 향상됩니다.뿐만 아니라 Kubernetes의 자동 확장 및 복구 기능은 시스템의 안정성을 높이고 유지 보수 부담을 줄여줍니다. 또한 한 번 Job을 구성해두면 클러스터만 변경해 실행이 가능하기 때문에 이중화에도 효과적입니다.그럼 Kubernetes Job이 어떤 식으로 동작을 하는지 간단하게 알아보고, Job 템플릿을 생성 후 실제로 실행하고 모니터링해 보겠습니다.Kubernetes Job 동작 방식Kubernetes Job은 클러스터 내에서 자원을 조정하고 작업을 스케줄링하는 컨트롤 플레인을 통해 파드에 스케줄링받아 실행됩니다.출처: Kubernetes Components사용자가 Job 생성을 요청하면 Kubernetes API 서버가 요청을 받아서, 클러스터의 모든 상태 정보를 저장하는 etcd에 리소스를 저장합니다.etcd에 리소스가 저장되면, 해당 리소스의 이벤트를 감시하는 컨트롤러 매니저가
go
helm
kubernetes
Copyright © 2025. Codenary All Rights Reserved.