paint-brush
DynamoDB 보조 인덱스를 사용해야 하는 경우~에 의해@rocksetcloud
4,540 판독값
4,540 판독값

DynamoDB 보조 인덱스를 사용해야 하는 경우

~에 의해 Rockset16m2024/05/23
Read on Terminal Reader

너무 오래; 읽다

DynamoDB의 보조 인덱스는 데이터에 대한 새로운 액세스 패턴을 활성화하는 강력한 도구입니다.
featured image - DynamoDB 보조 인덱스를 사용해야 하는 경우
Rockset HackerNoon profile picture

인덱스는 모든 데이터베이스에 대한 적절한 데이터 모델링의 중요한 부분이며 DynamoDB 도 예외는 아닙니다. DynamoDB의 보조 인덱스는 데이터에 대한 새로운 액세스 패턴을 활성화하는 강력한 도구입니다.


이번 게시물에서는 DynamoDB 보조 인덱스를 살펴보겠습니다. 먼저 DynamoDB를 생각하는 방법과 보조 인덱스가 해결하는 문제에 대한 몇 가지 개념적 요점부터 시작하겠습니다. 그런 다음 보조 인덱스를 효과적으로 사용하기 위한 몇 가지 실용적인 팁을 살펴보겠습니다. 마지막으로 보조 인덱스를 사용해야 하는 경우와 다른 솔루션을 찾아야 하는 경우에 대한 몇 가지 생각으로 마무리하겠습니다.


시작하자.

DynamoDB란 무엇이며 DynamoDB 보조 인덱스란 무엇입니까?

보조 인덱스의 사용 사례와 모범 사례를 살펴보기 전에 먼저 DynamoDB 보조 인덱스가 무엇인지 이해해야 합니다. 그러기 위해서는 DynamoDB의 작동 방식을 조금 이해해야 합니다.


여기서는 DynamoDB에 대한 기본적인 이해가 있다고 가정합니다. 보조 인덱스를 이해하기 위해 알아야 할 기본 사항을 다루겠지만, DynamoDB를 처음 사용하는 경우에는 보다 기본적인 소개부터 시작하는 것이 좋습니다.

DynamoDB에 대해 알아야 할 최소한의 정보

DynamoDB는 고유한 데이터베이스입니다. OLTP 워크로드용으로 설계되었으므로 대량의 소규모 작업을 처리하는 데 적합합니다. 장바구니에 항목 추가, 동영상 좋아요 표시, Reddit에 댓글 추가 등을 생각해 보세요. 이러한 방식으로 MySQL, PostgreSQL, MongoDB 또는 Cassandra와 같이 사용했을 수 있는 다른 데이터베이스와 유사한 애플리케이션을 처리할 수 있습니다.


DynamoDB의 주요 약속은 모든 규모에서 일관된 성능을 보장하는 것입니다. 테이블에 1MB의 데이터가 있든 1페타바이트의 데이터가 있든 관계없이 DynamoDB는 OLTP와 유사한 요청에 대해 동일한 지연 시간을 갖기를 원합니다. 이는 큰 문제입니다. 데이터 양이나 동시 요청 수를 늘리면 많은 데이터베이스의 성능이 저하됩니다. 그러나 이러한 보장을 제공하려면 몇 가지 장단점이 필요하며 DynamoDB에는 이를 효과적으로 사용하기 위해 이해해야 하는 몇 가지 고유한 특성이 있습니다.


첫째, DynamoDB는 내부적으로 여러 파티션에 데이터를 분산시켜 데이터베이스를 수평적으로 확장합니다. 이러한 파티션은 사용자에게는 표시되지 않지만 DynamoDB 작동 방식의 핵심입니다. 테이블에 대한 기본 키('파티션 키'라고 하는 단일 요소 또는 파티션 키와 정렬 키의 조합)를 지정하면 DynamoDB는 해당 기본 키를 사용하여 데이터가 어느 파티션에 있는지 결정합니다. . 모든 요청은 요청을 처리해야 하는 파티션을 결정하는 요청 라우터를 통과합니다. 이러한 파티션은 작기 때문에(일반적으로 10GB 이하) 독립적으로 이동, 분할, 복제 및 관리가 가능합니다.




