낮은 지연 기계 학습 기능 스토어에 대한 수요는 그 어느 때보다 높지만 실제로 규모로 하나를 구현하는 것은 여전히 도전입니다.ShareChat 엔지니어 인 Ivan Burmistrov와 Andrei Manakov가 P99 CONF 23 단계를 수행하여 ScyllaDB를 기반으로 낮은 지연 ML 기능 스토어를 구축하는 방법을 공유했을 때 분명했습니다. 이것은 새로운 제품을 채택하면 하루를 구할 수있는 깔끔한 사례 연구가 아닙니다.이것은 "수업을 배운"사설이며, 끊임없는 성능 최적화의 가치에 대한 견해입니다. 최종 목표는 초당 10억 개의 기능을 지원하는 것이었지만 시스템은 백만 개의 부하에서 실패했습니다.어떤 똑똑한 문제 해결으로 팀은 그것을 끌어 냈습니다.그러나 엔지니어들이 기본 데이터베이스를 확장하지 않고도 초기 실패에서 높은 성능 목표를 달성하는 방법을 살펴보자. 성능 최적화 및 낮은 지연 엔지니어링에 집착하십니까? P99 24 CONF에서 동료들과 함께, “모든 것의 성능”에 관한 무료 고전적인 가상 회의입니다. Michael Stonebraker, Postgres 창업자 및 MIT 교수 Bryan Cantrill, Oxide Computer의 공동 설립자 및 CTO Avi Kivity, KVM 제작자, ScyllaDB 공동 설립자 및 CTO Liz Rice, eBPF 전문가 Isovalent의 오픈소스 책임자 Andy Pavlo, CMU 교수 Ashley Williams, Axo 설립자 / CEO, 이전 Rust 핵심 팀, Rust Foundation 설립자 Carl Lerche, 도쿄 제작자, Rust 기여자 및 AWS 엔지니어 지금 등록하세요 - 무료입니다 지금 등록하세요 - 무료입니다 지금 등록하세요 - 무료입니다 ShareChat에서 Ivan의 또 다른 훌륭한 토론 외에도, Disney / Hulu, Shopify, Lyft, Uber, Netflix, American Express, Datadog, Grafana, LinkedIn, Google, Oracle, Redis, AWS, ScyllaDB 및 기타에서 성능 최적화에 대한 60 가지 이상의 엔지니어링 토론을 기대하십시오. ShareChat: 인도의 주요 소셜 미디어 플랫폼 도전의 범위를 이해하기 위해서는 인도의 주요 소셜 미디어 플랫폼인 ShareChat에 대해 조금 아는 것이 중요합니다.ShareChat 앱에서 사용자는 비디오, 이미지, 노래 등을 포함하여 15 개 이상의 다른 언어로 콘텐츠를 발견하고 소비합니다.ShareChat은 또한 사용자가 트렌드 태그 및 대회로 창의력을 자극하는 TikTok와 같은 짧은 비디오 플랫폼 (Moj)을 호스팅합니다. 두 애플리케이션 사이에서, 그들은 이미 325 백만 명 이상의 월간 활성 사용자를 보유하고있는 빠르게 성장하는 사용자 기반을 제공합니다. ShareChat에서 기계 학습 기능 스토어 이 이야기는 짧은 형태의 비디오 앱 Moj의 ML 기능 스토어 뒤에있는 시스템에 초점을 맞추고 있습니다. 그것은 매일 활성 사용자 약 20 백만 명, 매월 활성 사용자 100 백만 명에게 완전히 개인화 된 피드를 제공합니다. 피드는 초당 8,000 개의 요청을 제공하며 각 요청에 평균 2,000 개의 콘텐츠 후보자가 순위 (예를 들어, 권장할 수있는 10 개의 최고의 항목을 찾을 수 있습니다). ShareChat의 소프트웨어 엔지니어 인 Ivan Burmistrov는 다음과 같이 설명했습니다. "우리는 다른 '단체'에 대한 기능을 계산합니다. 포스트는 하나의 엔터티이고, 사용자는 다른 것입니다. 계산 관점에서, 그들은 매우 유사합니다. 그러나, 중요한 차이점은 각 유형의 엔터티에 대해 픽업해야 할 기능의 수입니다. 사용자가 피드를 요청할 때, 우리는 그 단일 사용자를 위해 사용자 기능을 픽업합니다. 그러나, 모든 포스트를 순위하기 위해, 우리는 순위가있는 각 후보자 (포스트)에 대한 기능을 픽업해야합니다. 그래서 포스트 기능에 의해 생성 된 시스템의 총 부하는 사용자 기능에 의해 생성 된 것보다 훨씬 니다. 무엇이 잘못되었는지 처음에는 사용자 기능이 가장 중요하기 때문에 실시간 사용자 기능 스토어를 구축하는 것이 주된 초점이었습니다.그때 팀은 그 목표를 염두에두고 기능 스토어를 구축하기 시작했습니다.그러나 그때 우선 순위가 바뀌고 포스트 기능도 초점이되었습니다.이 변화는 팀이 전신에 비해 두 가지 주요 차이를 가진 완전히 새로운 순위 시스템을 구축하기 시작했기 때문에 발생했습니다. 가까운 실시간 포스트 기능이 더 중요했습니다. 순위에 올릴 포스트의 수는 수백에서 수천으로 증가했습니다. 이반은 “우리가 이 새로운 시스템을 테스트하러 갔을 때 불행하게도 실패했습니다.초당 약 1백만 개의 기능으로 시스템이 반응이 없어 지붕을 통해 지연이 흘러갔습니다.”라고 설명했다. 궁극적으로, 문제는 시스템 아키텍처가 타일이라고 불리는 미리 집계된 데이터 버킷을 사용하는 방법에서 발생했습니다. 예를 들어, 그들은 주어진 분 또는 다른 시간 범위에서 게시물에 대한 좋아하는 수를 집계 할 수 있습니다.이로 인해 지난 2 시간 동안 여러 게시물에 대한 좋아하는 수와 같은 지표를 계산할 수 있습니다. 여기에는 시스템 아키텍처에 대한 높은 수준의 시각이 있습니다.재생 데이터 (좋아, 클릭 등)와 함께 몇 가지 실시간 주제가 있습니다.Flinks 작업은 그들을 타일로 집계하고 ScyllaDB에 작성합니다.그리고 ScyllaDB에서 타일을 요청하고 그들을 집계하고 결과를 피드 서비스에 반환하는 기능 서비스가 있습니다. 초기 데이터베이스 스키마 및 플레잉 구성은 확장성 문제를 초래했습니다.Originally, each entity had its own partition, with rows timestamp and feature name being ordered clustering columns. 타일은 1분, 30분, 1일의 세그먼트에 대해 계산되었으며, 1시간, 1일, 7일 또는 30일의 세그먼트에 대해서는 각 기능당 평균 70개의 타일을 수집해야 했다. 이 NoSQL 데이터 모델링 마스터 클래스에서 더 알아보세요 수학을 하면 왜 실패했는지 분명해집니다.시스템은 초당 약 22 억 행을 처리해야 했습니다.그러나 데이터베이스 용량은 초당 10 백만 행에 불과했습니다. 초기 최적화 그 시점에서 팀은 최적화 임무를 수행했습니다. 초기 데이터베이스 계획은 모든 기능 행을 함께 저장하여 특정 타임스탬프에 대한 프로토콜 버퍼로 시리즈화되었습니다. 아키텍처가 이미 Apache Flink을 사용하고 있기 때문에 Flink의 고급 데이터 파이프라인 구축 능력 덕분에 새로운 타일링 계획으로의 전환은 상당히 쉬웠습니다.이 최적화로 위의 방정식에서 "Functions"수배자가 제거되었으며 픽업에 필요한 행 수는 약 2 억에서 초당 200 백만 줄로 100배 줄어들었습니다. 팀은 또한 5 분, 3 시간 및 5 일 동안 추가 타일을 1 분, 30 분 및 1 일 타일에 추가하여 타일 구성을 최적화했습니다.이로 인해 평균 필요한 타일이 70에서 23로 줄어들어 라인 / 초를 약 73 백만으로 줄였습니다. 데이터베이스 측면에서 더 많은 행/초를 처리하기 위해, 그들은 ScyllaDB 압축 전략을 점진적에서 수준화로 변경했습니다. 그 옵션은 그들의 쿼리 패턴을 더 잘 맞추고 관련 행을 함께 유지하고 읽기 I/O를 줄였습니다.The result: ScyllaDB’s capacity was effectively doubled. 컴팩트 전략에 대해 더 알아보기 나머지 부하를 수용하는 가장 쉬운 방법은 ScyllaDB를 4배 확장하는 것입니다.그러나 더 / 더 큰 클러스터는 비용을 증가시킬 것이고 이는 예산에 포함되지 않았습니다.그래서 팀은 ScyllaDB 클러스터를 확장하지 않고도 확장성을 향상시키는 데 집중했습니다. Cache Locality 개선 ScyllaDB의 부하를 줄이는 한 가지 잠재적인 방법은 로컬 캐시 히트 비율을 개선하는 것이었기 때문에 팀은 이것을 달성하는 방법을 연구하기로 결정했습니다. 분명한 선택은 일관된 해시 접근법을 사용하는 것이 었습니다.이 기술은 요청에 대한 정보를 기반으로 클라이언트로부터 특정 복사본에 요청을 전달하는 것으로 알려져 있습니다. 팀은 Kubernetes 설정에서 NGINX Ingress를 사용했기 때문에, 일관된 해시를위한 NGINX의 기능을 사용하는 것이 자연스러운 선택처럼 보였습니다. 이 간단한 구성이 작동하지 않았습니다.특히: 클라이언트 하위 세트는 엄청난 키 리모핑을 이끌었습니다 – 최악의 경우 100 %까지. 노드 키가 해시 링에서 변경될 수 있기 때문에, 자동 스케일링으로 실제 시나리오를 사용할 수 없었습니다. Ingress가 가장 명백한 솔루션 인 gRPC 헤더를 지원하지 않기 때문에 요청에 해시 값을 제공하는 것은 어렵습니다. 지연은 심각한 악화를 겪었고, 꼬리 지연을 일으키는 원인이 무엇인지는 명확하지 않았다. Pods의 하위 집합을 지원하기 위해 팀은 그들의 접근 방식을 수정했습니다. 그들은 2단계 해시 함수를 만들었습니다: 먼저 엔터티를 해시 한 다음 무작위 사전을 추가했습니다. 이는 원하는 숫자에 걸쳐 엔터티를 배포했습니다. 이론적으로,이 접근법은 엔터티가 동일한 pod에 여러 번 매핑 될 때 충돌을 일으킬 수 있습니다. Ingress는 변수로 gRPC 헤더를 사용하는 것을 지원하지 않지만 팀은 해결 방법을 찾았습니다 : 경로 재 작성을 사용하고 경로 자체에 필요한 해시 키를 제공합니다. 불행히도, 지연 악화의 원인을 파악하는 데는 상당한 시간이 필요했을 것이고, 관찰 가능성도 향상되었습니다.A different approach was needed to scale the feature store in time. 그 기간을 충족시키기 위해 팀은 Feature 서비스를 27개의 다른 서비스로 분할하고 클라이언트에 따라 모든 엔터티를 수동으로 분할했습니다.그것은 가장 우아한 접근법이 아니었지만, 간단하고 실용적이었으며 훌륭한 결과를 달성했습니다.캐시 히트율은 95%로 향상되었으며 ScyllaDB 로딩은 초당 18.4 백만 행으로 줄어들었습니다.이 디자인으로 ShareChat은 3 월까지 기능 매장을 초당 1B 기능으로 확장했습니다. 그러나 이 “오래된 학교” 배포 분할 접근 방식은 여전히 이상적인 디자인이 아니었습니다. 27 개의 배포를 유지하는 것은 지루하고 비효율적이었습니다.또한 캐시 히트 비율은 안정적이지 않았으며 규모는 각 배포에서 높은 최소 팟 수를 유지해야 함으로써 제한되었습니다.이 접근법이 기술적으로 그들의 요구를 충족하더라도 팀은 더 나은 장기 솔루션을 찾는 것을 계속했습니다. 최적화의 다음 단계 : 일관된 해시, 기능 서비스 또 다른 최적화 라운드에 대비하여 팀은 기능 서비스와 함께 배포된 Envoy Proxy라고 불리는 sidecar를 사용하여 일관된 해시 접근 방식을 재검토했습니다.Envoy Proxy는 지연 꼬리 문제를 식별하는 데 도움이되는 더 나은 관찰성을 제공했습니다.The problem: different request patterns to the Feature service caused a huge load on the gRPC layer and cache. 그 후 팀은 기능 서비스를 최적화했습니다.그들은: 캐시 라이브러리 (VictoriaMetrics의 FastCache)를 구축하고 배치 스크립트와 더 나은 추방을 구현하여 mutex contention을 100x 감소시켰습니다. gprc-go를 구축하고 높은 파라날리즘 중에 논쟁을 피하기 위해 다른 연결을 통해 버퍼 풀을 구현했습니다. 사용된 객체 집합 및 조정된 쓰레기 수집기(GC) 매개 변수는 할당 속도와 GC주기를 줄이기 위해 사용되었다. Envoy Proxy가 15 %의 트래픽을 처리함으로써 결과는 유망했습니다 : 98 %의 캐시 히트율은 ScyllaDB의 로드를 7.4M 라인/초로 줄였으며 기능 매장을 1 억 기능/초에서 3 억 기능/초로 더욱 확장시킬 수 있습니다. 배운 교훈 이 시간표 관점에서이 여행이 어떻게 보였는지: 마지막으로, Andrei는이 프로젝트에서 배운 팀의 주요 교훈을 요약했습니다 (지금까지): ShareChat 팀이 시스템 디자인을 크게 바꾸었지만 ScyllaDB, Apache Flink 및 VictoriaMetrics는 계속 잘 작동했습니다. 각 최적화는 이전보다 어렵고 영향이 적습니다. 간단하고 실용적인 솔루션 (예를 들어 기능 스토어를 27 개의 배포로 나누는 것)은 실제로 작동합니다. 최상의 성능을 제공하는 솔루션은 항상 사용자 친화적이지는 않습니다. 예를 들어, 그들의 개정된 데이터베이스 계획은 좋은 성능을 제공하지만 유지하고 이해하기 어렵습니다. 때로는 기본 라이브러리를 포크하고 최상의 성능을 얻기 위해 특정 시스템에 맞게 조정해야 할 수도 있습니다. 그들의 완전한 P99 CONF 대화를 보세요! 그들의 완전한 P99 CONF 대화를 보세요! 그들의 완전한 P99 CONF 대화를 보세요! Cynthia Dunlop에 대한 리뷰 보기 Cynthia는 ScyllaDB의 컨텐츠 전략 고위 이사이며 20 년 이상 소프트웨어 개발 및 품질 엔지니어링에 대해 글을 쓰고 있습니다.