150m 고유 레이블이있는 텍스트 파일의 빠른 읽기를위한 API 아키텍처 설계

Aug 19 2020

150m 고유 레코드가있는 텍스트 파일을 가정하십시오.

각 레코드에는 (1) 문자열 및 (2) 정수의 두 열이 있습니다.

문자열은 고유 한 레이블이고 정수는 레이블의 값입니다.

유일한 쿼리는 주어진 레이블에 대한 정수 값을 반환합니다.

이 텍스트 파일을 API로 노출하기 위해 여러 아키텍처를 탐색하고 있습니다.

이 텍스트 파일은 72 시간마다 다시 생성됩니다. 데이터의 ~ 90 %는 재생성 동안 동일하게 유지되지만이 재생성은 타사에서 제어합니다. 72 시간마다 새 텍스트 파일을받습니다.

읽기 당 100ms-500ms의 쿼리 성능을 목표로합니다.

아키텍처 1

  • 텍스트 파일을 디스크에 저장하십시오. 텍스트 파일을 쿼리합니다. 메모리에 쿼리를 캐시합니다.
  • 장점 : 간단한 구현. 데이터 업데이트가 쉽습니다.
  • 단점 : 우아하지 않습니다. 캐시되지 않은 읽기 쿼리는 느립니다.

건축 2

  • 텍스트 파일을 기존 / NoSQL 데이터베이스로 구문 분석하고 각 행은 데이터베이스 레코드 / 문서로 처리됩니다. 데이터베이스에 대해 쿼리를 실행합니다.
  • 장점 : 표준 아키텍처처럼 보입니다.
  • 단점 : 1 억 5 천만 개의 데이터베이스 레코드를 업데이트하는 것은 느리고 낭비적인 것 같습니다. 특히 레코드의 90 %가 동일하게 유지되기 때문입니다.

아키텍처 3

  • Redis 또는 메모리 내 데이터베이스를 사용하여 5GB 텍스트 파일을 저장합니다. 메모리 내 데이터베이스에 대해 쿼리를 실행합니다.
  • 장점 : 빠른 쿼리. 데이터 업데이트가 쉽습니다.
  • 단점 : 비싸다.

아키텍처 4

  • ElasticSearch를 사용하여 레코드를 쿼리합니다.
  • 장점 : ElasticSearch는 검색 용으로 설계되었습니다.
  • 단점 : ES는 이러한 간단한 쿼리에 과도하게 사용할 수 있습니다.

질문 :

  1. 다른 아키텍처를 고려해야합니까, 아니면 간과 한 장단점이 있습니까?

  2. 이 엔지니어링 문제는 일반적으로 보입니다. 변경되는 1 억 5 천만 레코드의 데이터 저장소에 대해 빠른 읽기를 생성하려고 할 때 비용 / 성능의 균형을 유지하기위한 가장 "표준"아키텍처는 무엇입니까?

답변

6 AvnerShahar-Kashtan Aug 20 2020 at 04:47