샤딩을 통한 수평적 확장성은 흥미롭지만 결코 DynamoDB만의 고유한 기능은 아닙니다. 다른 많은 데이터베이스(관계형 및 비관계형 모두)는 수평 확장을 위해 샤딩을 사용합니다. 그러나 DynamoDB의 고유한 은 기본 키를 사용하여 데이터에 액세스하도록 강제하는 방식입니다. 요청을 일련의 쿼리로 변환하는 쿼리 플래너를 사용하는 대신 DynamoDB는 기본 키를 사용하여 데이터에 액세스하도록 합니다 . 본질적으로 데이터에 대해 직접 주소 지정이 가능한 인덱스를 얻습니다.


DynamoDB용 API는 이를 반영합니다. 개별 항목을 읽고, 쓰고, 삭제할 수 있는 개별 항목( GetItem , PutItem , UpdateItem , DeleteItem )에 대한 일련의 작업이 있습니다. 또한 동일한 파티션 키를 사용하여 여러 항목을 검색할 수 있는 Query 작업이 있습니다. 복합 기본 키가 있는 테이블이 있는 경우 동일한 파티션 키를 가진 항목은 동일한 파티션에 함께 그룹화됩니다. 정렬 키에 따라 정렬되므로 "사용자에 대한 가장 최근 주문 가져오기" 또는 "IoT 장치에 대한 마지막 10개의 센서 판독값 가져오기"와 같은 패턴을 처리할 수 있습니다.


예를 들어 사용자 테이블이 있는 SaaS 애플리케이션을 가정해 보겠습니다. 모든 사용자는 단일 조직에 속합니다. 다음과 같은 테이블이 있을 수 있습니다.



우리는 파티션 키가 '조직'이고 정렬 키가 '사용자 이름'인 복합 기본 키를 사용하고 있습니다. 이를 통해 조직 및 사용자 이름을 제공하여 개별 사용자를 가져오거나 업데이트하는 작업을 수행할 수 있습니다. Query 작업에 조직만 제공하여 단일 조직의 모든 사용자를 가져올 수도 있습니다.

보조 인덱스란 무엇이며 어떻게 작동합니까?

몇 가지 기본 사항을 염두에 두고 이제 보조 인덱스를 살펴보겠습니다. 보조 인덱스의 필요성을 이해하는 가장 좋은 방법은 보조 인덱스가 해결하는 문제를 이해하는 것입니다. 우리는 DynamoDB가 기본 키에 따라 데이터를 분할하는 방법과 기본 키를 사용하여 데이터에 액세스하도록 하는 방법을 살펴보았습니다. 일부 액세스 패턴에는 모두 적합하지만 다른 방식으로 데이터에 액세스해야 하는 경우에는 어떻게 해야 할까요?


위의 예에는 조직과 사용자 이름으로 액세스하는 사용자 테이블이 있습니다. 그러나 이메일 주소로 단일 사용자를 가져와야 할 수도 있습니다. 이 패턴은 DynamoDB가 추진하는 기본 키 액세스 패턴과 맞지 않습니다. 테이블이 서로 다른 속성으로 분할되어 있기 때문에 원하는 방식으로 데이터에 액세스할 수 있는 명확한 방법이 없습니다. 전체 테이블 스캔을 수행할 수 있지만 이는 느리고 비효율적입니다. 다른 기본 키를 사용하여 데이터를 별도의 테이블에 복제할 수 있지만 이로 인해 복잡성이 추가됩니다.


