기술 블로그 모음

국내 IT 기업들의 기술 블로그 글을 한 곳에서 모아보세요

전체 프론트엔드 백엔드 데브옵스 AI 아키텍처 DB 기타
Java 24 and IntelliJ IDEA
JetBrain Korea
Java 24 and IntelliJ IDEA

IntelliJ IDEA has supported Java 24 since an earlier release, with more enhancements being added in the later releases! I’m often asked, “What’s the best feature of Java 24?” My answer? Why pick ju...

ESBuild를 위한 HMR, 직접 만들기
토스
ESBuild를 위한 HMR, 직접 만들기

프론트엔드 개발 경험을 향상시키는 HMR(Hot Module Replacement)의 원리와 다양한 번들러가 HMR을 어떻게 지원하는지 살펴보고, ESBuild 기반 번들러를 직접 개발한 과정을 소개드려요.

기술블로그를 책으로, “요즘 우아한 AI 개발” 출간!
우아한형제들
기술블로그를 책으로, “요즘 우아한 AI 개발” 출간!

이번엔 AI 이야기 "요즘 우아한 AI 개발" 우아한형제들의 기술블로그 글을 엮은 두 번째 책, "요즘 우아한 AI 개발"을 소개합니다! 2023년 기술블로그 글을 엮어 펴낸 첫 책 "요즘 우아한 개발"이 좋은 반응을 얻은 데 힘입어, 이번에는 AI·데이터·로봇 이야기를 담은 시리즈 2탄, "요즘 우아한 AI 개발"을 출간했습니다. 🎉 "요즘 우아한 ...

자료구조를 활용한 복잡한 프론트엔드 컴포넌트 제작하기
토스
자료구조를 활용한 복잡한 프론트엔드 컴포넌트 제작하기

왜 토스증권 PC의 그리드 레이아웃을 왜 직접 구현하게 되었는지, 그리고 어떻게 만들어져 있는지를 이제부터 소개해 드릴게요.

NGINX Location 매칭 가이드
NGINX STORE
NGINX Location 매칭 가이드

NGINX Location 매칭 가이드 이번 포스트에서는 NGINX Location 블록별 요청 URI 가이드에 대한 설명입니다. NGINX는 웹 서버 소프트웨어로, 높은 성능과 안정성을 자랑합니다. 다양한 기능 중에서도 Location 블록은 특정 URI에 대한 요청을 처리하는 데 매우 중요한 역할을 합니다. 아래 자세한 가이드를 확인하려 상황에 맞...

리디, ‘AI TTS’ 도입… 자연스럽고 깊은 몰입감 선사
리디
리디, ‘AI TTS’ 도입… 자연스럽고 깊은 몰입감 선사

사람이 읽는 듯한 자연스러운 음성으로 생생하고 몰입감 있는 독서 경험 제공 The post 리디, ‘AI TTS’ 도입… 자연스럽고 깊은 몰입감 선사 appeared first on 리디주식회사 RIDI Corporation.

AI 시대, 직원 중심 애플리케이션 사용성 설계 전략
삼성 SDS
AI 시대, 직원 중심 애플리케이션 사용성 설계 전략

이 글은 AI 시대에 변화하는 업무 환경 속에서 직원들의 생산성을 극대화할 수 있는 애플리케이션 사용성 설계 전략을 다룹니다.

네이버 거리뷰 3D, 디지털 트윈을 곁들인
네이버 D2
네이버 거리뷰 3D, 디지털 트윈을 곁들인

연구실의 기술은 서비스나 상품을 통해 세상과 만나기를 기다립니다. 제가 속한 네이버랩스의 디지털 트윈(Digital Twin) 기술도 마찬가지입니다. 디지털 트윈은 현실 공간을 복제하여 가상 환경에서 3차원으로 동일하게 구현하는 기술로, 그간에는 주로 로봇과 자율주행의 핵심 기술 중 하나였습니다. 이 기술을 다양한 네이버 서비스에 확대 적용하고자 해왔...

IntelliJ IDEA에서 데이터베이스를 이용한 Java 개발 시 생산성을 높이는 9가지 팁
JetBrain Korea
IntelliJ IDEA에서 데이터베이스를 이용한 Java 개발 시 생산성을 높이는 9가지 팁

이 글에서는 데이터베이스를 이용해 Java 애플리케이션을 개발할 때 IntelliJ IDEA에서 생산성을 높일 수 있는 9가지 시간 절약 방법을 알려 드립니다. 새 프로젝트를 시작하거나 진행 중인 프로젝트에 뛰어드는 모든 경우에 도움이 될 팁입니다. IntelliJ IDEA Ultimate 다운로드 프로퍼티에서 자동으로 데이터 소스 만들기 Intell...

Rook Ceph 클러스터 Kubernetes 배포 가이드
NGINX STORE
Rook Ceph 클러스터 Kubernetes 배포 가이드

Rook Ceph 클러스터 Kubernetes 배포 가이드 이 포스트는 Kubernetes 클러스터에 Rook Ceph 클러스터를 배포하여 워커 노드의 스토리지를 통해 Ceph의 분산 스토리지 시스템을 구성하는 방법을 설명합니다. Rook은 Ceph를 Kubernetes에서 네이티브하게 실행할 수 있도록 지원하며, 이를 통해 블록, 파일, 오브젝트 스...

[웹툰 파헤치기]색다른 판타지물… ‘이종족 보호 관리국’
리디
[웹툰 파헤치기]색다른 판타지물… ‘이종족 보호 관리국’

The post [웹툰 파헤치기]색다른 판타지물… ‘이종족 보호 관리국’ appeared first on 리디주식회사 RIDI Corporation.

Amazon SageMaker Unified Studio 정식 출시
AWS KOREA
Amazon SageMaker Unified Studio 정식 출시

오늘, Amazon SageMaker Unified Studio의 정식 출시를 발표합니다. 조직의 모든 데이터를 찾아서 액세스하고 거의 모든 사용 사례에서 작업에 가장 적합한 도구를 사용하여 작업을 수행할 수 있는 단일 데이터 및 AI 개발 환경입니다. 제 동료인 Antje는 AWS re:Invent 2024에서 이 제품을 평가판으로 선보이면서 다음과...

이스트시큐리티 보안툰 #25|보안행 열차에서 살아남기 (Feat. 보안솔루션 서열전쟁)
이스트 시큐리티
이스트시큐리티 보안툰 #25|보안행 열차에서 살아남기 (Feat. 보안솔루션 서열전쟁)

안녕하세요, 이스트시큐리티입니다.   기업 내 다양한 보안 솔루션을 따로 운영하며 복잡하고 비효율적인 관리에 어려움을 느끼고 계신가요? 이제 이스트시큐리티의 AI 기반 차세대 통합보안 플랫폼, '알약 XDR'로 간편하게 해결 가능합니다. 알약 XDR은 기존의 특정 기능에 특화된 SIEM(탐지), SOAR(자동화)의 강점을 모두 결합하여 탐지부...

Amazon S3 Tables와 Amazon SageMaker Lakehouse 통합 정식 출시
AWS KOREA
Amazon S3 Tables와 Amazon SageMaker Lakehouse 통합 정식 출시

지난 AWS re:Invent 2024에서 Amazon S3 Tables를 출시했습니다. Amazon S3 테이블은 대규모 테이블 형식 데이터 저장을 간소화하는 내장 Apache Iceberg를 지원하며, 통합된 개방형 보안 데이터 레이크하우스로 분석 및 AI를 간소화하는 Amazon SageMaker Lakehouse를 출시했습니다. 또한 Amazo...

[국외발신][경찰청통보문자]위반 통지문자가 전달되었습니다 열람바람 : hxxp://b.b***.work
이스트 시큐리티
[국외발신][경찰청통보문자]위반 통지문자가 전달되었습니다 열람바람 : hxxp://b.b***.work

  [3월 둘째주] 알약 스미싱 알림 본 포스트는 알약M 사용자 분들이 '신고하기' 기능을 통해 알약으로 신고해 주신 스미싱 내역 중 '특이 문자'를 자체 수집,&n...

AI 프로젝트에서 ROI가 더욱 중요한 이유
삼성 SDS
AI 프로젝트에서 ROI가 더욱 중요한 이유

이 아티클은 AI 프로젝트에 얼마나 많은 재정, 시간, 인적 자원을 투입해야 할지 측정하는 ROI의 중요성에 대해 깊은 통찰을 제시합니다.

[무엇이든 물어보안] 회사에서 주고받는 파일은 모두 안전할까?
이스트 시큐리티
[무엇이든 물어보안] 회사에서 주고받는 파일은 모두 안전할까?

안녕하세요, 이스트시큐리티입니다.   업무 중 자주 주고받는 파일들, 이메일 첨부파일이나 다운로드한 문서가 당연히 안전할 거라 생각하시나요? 하지만 우리가 익숙하게 사용하는 파일들조차도 보안 위협을 포함하고 있을 가능성이 있습니다. 오히려 ‘늘 받던 파일’, ‘믿을 수 있는 상대가 보낸 파일’이라는 ...