일반적으로 ETL 흐름의 전형적인 경우와 비슷합니다. 새 파일을 가져오고, 데이터를 추출하고, 형식으로 변환하고, DB에로드합니다. 몇 가지 참고 사항 :

  1. 기억해야 할 중요한 점은로드 및 쿼리가 완전히 관련이없는 다른 작업에 대한 것입니다. 한 가지 질문은 "레코드의 90 %가 중복 될 때 매일 150m 레코드 파일을 데이터 저장소에 효율적으로로드하는 방법"이고 다른 하나는 "150m 레코드 키 / 값 저장소를 효율적으로 쿼리하는 방법"입니다. 이 두 질문은 독립적이므로 별도로 답하십시오.

  2. 첫 번째 질문에 대해 90 % 동일한 레코드를로드하는 것이 낭비라고 걱정합니다. 소요 시간을 측정 했습니까? 텍스트 파일에서 150m 레코드를 읽는 데 몇 초가 걸리며 좋은 키 / 값 저장소는 중복 UPDATE 작업을 최적화 할 수 있어야합니다. 또는 새 파일을 이전 파일과 비교하여 ETL 흐름의 일부로 실제 변경 목록을 만든 다음로드를 진행합니다. 솔루션을 평가할 수 있도록이 솔루션에 대한 메트릭 (총 읽기 시간, 차이,로드,로드 중 쿼리 작업 중단 등)을 정의합니다.

  3. 질문 # 2의 경우 기성 옵션이있는 경우 사용자 지정 솔루션을 구현하지 마십시오. ElasticSearch는 키가있는 정수를 저장하기 때문에 과도 할 수 있지만, 디스크 지원 메모리 캐싱, MRU 캐싱 또는 사용량에 따라 다른 캐싱 전략을 포함하여 읽기에 좋은 성능을 제공 할 키 / 값 저장소가 많이 있습니다. 아마도 앞서 언급 한 no-op UPDATE 작업 등이 있습니다. 다시 질문 # 1에서 성공을위한 메트릭을 정의하십시오. "5GB를 RAM에로드하는 것은 비용이 많이 듭니다. 서버에 RAM이 얼마나 있습니까? 일반적인 쿼리를 캐싱하는 것을 고려하고 있습니다. 필요한가요? 캐시되지 않은 읽기 속도가 얼마나 빠릅니까? 측정! 관련 레코드를 미리 캐싱하는 것과 같은 사용자 지정 캐싱 전략이 필요합니까? ? 사용 패턴을 조사하십시오.

최선의 접근 방법이 무엇인지 말할 수 없습니다. 예산 및 사용 패턴, 시스템에 대한 향후 계획 및 확장 가능성, 타사 데이터 소스와의 관계 (예 : 차이점 만 생성하도록 설득하거나 타임 스탬프 / 버전 태그를 추가하도록 설득 할 수 있음) 등 사용자 만 알고있는 변수가 너무 많습니다. 기록 등). 내가 할 수있는 일은 핵심 패턴을 제안하는 것뿐입니다. 쿼리 흐름에서 수집 흐름을 분리하고, 검증 된 도구를 사용하고, 무엇보다도 측정, 측정, 측정합니다.

1 KyryloShpytsya Aug 28 2020 at 12:02

DJBernstein의 cdb 에서 취한 접근 방식을 고려할 수 있습니다 .

cdb는 상수 데이터베이스를 만들고 읽을 수있는 빠르고 안정적이며 간단한 패키지입니다. 데이터베이스 구조는 여러 기능을 제공합니다.

빠른 조회 : 대규모 데이터베이스에서 성공적으로 조회하려면 일반적으로 두 번의 디스크 액세스 만 필요합니다. 실패한 조회에는 하나만 필요합니다.

낮은 오버 헤드 : 데이터베이스는 2048 바이트, 레코드 당 24 바이트, 키 및 데이터 공간을 사용합니다.

임의 제한 없음 : cdb는 최대 4GB의 모든 데이터베이스를 처리 할 수 ​​있습니다. 다른 제한은 없습니다. 레코드는 메모리에 맞지 않아도됩니다. 데이터베이스는 기계 독립적 인 형식으로 저장됩니다.

빠른 원자 데이터베이스 교체 : cdbmake는 다른 해싱 패키지보다 두 배 더 빠르게 전체 데이터베이스를 다시 작성할 수 있습니다.

빠른 데이터베이스 덤프 : cdbdump는 데이터베이스의 내용을 cdbmake 호환 형식으로 인쇄합니다.

cdb는 전자 메일과 같은 중요 업무용 응용 프로그램에서 사용하도록 설계되었습니다. 데이터베이스 교체는 시스템 충돌에 대해 안전합니다. 독자는 재 작성 중에 일시 중지 할 필요가 없습니다.

아마 당신은 같이 4GiB 제한이없는 현대 구현하려는 것 이 하나.