LinkedIn은 초당 4만 개 이상의 회원 프로필을 제공합니다. 요청 수는 매년 두 배로 증가하고 있습니다.
과거에는 Oracle에서 오픈 소스 문서 플랫폼인 Espresso로 마이그레이션하고 더 많은 노드를 추가하여 대기 시간, 처리량 및 비용 문제를 해결했습니다.
우리는 이제 증가하는 부하로 인해 일부 핵심 구성 요소에 부담을 주고 있으며 더 이상 노드 추가 전략으로 확장 문제를 해결할 수 없습니다.
대신 Couchbase를 읽기 확장을 위한 중앙 집중식 스토리지 계층 캐시로 도입하기로 결정했습니다.
이 솔루션은 99% 이상의 캐시 적중률을 달성하고, 꼬리 대기 시간을 60% 이상 줄였으며, 서비스 비용을 연간 10% 줄였습니다.
이 결정은 또한 캐시가 기본 스토리지 인프라에 의해 지원되지 않기 때문에 여러 엔지니어링 문제를 제시했습니다.
지금까지 Profile 백엔드는 애플리케이션과 데이터베이스 간의 읽기 캐시로 memcached를 사용하여 중앙 집중식 캐시를 사용했습니다.
캐시 솔루션이 제대로 작동하지 않았습니다. 캐시 확장, 노드 교체 및 캐시 준비 문제 중에 성능 저하가 발생했습니다. memcached의 유지 관리는 어려웠습니다.
2014년 Oracle에서 Espresso로 마이그레이션할 때 Espresso의 기본 제공 확장성 및 대기 시간 특성 때문에 더 이상 읽기 캐시가 필요하지 않았습니다.
Espresso와 함께 백엔드 애플리케이션의 클러스터 크기를 확장하여 피크 시 1만 QPS 이상의 서비스 호출 수를 지원하도록 Espresso 프로필 데이터 저장소를 확장하는 데 성공했습니다. 결국 이러한 접근 방식은 Espresso 공유 구성 요소의 상한선에 도달했으며 이를 높이려면 상당한 엔지니어링 투자가 필요했습니다.
회원 프로필은 Espresso에 Avro 바이너리 형식으로 저장됩니다. Espresso는 문서 스키마를 지원하며 스키마는 시간이 지남에 따라 발전할 수 있습니다. 스키마 버전 번호는 업데이트할 때마다 증가합니다.
LinkedIn 회원이 프로필을 업데이트하면 요청이 프로필 백엔드 애플리케이션으로 전송되며, 이 백 엔드 애플리케이션은 문서를 Espresso에 유지하기 전에 Avro 바이너리 형식으로 변환하여 변경 내용을 직렬화합니다.
누군가 LinkedIn 프로필을 볼 때 프로필 프런트 엔드 응용 프로그램은 Espresso에서 프로필을 가져오는 프로필 백 엔드 응용 프로그램에 읽기 요청을 보내고, Avro 이진 형식의 콘텐츠를 문서로 변환하여 프런트 엔드 응용 프로그램으로 반환하는 응답을 역직렬화합니다.
프로필 보기 또는 업데이트는 그림 1에 요약된 대로 여러 응용 프로그램을 통해 이동합니다.
Espresso는 라우터와 스토리지 노드로 구성됩니다. Espresso 라우터는 프로파일 요청에 대한 프록시 역할을 하며, 레코드의 고유 ID를 사용하여 멤버의 프로파일을 보유하는 데이터베이스 파티션을 결정하고 읽기/쓰기 요청을 올바른 Espresso 스토리지 노드로 전달합니다. 모든 Espresso 라우터에는 OHC(오프 힙 캐시)가 있습니다.
모든 Espresso 라우터에는 자주 액세스하는 레코드를 유지하기 위해 "Window Tiny-LFU" 캐시 제거 정책으로 구성된 OHC가 있습니다.
OHC는 핫 키 캐시로서 매우 효율적인 것으로 입증되었습니다. 그러나 LinkedIn 회원 프로필 사용 사례의 경우 OHC 캐시는 두 가지 이유로 캐시 적중률이 낮습니다.
OHC는 라우터의 로컬 캐시이며 지정된 라우터에 대한 읽기 요청만 볼 수 있습니다. 프로필 요청은 프로젝션(즉, 응용 프로그램이 전체 문서가 아닌 관심 필드만 요청)을 사용하여 캐시 적중률을 더욱 줄입니다.
LinkedIn에서는 Couchbase를 다양한 응용 프로그램의 분산 키-값 캐시로 사용했습니다. 서버 재시작 간의 데이터 지속성, 모든 문서를 계속 사용할 수 있는 상태에서 한 노드가 장애 조치될 수 있도록 하는 복제, 가동 중지 시간 없이 해당 노드를 추가하거나 제거할 수 있는 동적 확장성을 포함하여 memcached에 대해 제공하는 향상된 기능을 위해 선택됩니다.
프로필 Espresso 클러스터는 우리가 했던 것처럼 용량을 확장하기 위해 더 많은 하드웨어를 추가하는 것이 더 이상 주요 리엔지니어링 노력 없이는 선택 사항이 아닌 지점까지 성장했습니다.
Couchbase는 LinkedIn에서 널리 사용되기 때문에 사용 사례로 고려한 것은 당연합니다. 또한 Couchbase를 Espresso의 업 스케일링 솔루션으로 사용하기 위해 Couchbase 캐시가 스토리지 계층에 상주 할 수 있으므로 애플리케이션 소유자가 캐싱 내부를 처리 할 필요가 없다는 이점을 얻을 수 있습니다.
그러나 업스케일링을 위해 캐시를 사용하려면 SOT(Source of Truth)와 완전히 독립적으로 작동해야 하며 오류 발생 시 SOT로 대체되지 않아야 합니다. 우리는 세 가지 설계 원칙을 해결하여 이러한 요구 사항을 해결했습니다.
업스케일링에 사용되는 캐시에 대한 세 가지 디자인 원칙은 다음과 같습니다.
모든 Couchbase 오류에 대한 보장된 복원력항상
캐시된 데이터 가용성SOT와 캐시 간의 데이터 차이에 대해 엄격하게 정의된 SLO(서비스 수준 목표)입니다.
Couchbase 오류에 대한 복원력은 SOT로 대체할 수 없기 때문에 매우 중요합니다.
통합 시스템의 중요한 구성 요소를 보호하고 캐시 오류로 인해 일련의 오류가 발생하는 것을 방지하기 위해 다음과 같은 가드레일을 구현했습니다.
에스프레소 라우터: 라우터가 액세스할 수 있는 모든 Couchbase 버킷의 상태를 추적하기 위해 모든 라우터에 Couchbase 상태 모니터를 유지 관리합니다.
상태 모니터는 미리 결정된 임계값에 대한 요청 예외 비율에 따라 버킷의 상태를 평가합니다.
버킷이 비정상인 경우 라우터는 버킷에 대한 새 요청 디스패치를 중지하여 요청이 라우터의 힙에 누적되는 것을 방지하여 클라이언트 시간 초과 및 라우터 다운을 초래합니다.
Couchbase 리더의 복제본 실패: 프로필 데이터에 대해 3개의 복제본(리더의 복제본 및 2개의 팔로워 복제본)을 선택하고 리더-팔로워 인터페이스(API)를 구현합니다. 모든 요청은 리더의 복제본에 의해 이행됩니다.
리더의 복제본이 실패하면 라우터는 팔로워의 복제본에서 데이터를 가져옵니다.적격한 실패한 Couchbase 요청 재시도: Couchbase 실패는 가능한 모든 이유로 인해 발생할 수 있음에도 불구하고 Couchbase 예외는 Espresso 라우터 문제, 네트워킹 문제 또는 Couchbase 서버 측 문제의 1가지 범주 중 3가지로 분류됩니다.
처음 두 범주의 경우 문제가 지역화되고 일시적일 수 있으며 재시도가 성공할 수 있다는 가정하에 다른 라우터에서 실패한 Couchbase 요청을 다시 시도합니다.
데이터 센터 트래픽 장애 조치(failover) 중을 포함하여 캐시된 데이터를 모든 곳에서 항상 사용할 수 있도록 하려면 모든 데이터 센터에서 전체 프로필 데이터 세트를 캐시하도록 선택합니다.
프로필 페이로드가 작기 때문에 95번째 백분위수가 24KB 미만이기 때문에 좋은 옵션입니다.
모든 캐시 레코드에 대해 무한 TTL(Time-To-Live)을 사용하여 모든 데이터 센터에서 데이터를 사용할 수 있도록 하는 것은 간단합니다. 그러나 이는 예를 들어 삭제 누락으로 인해 영구적인 데이터 발산으로 이어질 수 있습니다(예: Espresso 데이터베이스에서 삭제가 발생했지만 Couchbase에 도달하기 전에 손실됨).
누락된 삭제는 드문 이벤트이지만, 예를 들어 Kafka 인프라 중단으로 인해 특정 이벤트가 캐시 업데이트 프로그램에서 사용되기 전에 보존 기간에서 떨어질 수 있는 경우에도 여전히 발생할 수 있습니다.
결과적으로 만료된 레코드가 Couchbase에서 제거되도록 캐시된 데이터에 대해 유한한 TTL을 설정하도록 선택합니다.
Couchbase 캐시가 콜드되거나 SOT에서 벗어나는 것을 방지하기 위해 주기적으로 Couchbase를 부트스트랩합니다.
부트스트래핑 기간은 캐시된 데이터 TTL 내에 있으므로 Espresso에 있는 레코드가 다음 부트스트래핑 전에 만료되지 않도록 합니다.
Couchabse 캐시에 대한 쓰기 액세스 권한이 있는 구성 요소(Espresso 라우터, 캐시 부트스트래퍼 및 캐시 업데이터) 간의 경합 조건으로 인해 데이터 차이가 발생할 수 있습니다. 이를 방지하기 위해 오래된 레코드가 Couchbase에 삽입되는 것을 방지하기 위해 동일한 키의 캐시 업데이트를 주문합니다. 업데이트를 주문하기 위해 캐시 레코드와 연결된 SCN(시스템 변경 번호) 값을 비교합니다. 개념적으로 SCN은 논리적 타임스탬프로, 커밋된 각 데이터베이스 행에 대해 Espresso 스토리지 엔진은 SCN 값을 생성하여 binlog에 보관합니다. SCN 값의 순서는 데이터 센터, 클러스터, 데이터베이스 및 데이터베이스 파티션 내의 커미트 순서를 반영합니다.
Pegasus 데이텀 판독기를 사용하면 개별 프로파일 레코드에 대한 레코드 역직렬화를 수행할 때 다양한 백분위수(밀리초 단위로 측정)에서 성능 향상을 확인할 수 있습니다. 제어 데이텀 리더(Espresso)와 처리 데이텀 리더(Pegasus)를 비교하면 Pegasus 데이텀 리더가 전반적으로 훨씬 더 나은 성능을 발휘합니다. 95번째 백분위수 대기 시간은 34.1%, 99번째 백분위수 대기 시간은 37.4%, 99번째 백분위수 대기 시간은 28% 감소했습니ek.
Espresso 하이브리드 캐시 계층을 사용하면 Espresso 스토리지 노드 수를 90%까지 줄일 수 있습니다. 또한 새로운 인프라(예: 새 Couchbase 클러스터, Samza 부트스트래핑 및 업데이트 작업)를 설정하고 업컨버전 및 프로젝션을 처리하기 위해 Profile 백엔드 컴퓨팅 리소스를 늘리기 위해 추가 비용이 발생하기 때문에(예: 최대 30% 버퍼 설정) 보수적으로 LinkedIn은 회원 프로필 요청을 처리하는 데 드는 비용을 연간 약 10% 절감할 수 있을 것으로 추정합니다.
Espresso 통합 Couchbase를 채택함으로써 성장하는 LinkedIn 회원 기반을 지원하고, 프로필 데이터 저장소를 확장하고, 서비스 비용을 낮추고, 성능이나 회원 경험에 영향을 미치지 않으면서 모든 작업을 수행한다는 목표를 달성할 수 있었습니다.
공동 저자 : Estella Pham 및 Guanlin Lu
'먼테크' 카테고리의 다른 글
시스템설계 (0) | 2023.07.09 |
---|---|
분산시스템 (0) | 2023.07.09 |
지시 모델은 HELM 벤치마크에서 모든 개방형 7B 모델을 능가 (0) | 2023.07.05 |
생성형 AI의 경제적인 미래 #1 (0) | 2023.07.02 |
AudioLM (말하고 듣기 가능한 LM) 에 대하여 (0) | 2023.07.02 |