보조 인덱스가 등장하는 곳입니다. 보조 인덱스는 기본적으로 다른 기본 키를 사용하여 완전히 관리되는 데이터 복사본입니다. 인덱스의 기본 키를 선언하여 테이블에 보조 인덱스를 지정합니다. 테이블에 쓰기가 들어오면 DynamoDB는 해당 데이터를 보조 인덱스에 자동으로 복제합니다.


참고 *: 이 섹션의 모든 내용은 글로벌 보조 인덱스에 적용됩니다. DynamoDB는 약간 다른 로컬 보조 인덱스도 제공합니다. 거의 모든 경우에 글로벌 보조 인덱스가 필요할 것입니다. 차이점에 대한 자세한 내용은 글로벌 또는 로컬 보조 인덱스 선택 에 대한 이 문서를 확인하세요.*


이 경우 "Email"이라는 파티션 키를 사용하여 테이블에 보조 인덱스를 추가하겠습니다. 보조 인덱스는 다음과 같습니다.



이는 동일한 데이터이며 다른 기본 키로 재구성되었습니다. 이제 이메일 주소로 사용자를 효율적으로 찾을 수 있습니다.


어떤 면에서는 이는 다른 데이터베이스의 인덱스와 매우 유사합니다. 둘 다 특정 속성에 대한 조회에 최적화된 데이터 구조를 제공합니다. 그러나 DynamoDB의 보조 인덱스는 몇 가지 주요 측면에서 다릅니다.


첫째, 가장 중요한 점은 DynamoDB의 인덱스가 기본 테이블과 완전히 다른 파티션에 있다는 것입니다. DynamoDB는 모든 조회가 효율적이고 예측 가능하길 원하며 선형 수평 확장을 제공하려고 합니다. 이렇게 하려면 쿼리하는 데 사용할 속성별로 데이터를 다시 샤딩해야 합니다.



다른 분산 데이터베이스에서는 일반적으로 보조 인덱스에 대한 데이터를 다시 샤딩하지 않습니다. 일반적으로 샤드의 모든 데이터에 대한 보조 인덱스만 유지합니다. 그러나 인덱스가 분할 키를 사용하지 않는 경우 분할 키가 없는 쿼리는 데이터를 찾기 위해 모든 분할에 걸쳐 분산 수집 작업을 수행해야 하므로 데이터를 수평적으로 확장하는 이점 중 일부를 잃게 됩니다. 찾고 있어요.


DynamoDB의 보조 인덱스가 다른 두 번째 방법은 (종종) 전체 항목을 보조 인덱스에 복사한다는 점입니다. 관계형 데이터베이스의 인덱스의 경우 인덱스에는 인덱싱되는 항목의 기본 키에 대한 포인터가 포함되는 경우가 많습니다. 인덱스에서 관련 레코드를 찾은 후 데이터베이스는 전체 항목을 가져와야 합니다. DynamoDB의 보조 인덱스는 기본 테이블과 다른 노드에 있기 때문에 원래 항목으로 돌아가는 네트워크 홉을 피하려고 합니다. 대신 읽기를 처리하기 위해 필요한 만큼의 데이터를 보조 인덱스에 복사합니다.


DynamoDB의 보조 인덱스는 강력하지만 몇 가지 제한 사항이 있습니다. 우선, 읽기 전용이므로 보조 인덱스에 직접 쓸 수 없습니다. 대신, 기본 테이블에 쓰고 DynamoDB가 보조 인덱스에 대한 복제를 처리합니다. 둘째, 보조 인덱스에 대한 쓰기 작업에 대한 요금이 부과됩니다. 따라서 테이블에 보조 인덱스를 추가하면 테이블의 총 쓰기 비용이 두 배로 늘어나는 경우가 많습니다.

보조 인덱스 사용 팁

이제 보조 인덱스가 무엇이고 어떻게 작동하는지 이해했으므로 이를 효과적으로 사용하는 방법에 대해 이야기해 보겠습니다. 보조 인덱스는 강력한 도구이지만 잘못 사용될 수 있습니다. 보조 인덱스를 효과적으로 사용하기 위한 몇 가지 팁은 다음과 같습니다.

