Dynamo는 새롭게 소개된 AWS의 NoSQL서비스이다.
Key-Value 형태로 대용량의 데이타를 저장할 수 있으며, 고속의 데이타 access를 제공한다.
데이타 모델
먼저 데이타 모델을 살펴보자, RDBMS의 일반적인 테이블 구조와 유사하지만, 조금 더 유연성을 가지고 있다.
RDBMS와 똑같이 테이블이라는 개념을 가지고 있으며, 테이블은 테이블명과 각각의 ROW로 구성된다.
테이블은 Unique한 Primary Key를 가지고 있다. 이를 Key라고 정의한다.
테이블의 ROW에 해당하는 내용은 item이라고 부르는데, 각 item은 key에 의해서 구분된다.
RDBMS와는 다르게, 각 ROW는 똑같은 Column을 갖는 것이 아니라, 각 row 마다 다른 column을 가질 수 있다
그래서, 각 컬럼을 name = value 식으로 정의하는데, 이 각각을 attribute라고 정의한다.
아마존 웹사이트에 나와 있는 예제를 한번 살펴보자.
ProductCatalog 라는 테이블이 있다고 하자, 이 테이블의 Primary Key는 Id라는 필드를 사용한다. 이 Primary Key 필드는 모든 item들이 가지고 있어야 한다.
Item 1
{
Id = 101
ProductName = "Book 101 Title"
ISBN = "111-1111111111"
Authors = [ "Author 1", "Author 2" ]
Price = -2
Dimensions = "8.5 x 11.0 x 0.5"
PageCount = 500
InPublication = 1
ProductCategory = "Book"
}
Item 2
{
Id = 201
ProductName = "18-Bicycle 201"
Description = "201 description"
BicycleType = "Road"
Brand = "Brand-Company A"
Price = 100
Gender = "M"
Color = [ "Red", "Black" ]
ProductCategory = "Bike"
}
위의 예를 보면 알겠지만, 모든 Item들은 Id라는 Key 필드를 가지고 있지만, 각각의 Column들은 내용이 다르다. Item 1에는 ISBN 필드가 있지만, Item 2에는 ISBN 필드가 없다.
Dynamo는 RDBMS와는 다르게 Index 필드가 없다. (다른 NoSQL도 Index가 없는 경우가 많지만) 대신 range query나 sorting을 지원하기 위해서 range key라는 추가적인 키를 제공한다. Primary Key를 정의시 Unique한 Key 필드 하나만 정의하거나 (이를 Hash Key라고 한다.) 또는 이 range key를 추가로 지정하면, 쿼리 결과가 ascending 순서로 sorting이 되며, 쿼리 역시 이 range key를 기반으로 특정 범위의 데이타만 query 할 수 있다.
이 range key는 table 생성시에 hash key와 함께 정의한다.
성능
내부적으로 SSD 디스크를 이용하기 때문에, 높은 IO 성능을 보장할 수 있으며 read / write 성능을 보장하는 옵션을 가지고 있다.
Read/Write Unit이라는 옵션인데, 1KB item 1개를 1초동안 쓰거나 읽는 단위가 1 Unit이다. 2 Write Unit은 1K 데이타를 1초동안 2개 Write할 수 있는 성능 지표이다.
Units of Capacity required for reads = Number of item reads per second x item size (rounded up to the nearest KB)
Units of Capacity required for writes = Number of item writes per second x item size (rounded up to the nearest KB)
ReadUnit = [초당 읽는 item(row) 수] * [ item 크기 (kb로 반올림) ]
WriteUnit = [초당 쓰는 item(row) 수] * [ item 크기 (kb로 반올림) ]
1 ReadUnit은 초당 1KB짜리 1개의 Item을 읽을 수 있는 성능 단위이다.
예를 들어, 21.5 kb 짜리 item을 초당 100개를 읽는 성능이 필요하다면, Read Unit = 100 * 22 (반올림) = 2200 이 필요하다.
쓰기 성능도, 마찬가지 방식으로 WriteUnit이라는 단위로 지정한다.
각각 최대 10,000 Unit 까지 지원하며, 이 이상을 원할 경우, Amazon Support에 신청하면, 더 높은 Unit으로 올릴 수 있다. (최대 한계는 나와있지 않음)
Unit의 개념은 성능을 보장한다는 개념에서 긍정적이지만, 반대로 성능을 제약한다는 문제를 가지고 있다.
즉 정해진 Unit 보다 많은 read나 write가 발생할 경우, Dynamo는 이를 처리하지 않고 error 처리를 해버린다.
"ProvisionedThroughputExceededException" 그래서 Spike 형태의 request가 들어올 때는 문제가 된다.
프로그램 로직상에서 "ProvisionedThroughputExceededException" 에 대한 처리가 필요한데, 이 에러가 발생하였을 경우에는 프로그램적으로 retry를 하도록 하는 로직을 포함하는 것을 권장한다.
일관성 보장 옵션
Dynamo와 같은 NoSQL 계열의 데이타베이스는 데이타를 여러개의 노드에 나눠서 저장하고, 백업을 위해서 다른 노드로 복제하기 때문에, 복제가 완료되기 전에 클라이언트가 다른 노드에서 데이타를 읽으면 예전의 데이타를 읽을 수 있다. 이런 문제가 일관성 문제인데, 일반적인 NoSQL은 이러한 일관성을 보장하지 않는다. 복제할 때까지 시간이 걸린다는 것을 가정하고, (시간 자체는 짧으나) 그 시간동안은 일관성이 보장이 안되는데, 이러한 일관성 보장 정책을 Eventually Consistent Read라고 한다. 반대로, 데이타를 쓴 다음 모든 노드에서 데이타를 읽었을때, 같은 데이타를 바로 리턴하게 할 수 있는데, 이 경우에는 데이타가 써진 후에, 다른 노드 까지 replicated될때까지 기다려야 한다. 그래서 당연히 Read 응답시간이 Eventually Consistency Read보다 느리다. 이러한 일관성 정책을 Strongly Consistent Read라고 한다. Strong Consistency의 경우 Eventually Contentency와 같은 성능을 보장하려면, 더 빨리 data write를 발생시켜야 하기 때문에, 내부적으로 더 높은 write unit이 필요하게 된다. 그래서, Eventually Consistency의 경우 Strong Consistency에 비해서 가격이 50% 정도 저렴하다.
Query
데이타베이스이기 때문에, 데이타에 대한 Query를 지원한다.
Primary Key를 가지고 get이 가능할 뿐더러, range key를 이용하여, subset을 query하는 range query가 가능하다.
쿼리 후 list(set) 형태의 데이타가 리턴되었을 경우, 한번에 리턴할 수 있는 데이타 set의 최대 크기는 1MB이다.
1MB가 넘을 경우에는 pagenation을 해야 하는데, 1MB 가 넘는 경우 LastEveluatedKey라는 값을 리턴하여, (일종의 DB cursor와 같은 역할) 다음번 read시 부터는 이 키 부터 리드할 수 있도록 pointing을 해준다
또는 명시적으로 Limit 라는 parameter를 이용하여, Query에서 리턴되는 수를 정할 수 있다. (SQL의 "top"과 같은 개념) 전체 쿼리 결과가 1000개라도 Limit 10 으로 하면, 소팅된 순서에서 상위 10개의 item 만 리턴한다.
다음으로는 "Count"라는 parameter가 있는데, 이 Count는 RDBMS의 select count(*)와 같은 개념이다. Query 결과로 리턴되는 총 Item의 수를 리턴한다.
주의할점은 Dynamo는 NoSQL이다. RDBMS와 다르다.
key 기반의 select와, range query는 지원하지만, group by, where, index등의 쿼리 기능은 없다. (데이타 모델 설계 자체를 RDBMS와 다르게 해야 한다.)
Scan
Scan 기능은 테이블의 모든 Item을 순차적으로 읽어오는 기능으로, Query와 마찬가지로, 한번 API call에 1MB까지만 읽어올 수 있고, LastEvaluatedKey 값을 이용해서 다음 데이타를 연속적으로 읽어올 수 있다. 처음부터 테이블을 Scan 하기 때문에, 당연히 많은 시간이 소요된다.
Dynamo는 RDBMS와는 다르게 Index 필드가 없다. (다른 NoSQL도 Index가 없는 경우가 많지만) 대신 range query나 sorting을 지원하기 위해서 range key라는 추가적인 키를 제공한다. Primary Key를 정의시 Unique한 Key 필드 하나만 정의하거나 (이를 Hash Key라고 한다.) 또는 이 range key를 추가로 지정하면, 쿼리 결과가 ascending 순서로 sorting이 되며, 쿼리 역시 이 range key를 기반으로 특정 범위의 데이타만 query 할 수 있다.
이 range key는 table 생성시에 hash key와 함께 정의한다.
성능
내부적으로 SSD 디스크를 이용하기 때문에, 높은 IO 성능을 보장할 수 있으며 read / write 성능을 보장하는 옵션을 가지고 있다.
Read/Write Unit이라는 옵션인데, 1KB item 1개를 1초동안 쓰거나 읽는 단위가 1 Unit이다. 2 Write Unit은 1K 데이타를 1초동안 2개 Write할 수 있는 성능 지표이다.
Units of Capacity required for reads = Number of item reads per second x item size (rounded up to the nearest KB)
Units of Capacity required for writes = Number of item writes per second x item size (rounded up to the nearest KB)
ReadUnit = [초당 읽는 item(row) 수] * [ item 크기 (kb로 반올림) ]
WriteUnit = [초당 쓰는 item(row) 수] * [ item 크기 (kb로 반올림) ]
1 ReadUnit은 초당 1KB짜리 1개의 Item을 읽을 수 있는 성능 단위이다.
예를 들어, 21.5 kb 짜리 item을 초당 100개를 읽는 성능이 필요하다면, Read Unit = 100 * 22 (반올림) = 2200 이 필요하다.
쓰기 성능도, 마찬가지 방식으로 WriteUnit이라는 단위로 지정한다.
각각 최대 10,000 Unit 까지 지원하며, 이 이상을 원할 경우, Amazon Support에 신청하면, 더 높은 Unit으로 올릴 수 있다. (최대 한계는 나와있지 않음)
Unit의 개념은 성능을 보장한다는 개념에서 긍정적이지만, 반대로 성능을 제약한다는 문제를 가지고 있다.
즉 정해진 Unit 보다 많은 read나 write가 발생할 경우, Dynamo는 이를 처리하지 않고 error 처리를 해버린다.
"ProvisionedThroughputExceededException" 그래서 Spike 형태의 request가 들어올 때는 문제가 된다.
프로그램 로직상에서 "ProvisionedThroughputExceededException" 에 대한 처리가 필요한데, 이 에러가 발생하였을 경우에는 프로그램적으로 retry를 하도록 하는 로직을 포함하는 것을 권장한다.
일관성 보장 옵션
Dynamo와 같은 NoSQL 계열의 데이타베이스는 데이타를 여러개의 노드에 나눠서 저장하고, 백업을 위해서 다른 노드로 복제하기 때문에, 복제가 완료되기 전에 클라이언트가 다른 노드에서 데이타를 읽으면 예전의 데이타를 읽을 수 있다. 이런 문제가 일관성 문제인데, 일반적인 NoSQL은 이러한 일관성을 보장하지 않는다. 복제할 때까지 시간이 걸린다는 것을 가정하고, (시간 자체는 짧으나) 그 시간동안은 일관성이 보장이 안되는데, 이러한 일관성 보장 정책을 Eventually Consistent Read라고 한다. 반대로, 데이타를 쓴 다음 모든 노드에서 데이타를 읽었을때, 같은 데이타를 바로 리턴하게 할 수 있는데, 이 경우에는 데이타가 써진 후에, 다른 노드 까지 replicated될때까지 기다려야 한다. 그래서 당연히 Read 응답시간이 Eventually Consistency Read보다 느리다. 이러한 일관성 정책을 Strongly Consistent Read라고 한다. Strong Consistency의 경우 Eventually Contentency와 같은 성능을 보장하려면, 더 빨리 data write를 발생시켜야 하기 때문에, 내부적으로 더 높은 write unit이 필요하게 된다. 그래서, Eventually Consistency의 경우 Strong Consistency에 비해서 가격이 50% 정도 저렴하다.
Query
데이타베이스이기 때문에, 데이타에 대한 Query를 지원한다.
Primary Key를 가지고 get이 가능할 뿐더러, range key를 이용하여, subset을 query하는 range query가 가능하다.
쿼리 후 list(set) 형태의 데이타가 리턴되었을 경우, 한번에 리턴할 수 있는 데이타 set의 최대 크기는 1MB이다.
1MB가 넘을 경우에는 pagenation을 해야 하는데, 1MB 가 넘는 경우 LastEveluatedKey라는 값을 리턴하여, (일종의 DB cursor와 같은 역할) 다음번 read시 부터는 이 키 부터 리드할 수 있도록 pointing을 해준다
또는 명시적으로 Limit 라는 parameter를 이용하여, Query에서 리턴되는 수를 정할 수 있다. (SQL의 "top"과 같은 개념) 전체 쿼리 결과가 1000개라도 Limit 10 으로 하면, 소팅된 순서에서 상위 10개의 item 만 리턴한다.
다음으로는 "Count"라는 parameter가 있는데, 이 Count는 RDBMS의 select count(*)와 같은 개념이다. Query 결과로 리턴되는 총 Item의 수를 리턴한다.
주의할점은 Dynamo는 NoSQL이다. RDBMS와 다르다.
key 기반의 select와, range query는 지원하지만, group by, where, index등의 쿼리 기능은 없다. (데이타 모델 설계 자체를 RDBMS와 다르게 해야 한다.)
Scan
Scan 기능은 테이블의 모든 Item을 순차적으로 읽어오는 기능으로, Query와 마찬가지로, 한번 API call에 1MB까지만 읽어올 수 있고, LastEvaluatedKey 값을 이용해서 다음 데이타를 연속적으로 읽어올 수 있다. 처음부터 테이블을 Scan 하기 때문에, 당연히 많은 시간이 소요된다.
'클라우드 컴퓨팅 & NoSQL > Amazon Web Service' 카테고리의 다른 글
Amazon의 설치 배포 자동화 솔루션 Opsworks (0) | 2013.02.26 |
---|---|
간단한 S3 Performance Test (3) | 2013.01.25 |
Amazon S3 서비스 소개 (0) | 2012.12.06 |
EMR 특징 (1) | 2012.12.06 |
Dynamo 특징 (0) | 2012.12.06 |