스터디 배경

테이블의 변경 히스토리를 저장하기 위해 DynamoDB를 사용하는 것이 좋다고 판단됌. 로그 데이터이기 때문에 데이터들의 일관성 문제가 없으며 많은 데이터를 효율적으로 저장하고 쿼리할 수 있기 때문.

개념

https://yogae.github.io/aws/2018/12/06/dynamodb_summary.html

https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/SecondaryIndexes.html

  • 기본키

    • 파티션 키
      • 내부 해시 함수에 대한 입력으로 사용되는 키
      • 파티션 키로만 구성되어 있는 테이블에서는 동일한 파티션 키 값을 가질 수 없음.
    • 파티션 키 및 정렬 키 (복합 기본키)
      • 동일한 파티션 키 값을 가질 수 있으며, 두 아이템의 정렬키 값을 달라야함.
      • 파티션 키가 동일한 모든 항목은 정렬키 값을 기준으로 정렬
  • 보조 인덱스

    • 글로벌 보조 인덱스
      • 파티션 키 및 정렬키가 기본테이블의 파티션/정렬키와 다를 수 있는 인덱스
      • 모든 글로벌 보조 인덱스는 파티션 키가 있어야 하며, 선택사항으로 정렬키를 가질 수 있음.
  • 모든 파티션에서 전체 테이블을 쿼리

    • 로컬 보조 인덱스
      • 기본 테이블과 파티션 키는 동일하지만, 정렬 키는 다른 인덱스
      • 모든 로컬 보조 인덱스에는 기본 테이블의 파티션 및 정렬키가 자동적으로 포함 된다.
      • 파티션 키 값으로 지정한 대로 단일 파티션을 쿼리할 수 있음.

프로비저닝 vs 온디멘드

https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html

DynamoDB의 과금 방식중 온디멘드 방식과 프로비저닝 방식이 있다. 우리 서비스의 경우

  • 트래픽이 점점 증가해나가고 있음, 또한 마케팅 여부에 따라 증가하거나 감소할 가능성이 있음.
  • 스크래핑 작업 특성상, 한번 스크래핑이 시작하면 많은양의 읽기 쓰기가 동작되며, 최적화된 쓰기/읽기 유닛 책정이 어려움.

두가지 이유로 인해 읽기/쓰기 유닛을 책정하는 것보다는 온디멘드 방식을 사용하는 것이 좋다고 판단됌.

온디멘드 방식을 사용하게 되면, 읽기/쓰기 유닛을 효율적으로 사용하기 위한 테이블 설계에 대한 부담이 줄어 드는 장점도 있다.

테이블 설계

  • DynamoDB 애플리케이션에서는 가능한 적은 수의 테이블을 유지해야 합니다. 대부분의 잘 설계된 애플리케이션은 단 하나의 테이블만 요구합니다.
  • 쿼리를 처리할 때 데이터를 변화시키는 대신(RDBMS 시스템의 방식), NoSQL 데이터베이스는 데이터베이스의 모양이 쿼리 대상과 일치하도록 데이터를 구성합니다. 이는 속도와 확장성 향상에 중요한 요소입니다.
  • 정렬 순서를 사용합니다. 핵심 설계가 함께 정렬할 것을 요구하는 경우, 관련 항목을 그룹으로 묶어 효율적으로 쿼리할 수 있습니다. 이는 중요한 NoSQL 설계 전략입니다.