k8s – Multi Master Node 구성 (고가용성)
NGINX STORE
k8s – Multi Master Node 구성 (고가용성)

k8s – Multi Master Node 구성 (고가용성) Kubernetes 클러스터는 단일 마스터 노드로 운영될 경우 장애 발생 시 클러스터 전체가 정상적으로 동작하지 않을 위험이 있습니다. 이를 방지하기 위해 Multi Master Node 구성을 활용하면 클러스터의 안정성과 가용성을 향상시킬 수 있습니다. 본 문서에서는 Multi ...

SVG 포맷으로 유포되는 악성코드 주의!
이스트 시큐리티
SVG 포맷으로 유포되는 악성코드 주의!

    안녕하세요? 이스트시큐리티 시큐리티대응센터(이하 ESRC)입니다. ESRC에서는 지난해 하반기부터 SVG 포맷의 악성코드가 유포되는 공격들을 모니터링하던 중 최근 국내 기업을 대상으로 해당 공격이 진행된 정황을 포착하였습니다.   해당 공격은 글로벌 해운 업체의 선적물 안내 메일로 위장한 피싱 메일을 통해 유포되었으며...

K9s – Kubernetes Cluster Manager
NGINX STORE
K9s – Kubernetes Cluster Manager

K9s – Kubernetes Cluster Manager K9s 는 Kubernetes 클러스터 관리의 효율성을 극대화하기 위해 설계된 강력한 CLI 도구입니다. YAML 파일을 작성하거나 복잡한 kubectl 명령어를 기억하지 않고도 직관적인 Terminal UI에서 Kubernetes 리소스를 손쉽게 관리하고 모니터링할 수 있습니다. ...

네이버 AI, 의료진의 시간을 되찾다 | Healthcare AI팀의 이야기
네이버 클라우드
네이버 AI, 의료진의 시간을 되찾다 | Healthcare AI팀의 이야기

안녕하세요, 누구나 쉽게 시작하는 클라우드 네이버클라우드(ncloud.com)입니다. Healthcare AI팀은 어떻게 의료 현장을 변화시키고 있을까요? 기술을 통해 의료 환경에 실질적인 변화를 불러오겠다는 목표와 연구에 대한 책임감을 가지고 다양한 기술적 도전을 이어가고 있는 Healthcare AI 팀 이재덕 님과 조혜정 님. 인턴으로 시작해 이...

AI 에이전트의 확산과 과제
삼성 SDS
AI 에이전트의 확산과 과제

이 아티클은 인프라 현대화, 데이터 통합, 보안 및 규정 준수 문제를 중심으로 AI 에이전트 도입의 현실적 난관과 기회를 살펴봅니다.

2024 Frontend Global Workshop 참석 후기
라인
2024 Frontend Global Workshop 참석 후기

들어가며 안녕하세요. LINE+ UIT 조직에서 프런트엔드 개발을 하고 있는 강형민입니다. LY에서는 매년 'Front-end Global Workshop'을 개최하고 있습니다. ...

클라우드 스토리지 유형과 특징, 활용 방안
NGINX STORE
클라우드 스토리지 유형과 특징, 활용 방안

클라우드 스토리지 유형과 특징, 활용 방안 이 포스트는 클라우드에서 주로 제공하는 세 가지 주요 스토리지 유형인 오브젝트 스토리지, 파일 스토리지, 블록 스토리지의 특징과, 각각의 스토리지를 어떤 상황에서 활용하는 것이 적합한지 설명합니다. 이러한 스토리지는 클라우드뿐만 아니라 온프레미스 환경에서도 활용할 수 있으며, 요구사항에 따라 적절한 방식으로 ...

[현장스케치] "AI-DOL", 인간의 가장 창의적 영역을 AI가 어떻게 이해하고 지원할 수 있을까?
네이버 클라우드
[현장스케치] "AI-DOL", 인간의 가장 창의적 영역을 AI가 어떻게 이해하고 지원할 수 있을까?

안녕하세요, 누구나 쉽게 시작하는 클라우드 네이버클라우드 ncloud.com입니다. "AI가 인간을 대체할 수 있을까?" 이 질문에서 시작된 MBC 예능 프로그램 "PD가 사라졌다!'가 시즌 2, 'AI-DOL (AI돌)'로 돌아옵니다! 이번 프로그램에서는 아이칠린(ICHILLIN'), 첫사랑(CSR), 우아(Woo!ah!), 퍼플키스(PURPLE K...

Amazon Bedrock, DeepSeek-R1 완전 관리형 서버리스 모델 정식 출시
AWS KOREA
Amazon Bedrock, DeepSeek-R1 완전 관리형 서버리스 모델 정식 출시

1월 30일부터 Amazon Bedrock Marketplace와 Amazon Bedrock 사용자 지정 모델 가져오기를 통해 DeepSeek-R1 모델을 Amazon Bedrock에서 사용할 수 있게 되었습니다. 그 이후로 수천 명의 고객이 Amazon Bedrock에 이 모델을 배포했습니다. 고객들은 안전한 AI 배포를 위한 견고한 가드레일과 포괄...

AWS 주간 소식 모음: Amazon Q CLI 에이전트, AWS Step Functions, AWS Lambda 업데이트 등
AWS KOREA
AWS 주간 소식 모음: Amazon Q CLI 에이전트, AWS Step Functions, AWS Lambda 업데이트 등

북반구의 날씨가 점차 따뜻해짐에 따라, 학습 및 교류의 기회가 더욱 많아지고 있습니다. 이번 주에 샌프란시스코에 머물 예정이며, AWS GenAI Loft에서 열리는 Nova Networking Night에서 만나 라이브 데모와 실제 구현을 통해 Amazon Nova 파운데이션 모델(FM)의 세계를 자세히 살펴보겠습니다. AWS Pi Day는 이제 연...

NELO Alaska: 대용량 로그 데이터 저장을 위한 Apache Iceberg 도입기
네이버 D2
NELO Alaska: 대용량 로그 데이터 저장을 위한 Apache Iceberg 도입기

