엔지니어링 팀은 DynamoDB의 데이터에 대해 복잡한 필터, 집계 및 텍스트 검색을 실행해야 하는 경우가 많습니다. 그러나 DynamoDB는 실시간 분석이 아닌 트랜잭션 처리에 최적화된 운영 데이터베이스입니다. 결과적으로 많은 엔지니어링 팀은 DynamoDB 분석의 한계에 부딪혀 대체 옵션을 모색하고 있습니다.
이는 운영 워크로드가 복잡한 분석 워크로드와 액세스 패턴이 매우 다르기 때문입니다. DynamoDB는 제한된 작업 세트만 지원하므로 분석이 어렵고 일부 상황에서는 불가능합니다. DynamoDB를 지원하는 회사인 AWS 조차도 기업에 분석을 다른 목적으로 구축된 솔루션으로 오프로드하는 것을 고려하라고 조언합니다. 일반적으로 참조되는 솔루션 중 하나는 오늘 살펴볼 Elasticsearch입니다.
DynamoDB 는 가장 널리 사용되는 NoSQL 데이터베이스 중 하나이며 게임, 소셜 미디어, IoT 및 금융 서비스 분야의 많은 웹 규모 회사에서 사용됩니다. DynamoDB는 확장성과 단순성 때문에 선택한 데이터베이스로, 초당 2,000만 요청 규모에서 한 자릿수 밀리초의 성능을 지원합니다. 이러한 속도를 대규모로 달성하기 위해 DynamoDB는 운영 워크로드(개별 데이터 기록에 대한 높은 빈도, 짧은 지연 시간 작업)의 성능을 확보하는 데 중점을 두고 있습니다.
Elasticsearch 는 Lucene을 기반으로 구축된 오픈 소스 분산 검색 엔진으로, 텍스트 검색 및 로그 분석 사용 사례에 사용됩니다. Elasticsearch는 분석 대시보드를 위한 시각화 도구인 Kibana를 포함하는 대규모 ELK 스택의 일부입니다. Elasticsearch는 유연하고 사용자 정의가 용이한 것으로 알려져 있지만, 성능을 유지하려면 클러스터와 인덱스 운영 및 관리가 필요한 복잡한 분산 시스템입니다. Elastic과 AWS에서 제공하는 Elasticsearch 관리형 제품이 있으므로 EC2 인스턴스에서 직접 실행할 필요가 없습니다.
Shameless Plug: Rockset은 클라우드용으로 구축된 실시간 분석 데이터베이스입니다. DynamoDB에 대한 커넥터가 내장되어 있으며 1초 미만의 검색, 집계 및 조인을 위해 데이터를 수집하고 인덱싱합니다. 하지만 이 게시물은 해당 옵션을 살펴보고 싶은 경우를 대비해 DynamoDB 및 Elasticsearch의 사용 사례를 강조하는 것입니다.
AWS Lambda를 사용하면 분석을 위해 DynamoDB 데이터를 Elasticsearch에 지속적으로 로드할 수 있습니다. 작동 방식은 다음과 같습니다.
DynamoDB용 Logstash 플러그인을 포함하여 Elasticsearch에 데이터를 동기화하는 대체 접근 방식이 있지만 현재는 지원되지 않으며 구성이 복잡할 수 있습니다.
텍스트 검색은 가장 관련성이 높은 결과를 찾기 위해 문서 내의 텍스트를 검색하는 것입니다. 최상의 결과를 찾기 위해 단어의 일부, 단어의 동의어나 반의어, 단어 문자열을 함께 검색하고 싶을 때가 있습니다. 일부 애플리케이션은 중요도에 따라 검색어에 가중치를 다르게 부여하기도 합니다.
DynamoDB는 분할을 사용하여 데이터를 필터링함으로써 일부 제한된 텍스트 검색 사용 사례를 지원할 수 있습니다. 예를 들어, 전자상거래 사이트인 경우 제품 카테고리를 기준으로 DynamoDB의 데이터를 분할한 다음 인메모리 검색을 실행할 수 있습니다. 분명히 이것은 Amazon.com 소매 부서가 많은 텍스트 검색 사용 사례를 처리하는 방법입니다. DynamoDB는 데이터의 특정 하위 문자열이 포함된 문자열을 찾을 수 있는 포함 함수 도 지원합니다.
전자상거래 사이트에서는 제품 카테고리를 기준으로 데이터를 분할할 수 있습니다. 브랜드 및 색상과 같은 추가 속성이 검색되는 데이터와 함께 표시될 수 있습니다.
전체 텍스트 검색이 애플리케이션의 핵심인 시나리오에서는 관련성 순위가 있는 Elasticsearch와 같은 검색 엔진을 사용하는 것이 좋습니다. Elasticsearch의 높은 수준에서 텍스트 검색이 작동하는 방식은 다음과 같습니다.
관련성 순위 : Elasticsearch에는 기본적으로 검색 결과에 제공하는 관련성 순위가 있거나 특정 애플리케이션 사용 사례에 맞게 순위를 사용자 정의할 수 있습니다. 기본적으로 Elasticsearch는 용어 빈도, 역 문서 빈도 및 필드 길이 표준을 기반으로 순위 점수를 생성합니다.
텍스트 분석 : Elasticsearch는 텍스트를 토큰으로 나누어 데이터를 색인화하는 작업을 토큰화라고 합니다. 그런 다음 정규화된 용어에 분석기가 적용되어 검색 결과가 향상됩니다. 기본 표준 분석기는 유니코드 컨소시엄에 따라 텍스트를 분할하여 일반적인 다중 언어 지원을 제공합니다.
Elasticsearch에는 퍼지 검색, 자동 완성 검색, 그리고 훨씬 더 고급 관련성과 같은 개념도 포함되어 있어 애플리케이션의 특정 사항에 맞게 구성할 수 있습니다.
복잡한 필터를 사용하여 결과 집합의 범위를 좁힐 수 있으므로 데이터를 더 빠르고 효율적으로 검색할 수 있습니다. 많은 검색 시나리오에서는 여러 필터를 결합하거나 일정 기간 등의 데이터 범위에 대해 필터링하려고 합니다.
DynamoDB는 데이터를 분할하고 적절한 파티션 키를 선택하면 데이터 필터링을 더욱 효율적으로 만드는 데 도움이 될 수 있습니다. DynamoDB는 데이터를 복제하고 다른 기본 키를 사용하여 추가 필터를 지원할 수 있도록 보조 인덱스도 지원합니다. 데이터에 대한 액세스 패턴이 여러 개인 경우 보조 인덱스가 도움이 될 수 있습니다.
예를 들어 배송 상태에 따라 품목을 필터링하도록 물류 애플리케이션을 설계할 수 있습니다. DynamoDB에서 이 시나리오를 모델링하기 위해 파티션 키가 Item_ID
이고 정렬 키가 Status
이며 구매자 속성이 ETA
및 SLA
인 물류용 기본 테이블을 생성합니다.
또한 배송 지연이 SLA를 초과하는 경우를 대비해 DynamoDB에서 추가 액세스 패턴을 지원해야 합니다. DynamoDB의 보조 인덱스를 활용하여 SLA를 초과하는 배송만 필터링할 수 있습니다.
기본 테이블에 이미 있는 ETA 속성의 복제본인 ETADelayedBeyondSLA
필드에 인덱스가 생성됩니다. 이 데이터는 ETA가 SLA를 초과하는 경우에만 ETADelayedBeyondSLA
에 포함됩니다. 보조 인덱스는 쿼리에서 스캔해야 하는 데이터의 양을 줄이는 희소 인덱스입니다. buyer
는 파티션 키이고 정렬 키는 ETADelayedBeyondSLA
입니다.
보조 인덱스를 사용하면 복잡한 필터와 관련된 액세스 패턴을 포함하여 애플리케이션에서 여러 액세스 패턴을 지원할 수 있습니다.
DynamoDB의 쿼리 및 스캔 API에는 표현식과 일치하지 않는 결과를 필터링하는 필터 표현식 작업이 있습니다. filterexpression
쿼리 또는 테이블 스캔 작업 후에만 적용되므로 여전히 쿼리에 대한 데이터 제한이 1MB로 제한됩니다. 즉, filterexpression
은 애플리케이션 논리를 단순화하고, 응답 페이로드 크기를 줄이고, TTL(Time to Live) 만료를 검증하는 데 도움이 됩니다. 요약하자면, 애플리케이션의 액세스 패턴에 따라 데이터를 분할하거나 보조 인덱스를 사용하여 DynamoDB의 데이터를 필터링해야 합니다.
DynamoDB는 빠른 데이터 검색을 위해 데이터를 키와 값으로 구성하므로 복잡한 필터링에는 적합하지 않습니다. 복잡한 필터가 필요한 경우 Elasticsearch와 같은 검색 엔진으로 전환하는 것이 좋습니다. 이러한 시스템은 건초 더미 쿼리에 이상적입니다.
Elasticsearch에서는 컬럼 값이 게시 목록으로 저장되는 문서 목록을 의미하는 검색 인덱스에 데이터가 저장됩니다. 조건자가 있는 모든 쿼리(예: WHERE
user=A)는 조건자를 만족하는 문서 목록을 빠르게 가져올 수 있습니다. 게시 목록이 정렬되므로 쿼리 시 모든 필터링 기준이 충족되도록 신속하게 병합할 수 있습니다. Elasticsearch는 또한단순 캐싱을 사용하여 자주 액세스하는 복잡한 필터 쿼리의 검색 프로세스 속도를 높입니다.
일반적으로 Elasticsearch에서 비점수 쿼리 라고 하는 필터 쿼리는 텍스트 검색 쿼리보다 더 빠르고 효율적으로 데이터를 검색할 수 있습니다. 이는 이러한 쿼리에는 관련성이 필요하지 않기 때문입니다. 게다가 Elasticsearch는 범위 쿼리도 지원하므로 상한과 하한 경계 사이(예: 0-5 age
사이)의 데이터를 신속하게 검색할 수 있습니다.
집계는 비즈니스 인텔리전스나 추세 분석을 위해 데이터를 수집하고 요약 형식으로 표현하는 것입니다. 예를 들어 애플리케이션의 사용량 측정항목을 실시간으로 표시할 수 있습니다.
DynamoDB는 집계 함수를 지원하지 않습니다. AWS에서 권장하는 해결 방법은 DynamoDB 및 Lambda를 사용하여 DynamoDB 테이블의 데이터 집계 보기를 유지하는 것입니다.
Twitter와 같은 소셜 미디어 사이트의 좋아요 집계를 예로 들어 보겠습니다. tweet_ID
기본 키로 설정하고 정렬 키를 좋아요를 집계하는 기간으로 설정하겠습니다. 이 경우 DynamoDB 스트림을 활성화하고 Lambda 함수를 연결하여 트윗이 좋아요(또는 싫어요)될 때 타임스탬프(예: last_ updated
)와 함께 like_count
에 표로 표시되도록 하겠습니다.
이 시나리오에서는 DynamoDB 스트림과 Lambda 함수를 사용하여 like_count를 테이블의 속성으로 표로 작성합니다.
또 다른 옵션은 집계를 Elasticsearch와 같은 다른 데이터베이스로 오프로드하는 것입니다. Elasticsearch는 핵심적인 검색 색인이며 집계 기능을 지원하는 확장 기능을 추가했습니다. 이러한 확장 중 하나는 문서 값을 열 기반 방식으로 저장하기 위해 인덱스 시 구축된 구조인 doc 값 입니다. 이 구조는 기본적으로 doc 값을 지원하는 필드에 적용되며 doc 값과 함께 제공되는 일부 저장소 팽창이 있습니다. DynamoDB 데이터 집계에 대한 지원만 필요한 경우 광범위한 데이터 세트에 대한 분석 쿼리를 위해 데이터를 효율적으로 압축할 수 있는 데이터 웨어하우스를 사용하는 것이 더 비용 효율적일 수 있습니다.
다음은 Elasticsearch 집계 프레임워크에 대한 높은 수준의 개요입니다.
버킷 집계 : 버킷팅은 SQL 데이터베이스 세계의 GROUP BY
와 유사하다고 생각할 수 있습니다. 필드 값이나 범위를 기준으로 문서를 그룹화할 수 있습니다. Elasticsearch 버킷 집계에는 조인 지원 부족에 대한 일반적인 해결 방법인 중첩 집계 및 상위-하위 집계도 포함됩니다.
측정항목 집계: 측정항목을 사용하면 문서 집합에 대해 SUM
, COUNT
, AVG
, MIN
, MAX
등과 같은 계산을 수행할 수 있습니다. 측정항목을 사용하여 버킷 집계 값을 계산할 수도 있습니다.
파이프라인 집계 : 파이프라인 집계의 입력은 문서가 아닌 다른 집계입니다. 일반적인 용도로는 평균 및 측정항목을 기준으로 한 정렬이 있습니다.
집계를 사용할 때, 특히 Elasticsearch를 확장할 때 성능에 영향을 미칠 수 있습니다.
Elasticsearch는 DynamoDB의 데이터에 대해 복잡한 검색 및 집계를 수행하기 위한 하나의 솔루션이지만, 많은 서버리스 지지자들은 이 선택에 대해 우려를 표명했습니다. 엔지니어링 팀은 서버가 없고 운영 오버헤드가 거의 없이 대규모로 사용할 수 있다는 점에서 DynamoDB를 선택합니다. 우리는 다른 블로그에서 설정 용이성, 유지 관리, 쿼리 기능 및 지연 시간에 대해 Athena, Spark 및 Rockset을 포함하여 DynamoDB 분석을 위한 몇 가지 다른 옵션을 평가했습니다.
Rockset은 Elasticsearch의 대안이며 Alex DeBrie는 Rockset에서 SQL을 사용하여 쿼리를 필터링하고 집계하는 방법을 살펴보았습니다. Rockset은 DynamoDB에 대한 커넥터가 내장된 클라우드 네이티브 데이터베이스로, 복잡한 조인과 관련된 사용 사례를 포함하여 분석 사용 사례를 쉽게 시작하고 확장할 수 있습니다. $300 크레딧이 포함된 무료 평가판을 통해 Elasticsearch의 대안으로 Rockset을 탐색해 보실 수 있습니다.