파티션 키 설계

  • 워크로드 배분

    • 파티션 키 설계 : 트래픽이 하나의 항목으로 너무 집중되는 경우, 자주 액세스 하는 항목이 동일한 파티션에 상주하지 않도록 파티션 균형 재조정

    • https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/bp-partition-key-uniform-load.html

      파티션 키 값 균일성
      사용자 ID, 애플리케이션의 사용자가 많은 경우. 좋음
      상태 코드, 가능한 상태 코드가 몇 개 없는 경우. 나쁨
      항목 생성 날짜, 가장 가까운 시간(예: 날, 시, 분)으로 반올림. 나쁨
      디바이스 ID, 각 디바이스가 비교적 비슷한 간격으로 데이터에 액세스하는 경우. 좋음
      디바이스 ID, 추적되는 디바이스는 많지만 다른 디바이스보다 한 디바이스가 훨씬 더 인기 있는 경우. 나쁨
  • 쓰기 샤딩

    • 여러 파티션 키 공간에 워크로드를 더 골고루 배분할 수 있도록, 파티션 키 값 끝에 난수나 접미사를 추가하여 병렬처리함

    • 데이터 입력시, 가능하다면, 여러 파티션을 골고루 순회하며 입력할 수 있도록 쿼리

      • 아래 표에서 첫번째 표보다, 두번째 표가 서로 다른 파티션 키 값을 사용, 병렬처리 성능 향상
      UserID MessageID
      U1 1
      U1 2
      U1
      U1 … 최대 100
      U2 1
      U2 2
      U2
      U2 … 최대 200
      UserID MessageID
      U1 1
      U2 1
      U3 1
      U1 2
      U2 2
      U3 2

    여러 UserID를 순회하면서 값을 입력한다면, 병렬 처리 성능이 향상한다.

정렬키 설계

  • https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/bp-sort-keys.html

  • 복합정렬키를 사용하면, 데이터의 계층적 관계를 정의할 수 있도록 도와준다

    [country]#[region]#[state]#[county]#[city]#[neighborhood]

    위와같이, 정렬키를 구성한다면, begins_with, between, >, < 등 연산자를 사용하는 범위 쿼리를 사용하여 위치 목록을 효율적으로 범위 쿼리 할 수 있다.

보조키 설계

https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/bp-indexes-general.html

  • 일반적으로 로컬 보조 인덱스보다, 글로벌 보조 인덱스 사용

  • 스토리지 및 IO 비용 감소를 위해 : 인덱스 수와 크기를 최대한 작게 유지

예시

Case1

https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/bp-sort-keys.html

         기본 키와 데이터 항목 속성을 가진 테이블을 표시하는 버전 관리의 예

버전 관리에 정렬키를 사용하는 경우로 v0_ v00_ v000_ 같은 계층구조로 버전을 효율적으로 쿼링함.

Case2

https://dev.overnodes.com/entry/AWS-DynamoDBNoSQL

image-20200324180519822

image-20200324180741274

Collector-1 / Collector-2, Details/Remittance-1 키의 네임이 아니라, Value이다

스터디 적용

거래 태깅 변경 로그의 테이블 설계

파티션키, 정렬키 설계

  • 키후보

    1. 파티션키 : 회사 ID / 정렬키 : 거래ID + 입력시간(DTS_UPDATE)

    2. 파티션키 : 거래 ID / 정렬키 : 입력시간(DTS_UPDATE)

    3. 파티션키 : 거래ID + 입력시간(DTS_UPDATE)

  • 사용 쿼리

    • 조회 쿼리
      • 한 회사의 종합적인 태그 변경 로그를 분석할 경우 1번의 케이스가 적절
      • 한 거래 내역의 태그 변경 로그를 쿼리할 경우 2번의 케이스가 적절
    • 다중 입력시 병렬처리 성능 최적화 관점
      • 1번 케이스의 경우, 스크래핑시나 스마트 태그시 한 파티션에 워크로드가 집중되는 문제가 있음
      • 3번 케이스의 경우, 워크로드 분산에는 최적화되지만, 데이터의 구조가 실제 사용 케이스와 다름
      • 2번 케이스가 적절함.

조회쿼리/다중입력을 고려하여 2번 케이스가 가장 적절하다고 판단됌.

보조키 사용

  • 한 회사의 종합적인 태그 변경 로그를 분석할 케이스가 있을 수 있기 때문에 회사ID 보조키를 사용한다.
  • 2번 케이스로 구성할경우, 회사 ID는 기본키와 별개이므로, 글로벌 보조키를 사용한다.