로그 모니터링 시스템은 서비스 운영을 위해서 반드시 필요한 시스템입니다. 로그 모니터링 시스템 구축에는 인덱스 기반의 빠른 검색을 제공하는 검색 엔진인 Elasticsearch가 널리 사용됩니다. 네이버도 Elasticsearch 기반의 로그 모니터링 시스템을 구축했으며, 수천 대의 서버로 수 페타바이트 규모의 로그 데이터를 저장하고 있습니다. 최근 들어 서비스 규모가 확장되고 저장해야 하는 로그 데이터의 규모와 트래픽 양이 급속도로 증가하면서 Elasticsearch 기반의 로그 모니터링 시스템은 비용 문제와 더불어 확장성 문제에 직면하게 됐습니다. 네이버는 저비용으로 대용량의 로그 데이터를 수집할 수 있도록 Apache Iceberg(이하 Iceberg)를 도입한 신규 컴포넌트 Alaska를 개발해 네이버의 로그 모니터링 시스템 플랫폼 NELO에 적용했습니다. 이 글에서는 기존 로그 모니터링 시스템의 문제와 Iceberg의 특징을 소개하고, Alaska의 작동 방식과 Alaska를 NELO에 적용한 이후의 변화를 소개합니다. Elasticsearch 기반 기존 로그 모니터링 시스템의 한계 Elasticsearch를 기반으로 구축된 기존 로그 모니터링 시스템의 구조를 간략하게 도식화하면 다음 그림과 같습니다. 클라이언트로부터 수신된 로그 데이터는 Kafka에 적재된 후 Elasticsearch에 저장됩니다. Elasticsearch는 SSD 타입의 스토리지로 구성된 Hot 계층(Hot Tier)과 HDD 타입의 스토리지로 구성된 Warm 계층(Warm Tier)으로 구분되어 있습니다. 로그 데이터는 Hot 계층에 3일간 저장된 후 Warm 계층으로 이동되어 최대 90일까지 저장됩니다. 이렇게 Hot 계층과 Warm 계층의 두 단계로 나누어 데이터를 저장하면 검색이 빈번하게 일어나지 않는 데이터를 효율적이면서 저비용으로 저장할 수 있습니다. 기존 로그 모니터링 시스템은 수년간 이와 같은 구조로 운영되었습니다. 그동안 데이터가 증가함에 따라 Warm 계층에 저장된 데이터의 크기도 급증했습니다. Elasticsearch는 단일 클러스터로 저장할 수 있는 데이터의 크기에 제한이 있기 때문에 다수의 Elasticsearch 클러스터를 구성해 클러스터 수준에서 확장을 진행했습니다. 그 과정에서 모든 클러스터가 한계 수준까지 도달해 운영 장애를 빈번하게 겪었습니다. 연간 수십억 원의 인프라 사용 비용도 부담이 되었습니다. 두 계층으로 구성된 Elasticsearch 클러스터는 더 이상 로그를 효율적으로 저장할 수 있는 구조가 아니게 되었습니다. 새로운 타입의 데이터 저장 스토리지의 필요성 Warm 계층에 저장된 데이터의 크기가 급증하는 이유에는 장기간 로그의 저장에 대한 요구 사항도 있습니다. 기존 로그 모니터링 시스템은 Elasticsearch에 최대 90일까지 로그 데이터를 저장할 수 있게 허용했습니다. 하지만 서비스의 법적 요구 사항 등의 이유로 예외로 1년 이상의 로그 데이터 저장을 허용하고 있었습니다. 기존 로그 모니터링 시스템이 한계에 도달하면서 이러한 장기간 로그 데이터 저장에 대한 요구 사항을 Elasticsearch로 수용하는 것이 적합한지 검토하게 되었습니다. 이를 확인하기 위해 실제로 로그 데이터의 사용자들이 어느 시점의 데이터에 관심이 많은지 분석해 보았습니다. 다음은 한 달 동안 사용자들의 검색 요청 로그를 분석한 그래프입니다. 그래프에서 X축인 Data age는 데이터가 저장되고 지난 시간을 의미합니다. Y축은 해당 Data age에 속한 데이터를 검색하는 쿼리의 비율입니다. 분석 결과, 전체 검색 쿼리 중 95%의 쿼리가 당일에 발생한 데이터에 대한 것이었으며, 99%의 쿼리가 일주일 이내의 데이터를 위한 것이었습니다. 단 0.5%의 쿼리만이 2주 이상 지난 데이터를 요청하는 쿼리였습니다. Elasticsearch는 일반적으로 데이터 저장과 쿼리 계산을 위한 컴퓨팅을 같은 노드에서 담당하고 있기 때문에 이렇게 거의 검색되지 않는 데이터를 저장하는 것은 효율적인 일이 아닙니다. 최신 버전의 Elasticsearch는 원격 스토리지에 데이터를 저장하고 검색하는 기능을 제공합니다. 하지만 Elasticsearch의 규모가 한계 크기에 도달한 로그 모니터링 시스템에 적용할 수는 없었습니다. Elasticsearch는 마스터 노드가 관리할 수 있는 메타데이터 규모에 한계가 있기 때문입니다. 이러한 문제를 해결하려면 Elasticsearch에는 검색이 자주 일어나는 단기간의 데이터 저장만 허용하고, 장기간 데이터를 저장할 새로운 스토리지가 필요하다는 판단이 들었습니다. Elasticsearch를 대체하는 신규 스토리지에서는 데이터 저장을 위한 스토리지와 검색을 위한 컴퓨팅을 분리한다 아이디어를 기본으로 설계를 시작했습니다. 또한 Elasticsearch처럼 특정 쿼리 엔진에 제한(lock-in)되지 않는 오픈 데이터 포맷을 중요한 요구 사항 중 하나로 설정했습니다. 저비용의 스토리지에 검색이 가능한 데이터 포맷으로 데이터를 저장할 수 있는 여러 방식을 비교하고 분석했습니다. 여러 방식으로 시뮬레이션을 실행한 결과, Iceberg로 실행한 시뮬레이션에서 현재 수준에서 기존 로그 모니터링 시스템보다 최소 50% 이상 비용을 절감할 수 있다는 결론을 얻었습니다. 최종적으로 Iceberg를 선택해 로그 데이터 저장을 위한 새로운 타입의 스토리지를 구현한 컴포넌트인 Alaska를 개발해 적용했습니다. Iceberg의 특징 기존 로그 모니터링 시스템의 구조와 규모 때문에 새로운 타입의 스토리지에는 다음과 같은 요구 사항이 있었습니다. 데이터 쓰기/읽기가 동시에 가능해야 한다. 데이터 쓰기/읽기가 발생하는 상황에서 동시에 스키마 변경이 가능해야 한다. 단일 테이블로 페타바이트 규모의 데이터를 저장할 수 있어야 한다. 수십만 개의 테이블 운영이 가능해야 한다. 데이터 포맷으로 인한 쿼리 엔진 제한이 없어야 한다. 데이터 저장소와 쿼리 컴퓨팅 노드가 분리되어 있어야 한다. 데이터 압축 효율이 우수해야 한다. 이 요구 사항을 구현할 수 있는 기술로는 오픈 테이블 포맷을 사용하는 Iceberg와 Delta Lake, Apache Hudi가 있습니다. 그 중에 Iceberg의 커뮤니티가 가장 활발하게 업데이트되고 있었습니다. 또한 Databricks, Snowflake 등 여러 회사가 Iceberg를 두고 벌이던 기술 경쟁이 Databricks가 Iceberg를 만든 Tabular 회사를 인수하면서 일단락 되었고, Iceberg가 오픈 테이블 포맷 기술의 주도권을 갖게 되었습니다. 여러 사정을 고려해서 Alaska 컴포넌트에 Iceberg의 오픈 테이블 포맷을 적용하기로 결정했습니다. Iceberg는 '데이터', '메타데이터', '카탈로그'의 세 부분으로 나누어 데이터를 저장합니다. 데이터는 칼럼 스토리지 데이터 포맷인 Parquet로 관리되고, zstd 형식으로 압축됩니다. 이러한 데이터는 오브젝트 스토리지에 저장됩니다. 메타데이터는 하나의 테이블을 구성하기 위한 데이터 파일의 집합 관계와 스키마 정보를 JSON, Avro와 같은 형태로 저장합니다. 데이터와 마찬가지로 메타데이터도 오브젝트 스토리지에 저장됩니다. 카탈로그는 메타데이터의 메타라고 볼 수 있습니다. 가장 최신의 메타데이터의 위치 정보와 같은 최소한의 정보만 카탈로그에서 관리됩니다. 일반적으로 카탈로그 데이터는 데이터베이스에 저장됩니다. 이와 같이 테이블을 구성한 파일에 대한 메타데이터까지 함께 관리하기 때문에 Iceberg를 단순한 데이터 포맷이 아니라 테이블 포맷이라고 부릅니다. Iceberg는 ACID 트랜잭션을 지원하며 schema evolution, hidden partitioning 등 데이터를 다루는 데 유용한 기능을 제공합니다. 신규 로그 모니터링 시스템의 구조 Iceberg를 기반으로 개발한 새로운 로그 모니터링 시스템은 기존 Elasticsearch 기반의 로그 모니터링 시스템을 대체하는 것이 아닙니다. Elasticsearch에는 실시간 모니터링이 필요한 짧은 기간의 로그를 저장하고, 장기간 보관이 필요한 데이터는 새로운 스토리지를 활성화해 저장하도록 설계했습니다. 기존 로그 모니터링 시스템에서는 Kafka에 적재된 로그 데이터를 Elasticsearch에 인덱싱하는 방식을 사용했습니다. 신규 로그 모니터링 시스템도 동일한 Kafka 토픽으로부터 데이터를 읽어 Iceberg 테이블 포맷으로 저장합니다. Elasticsearch의 Warm 계층에서 데이터를 읽어 저장하는 방식을 택하지 않은 이유는 다음과 같습니다. 실시간 검색/모니터링이 필요하지 않은 데이터는 Elasticsearch에 저장하지 않고 직접 Iceberg로 저장할 수 있습니다. Elasticsearch와 Iceberg에 중복 데이터가 저장되더라도 Iceberg 기반 시스템 비용이 매우 저렴합니다. Elasticsearch의 Warm 계층으로부터 데이터를 읽으면 HDD 기반의 클러스터에 큰 부하가 발생합니다. 신규 로그 모니터링 시스템의 아키텍처는 다음 그림처럼 크게 데이터 적재 부분(Data ingestion & optimization)과 데이터 쿼리 부분(Data query)으로 나눌 수 있습니다. 데이터 적재 부분은 다음과 같은 요소로 구성되어 있습니다. Orca: Kafka의 데이터를 Iceberg 테이블 포맷으로 변환해 오브젝트 스토리지에 저장하는 컴포넌트 Polarbear: Iceberg 테이블 데이터를 최적화하고 데이터 라이프사이클을 관리하는 컴포넌트 Puffin: Iceberg 카탈로그 컴포넌트 데이터 쿼리 부분은 다음과 같은 요소로 구성되어 있습니다. Trino: Icerbeg 테이블 조회를 위한 쿼리 컴퓨팅 엔진 API Server: Alaska 데이터 조회를 위한 NELO Open API 제공 Frontend: Alaska 쿼리 UI 제공(웹 UI) 신규 로그 모니터링 시스템은 데이터 프로세싱을 위해서 Kappa Architecture를 따르고 있습니다. 즉, 실시간으로 저장되고 있는 로그 데이터 테이블에 사용자가 접근해 데이터를 조회할 수 있는 구조입니다. 전통적인 Lambda Architecture처럼 여러 개의 테이블을 운용해 데이터 변환 과정을 거쳐 사용자에게 제공하는 방식은 로그 저장 목적으로 사용하기에는 너무 복잡하고 비용 측면에서 효율적이지 않은 구조입니다. Iceberg의 오픈 테이블 포맷은 ACID 트랜잭션을 지원하기 때문에 실시간으로 쓰기가 발생하는 테이블을 동시에 사용자가 읽어도 데이터 정합성을 보장하며 서비스할 수 있습니다. 이러한 구조를 통해서 사용자는 짧은 지연 시간(데이터 동기화 주기 5분) 안에 데이터를 조회할 수 있습니다. 데이터 저장을 위해 사용하는 사내 오브젝트 스토리지 서비스인 Nubes는 MinIO라는 S3 게이트웨이를 활용해 S3 인터페이스를 기반으로 Iceberg와 연동되어 있습니다. 신규 로그 모니터링 시스템의 아키텍처에서 설명한 Orca, Polarbear, Puffin은 모두 Iceberg Java SDK를 기반으로 직접 개발한 컴포넌트입니다. 프로젝트 초기에 오픈 소스를 활용해 PoC(Proof of Concep)를 진행했지만 여러 이유로 오픈 소스를 사용할 수 없었습니다. 신규 로그 모니터링 시스템 개발 초기에 검토한 오픈 소스와 사용 불가 이유는 다음과 같습니다. 데이터 적재 kafka-connect: 기능적 요구 사항은 충족했습니다. 하지만 지원하는 동기화 대상 테이블의 수가 적었습니다. 동기화 대상 테이블의 수가 수십만이었지만, kafka-connect는 테이블의 수가 수백 개의 수준에만 도달해도 OOM(Out of Memory)이 발생했습니다. flink: Kafka의 데이터를 Iceberg로 저장하는 기능은 제공하지만 단일 테이블에 대해서만 작동합니다. 즉, 테이블 fan-out 기능이 존재하지 않습니다. 동기화해야 하는 테이블의 수만큼 flink 애플리케이션을 실행해야 하는 경우가 있어, 현실적으로 운영에 어려움이 있는 문제가 있습니다. 데이터 최적화 Trino, Spark, Hive 등 Iceberg 테이블을 지원하는 쿼리 엔진: 데이터 최적화 및 라이프사이클을 관리하는 것이 기능적으로는 가능합니다. 그러나 요구하는 테이블의 규모를 지원하려면 비용 부담이 커집니다. 또한 세부적인 스케줄링 및 스로틀링 설정이 어렵기 때문에 오브젝트 스토리지에 과한 부담이 발생할 수 있습니다. 카탈로그 Hive metastore, Nessie, Polaris, Unity 등 Iceberg 테이블을 지원하는 카탈로그: 최초 설계에서는 Hive metastore를 사용했으나 Hive lock 버그로 인해 경합이 심할 때에는 데드락에 빠지는 이슈가 발생했습니다. 또한 장기적으로 Iceberg REST 카탈로그를 표준으로 만들고, 다른 카탈로그를 직접적으로 사용하는 것을 중단할 계획이 있다는 것을 Iceberg 커뮤니티를 통해서 확인했습니다. REST 카탈로그는 표준 스펙만 존재하며 공식적인 구현체가 존재하지 않습니다. Snowflake에서 최근에 Polaris라는 REST 카탈로그 스펙에 준한 카탈로그를 공개했지만 특정 카탈로그에 제한될 우려가 있습니다. 또한 카탈로그를 사용자에게 공개해 데이터 연동(data federation)을 제공할 계획이 있어, 컴포넌트를 직접 개발하는 것이 효율적이라고 판단했습니다. 데이터 적재 다음 그림은 Orca 컴포넌트가 Kafka의 데이터를 Iceberg 테이블 포맷으로 변환해 저장하는 과정을 도식화한 그림입니다. Kafka에 쌓여 있는 로그 데이터를 Iceberg 테이블 포맷으로 변환해 저장할 때에는 다음과 같은 단계로 데이터를 처리합니다. Kafka 데이터 수신 Kafka 토픽으로부터 데이터를 읽습니다. 다중 컨슈머 구성을 통해서 I/O 병목 문제를 해결하고 처리량을 극대화했습니다. 로그 데이터 관리 및 전달 데이터를 수신한 후 데이터를 내부 메모리 큐에 적재합니다. 메모리 큐에 적재된 데이터는 레코드 리포지토리를 통해 각 Iceberg 테이블에 대응하는 Writer로 분배됩니다. 데이터 포맷 변환 및 저장 각 Writer는 데이터를 Parquet 형식으로 변환한 뒤 Writer 내부 메모리 버퍼에 저장합니다. Flush Manager가 특정 주기로 오브젝트 스토리지에 데이터를 저장하고 Iceberg 테이블에 커밋합니다. 간단해 보이는 구조이지만 다음과 같은 여러 가지 상황을 고려해 설계되었습니다. 테이블 fan-out 기능:Kafka 토픽에 저장되어 있는 로그는 tenant별로 분리되어 각 Iceberg 테이블에 저장됩니다. 그렇기 때문에 단일 데이터 스트림에서 다수의 테이블로 데이터를 전송하는 fan-out 기능이 필요합니다. 테이블 데이터가 처음 인입되는 시점에 동적으로 Writer가 생성되고 flush가 실행되는 시점에 메모리가 해제되도록 설계했습니다. 효율적인 메모리 관리:초당 수십만 건에 이르는 로그 데이터를 실시간으로 처리하려면 메모리 사용량 최적화가 필수입니다. 실시간으로 유입되는 데이터를 변환해 메모리에 적재하고 5분 단위로 flush를 진행해 메모리를 주기적으로 확보하도록 설계했습니다. 특정 테이블에 데이터가 많이 유입될 경우에는 해당 테이블에 해당하는 데이터를 파일로 먼저 내보내는 롤오버 동작을 수행합니다. 메모리 사용량이 급증할 경우에는 전체 Writer에서 강제 flush를 실행해 OOM을 예방합니다. Kafka 오프셋 관리:Kafka로부터 읽은 데이터의 Iceberg 테이블 커밋이 완료된 이후에 Kafka 오프셋 커밋이 가능합니다. Kafka로부터 읽어 온 batch 단위로 Iceberg 테이블에 커밋을 하면 너무 작은 파일 단위로 커밋이 실행되기 때문에 처리량 측면에서 성능이 저하될 수 있습니다. 그래서 Kafka로부터 읽은 데이터가 충분히 메모리에 쌓였을 때 커밋을 실행해야 하는데, 이럴 경우 Kafka에서 제공하는 자동 오프셋 커밋 기능을 사용할 수 없어 수동으로 오프셋을 관리해야 합니다.내부 메모리에 오프셋을 저장하고 실제로 Iceberg 테이블에 커밋이 성공한 위치까지의 오프셋만 다시 Kafka에 커밋되도록 구현했습니다. 데이터 손실은 발생하지 않지만 중복 데이터가 Iceberg 테이블에 저장될 수 있는 구조(at-least-once)로 설계했습니다.Iceberg의 equality delete 기능을 사용하면 중복 데이터를 방지할 수 있지만 Iceberg 테이블 운용 비용이 비싸지기 때문에 채택하지 않았습니다. 로그 데이터 유실은 중요한 문제가 될 수 있지만, 중복 발생은 대부분 크게 문제가 되지 않습니다. 또한 모든 로그에 유니크 아이디를 부여하고 있어서, 필요시 사용자가 쿼리를 통해서 중복 데이터를 제거할 수 있도록 안내하고 있습니다. 데이터 변환:기본적으로 신규 필드가 유입될 경우 시스템에서 해당 필드를 String으로 취급해 스키마를 자동으로 업데이트합니다(사용자는 UI와 API를 통해서 신규 필드를 원하는 타입으로 생성할 수 있습니다). 신규 필드가 유입되면 해당 테이블에 대해서 메모리에 쌓여 있던 데이터에 강제 flush를 실행한 이후에 스키마 업데이트를 진행하고 다시 메모리에 데이터를 쌓기 시작합니다.특정 필드에 대해서 변환이 불가능한 경우 에러 필드에 원본 데이터와 이유를 함께 저장합니다. Iceberg 테이블은 칼럼 이름의 대소문자 구분을 지원하지만, 쿼리 엔진이 대소문자 구분을 지원하지 않기 때문에 칼럼 이름을 대소문자를 구분하지 않게(case-insensitive) 설정해야 합니다. 대소문자만 다른 이름을 가진 중복되는 필드가 유입되면 에러 필드에 저장합니다. 또한 String이 아닌 다른 타입으로 생성된 필드에 대해서 지원되지 않는 값으로 데이터가 유입될 경우(예: 숫자 타입에 문자열 유입) 에러 필드에 저장합니다. 사용자는 에러 필드를 조회해 누락된 데이터 값과 누락된 사유를 확인할 수 있습니다.알 수 없는 이유로 데이터 변환에 실패하면 DLQ(dead-letter queue)에 전송해 후처리를 실행할 수 있도록 합니다. 트래픽이 증가해 데이터 적재 컴포넌트를 많은 수로 확장(scale-out)하면 단일 Iceberg 테이블에 대해서 여러 노드가 동시에 Write를 실행하게 됩니다. 이럴 경우 다음과 같은 문제가 발생할 수 있습니다. Iceberg 테이블에 대해 동시에 발생한 커밋이 충돌해 실패 가능성 높아집니다. 여러 노드에 데이터가 분산되어 작은 파일로 쪼개져서 Write가 일어납니다. 이 때문에 오히려 처리량이 저하될 수 있으며 오브젝트 스토리지에도 작은 파일로 인해 부담이 발생할 수 있습니다. 또한 추후 데이터 최적화를 위한 Rewriting 과정에서도 문제가 될 수 있습니다. 위와 같은 문제 때문에 데이터 적재 컴포넌트가 단일 노드에서 최대한의 성능을 낼 수 있도록 최적화에 많은 신경을 써서 개발을 진행했습니다. 추후 Kafka 토픽 커스텀 파티셔너를 통해서 개선할 계획도 있습니다. 데이터 최적화 데이터 최적화 컴포넌트는 다음과 같은 두 가지 역할을 수행합니다. Iceberg 테이블 데이터 최적화 및 라이프사이클 관리 Iceberg 테이블 관련 API 제공 데이터 최적화를 진행하지 않으면 Iceberg 테이블에 쌓이는 파일이 너무 많아져서 전체적인 성능이 저하될 수 있습니다. 이러한 데이터 최적화 및 라이프사이클 관리를 위한 태스크를 주기적으로 실행해 테이블의 상태를 최적의 상태로 유지합니다. 또한 API 서버로부터 Iceberg 테이블에 관련된 메타데이터 정보 및 스키마 업데이트 등을 요청받아 처리하는 역할도 수행합니다. 데이터 최적화 컴포넌트는 임베디드 분산 캐시를 내장하고 있으며, 해당 캐시를 통해서 노드의 리더를 선출합니다. 리더로 선출된 노드는 수행해야 할 테스크를 주기적으로 스케줄링해 내부 시스템 테이블로 생성합니다. 이때 시스템 테이블 또한 Iceberg 테이블을 기반으로 생성됩니다. 나머지 팔로워 노드는 시스템 테이블이 업데이트될 때 자신에게 할당된 태스크를 읽어 실행합니다. Iceberg 테이블 최적화 및 라이프사이클 관리를 위해 실행하는 배치 잡(batch job)은 다음과 같습니다. Rewriting data:같은 시간 파티션 안에 있는 파일을 병합하는 작업입니다.데이터 적재 시 5분 주기로 데이터 flush를 실행하기 때문에 실제 테이블에 쓰인 데이터는 작은 파일로 나누어져 있습니다. 예를 들어 데이터 적재 노드가 1개라면 하루에 최소 288개의 파일이 생성(5분당 최소 1개 파일 생성)됩니다. fan-out 대상 테이블의 수가 10,000개라면 하루에 최소 288만 개의 파일이 생성됩니다. 이 상태로 오랜 시간 데이터 적재를 진행하면 파일의 수가 많아져 메타데이터가 거대해지고 커밋 성능이 저하됩니다. 그리고 작은 파일에 대한 I/O가 증가해 쿼리 성능이 저하됩니다. 지속적인 작은 파일 쓰기는 오브젝트 스토리지에도 부담이 됩니다. 그래서 파일을 병합하는 작업을 주기적으로 실행합니다.테이블은 시간 파티션으로 나누어져 있는데, 같은 시간 파티션 안에 존재하는 파일을 병합하는 작업을 매시간 실행합니다. 목표 병합 파일의 크기는 128MiB로 설정되어 있습니다. 트래픽이 많은 일부 테이블을 제외하고 대부분 1시간 로그 데이터가 1개의 파일로 병합됩니다.시간 순서로 유입되지 않고 과거 시간의 로그와 뒤섞인 데이터(disorder data)가 인입되는 테이블의 경우에는 긴 시간 범위에 대해서 병합 작업을 진행합니다. 로그 모니터링 시스템이 네이버 모바일 앱의 로그 수집도 지원하기 때문에 disorder data가 발생합니다. 운영체제의 정책 등 모바일 기기의 특성상 네트워크, 배터리 상태에 따라 로그를 전송하는 시점이 늦어질 수 있습니다. 그래서 최대 3일 전의 로그까지 수집하는 것을 정책상 허용합니다. 이때 3일 이내의 시간 파티션에 계속 작은 파일이 생성되는 문제가 발생하고, 이러한 테이블에 대해서는 매시간마다 3일 내의 모든 파티션을 병합하는 작업을 실행합니다.데이터 적재 지연이 발생하거나 제대로 된 정보가 수신되지 않을 경우에는 해당 작업 스케줄링을 중단합니다. 데이터 지연을 고려하지 않으면 이미 병합이 종료된 시간 파티션에 다시 작은 파일이 생성되어 문제를 유발할 수 있기 때문입니다. Expire snapshot: 주기적으로 스냅숏을 삭제하는 작업입니다. Iceberg 테이블은 매 커밋마다 스냅숏 정보를 남깁니다. 스냅숏을 관리하지 않으면 무한대로 스냅숏이 생성되어 메타데이터 파일이 매우 커지고, 작은 파일이 쌓이는 문제가 발생합니다. 주기적으로 테이블마다 최근 10개의 스냅숏만 남기고 삭제합니다. Optimize table: Rewriting data와 Expire snapshot을 하나의 잡(job)으로 구성해 파일 병합이 종료된 이후에 스냅숏을 삭제하는 작업입니다. Retention: 보존 기간이 지난 로그를 삭제하는 작업입니다. 각 테이블마다 설정된 로그 보존 기간이 있습니다. 보존 기간이 지난 로그를 하루에 한 번씩 삭제합니다. Delete table: 삭제 요청이 있는 Iceberg 테이블을 물리적으로 삭제하는 작업입니다. 삭제 요청이 있은 시점으로부터 3일(데이터 복구 가능 기간)이 지난 뒤에 실행합니다. Iceberg SDK가 제공하는 삭제 API 실행 이후에도 실제 스토리지에 가비지 데이터가 남아 있을 수 있습니다. S3 API를 사용해 해당 테이블 디렉터리 하위에 존재하는 모든 파일에 대해 다시 한번 삭제를 실행합니다. Delete orphan files: 가비지 데이터를 삭제하는 작업입니다. Iceberg 테이블에 데이터 커밋 시 충돌이 발생하면 메타데이터, 데이터 영역에 모두 가비지 데이터가 발생할 수 있습니다. 메타파일과 실제 오브젝트 스토리지에 존재하는 파일을 주기적으로 대조해 가비지 데이터를 삭제합니다. 작업 실행 중 신규 파일이 커밋되면 신규 파일도 삭제될 위험이 있어서 생성된 지 7일 이상 지난 파일에 대해서만 가비지 데이터 분류를 실행합니다. 리더 노드는 주기적으로 배치 잡을 실행합니다. 태스크는 각 테이블의 평균 사이즈를 기준으로 빈 패킹(bin packing) 방식으로 모든 노드에 할당됩니다. 할당된 결과는 Iceberg 시스템 테이블로 저장되고, 각 노드는 해당 시스템 테이블을 주기적으로 읽어 자신에게 할당된 태스크를 실행합니다. 실행이 완료된 태스크는 시스템 테이블에서 삭제됩니다. 태스크 스케줄링 상태가 Iceberg 테이블로 저장되어 있기 때문에 노드가 다시 시작되어도 하던 작업을 이어서 실행할 수 있습니다. 카탈로그와 데이터 연동 신규 로그 모니터링 시스템은 Iceberg REST 카탈로그를 사용합니다. REST 카탈로그의 핸들러 등의 구현체는 Iceberg SDK에 포함되어 있습니다. SDK를 기반으로 Spring Boot로 래핑해 서버로 작동하게 만든 것이 Puffin입니다. REST 카탈로그를 사용하려면 실제 메타데이터가 저장될 저장소를 지정해야 하는데, MySQL을 백엔드 카탈로그로 지정해 사용합니다. Alaska의 초기 설계부터 카탈로그를 사용자에게 제공해 데이터 연동을 지원하려 했습니다. 로그에 포함되어 있는 데이터를 분석하려는 사용자가 많은데, 기존 로그 모니터링 시스템 환경에서는 Open API를 사용해 로그를 다운로드해 분석하는 사용자가 대부분이었습니다. 그렇기 때문에 카탈로그를 사용자에게 제공하면 사용자는 데이터 다운로드 없이 자신의 쿼리 엔진과 직접 연동해 바로 SQL 쿼리를 실행해 쉽게 데이터 분석을 실행할 수 있게 됩니다. 데이터 연동을 위해서 카탈로그에 다음과 같은 기능을 구현했습니다. 기존 로그 모니터링 시스템에서 발급받은 access key 기반으로 인증 시스템과 연동합니다(authentication). 인증된 정보를 기반으로 권한이 있는 테이블에만 접근할 수 있도록 제어합니다(authorization). 데이터 연동 시 read-only API에만 접근을 허용해 테이블에 커밋 및 삭제 등을 실행할 수 없게 합니다. 인증 기능은 Iceberg REST 카탈로그 표준 스펙에 맞춰 구현했고, iceberg.rest-catalog.oauth2.token 설정의 access key 값을 통해 사용자가 권한이 있는 테이블에 읽기 전용으로 접근할 수 있게 했습니다. 데이터 쿼리 신규 로그 모니터링 시스템의 쿼리 엔진으로는 Trino를 채택했습니다. Trino에 의존성을 가지지 않도록 내부 구조를 설계했기 때문에 필요하다면 언제든지 Spark와 같은 다른 쿼리 엔진으로 교체할 수 있습니다. 사용자는 웹 UI 혹은 Open API를 통해서 쿼리를 실행할 수 있습니다. 신규 로그 모니터링 시스템에서는 기본적으로 다음과 같이 쿼리를 크게 Main query와 Sub query로 구분합니다. Main query는 원본 로그 데이터 테이블을 대상으로 실행하는 쿼리입니다. 기본적으로 비동기로 실행됩니다(non-interactive query). CTAS(Create Table As Select) 쿼리로 실행되며, 쿼리 결과는 또 다른 테이블로 저장됩니다. Sub query는 메인 쿼리에 의해서 생성된 쿼리 결과 테이블을 대상으로 실행하는 쿼리입니다. 동기 방식으로 실행됩니다(interactive query). 이렇게 Main query를 비동기 방식으로 실행해 쿼리 결과를 테이블로 저장하는 이유는 대용량의 데이터를 검색할 때 실행 시간이 매우 길어질 수 있기 때문입니다. 일반적으로 인덱스가 없기 때문에 Elasticsearch보다 응답 속도가 느립니다. 장기간 검색을 허용하기 때문에 검색하는 데이터의 양과 쿼리 형태에 따라서 결과를 얻는 데 수시간이 소요될 수도 있습니다. 이러한 상황에서 동기 방식으로 쿼리를 실행하면 사용자는 응답이 올 때까지 웹브라우저가 종료되지 않도록 유지하고 대기해야 합니다. 또한 Main query를 통해 최대한 관심 있는 데이터 영역만 필터링해 쿼리 결과 테이블을 만들면 그 이후부터는 빠른 속도로 관심 있는 데이터 영역을 탐색할 수 있게 됩니다. 이러한 사용자 경험을 고려해 위와 같이 쿼리 방식을 설계했습니다. 새로운 타입의 데이터 저장 스토리지의 필요성에서 살펴본 것처럼 장기 보관 데이터에 대해서는 쿼리가 발생하는 비율이 낮습니다. 그렇기 때문에 Trino 클러스터를 적은 리소스로 제공하고 있습니다. 다만 신규 SQL 쿼리 기능의 도입으로 이전에 없던 쿼리 패턴이 등장해 쿼리 리소스가 과도하게 소모될 가능성이 생겼습니다. 이에 따라 다음과 같이 쿼리에 제약 사항을 두었습니다. 테이블마다 Main query는 동시에 최대 한 개만 실행합니다. Sub query의 실행 속도를 사용자마다 15queries/min로 제한합니다. 쿼리를 ANTLR 4 기반으로 분석해 SQL 문법을 제한합니다. SELECT 쿼리만 허용합니다. WITH, JOIN, UNION, INTERSECT, EXCEPT 연산자를 사용할 수 없습니다. 중첩 쿼리(nested query)를 사용할 수 없습니다. FROM 절에는 반드시 한 개의 대상 테이블만 명시합니다. SQL 쿼리 실행 시 사용되는 리소스를 제한합니다. 사용자 쿼리 요청 시 바로 실행하지 않고 쿼리 플래닝을 통해서 리소스를 예측합니다. 예측된 리소스가 제한 값을 초과하면 사용자에게 에러를 반환합니다. 이와 같은 제약 사항이 없다면 무거운 데이터 분석 쿼리가 많이 유입되어 쿼리 엔진 비용이 급속도로 증가할 가능성이 있습니다. 제약 사항을 넘어서는 쿼리 실행이 필요할 경우에는 카탈로그 데이터 연동을 통해서 사용자의 쿼리 엔진 리소스를 사용하도록 안내하고 있습니다. 신규 로그 모니터링 시스템 적용 결과 Iceberg 기반의 신규 로그 모니터링 시스템을 오픈하면서 기존 Elasticsearch 기반의 로그 데이터는 최대 데이터 보관 기간을 14일로 단축했습니다. 이러한 정책을 통해서 2,000대 이상의 Elasticsearch 노드를 줄일 수 있었으며, 데이터 용량도 수 페타바이트 규모에서 수백 테라바이트 규모로 감소했습니다. 대신 기존에 90일로 제한한 최대 로그 보관 기간을 신규 로그 모니터링 시스템을 활성화할 경우 최대 5년까지로 늘였습니다. 이를 통해서 예상되는 인프라 비용이 매년 수 십억 원까지 절감되었습니다. 늘어나는 트래픽 추세를 감안하면 절감되는 비용은 매년 그 이상이 될 것이라 예상합니다. 이렇게 비용을 절감할 수 있는 이유는 다음과 같습니다. 상대적으로 비용이 저렴한 오브젝트 스토리지에 데이터를 저장합니다. Parquet 데이터 포맷에 zstd 압축을 적용해 데이터 압축률이 높습니다. 다음 그래프에 나타난 것처럼 전체 평균 원본 데이터 대비 약 6% 수준으로 압축됩니다. 쿼리 엔진 리소스를 분리해 최소한의 규모로 운영합니다. 기존 Elasticsearch 기반 모니터링 시스템의 Warm 계층의 데이터 노드와 비교해 Trino 클러스터 규모가 더 작습니다. 다음 그래프는 데이터 적재 이후 데이터 최적화 과정의 파일 병합을 통해서 감소된 파일 비율입니다. 평균적으로 약 7.5%의 수준으로 감소했습니다. 파일 병합 작업을 통해 테이블을 최적화하지 않는다면 데이터 쓰기/읽기 측면서 시스템이 정상적으로 작동할 수 없습니다. 다음은 신규 로그 모니터링 시스템의 UI입니다. 원하는 테이블을 선택해 쿼리(Main query)를 실행하면 그 결과가 다시 Iceberg 테이블로 저장됩니다. 그 이후에 해당 결과에 여러 가지 필터를 적용해 실시간으로 데이터를 탐색할 수 있습니다. 마치며 네이버의 기존 로그 모니터링 시스템은 Elasticsearch를 기반으로 구성되었으며, 수 천대의 서버로 수 페타바이트 규모의 로그 데이터를 저장했습니다. 데이터 쿼리 패턴을 분석한 결과, 대규모 데이터 중에서 70%의 데이터는 검색이 거의 이루어지지 않는 콜드 데이터였습니다. 이런 데이터를 고비용, 고성능 저장소인 Elasticsearch에 저장해야 할지 검토하게 되었습니다. 검색이 거의 이루어지지 않지만 법적 요구 사항과 사후 분석을 위해 장기간 로그 저장에 대한 요구 사항이 많았기 때문에 새로운 저비용의 로그 검색 시스템을 구축하기로 결정했습니다. 새로운 로그 모니터링 시스템은 Iceberg라는 오픈 테이블 포맷을 기반으로 구성됩니다. 오브젝트 스토리지에 로그를 저장하는 기술을 개발하고, Trino 쿼리 엔진에 기반해 로그 검색 시스템을 구축했습니다. 새로운 저비용의 로그 모니터링 시스템으로 연간 수십억 원의 인프라 비용을 절감할 수 있는 기반을 마련할 수 있게 되었고, 새로운 방식의 SQL 로그 검색/분석 기능을 사용자에게 제공할 수 있게 되었습니다. Iceberg의 오픈 테이블 포맷을 사용한 데이터 저장은 데이터 분석 플랫폼에서는 흔하게 쓰이는 방식입니다. 하지만 로그 모니터링(observability) 측면에서 기존 로그 모니터링 시스템의 요구 사항을 만족하는 신규 시스템을 구축하는 것은 쉽지 않은 일이었습니다. 특히나 데이터 적재와 최적화를 위한 오픈 소스의 활용이 어려워 Iceberg SDK를 사용해 직접 컴포넌트를 개발해야 했습니다. Iceberg SDK에 대한 레퍼런스가 부족해 데이터를 시간 단위로 나누어 저장하고 다시 병합하며 메타데이터를 관리하는 부분의 개발은 초기 단계에서부터 많은 어려움이 있었습니다. 또한 신규 시스템의 트래픽이 사내 오브젝트 스토리지 시스템에 부하를 발생시켜, 해당 문제를 해결하는 것도 쉽지 않은 일이었습니다. 하지만 컴포넌트를 자체 개발함으로써 특정 엔진에 제한되지 않고, 최신의 Iceberg 버전을 적용할 수 있다는 점은 매우 큰 장점입니다. 신규 로그 모니터링 시스템 오픈 이후에 사용자들은 단순히 장기 보관 데이터에 대한 검색뿐만 아니라 최신 데이터에 대해서도 기존 Elasticsearch의 Lucene 쿼리로 분석하기 힘든 것을 SQL 기반으로 분석하기 시작했습니다. NELO라는 사내 로그 모니터링 플랫폼은 데이터 분석을 위한 시스템은 아니지만 Iceberg 기반의 신규 로그 모니터링 시스템이 데이터 레이크(data lake)의 데이터 소스 중 하나로 활용될 수 있기를 기대하고 있습니다. 해당 글은 N INNOVATION AWARD 2024 특집편으로 수상작 '대용량/장기간 데이터를 위한 저비용 로그 검색 시스템 : NELO Alaska'의 수상팀에서 작성해주셨습니다. N INNOVATION AWARD는 2008년부터 이어진 네이버의 대표적인 사내 기술 어워드로 매년 우수한 영향력과 성과를 보여준 기술을 선정하여 축하와 격려를 이어오고 있습니다.