보조 인덱스에 읽기 전용 패턴을 적용해 보세요.

첫 번째 팁은 분명해 보입니다. 보조 인덱스는 읽기에만 사용할 수 있으므로 보조 인덱스에 읽기 전용 패턴을 갖는 것을 목표로 해야 합니다! 그런데 저는 이런 실수를 늘 봅니다. 개발자는 먼저 보조 인덱스에서 읽은 다음 기본 테이블에 씁니다. 이로 인해 추가 비용과 추가 대기 시간이 발생하며 일부 사전 계획을 통해 이를 방지할 수 있는 경우가 많습니다.


DynamoDB 데이터 모델링에 대해 읽어본 적이 있다면 액세스 패턴을 먼저 생각해야 한다는 것을 알고 계실 것입니다. 먼저 정규화된 테이블을 디자인한 다음 쿼리를 작성하여 함께 조인하는 관계형 데이터베이스와는 다릅니다. DynamoDB에서는 애플리케이션이 수행할 작업을 생각한 다음 해당 작업을 지원하도록 테이블과 인덱스를 설계해야 합니다.


나는 테이블을 디자인할 때 쓰기 기반 액세스 패턴부터 먼저 시작하는 것을 좋아합니다. 글을 쓰면서 나는 사용자 이름의 고유성이나 그룹의 최대 회원 수와 같은 일종의 제약 조건을 유지하는 경우가 많습니다. 이상적으로는 DynamoDB 트랜잭션을 사용하지 않거나 경쟁 조건이 발생할 수 있는 읽기-수정-쓰기 패턴을 사용하지 않고 이를 간단하게 만드는 방식으로 테이블을 설계하고 싶습니다.


이러한 작업을 진행하면서 일반적으로 쓰기 패턴과 일치하는 항목을 식별하는 '기본' 방법이 있다는 것을 알게 될 것입니다. 이것이 결국 기본 키가 됩니다. 그런 다음 보조 인덱스를 사용하면 추가 보조 읽기 패턴을 쉽게 추가할 수 있습니다.


이전의 사용자 예에서 모든 사용자 요청에는 조직과 사용자 이름이 포함될 가능성이 높습니다. 이를 통해 개별 사용자 기록을 조회하고 사용자의 특정 작업을 승인할 수 있습니다. 이메일 주소 조회는 '비밀번호 찾기' 흐름이나 '사용자 검색' 흐름과 같이 덜 눈에 띄는 액세스 패턴에 대한 것일 수 있습니다. 이는 읽기 전용 패턴이며 보조 인덱스에 잘 맞습니다.

키가 변경 가능한 경우 보조 인덱스를 사용하세요.

보조 인덱스 사용에 대한 두 번째 팁은 액세스 패턴에서 변경 가능한 값으로 보조 인덱스를 사용하는 것입니다. 먼저 그 이유를 이해한 다음, 적용되는 상황을 살펴보겠습니다.


DynamoDB를 사용하면 UpdateItem 작업을 통해 기존 항목을 업데이트할 수 있습니다. 그러나 업데이트에서는 항목의 기본 키를 변경할 수 없습니다 . 기본 키는 항목의 고유 식별자이며 기본 키를 변경하면 기본적으로 새 항목이 생성됩니다. 기존 항목의 기본 키를 변경하려면 이전 항목을 삭제하고 새 항목을 만들어야 합니다. 이 2단계 프로세스는 더 느리고 비용이 많이 듭니다. 원래 항목을 먼저 읽은 다음 트랜잭션을 사용하여 원래 항목을 삭제하고 동일한 요청에서 새 항목을 생성해야 하는 경우가 많습니다.


