developer tip

DynamoDB의 로컬 인덱스와 글로벌 인덱스의 차이점

optionbox 2020. 8. 9. 10:21
반응형

DynamoDB의 로컬 인덱스와 글로벌 인덱스의 차이점


이 두 가지 보조 인덱스와 그 차이점이 궁금합니다. 이것이 어떻게 생겼는지 상상하기 어렵습니다. 그리고 이것은 나뿐만 아니라 더 많은 사람들에게 도움이 될 것이라고 생각합니다.


로컬 보조 인덱스는 여전히 원래 해시 키에 의존합니다. 해시 + 범위가있는 테이블을 제공 할 때 LSI를 hash + range1, hash + range2 .. hash + range6로 생각하십시오. 쿼리 할 범위 속성이 5 개 더 있습니다. 또한 프로비저닝 된 처리량은 하나만 있습니다.

글로벌 보조 인덱스는 인덱스마다 다른 해시 / 범위 키라는 새로운 패러다임을 정의합니다.
이것은 테이블 당 하나의 해시 키의 원래 사용을 중단합니다. 그렇기 때문에 GSI를 정의 할 때 인덱스 당 프로비저닝 된 처리량을 추가하고 이에 대한 비용을 지불해야합니다.

차이점에 대한 자세한 내용은 GSI 발표 에서 확인할 수 있습니다.


다음은 문서의 공식적인 정의입니다.

글로벌 보조 인덱스 — 테이블에있는 것과 다를 수있는 해시 및 범위 키가있는 인덱스입니다. 인덱스에 대한 쿼리는 모든 파티션에서 테이블의 모든 데이터에 걸쳐있을 수 있으므로 글로벌 보조 인덱스는 "글로벌"로 간주됩니다.

Local secondary index — 테이블과 동일한 해시 키가 있지만 범위 키가 다른 인덱스입니다. local secondary index는 local secondary index의 모든 파티션이 동일한 해시 키를 가진 테이블 파티션으로 범위가 지정된다는 점에서 "로컬"입니다.

그러나 차이점은 주요 정의 측면에서 가능성을 뛰어 넘습니다. 인덱스 유지 비용과 노력에 직접적인 영향을 미치는 몇 가지 중요한 요소를 아래에서 찾으십시오.

  • 처리량 :

로컬 보조 인덱스는 테이블의 처리량을 사용합니다. 로컬 인덱스를 통해 레코드를 쿼리하면 작업이 테이블의 읽기 용량 단위를 사용합니다. 로컬 인덱스가있는 테이블에서 쓰기 작업 (생성, 업데이트, 삭제)을 수행하면 두 개의 쓰기 작업이 발생합니다. 하나는 테이블 용이고 다른 하나는 인덱스 용입니다. 두 작업 모두 테이블에서 쓰기 용량 단위를 사용합니다.

글로벌 보조 인덱스에는 자체 프로비저닝 된 처리량이 있습니다. 인덱스를 쿼리 할 때 작업은 인덱스에서 읽기 용량을 사용하고 글로벌 인덱스가있는 테이블에서 쓰기 작업 (생성, 업데이트, 삭제)을 수행 할 때 두 가지가 있습니다. 쓰기 작업, 하나는 테이블 용, 다른 하나는 인덱스 용 *.

* Global Secondary Index에 대해 프로비저닝 된 처리량을 정의 할 때 다음 요구 사항에 특히주의해야합니다.

테이블 쓰기가 성공하려면 테이블 및 모든 글로벌 보조 인덱스에 대해 프로비저닝 된 처리량 설정에 쓰기를 수용 할 수있는 충분한 쓰기 용량이 있어야합니다. 그렇지 않으면 테이블에 대한 쓰기가 제한됩니다.

  • 관리 :

Local Secondary Index는 테이블을 생성 할 때만 생성 할 수 있으며 기존 테이블에 Local Secondary Index를 추가 할 수있는 방법이 없으며, 인덱스를 생성 한 후에는 삭제할 수 없습니다.

Global Secondary Index는 테이블을 생성하여 기존 테이블에 추가 할 때 생성 될 수 있으며, 기존 Global Secondary Index를 삭제할 수도 있습니다.

  • 일관성 읽기 :

Local Secondary Index는 최종 또는 강력한 일관성을 지원하는 반면 Global Secondary Index는 최종 일관성 만 지원합니다.

  • 투사:

로컬 보조 인덱스를 사용하면 인덱스에 프로젝션되지 않은 속성을 검색 할 수 있습니다 (추가 비용 : 성능 및 소비 용량 단위). Global Secondary Index를 사용하면 인덱스에 프로젝션 된 속성 만 검색 할 수 있습니다.

보조 인덱스에 정의 된 키의 고유성에 대한 특별 고려 사항 :

Local Secondary Index에서 범위 키 값은 주어진 해시 키 값에 대해 고유 할 필요가 없습니다. 동일한 것이 Global Secondary Index에 적용되며 키 값 (해시 및 범위)은 고유 할 필요가 없습니다.

출처 : http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SecondaryIndexes.html


색인별로 가능한 검색은 다음과 같습니다.

  • 해시
  • 해시 + 범위
  • 해시 + 로컬 인덱스
  • 글로벌 인덱스
  • 글로벌 인덱스 + 범위 인덱스

테이블의 해시 및 범위 인덱스 : Amazon AWS SDK 이전 버전의 일반적인 인덱스입니다.

