고객과 직원의 경험을 향상시키는 직관적이고 AI 기반의 비즈니스 솔루션을 제공하는 글로벌 소프트웨어 서비스(SaaS) 회사입니다. Freshworks는 실시간 데이터를 활용하여 의사결정을 내리고 75,000 이상의 고객들에게 더 좋은 경험을 제공하는 데 의존합니다. 제품 간 일일 이벤트가 수백만 개에 이르러 방시간 데이터 처리가 중요하게 됩니다. 이런 필요성을 충족하기 위해 Freshworks는 Databricks 위에 실시간 수집 파이프라인을 구축하였고, 이 파이프라인은 다양한 스키마를 제품 간에 관리하고 분당 수백만 건의 이벤트를 처리하는 데 있어 30분 안에 이뤄지는 서비스 수준 계약(SLA)을 유지하면서 다중 세입자 환경에서 세입자 수준의 데이터 격리를 보장할 수 있습니다.
이를 달성하기 위해 강력하고 유연하며 최적화된 데이터 파이프 라인을 구축하려 했습니다.
Freshworks의 기존 파이프라인은 Python 소비자로 구축되었습니다; 여기서 각 사용자의 액션은 실시간으로 제품에서 Kafka로 이벤트를 전송하며, 이 Python 소비자들은 이런 이벤트를 변환하고 새로운 Kafka 주제로 라우팅합니다. 그 뒤에 Rails 배치 시스템은 이런 변환된 데이터를 AWS S3에 저장된 CSV 파일로 변환하고, Apache Airflow 작업은 이런 배치 데이터를 데이터 웨어하우스로 로드합니다. 수집 후에는 중간 파일이 삭제되어 저장 공간이 관리됩니다. 이런 아키텍처 구조는 초기 성장에 적합했으나, 이벤트 볼륨이 급증하면서 한계에 부딪혔습니다.
급속한 성장은 핵심 과제들을 드러냈습니다:
규모와 복잡성이 증가함에 따라, 기존 시스템의 취약성과 오버헤드는 비즈니스 성장과 분석 요구를 지원하기 위한 통합적이고 확장 가능하며 자율적인 데이터 아키텍처의 필요성을 명확하게 드러냈습니다.
솔루션 - Spark 구조화된 스트리밍 과 Delta Lake를 중심으로 한 근본적인 재설계는 거의 실시간 처리, 확장가능한 변환, 그리고 운영의 단순성에 초점을 맞추었습니다.
우리는 Spark 구조화된 스트리밍이 Kafka에서 직접 데이터를 소비하고, 이 데이터를 변환한 후 Delta Lake에 기록하는 하나의 아키텍처를 설계했습니다 - 이 모든 과정이 하나의 작업에서 Databricks 내부에서 실행됩니다.
이런 변화로 데이터 이동이 줄어들고, 유지 보수와 문제 해결이 단순화되며, 인사이트 도달 시간이 가속화되었습니다.
스트리밍 구성 요소 : Spark 구조화된 스트리밍
Kafka에서 들어오는 각 이벤트는 Spark 스트리밍에서 정확도, 규모, 비용 효율성을 최적화한 일련의 변환 단계를 신중하게 진행합니다:
저장 구성요소: 레이크하우스
변환된 후에, 이 데이터는 몇 가지 강력한 최적화를 활용하여 직접 Delta Lake 테이블 에 기록됩니다:
실시간 조정 & 적응
자동 조정은 파이프 라인에 내장되어 있어, 시스템이 동적으로 크기를 조절하여 볼륨과 비용을 가장 효율적으로 처리할 수 있도록 보장하면서 성능에 영향을 주지 않습니다.
스케일링은 배치 지연과 실행 시간에 의해 주도되며, 실시간으로 모니터링됩니다. Resizing은 Spark의 QueryListener (각 배치 후의 OnProgress 방법)를 통해 작업 API를 통해 트리거되어, 처리 중인 작업이 방해받지 않게 합니다. 이렇게 하면 시스템은 수동 개입 없이 반응적이고 탄력적이며 효율적입니다.
내장된 탄력성: 실패를 세련되게 처리하기
데이터 무결성 및 가용성을 유지하기 위해, 이 아키텍처는 견고한 장애 복구를 포함합니다:
각 단계에서의 관찰 가능성과 모니터링
강력한 모니터링 스택—Prometheus, Grafana, 그리고 Elasticsearch로 구축된—이 Databricks와 통합되어 우리에게 종단 간 가시성을 제공합니다:
변환 & 배치 실행 메트릭:
위의 메트릭을 사용하여 변환 건강 상태를 추적하고, 문제를 식별하며, 신속한 조사를 위한 알림을 트리거하세요.
복잡성에서 신뢰성으로
아마도 가장 크게 변화한 것은 단순성입니다.
한때는 다섯 시스템과 수많은 통합 포인트가 포함되었던 것이 Databricks 내에서 완전히 작동하는 단일, 관찰 가능, 자동 조정 파이프라인 으로 바뀌었습니다. 우리는 불안정한 의존성을 제거하고, 작업을 간소화하고, 팀이 더 빠르게 그리고 더 큰 자율성으로 작업할 수 있게 했습니다.본질적으로 움직이는 부분이 줄어들면서 놀람이 줄어들고 신뢰도가 상승하였습니다.
스트리밍과 Deltalake을 중심으로 데이터 스택을 상상해 보면, 우리는 오늘날의 규모뿐만 아니라 내일의 성장에 대응할 수 있는 시스템을 구축하였습니다.
데이터 아키텍처를 재상상하면서 우리는 몇 가지 기술을 평가하였는데, 이 가운데에는 Amazon EMR의 Spark, Apache Flink, 그리고 Databricks 등이 있었습니다. 철저한 벤치마킹 후에, Databricks가 가장 적합한 선택으로 부상하였는데, 이는 성능, 단순성, 그리고 Freshworks의 발전하는 요구 사항을 충족시켜 줄 수 있는 생태계 조정의 독특한 혼합을 제공하기 때문입니다.
데이터 처리를 위한 통합된 생태계
여러 도구를 결합하는 대신, Databricks는 작업 조정, 데이터 거버넌스, 그리고 CI/CD 통합, 을 포괄하는 종단 간 플랫폼을 제공하여 복잡성을 줄이고 개발을 가속화합니다.
최적화된 Spark 플랫폼
고성능 캐싱
Delta Lake: 실시간 및 신뢰성 있는 수집을 위한 기초
Delta Lake은 파이프라인에서 중요한 역할을 하며, 대규모에서 지연 시간이 짧은 ACID 준수, 고무질적인 데이터 처리를 가능하게 합니다.
| Delta Lake 특징 | SaaS 파이프 라인 이점 |
|---|---|
| ACID 트랜잭션 | Freshworks는 다양한 출처로부터 높은 빈도의 스트리밍을 적고, 데이터에 대한 동시적 쓰기를 수행합니다. Delta Lake의 ACID 준수는, 읽기 & 쓰기 간 데이터 일관성을 보장합니다. |
| 스키마 진화 | 제품의 빠르게 성장하고 특성상 진화하는 스키마 때문에, 델타 레이크의 스키마 진화는 바뀌는 요구사항에 적응하고, 이러한 것들이 델타 테이블에 원활하게 적용되고 스파크 스트리밍 애플리케이션에 자동으로 반영됩니다. |
| 시간 이동 | 수백만 건의 거래 & 감사 필요성이 있음에 따라, 델타 레이크에서 데이터의 스냅샷으로 돌아갈 수 있는 능력은 감사와 롤백을 시간이 필요로 하는 지점까지 지원합니다. |
| 확장 가능한 변경 처리 및 삭제 벡터 | Delta Lake는 큰 데이터 파일들을 다시 쓸 필요 없이 트랜잭션 로그를 통한 효율적인 삽입/업데이트/삭제 연산을 지원하고 가능하게 합니다. 이것은 수집 지연 시간을 몇 시간에서 몇 분으로 줄이는 데 중요했습니다. |
| 오픈 형식 | Freshworks가 다중 테넌트 SAAS 시스템인 만큼, 열려 있는 Delta 형식은 레이크하우스 위의 분석 도구와의 광범위한 호환성을 제공합니다; 다중 테넌트 읽기 작업을 지원합니다. |
그래서, Databricks Spark의 속도, Delta Lake의 안정성, 그리고 Databricks의 통합 플랫폼을 결합함으로써, Freshworks의 실시간 분석을 위한 확장성 있는, 견고하고, 비용 효율적인 미래 준비 기반이 만들어졌습니다.
변환은 그것의 도전 없이 이루어지지 않습니다. 그동안 우리는 몇 가지 놀라운 점들을 경험하며 귀중한 교훈들을 배웠습니다:
1. 상태 저장소 오버헤드: 높은 메모리 사용량과 안정성 문제
Spark의 dropDuplicatesWithinWatermark 사용은 높은 메모리 사용과 특히 자동 스케일링 도중에 불안정성을 초래하고, 작은 파일들 때문에 S3 리스트 비용이 증가하였습니다.
해결: 중복 제거를 위해 Delta 기반 캐싱으로 전환하면서 메모리 효율성과 안정성이 크게 향상됐습니다. 전체 S3 목록 비용과 메모리 사용량이 크게 줄어들어서, 데이터 중복 제거의 시간과 비용을 줄일 수 있었습니다.
2. 액체 클러스터링: 공통적인 도전 사항들
다수의 칼럼에 클러스터링하면 데이터 분포가 듬성듬성해져 데이터 스캔이 늘어나고 쿼리 성능이 저하됩니다.
쿼리에는 여러 차차로 조건이 있는 기본 조건이 있었고; 여러 열에 클러스터링하면 기본 조건 열에 데이터가 흩어지게 되었습니다.
해결: 단일 주요 열에 클러스터링을 하는 것은 더 나은 파일 조직화를 이끌어내고, 데이터 스캔을 최적화함으로써 쿼리를 더 빠르게 만들었습니다.
3. 가비지 컬렉션(GC) 문제: 작업 재시작 필요
장기 실행 작업(7일 이상)은 성능이 느려지고 가비지 컬렉션 주기가 더 자주 일어나게 됩니다.
해결: 우리는 지속적인 GC 주기와 성능 저하를 완화하기 위해 주간 작업 재시작을 도입해야 했습니다.
4. 데이터 왜곡: Kafka Topic 불균형 처리하기
서로 다른 Kafka 주제별로 데이터량이 불균형하게 변동하는 것을 관찰되었습니다. 이로 인해 처리 노드 간에 불균형한 데이터 분포를 초래하여 작업 부하가 왜곡되고 리소스 이용이 비균등하게 되었습니다.
해결: 변환 전에 다시 파티션하면 데이터 분포가 고르고 균형이 맞게 되어 데이터 처리 부하를 균형화하고 처리량을 향상시킵니다.
5. 조건별 병합: 병합 성능 최적화하기
필요한 컬럼이 몇 개뿐이라도, 병합 작업은 대상 테이블에서 모든 컬럼을 로드하였고, 이로 인해 병합 시간과 I/O 비용이 높았습니다.
해결: 우리는 병합 전에 안티조인을 구현했고, 늦게 도착하거나 관련 없는 레코드를 조기에 폐기하여, 불필요한 데이터가 로드되지 않도록 함으로써 병합 속도를 크게 향상시켰습니다.
Databricks와 Delta Lake를 사용하여 Freshworks는 데이터 아키텍처를 재정의하였습니다 - 파편화되고 수동적인 작업흐름에서 현대적이고 통합된 실시간 플랫폼으로 이동하였습니다.
이는
이러한 변화는 Freshworks의 모든 고객이 IT부터 지원까지, 비즈니스 요구들을 지원하고 처리하는 데이터의 크기에 대해 걱정하지 않고 더 빠르게 데이터 기반의 결정을 내릴 수 있도록 지원합니다.
(이 글은 AI의 도움을 받아 번역되었습니다. 원문이 궁금하시다면 여기를 클릭해 주세요)