2024 네이버 통합검색의 웹 성능 리뷰
네이버 D2
2024 네이버 통합검색의 웹 성능 리뷰

네이버 검색은 사용자 중심의 빠르고 원활한 검색 경험을 제공하기 위해 지속적으로 웹 성능을 모니터링하고 최적화하고 있습니다. 2024년에는 특히 LCP(Largest Contentful Paint)를 핵심 성능 지표로 삼아 여러 최적화 작업을 진행하였으며, 그 결과 네이버 검색의 웹 성능은 목표로 삼았던 구글 글로벌 LCP와 유사한 수준인 LCP p95 기준 2.31초를 달성할 수 있었습니다. 또한 2024년에 새로운 서치 피드 서비스가 도입되면서 기존의 웹 기반 성능 지표로는 측정하기 어려운 무한 스크롤 영역을 측정할 수 있는 새로운 성능 지표를 개발하여 관리하고 있습니다. 새로운 성능 지표는 동적 콘텐츠 로딩의 체감 속도와 이미지 렌더링 타이밍을 평가하는 데 활용됩니다. 이 글에서는 1) 2024년 네이버 통합검색의 웹 성능을 정리하고, 2) 새롭게 도입된 성능 지표를 소개하며, 3) 2024년 네이버에서 진행한 몇 가지 성능 개선 사례를 살펴봅니다. 2024년 네이버 통합검색 성능 연간 지표 네이버 검색은 LCP를 가장 중요한 성능 지표로 설정하고 있으며, 구글 글로벌 LCP 수준인 p95(95번째 퍼센타일) 기준 2.5초 이하를 목표로 하고 있습니다. 2024년 12월 기준 네이버 검색의 LCP Good Score는 96.59%를 기록했는데, 이는 대부분의 사용자들이 페이지 로딩 시 콘텐츠가 빠르고 원활하게 표시되고 있음을 의미합니다. 꾸준히 시스템을 모니터링하고 개선하기 위해 노력한 덕분에 2024년 하반기부터 성능 지표가 점진적으로 개선될 수 있었습니다. 2024년 네이버 통합검색 성능 개선 사례에서 구체적인 개선 사례를 확인할 수 있습니다. 2024년 네이버 검색의 전체 LCP는 p95 기준 약 2.31초이며, INP(Interaction to Next Paint)는 0.26초입니다. INP는 사용자가 버튼을 클릭하거나 입력을 했을 때 화면이 다음 단계로 넘어가기까지 걸리는 시간을 의미합니다. INP는 Core Web Vitals의 주요 지표 중 하나로 네이버 검색에서도 유심히 모니터링하고 있습니다. 구글에서는 좋은 INP를 200ms 이하로 안내하고 있습니다. 2024년 하반기부터 네이버 검색의 INP 지표가 점점 개선되고 있지만, 아직 목표 기준인 60ms를 초과하므로 추가적인 최적화 작업이 필요합니다. 2024년 네이버 통합검색의 새로운 성능 지표 네이버 검색은 최근 무한 스크롤 방식의 서치 피드(Search Feed)를 도입하여 사용자 경험을 개선하기 위해 노력하고 있습니다. 그런데 기존의 LCP 지표만으로는 동적으로 로드되는 무한 스크롤 영역의 성능을 정확하게 평가하는 데 한계가 있었습니다. LCP는 페이지를 최초로 로딩할 때 주요 콘텐츠의 시각적 완성도를 측정하는 데 효과적이지만, 사용자가 직접 스크롤로 새로운 데이터를 요청하는 서치 피드의 특성을 반영하기 어려웠습니다. 이러한 문제를 해결하기 위해 네이버 검색에서는 새로운 성능 지표를 정의하여 관리하고 있습니다. 피드 사용자 체감 성능 지표: FUPP FUPP(Feed User Perceived Performance)는 서치 피드의 동작 흐름과 사용자 상호작용을 기반으로 설계된 지표입니다. 사용자가 화면 아래까지 스크롤하여 새로운 콘텐츠를 요청하면, 백엔드 API 호출이 트리거되고 해당 데이터를 받아 화면에 렌더링하는 과정이 시작됩니다. FUPP는 API 호출이 시작되는 시점부터 서치 피드의 첫 번째 주요 이미지가 화면에 완전히 렌더링될 때까지의 시간을 측정합니다. 이는 단순히 네트워크 응답 속도뿐 아니라 데이터 처리와 시각적 요소의 표시 시간까지 포괄함으로써, 사용자가 실제로 새로운 콘텐츠를 '인지'하는 순간을 측정합니다. 즉, FUPP는 무한 스크롤 환경에서 사용자가 다음 콘텐츠를 얼마나 빠르게 확인할 수 있는지를 평가하는 기준입니다. 위 내용을 바탕으로 FUPP를 측정한 결과 p95 기준 약 1.5초로 나타났습니다. 이는 대다수 사용자가 1.5초 이내에 새로 로드된 서치 피드 콘텐츠를 확인할 수 있음을 의미합니다. 다시 말해 사용자가 화면 아래에 도달하기 1.5초 전에 서치 피드를 요청하면 끊김 없이 콘텐츠를 확인할 수 있습니다. 피드 이미지 로드 타이밍 지표: FILT 대부분의 서치 피드에서 가장 많은 영역을 차지하는 부분은 이미지입니다. 따라서 이미지 로딩 속도가 사용자 체감 성능에 많은 영향을 주게 됩니다. 네이버 검색에서는 FILT(Feed Image Load Timing)라는 지표를 도입해 서치 피드에서 이미지가 언제, 어떻게 로드되었는지를 분석하고 있습니다. 이미지가 노출되는 시점을 총 4가지 유형으로 세분화하여 FILT를 측정했습니다. 첫 번째 유형은 Standby(대기 중)로 이미지 로딩이 아직 시작되지 않은 상태를 의미합니다. 브라우저의 lazy loading 방식을 이용하므로 Standby는 아직 브라우저가 이미지를 로드하지 않은 상태입니다. 측정한 결과 전체 이미지 중 14%가 이 유형에 해당했습니다. 두 번째 유형인 Early(미리 로드됨)는 사용자가 해당 피드 영역에 도달하기 전에 이미지가 로드된 경우로, 사용자는 끊김 없이 피드를 소비할 수 있습니다. 전체 이미지의 75%를 차지합니다. 세 번째 유형은 Viewport(화면 내 로드됨)로 사용자가 피드에 진입한 시점에는 이미지가 로드 중이었지만 피드를 소비하는 과정에서 로드가 완료되는 경우입니다. 전체 이미지의 약 11%를 차지하고 있습니다. 마지막 유형은 Late(늦은 로딩)로 사용자가 피드를 지나친 후에 이미지가 로드된 경우입니다. 즉, 사용자가 해당 이미지를 확인하지 못한 상태로 피드를 지나쳤음을 의미합니다. 다행히 이런 경우는 0% 수준으로 확인되었습니다. 서치 피드 최적화 FUPP와 FILT 지표로 서치 피드의 성능을 정량적으로 측정하고 모니터링할 수 있는 체계를 구축했고, 이를 활용해서 서치 피드 최적화 실험을 진행했습니다. 무한 스크롤 방식의 고민 중 한 가지는 콘텐츠를 호출하는 시점입니다. 사용자가 화면을 끝까지 스크롤한 이후 콘텐츠를 로드한다면 대기 시간이 발생하여 사용성에 문제가 생길 수 있습니다. 반면 사용자가 화면 아래에 도달하기 전에 콘텐츠를 너무 빠르게 로드하면 소비 의도가 없는 사용자에게도 콘텐츠가 노출되어 서버 리소스가 불필요하게 소모될 수 있습니다. 그래서 우리는 로드 시점에 따른 사용성과 서버 부하 등을 확인할 수 있는 ABT를 진행했습니다. 화면 맨아래에서부터 200&Tilde1,600px 구간을 실험 구간으로 설정하고, 구간별로 서치 피드 호출 시점을 조정하여 소비 지표와 시스템 지표를 종합적으로 확인했습니다. 그 결과 콘텐츠 로드 시점을 100px 조정할 때마다 서버 호출량은 5%, 사용자 도달률은 2% 변동하는 패턴을 확인할 수 있었습니다. 예를 들어 화면 아래에서 600px 위치에서 콘텐츠를 로드하면, 800px 위치 대비 서버 호출량이 10% 감소했으나 사용자 도달률도 4% 하락했습니다. FILT 지표 역시 주목할 만한 변화를 보였습니다. 로드 시점이 늦어질수록 Viewport 비중이 증가했는데, 이는 이미지 요청 시점이 늦어졌기 때문에 발생한 현상으로 예측한 결과였습니다. 흥미로운 부분은 특정 시점(약 1,000px) 이후에는 로드 시점을 더 앞당겨도 Early 비중이 개선되지 않는다는 점이었습니다. 소비 지표(클릭률, 이탈률 등)에서도 유의미한 인사이트를 확인할 수 있었습니다. 로드 시점이 늦어질수록 소비 지표는 안 좋아질 것으로 예상했고, 실제로도 가설을 입증하는 데이터를 확인할 수 있었습니다. 반면 로드 시점이 빠를수록 소비 지표가 개선될 것이라는 초기 가설과 달리 특정 시점(약 1,200px)을 기준으로 소비 지표는 오히려 감소했습니다. 이는 콘텐츠 소비 의도가 없는 사용자에게까지 피드가 노출되므로 해당 사용자들이 피드를 무시하거나 빠르게 이탈하는 행동 패턴에 기인한 것으로 판단하였습니다. 실험 데이터를 종합한 결과, 화면 아래에서부터 600&Tilde1,000px 구간에서 서치 피드를 호출하는 것이 가장 효율적이라는 결론을 내렸습니다. 현재 네이버 검색은 1,000px을 기준점으로 채택하여 서비스 안정성과 사용자 경험을 동시에 개선했으며, 향후 트래픽 변동이나 사용자 패턴 변화에 따라 데이터 기반으로 유연하게 조정할 계획입니다. 2024년 네이버 통합검색 성능 개선 사례 네이버 검색에서 2024년에 진행한 몇 가지 성능 개선 사례를 소개합니다. 지역플러스 영역 LCP 개선 네이버 검색의 지역플러스 영역은 장소 검색 시 표시되는 검색 결과로, 주로 이미지와 함께 노출됩니다. 2024년 5월 30일 업데이트로 LCP p95 수치가 3,000ms에서 2,000ms로 30% 개선되었습니다. 이러한 성능 개선의 핵심 요인은 CSS의 background-image 속성을 사용해 이미지를 로딩하는 방식에서 img 태그를 사용하는 방식으로 변경한 데 있습니다. 과거에는 Internet Explorer 환경에 대응해야 해서 object-fit 속성 대신 background-image 속성을 사용할 수 밖에 없었습니다. background-image 속성을 사용하여 이미지를 삽입하는 방식은 브라우저가 DOM 파싱이 완료된 후에 CSS 파일을 파싱하면서 이미지를 요청합니다. 그 결과 이미지가 렌더링되기까지 추가적인 지연이 발생하며, 이는 LCP를 악화시키는 요인이 될 수 있습니다. 반면 HTML의 img 태그를 활용하는 방식은 HTML 문서를 파싱하는 즉시 img 태그를 인식하고 리소스 요청을 시작합니다. 이 방식은 브라우저의 초기 파싱 단계에서 이미지를 빠르게 불러오므로 이미지 렌더링 시간을 단축하고 LCP에 긍정적인 영향을 줄 수 있습니다. 다음의 그림은 각 이미지 로딩 방식을 적용했을 때 브라우저에서 이미지를 로드하는 과정을 나타낸 것입니다. 파란색 박스로 표시된 영역은 img 태그를 사용했을 때, 빨간색 박스로 표시된 영역은 background-image 속성을 사용했을 때입니다. 이번 개선 사례에서 네이버 검색의 성능 최적화 작업이 단순히 코드 최적화나 서버 인프라 개선에 국한되지 않으며, 프런트엔드 렌더링 전략의 미세 조정만으로도 상당한 효과를 얻을 수 있다는 점을 확인할 수 있었습니다. 네이버 통합검색 성능 개선에 도움을 주신 플레이스 검색 서비스 개발팀의 이대희 님, 임지수 님(메인&플레이스UI개발)께 감사드립니다. 크리스마스 브랜드검색 Flicking 성능 개선 크리스마스 시즌 동안, 네이버 검색의 특정 영역에서 egjs/Flicking을 활용한 UI의 화면이 끊기는 현상이 발생했습니다. 비록 이 문제가 Web Vitals 지표에는 큰 영향을 주지 않았지만, 사용자 경험에는 부정적인 인상을 남길 가능성이 높았습니다. 문제의 원인을 분석한 결과, 첫 번째로 marginLeft 속성을 지속적으로 변경함에 따라 브라우저가 레이아웃 재계산(reflow)을 빈번하게 수행하게 된 부분이 큰 영향을 주었습니다. 이로 인해 화면의 애니메이션이 부드럽게 이어지지 않고 중간에 끊기는 현상이 발생했습니다. 두 번째로, 배경 이미지를 CSS의 background-image 속성으로 로드했기 때문에 이미지 로딩 속도가 상대적으로 느려졌습니다. 이 문제를 해결하기 위해 marginLeft 속성 대신 transform:transX 속성을 적용하도록 안내했습니다. 이렇게 하면 레이아웃을 재계산하지 않고 GPU 가속을 활용하므로 애니메이션이 훨씬 부드럽게 구현됩니다. 또한 앞선 사례에서 소개한 것처럼 background-image 속성 대신 img 태그 기반의 방식으로 이미지를 렌더링하도록 변경하여 이미지 로드 속도를 향상시켰습니다. egjs/Flicking을 사용할 때 marginLeft를 사용한 원인을 확인해 보니 Flicking 애니메이션 도중 Parallax 효과를 구현하기 위해서였습니다. 사실 egjs/Flicking에서도 Parallax 기능을 제공하고 있었지만 당시 제공된 문서의 설명이 충분하지 않아 실제 적용 과정에서 어려움을 겪었던 것으로 파악됩니다. 이에 따라 관련 내용을 보완하였으며, 이외에도 egjs/Flicking에서 제공하는 다양한 기능을 제대로 활용할 수 있도록 지속적으로 문서를 개선할 계획입니다. 마치며 2024년 네이버 통합검색의 웹 성능은 꾸준한 관리로 지속적인 개선을 이루었으며, LCP p95 기준 2.31초를 기록할 만큼 안정적인 수준에 도달했습니다. 또한, 새로운 서치 피드 서비스에 적합한 성능 지표인 FUPP와 FILT를 도입하여 무한 스크롤 영역의 성능을 보다 정밀하게 측정하고 최적화할 수 있었습니다. 앞으로 다음과 같은 부분을 개선할 계획입니다. SSR(ServerSideRendering)과 부분 CSR(ClientSideRendering)이 공존할 때 성능 측정 방법 개발 INP 지표 개선을 위한 추가 최적화 네이버 검색은 지속적으로 성능을 관찰하고 개선하여 더욱 빠르고 효율적인 검색 환경을 제공하고 사용자 경험을 극대화하는 것을 목표로 하고 있습니다.

네이버클라우드 X 서울대학교 KDT 빅데이터 핀테크 전문가 과정
네이버 클라우드
네이버클라우드 X 서울대학교 KDT 빅데이터 핀테크 전문가 과정

안녕하세요, 누구나 쉽게 시작하는 클라우드 네이버클라우드(ncloud.com)입니다. 서울대학교 KDT 빅데이터 핀테크 전문가 과정에 캡스톤 참여기업으로 함께한 네이버클라우드의 의미 있는 경험을 여러분과 나누고자 합니다! ✨ 학생들의 반짝이는 아이디어와 네이버클라우드의 기술이 만나 어떤 놀라운 시너지를 만들어냈는지, 함께한 학생들의 이야기를 만나보겠습...