글로벌 및 로컬 인덱스 : 테이블의 기존 해시 및 범위 인덱스 외에도 테이블에 생성 된 '추가'인덱스입니다. 글로벌 인덱스 는 해시와 유사합니다. 범위 인덱스 는 테이블의 해시와 함께 사용되는 범위 인덱스 와 유사하게 작동합니다. 코드의 엔티티 모델에서 getter는 다음과 같은 방식으로 주석 처리되어야합니다.

  • 글로벌 인덱스의 경우 :

    @DynamoDBIndexHashKey(globalSecondaryIndexName = INDEX_GLOBAL_RANGE_US_TS)
    @DynamoDBAttribute(attributeName = PROPERTY_USER)
    public String getUser() {
        return user;
    }
    
  • 글로벌 인덱스와 연관된 범위 인덱스의 경우 :

    @DynamoDBIndexRangeKey(globalSecondaryIndexName = INDEX_GLOBAL_RANGE_US_TS)
    @DynamoDBAttribute(attributeName = PROPERTY_TIMESTAMP)
    public String getTimestamp() {
        return timestamp;
    }
    

또한 글로벌 인덱스로 테이블을 읽는 경우에는 최종 읽기 (일관 적 읽기 아님) 여야합니다.

queryExpression.setConsistentRead(false);

그것을 넣는 한 가지 방법은 다음과 같습니다.

LSI-여러 다른 속성을 사용하여 쿼리를 "필터링"하거나 제한하면서 단일 Hash-Key에 대한 쿼리를 수행 할 수 있습니다.

GSI-테이블의 여러 해시 키에 대해 쿼리를 수행 할 수 있지만 결과적으로 처리량에 추가 비용이 듭니다.

A more extensive breakdown of the table types and how they work, below:

Hash Only

As you probably already know; a Hash-Key by itself must be unique as writing to a Hash-Key that already exists will overwrite the existing data.

Hash+Range

A Hash-Key + Range-Key allows you to have multiple Hash Keys that are the same, as long as they have a different range key. In this case, if you write to a Hash-Key that already exists, but use a Range-Key that is not already used by that Hash-Key, it makes a new item, whereas if an item with the same Hash+Range combination already exists, it overwrites the matching item.

Another way to think of this is like a file with a format. You can have a file with the same name (hash) as another, in the same folder (table), as long as their format (range) is different. Likewise, you can have multiple files of the same format as long as their name is different.

LSI

An LSI is basically the same as a Hash-Key + Range-Key, and follows the same rules as it, when creating items, except that you must also provide values for the LSIs, as well; they cannot be left empty/null.

To say an LSI is "Range-Key 2" is not entirely correct as you cannot have (using my file and format analogy from earlier) a file named: file.format.lsi and file.format.lsi2. You can, however, have file.format.lsi and file.format2.lsi or file.format.lsi and file2.format.lsi.

Basically, an LSI is just a "Filter-key", not an actual Range-Key; your base Hash and Range value combination must still be unique while the LSI values do not have to be unique, at all. An easier way to look at it may be to think of the LSI as data within the files. You could write code that finds all the files with the name "PROJECT101", regardless of their fileFormat, then reads the data inside to determine what should be included in the query and what is omitted. This is basically how LSI works (just without the extra overhead of opening the file to read its contents).

GSI

For GSI, you're essentially creating another table for each GSI, but without the hassle of maintaining multiple separate tables that mirror data between them; this is why they cost more throughput.

So for a GSI, you could specify fileName as your base Hash-Key, and fileFormat as your base Range-Key. You can then specify a GSI that has a Hash-Key of fileName2 and a Range-Key of fileFormat2. You can then query on either fileName or fileName2 if you like, unlike LSI where you can only query on fileName.

The main advantages are that you only have to maintain one table, instead of 2, and anytime you write to either the primary Hash/Range or the GSI Hash/Range(s), the other(s) will automatically be updated as well, so you can't "forget" to update the other table(s) like you can with a multi-table setup. Also, there's no chance of a lost connection after updating one and before updating the other, like there is with the multi-table setup.

Additionally, a GSI can "overlap" the base Hash/Range combination. So if you wanted to make a table with fileName and fileFormat as your base Hash/Range and filePriority and fileName as your GSI, you can.

Lastly, a GSI Hash+Range combination does not have to be unique, while the base Hash+Range combination does have to be unique. This is something that is not possible with a dual/multi table setup, but is with GSI. As a result, you MUST provide values for both the base AND GSI Hash+Range, when updating; none of these values can be empty/null.


Another way to explain: LSI helps you do additional queries on items with same Hash Key. GSI helps you do the similar queries on items "across the table". So very useful.

If you have a user profile table: unique-id, name, email. Here if you need to make the table queryable on name, email - then the only way is to make them GSI (LSI wont help)


This documentaion gives pretty good explanation :

https://aws.amazon.com/blogs/aws/now-available-global-secondary-indexes-for-amazon-dynamodb/

I could not comment on this Question ,but which is better in terms of write and read performance :

(Local Index with Table read and write throughput of 100) or (Global index with read /write throughput of 50 along with table's read/write throughput of 50 ? )

I do not need separate partition key for my use case , so local index should be sufficient for the required functionality.

참고URL : https://stackoverflow.com/questions/21381744/difference-between-local-and-global-indexes-in-dynamodb

반응형