반면, 보조 인덱스의 기본 키에 이 변경 가능한 값이 있는 경우 DynamoDB는 복제 중에 이 삭제 + 생성 프로세스를 처리합니다. 간단한 UpdateItem 요청을 발행하여 값을 변경할 수 있으며, DynamoDB가 나머지를 처리합니다.


나는 이 패턴이 두 가지 주요 상황에서 나타나는 것을 봅니다. 첫 번째이자 가장 일반적인 경우는 정렬하려는 변경 가능한 속성이 있는 경우입니다. 여기의 표준적인 예는 사람들이 지속적으로 포인트를 쌓는 게임에 대한 순위표 또는 가장 최근에 업데이트된 항목을 먼저 표시하려는 지속적으로 업데이트되는 항목 목록에 대한 것입니다. 파일을 '최종 수정'순으로 정렬할 수 있는 Google 드라이브와 같은 것을 생각해 보세요.


이것이 나타나는 두 번째 패턴은 필터링하려는 변경 가능한 속성이 있는 경우입니다. 여기서는 사용자의 주문 내역이 있는 전자상거래 상점을 생각해 볼 수 있습니다. 사용자가 상태별로 주문을 필터링하도록 허용할 수 있습니다. '배송됨' 또는 '배달됨'인 모든 주문을 표시해 주세요. 이를 파티션 키 또는 정렬 키의 시작 부분에 구축하여 정확한 일치 필터링을 허용할 수 있습니다. 항목의 상태가 변경되면 상태 속성을 업데이트하고 DynamoDB를 활용하여 보조 인덱스에서 항목을 올바르게 그룹화할 수 있습니다.


이 두 가지 상황 모두에서 이 변경 가능한 속성을 보조 인덱스로 옮기면 시간과 비용이 절약됩니다. 읽기-수정-쓰기 패턴을 피함으로써 시간을 절약하고 트랜잭션의 추가 쓰기 비용을 피함으로써 비용을 절약할 수 있습니다.


또한 이 패턴은 이전 팁과 잘 맞습니다. 이전 점수, 이전 상태 또는 마지막 업데이트 시간과 같은 변경 가능한 속성을 기반으로 쓰기 항목을 식별할 가능성은 거의 없습니다. 대신 사용자 ID, 주문 ID 또는 파일 ID와 같은 보다 지속적인 값으로 업데이트됩니다. 그런 다음 보조 인덱스를 사용하여 변경 가능한 속성을 기준으로 정렬하고 필터링합니다.

'지방' 파티션을 피하세요

위에서 DynamoDB가 기본 키를 기준으로 데이터를 파티션으로 나누는 것을 살펴보았습니다. DynamoDB는 이러한 파티션을 10GB 이하로 작게 유지하는 것을 목표로 하며, DynamoDB의 확장성의 이점을 얻으려면 파티션 전체에 요청을 분산시키는 것을 목표로 해야 합니다.


이는 일반적으로 파티션 키에 높은 카디널리티 값을 사용해야 함을 의미합니다. 사용자 이름, 주문 ID, 센서 ID 등을 생각해 보세요. 이러한 속성에는 많은 수의 값이 있으며 DynamoDB는 트래픽을 파티션 전체에 분산시킬 수 있습니다.


사람들이 메인 테이블에서는 이 원칙을 이해하지만 보조 인덱스에서는 완전히 잊어버리는 경우가 많습니다. 종종 그들은 특정 품목 유형에 대해 전체 테이블에 걸쳐 주문을 원합니다. 사용자를 알파벳순으로 검색하려는 경우 모든 사용자가 USERS 파티션 키로, 사용자 이름을 정렬 키로 사용하는 보조 인덱스를 사용합니다. 또는 전자상거래 상점에서 가장 최근 주문을 주문하려는 경우 모든 주문에 파티션 키로 ORDERS 있고 정렬 키로 타임스탬프가 있는 보조 인덱스를 사용합니다.


이 패턴은 DynamoDB 파티션 처리량 제한 에 근접하지 않는 소규모 트래픽 애플리케이션에 적합하지만 트래픽이 많은 애플리케이션에는 위험한 패턴입니다. 모든 트래픽이 단일 물리적 파티션으로 유입될 수 있으며 해당 파티션의 쓰기 처리량 제한에 빠르게 도달할 수 있습니다.


더욱이 가장 위험한 것은 이것이 메인 테이블에 문제를 일으킬 수 있다는 것입니다. 복제 중에 보조 인덱스 쓰기가 제한되면 복제 대기열이 백업됩니다. 이 대기열이 너무 많이 백업되면 DynamoDB는 기본 테이블에 대한 쓰기를 거부하기 시작합니다.


이는 도움을 주기 위해 고안되었습니다. DynamoDB는 보조 인덱스의 부실 상태를 제한하여 지연 시간이 많이 걸리는 보조 인덱스를 방지합니다. 그러나 전혀 예상하지 못한 상황에서 갑자기 나타나는 놀라운 상황이 될 수도 있습니다.

희소 인덱스를 전역 필터로 사용

사람들은 종종 보조 인덱스를 새로운 기본 키로 모든 데이터를 복제하는 방법으로 생각합니다. 그러나 보조 인덱스에 저장되기 위해 모든 데이터가 필요한 것은 아닙니다. 인덱스의 키 스키마와 일치하지 않는 항목이 있는 경우 해당 항목은 인덱스에 복제되지 않습니다.


이는 데이터에 전역 필터를 제공하는 데 정말 유용할 수 있습니다. 이에 대해 제가 사용하는 표준적인 예는 메시지 받은 편지함입니다. 기본 테이블에는 특정 사용자에 대한 모든 메시지가 생성된 시간순으로 정렬되어 저장될 수 있습니다.


하지만 당신이 나와 같다면 받은편지함에는 많은 메시지가 있을 것입니다. 또한 읽지 않은 메시지를 누군가에게 연락하라는 작은 알림과 같은 '할 일' 목록으로 처리할 수도 있습니다. 따라서 나는 대개 받은편지함에서 읽지 않은 메시지만 보고 싶습니다.


보조 인덱스를 사용하여 unread == true 인 전역 필터를 제공할 수 있습니다. 아마도 보조 인덱스 파티션 키는 ${userId}#UNREAD 와 같을 것이고 정렬 키는 메시지의 타임스탬프일 것입니다. 메시지를 처음 생성하면 보조 인덱스 파티션 키 값이 포함되므로 읽지 않은 메시지 보조 인덱스에 복제됩니다. 나중에 사용자가 메시지를 읽으면 statusREAD 로 변경하고 보조 인덱스 파티션 키 값을 삭제할 수 있습니다. 그러면 DynamoDB가 이를 보조 인덱스에서 제거합니다.


나는 이 방법을 항상 사용하는데, 정말 효과적이다. 또한 희소 인덱스를 사용하면 비용이 절약됩니다. 읽은 메시지에 대한 업데이트는 보조 인덱스에 복제되지 않으므로 쓰기 비용이 절약됩니다.

보조 인덱스 예측 범위를 좁혀 인덱스 크기 및/또는 쓰기를 줄입니다.

마지막 팁으로 이전 요점을 좀 더 자세히 살펴보겠습니다. 방금 항목에 인덱스에 대한 기본 키 요소가 없으면 DynamoDB가 보조 인덱스에 해당 항목을 포함하지 않는다는 것을 확인했습니다. 이 트릭은 기본 키 요소뿐만 아니라 데이터의 키가 아닌 속성에도 사용할 수 있습니다!


보조 인덱스를 생성할 때 보조 인덱스에 포함할 기본 테이블의 속성을 지정할 수 있습니다. 이를 지수의 투영 이라고 합니다. 기본 테이블의 모든 속성, 기본 키 속성만 포함하거나 속성의 하위 집합을 포함하도록 선택할 수 있습니다.


보조 인덱스에 모든 속성을 포함하고 싶은 유혹이 있지만 이는 비용이 많이 드는 실수일 수 있습니다. 프로젝션된 속성의 값을 변경하는 기본 테이블에 대한 모든 쓰기는 보조 인덱스에 복제된다는 점을 기억하세요. 전체 프로젝션이 포함된 단일 보조 인덱스는 테이블 쓰기 비용을 효과적으로 두 배로 늘립니다. 보조 인덱스가 추가될 때마다 쓰기 비용이 1/N + 1 만큼 증가합니다. 여기서 N 새 인덱스 이전의 보조 인덱스 수입니다.


또한 쓰기 비용은 항목 크기에 따라 계산됩니다. 테이블에 기록된 각 1KB의 데이터는 WCU를 사용합니다. 4KB 항목을 보조 인덱스에 복사하는 경우 기본 테이블과 보조 인덱스 모두에서 4WCU 전체를 지불하게 됩니다.


따라서 2차 지수 예측 범위를 좁혀 비용을 절약할 수 있는 두 가지 방법이 있습니다. 첫째, 특정 쓰기를 완전히 방지할 수 있습니다. 보조 인덱스 프로젝션의 속성을 건드리지 않는 업데이트 작업이 있는 경우 DynamoDB는 보조 인덱스에 대한 쓰기를 건너뜁니다. 둘째, 보조 인덱스에 복제되는 쓰기의 경우 복제되는 항목의 크기를 줄여 비용을 절약할 수 있습니다.


이것은 올바른 균형을 맞추는 데 까다로운 균형이 될 수 있습니다. 인덱스가 생성된 후에는 보조 인덱스 예측을 변경할 수 없습니다. 보조 인덱스에 추가 속성이 필요하다고 판단되면 새 프로젝션으로 새 인덱스를 생성한 다음 이전 인덱스를 삭제해야 합니다.

보조 인덱스를 사용해야 합니까?

이제 보조 인덱스에 대한 몇 가지 실용적인 조언을 살펴보았습니다. 이제 한 걸음 물러서서 더 근본적인 질문을 던져보겠습니다. 보조 인덱스를 사용해야 할까요?


앞서 살펴보았듯이 보조 인덱스는 다른 방식으로 데이터에 액세스하는 데 도움이 됩니다. 그러나 이로 인해 추가 쓰기 비용이 발생합니다. 따라서 보조 인덱스에 대한 나의 경험 법칙은 다음과 같습니다.


읽기 비용 절감이 쓰기 비용 증가보다 클 경우 보조 인덱스를 사용합니다.


이것은 말할 때는 분명해 보이지만 모델링할 때는 직관에 어긋날 수 있습니다. 다른 접근법을 생각하지 않고 "보조 인덱스에 던져라"라고 말하는 것은 너무 쉬운 것 같습니다.


이를 이해하기 위해 보조 인덱스가 적합하지 않은 두 가지 상황을 살펴보겠습니다.

작은 항목 컬렉션에 필터링 가능한 많은 속성이 있습니다.

DynamoDB를 사용하면 일반적으로 기본 키가 필터링을 수행하기를 원합니다. DynamoDB에서 쿼리를 사용한 다음 애플리케이션에서 자체 필터링을 수행할 때마다 약간 짜증이 납니다. 왜 기본 키에 이를 구축할 수 없습니까?


내 본능적인 반응에도 불구하고 데이터를 너무 많이 읽은 다음 애플리케이션에서 필터링하고 싶은 상황이 몇 가지 있습니다.

가장 흔히 볼 수 있는 위치는 사용자를 위해 데이터에 대해 다양한 필터를 제공하려고 하지만 관련 데이터 세트가 제한되어 있는 경우입니다.


운동 추적기를 생각해 보세요. 사용자가 운동 유형, 강도, 기간, 날짜 등과 같은 다양한 속성을 필터링하도록 허용할 수 있습니다. 그러나 사용자가 수행하는 운동 횟수는 관리 가능합니다. 고급 사용자라도 1000회 운동을 초과하려면 시간이 걸립니다. 이러한 모든 속성에 인덱스를 추가하는 대신 모든 사용자의 운동을 가져온 다음 애플리케이션에서 필터링할 수 있습니다.


여기가 제가 수학을 하는 것을 추천하는 곳입니다. DynamoDB를 사용하면 이 두 가지 옵션을 쉽게 계산하고 어느 옵션이 애플리케이션에 더 잘 작동하는지 파악할 수 있습니다.

대규모 항목 컬렉션에는 필터링 가능한 많은 속성이 있습니다.

상황을 조금 바꿔 보겠습니다. 항목 컬렉션이 크면 어떻게 될까요? 체육관용 운동 추적기를 구축 중이고 체육관 소유자가 체육관의 모든 사용자 에 대해 위에서 언급한 모든 속성을 필터링할 수 있도록 하려면 어떻게 해야 할까요?


이로 인해 상황이 변경됩니다. 이제 우리는 각각 수백 또는 수천 개의 운동을 하는 수백 또는 수천 명의 사용자에 대해 이야기하고 있습니다. 전체 항목 컬렉션을 과도하게 읽고 결과에 대해 사후 필터링을 수행하는 것은 의미가 없습니다.


그러나 보조 인덱스는 여기서도 실제로 의미가 없습니다. 보조 인덱스는 관련 필터가 존재한다고 믿을 수 있는 알려진 액세스 패턴에 적합합니다. 체육관 소유자가 다양한 속성(모두 선택 사항)을 필터링할 수 있도록 하려면 이 작업을 수행하기 위해 많은 수의 인덱스를 생성해야 합니다.


이전에 쿼리 플래너의 가능한 단점에 대해 이야기했지만 쿼리 플래너에는 장점도 있습니다. 보다 유연한 쿼리를 허용하는 것 외에도 인덱스 교차와 같은 작업을 수행하여 이러한 쿼리를 구성할 때 여러 인덱스의 부분 결과를 볼 수도 있습니다. DynamoDB에서도 동일한 작업을 수행할 수 있지만 이를 파악하기 위한 몇 가지 복잡한 애플리케이션 로직과 함께 애플리케이션 간에 많은 혼란이 발생하게 됩니다.


이러한 유형의 문제가 발생하면 일반적으로 이 사용 사례에 더 적합한 도구를 찾습니다. RocksetElasticsearch는 데이터 세트 전체에 유연한 보조 인덱스와 유사한 필터링을 제공하기 위해 제가 추천하는 권장 사항입니다.

결론

이번 포스팅에서는 DynamoDB 보조 인덱스에 대해 알아보았습니다. 먼저 DynamoDB의 작동 방식과 보조 인덱스가 필요한 이유를 이해하기 위해 몇 가지 개념을 살펴보았습니다. 그런 다음 보조 인덱스를 효과적으로 사용하는 방법을 이해하고 특정 특징을 알아보기 위한 몇 가지 실용적인 팁을 검토했습니다. 마지막으로, 다른 접근 방식을 사용해야 하는 경우를 확인하기 위해 보조 인덱스에 대해 어떻게 생각하는지 살펴보았습니다.


보조 인덱스는 DynamoDB 도구 상자의 강력한 도구이지만 만능은 아닙니다. 모든 DynamoDB 데이터 모델링과 마찬가지로, 시작하기 전에 액세스 패턴을 신중하게 고려하고 비용을 계산해야 합니다.


Alex DeBrie의 블로그 DynamoDB Filtering and Aggregation Queries Using SQL on Rockset 에서 Rockset을 사용하여 보조 인덱스와 유사한 필터링을 수행하는 방법에 대해 자세히 알아보세요.