Professional Documents
Culture Documents
AWS Builders - AWS 300 - NoSQL
AWS Builders - AWS 300 - NoSQL
고지 사항(Disclaimer)
본 컨텐츠는 고객의 편의를 위해 AWS 서비스 설명을 위해 온라인 세미나용으로 별도로 제작, 제공된 것입니다. 만약 AWS
사이트와 컨텐츠 상에서 차이나 불일치가 있을 경우, AWS 사이트(aws.amazon.com)가 우선합니다. 또한 AWS 사이트
상에서 한글 번역문과 영어 원문에 차이나 불일치가 있을 경우(번역의 지체로 인한 경우 등 포함), 영어 원문이 우선합니다.
AWS는 본 컨텐츠에 포함되거나 컨텐츠를 통하여 고객에게 제공된 일체의 정보, 콘텐츠, 자료, 제품(소프트웨어 포함) 또는 서비스를 이용함으로 인하여 발생하는 여하한 종류의 손해에
대하여 어떠한 책임도 지지 아니하며, 이는 직접 손해, 간접 손해, 부수적 손해, 징벌적 손해 및 결과적 손해를 포함하되 이에 한정되지 아니합니다.
SQL ? NoSQL ?
SQL ? NoSQL ?
SQL은 현재까지도 많이 활용되는 Database의 종류입니다. 대부분의 초기
개발은 RDBMS에서 시작되는 경우가 많습니다. SQL과 NoSQL은 각각의
특징이 있으며, 최신 Application에서는 “혼용”하여 활용 하고 있습니다.
SQL vs NoSQL
주요 주제
컬럼
3 Design
https://en.wikipedia.org/wiki/Database_normalization#Satisfying_1NF
RDBMS의 이점 - 인덱스
자주 활용되는 필터 조건에 대하여, 사전에 인덱스를 생성해 놓으면, 자동
적으로 데이터가 변경됨에 따라, 인덱스도 갱신이 진행되고 이를 활용하여
빠른 검색이 보장됩니다.
주요 주제
으아아!
• Document 처리
대규모 데이터 처리 - 1
OLTP 형태의 데이터 처리에서는 보통 Write:Read 비율이, 1:9~2:8수준으로
발생합니다. 이럴 경우 일단 접근할 수 있는 전략은 기존의 RDBMS에
Read Replica를 추가하여, Read확장성을 이용하는 방법입니다.
Master Node
대규모 데이터 처리 - 2
극단적으로, Read가 많이 발생하는 경우, 아니면 동일한 값을 재활용하는
Cache전략을 적용할 수 있는 경우, In-memory Database를 추가로 앞에
위치시킬 수 있습니다.
Read가 생각보다 많이 들
어오네.
앞에 In-memory DB를 추
가해서, Cache를 구성해볼
까?
주요 주제
Master Node
대규모 데이터 처리 - 3
비즈니스가 확장될 경우, Master Node에 대한 Write를 초기에는 Scale Up
으로 대치하지만 얼마 지나지 않아, 그 한계점에 도달하게 됩니다.
MainDB가 Write하는 것만
도 벅차하네...
Scale Up을 해 주어야겠
다...
주요 주제
Scale Up한지 얼마나 됬다
고 벌써 CPU가...
Master Node
대규모 데이터 처리 - 4
하나의 물리적인 서버가 처리할 수 있는 용량에는 한계가 있음을 인정하고,
여러개의 물리적인 서버에 분산 저장할 수 있는 Database나 Framework을
도입하게 됩니다.
방법이 없네..
Shard를 이용한 Database
Cluster군을 만들어야 겠
다..
필요할 때마다 Shard를 늘
Shard Node #3
려야지.
주요 주제Shard Node #2
Shard Node #5
Shard Node #1
Shard Node #4 Shard Node #6
대규모 데이터 처리 - 5
분산 Database에서 Node의 증가는 바로 운영 비용 및 운영상의 어려움을
맞닥뜨리게 됩니다.
내가 원한건 단순한 분산
Database였을 뿐이야!!
운영이 너무 힘들다 살려
줘!!
주요 주제
대규모 데이터 처리 - 6
태생적으로 분산 처리를 고려하여 만든 Database이면서, 대규모 Cluster를
구성해도 안정적인 운영 환경을 제공하는 서비스를 채택하게됩니다.
그래!
바로 내가 원한건
안정적인 Scalable한 DB
였던 거야!
밑에서 도는 내용은 신경
쓰지 말자.
주요 주제
주요
Key Value 주제 Design
Database
Key Value Database
Redis/Memcached/DynamoDB로 분류되는, Key-Value Database는 기본적
으로 Key”만”을 이용하여, 처리하도록 구성됩니다. 이는 기본적으로,
RDBMS에서 지원되는 기능을 직접 “키”를 이용하여 대치하여야 합니다.
인덱스가 없네 ?
USER#MOB#010-1234-5678 USER#USER001
ElastiCache USER#MOB#010-5678-1234 USER#USER002
Index Key 설계 - 2
실제 상황에서는 다양한 Filter조건을 이용하여 Record 검색을 수행합니다.
이럴 경우, Index용 Key를 AND 조건의 경우 모두 Concatenate하여 대리
수행할 수 있습니다. 인덱스를 생성해서
조회속도를 업!
[RDBMS Format – TB_USER]
ITEM_ID (PK) NAME RES_ID MOB ADDR
ElastiCache
Index Key 설계 - 4
OR 조건 검색이 필요할 경우에는, OR 전체를 묶는 새로운 키를 생성할 수
도 있습니다.
[RDBMS Format – TB_USER]
ITEM_ID (PK) NAME RES_ID MOB ADDR
주요
[Key Value format] 주제
KEY VALUE
아 주소가 비슷한 동 { “name”:”HONGILDONG”, “res_id”:”170724-4123456”,
명이인이 있다니!!! USER#USER001
“mob”:”010-1234-5678”, “addr” : “Seoul, Korea” }
USER#HONGILDONG#010-1234-4578 [ USER#USER001 ]
주요 주제
사용자가 추가될 때마다, +1을
해주어야 겠다. [Key Value format]
KEY VALUE
USER#SEOUL#USER_COUNT 3
{ “name”:”HONGILDONG”, “res_id”:”170724-4123456”,
USER#USER001
“mob”:”010-1234-5678”, “addr” : “Seoul, Korea” }
{ “name” : “KIMCHEONSOO”, “res_id”: “160424-3654321”,
USER#USER002
“mob”:”010-5678-1234”, “addr” : “Busan, Korea” }
ElastiCache
Record & Column conversion
Value에서, 다양한 형태의 자료구조를 제공하는 Database도 있지만, 기본
적으로, String은 대부분의 Key Value Database에서 모두 제공합니다.
String Value의 경우, JSON Type같이 Column Name(Attribute)가 포함될
경우, Record / Column의 경계가 매우 모호해지며, 다양한 응용이 생깁니
다.
아 나는 Credential 정보를 접근
하게 하고 싶지 않아, “레코드"
주요 주제
를 분리해야 겠군!
[Key Value format]
KEY VALUE
{ “name”:”HONGILDONG”, “res_id”:”170724-4123456”,
USER#USER001
“mob”:”010-1234-5678”, “addr” : “Seoul, Korea” }
ElastiCache
단순한 구조에서 다양한 활용
Key Value 구조는 직관적이기 때문에, 다양한 형태로 “조합”을 할 수 있습
니다. 아까 보여드린 예시도 Key Value구조의 특성을 이용한 한 예시일 뿐
입니다.
Index Record 생성
Value concatenation을 주요
이용한주제Composite Index 생성
DynamoDB는 Column 주요
형태의 Value 제공
주제
ETC
Partitioning
Redis/DynamoDB 모두 Sharding(Clustering)기능을 제공합니다. Redis는
사용자가 요청할 경우 Node 추가 시, Slot을 조정하여 이를 해결하고,
DynamoDB는 WCU/RCU와 용량을 판단하여, 자동 조정하게 되어 있습니
다.
[REDIS] [DynamoDB]
주요 주제
DynamoDB 특성
주요 주제
일정한 응답시간
어떻게 대용량 데이터 세트에서 일정한 시간안에 쿼리를 수행할 수 있을까?
바로, Partitioning을 통한 용량 제어와, 저장 시점에 Sorting을 수행하여 쿼
리의 수행 속도를 보장합니다
REST Gateway
shard manager
hashing (Partitioning) 주요 주제
Hash(Partition Key) Sort Key
ABCDE
https://en.wikipedia.org/wiki/Binary_search_algorithm
Repartitioning - 1
DynamoDB는 내부적으로 Shard(partition) manager가 개별 파티션의 상태
를 모니터링하고 있습니다.
만약, 특정 파티션이 개별 파티션의 한개치인 10GB에 도달하면
Repartitioning작업을 수행합니다.
REST Gateway
shard manager
hashing (Partitioning) 주요 주제
Hash(Partition Key) Sort Key Hash(Partition Key) Sort Key
...
REST Gateway
shard manager
3000 RCU 주요 주제
Hash(Partition Key) Sort Key Hash(Partition Key) Sort Key
...
즉, 0.01$가 됩니다.
3. 만약, Global Table기능을 활용한다면, “모든 리전”에 동일한 Autoscaling 정책을 지정합니다.
주요 주제
4. 대형 이벤트를 준비하신다면, Scale-in 이벤트를 잠시 비활성화 할 수 있습니다.
주요 주제
https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/elasticache-use-cases.html#elasticache-use-cases-testimonials
Leader Boards
Redis에서는 SortedSet을 지원합니다. 즉, 값이 들어올경우, Sorting을 통
한 정렬순서를 Insert 시점에 확정을 해 줍니다. 이로 인하여, 해당 값을 가
지고 갈 때에도 O(logN)의 시간을 보장해 줄 수 있습니다. 이를 잘 활용하
는게 게임에서 순위표를 실시간으로 확정할 경우 자주 활용됩니다.
주요 주제
Real-Time Counting
Redis에서는 위에서 언급한 Hash Type을 제공합니다. 이를 응용하면, 실시
간으로, 상품에 대한 Like/Dislike를 계산하면서, “누가” Like/Dislike를 선택
했는지 실시간으로 저장/파악할 수 있습니다.
* PIPELINING
MULTI
INCR REC#PROD#0030192#LIKES
# 상품 LIKE에 +1
HSET REC#PROD#0030192 USER#0190248 1
# USER#0190248 이 LIKE 했음을 표시
EXEC
주요 주제
http://oldblog.antirez.com/post/take-advantage-of-redis-adding-it-to-your-stack.html
DynamoDB Advanced Design
주요 주제
논리적 테이블을 하나의 DDB테이블로
효율적인 JOIN을 하기 위해서는 하나의 DDB테이블로 구성하여야 한다.
SELECT A.ID, A.NAME, A.TEL, A.ADDR, B.ACC_ID, B.BAL FROM USER A JOIN ACCOUNT B ON (A.ID = B.USER_ID) WHERE A.ID = “USER001”
--------------------------------------------------------------------------------------------------------------------------------
USER001, HNK, 821010XX, Seoul..., 03-240-X, 1000000
[Coding] String id = resultset.getString(1); String name = resultset.getString(2); String telno = resultset.getString(3); ...; String accounted = resultset.getString(5); ...
주요한번에
DynamoDB에서 JOIN 개념은 두개의 레코드를 주제조회하는 것입니다.
ID(Part) SK(Sort) NAME TEL ADDR ACC_ID BAL
USER001 USER HNK 821010xx Seoul...
USER001 ACC 03-240-X 1,000,000
Query
{ “TableName” : “USERMASTER”, “ProjectionExpression” : “id, sortkey, name, tel, addr, acc_id, bal”, “KeyConditionExpression” : “id = :v1”, ... }
[Coding] ItemCollection<UserMaster> items = table.query(spec); Iterator<Item> iterator = items.iterator(); Item item = null;
while(iterator.hasNext()) { item = iterator.next(); if( item.get(“sk“).equals( “USER” ) classmap(targetBean, User.class, item ) else classmap(targetBean, Acc.class,item) }
Parent-Child Query
RDBMS에서 Parent-Child (Master-Detail)형태의 View를 구성할 경우, 보통 2번의
Query를 수행
Parent View Query 1 : Master Table Query
ID NAME TEL ADDR
Child View
ACC_ID BAL
Query 2 : Child Table Query
03-240-X 1,000,000
01-210-X 500,000
주요
DynamoDB에서는, 하나의 Query에서 주제
여러 관련된 테이블 Record를 가
지고 올 수 있습니다.
ID(Part) SK(Sort) NAME TEL ADDR ACC_ID BAL
USER001 USER HNK 821010xx Seoul...
USER001 ACC3 03-240-X 1,000,000
USER001 ACC1 01-210-X 500,000
Provisioning
예를 들어, “사용자 테이블“,“어카운트 테이블“을 나누어서 설계를 하였다면 하면,
ID NAME TEL ADDR ACC_ID BAL USER_ID
평탄화/상보관계
여러 레코드를 하나의 레코드로
예를 들어, “사용자 테이블“, “초기 접속 서버“를 테이블로 나누어서 설계를 하였
다면 하면, 아래와 같이 구성할 수 있습니다.
ID NAME TEL ADDR SRV_ID USER_ID REGION
Column name Biz Domain Physical Type Comment Column name Biz Domain Physical Type Comment
주요 주제
HOME_TEL_NO TELNO_TYPE VARCHAR(11) Excluded Dash MODIFIED_DT DT_TYPE TIMESTAMP TZ
TABLE TB_SERVICE_WORKFORCE
Column name Biz Domain Physical Type Comment PK/SK INDEX_NAME
ID ID_TYPE, SVCID_TYPE String Employee_id , Service_id overloaded PK
Class UserInformation {
private String name;
private String password;
private bool isValid;
private accountId;
private List<Logs> histLogs;
private List<GameChar> characters; 여러건의 레코드를 Collection Attribute로 처리
private int totalGold;
}
[위 레코드에 대한 처리 방식] 주요 주제
private void storeToDDB(UserInformation userInfo) { 하나의 Instance를
List<dynamodb.Item> splittedItems = DynamoDBMapper.convertToItem(userInfo)
splittedItems.foreach(x => table.putItem(x));
DynamoDB Item으로 Split하
} 여 한꺼번에 저장
private UserInformation restoreFromDDB(String userid) {
List<dynamodb.Item> splittedItems = new ArrayList<dynamodb.Item>();
dynamodb.Item currentItem = table.getItem(“UserId”, userid); splittedItems.add(currentItem); 여러개의 DynamoDB Item을
while((String nextPos = currentItem.getString(“NextPos”)) != null) {
currentItem = table.getItem(“UserId”, nextPos); splittedItems.add(currentItem); 추적하여, 뭉친다음 하나의
}
return DynamoDBMapper.convertToUserItem(splittedItems);
Instance로 제공
}
않좋은 예시 – DDB Table
게임의 로그인 부터 사용자의 모든 데이터를 하나의 Row에 대응
주요 주제 16:1…”,…]
[예시] 주요 주제
읽기가 잦은 데이터 – ID/ PWD
쓰기/갱신이 잦은 데이터 – Character 속성, ITEM
유효기간이 있는 데이터 – LOG성 데이터들
기타 등등
데이터 컬럼 그룹핑
ID(Part) VALID NAME PWD LOGHIST ITEMS NEXTROW
USER001 YES HANK 202cb… [“2019-12-31 14:..”,
“2020-01-03 16:1…”,…]
[“aaa”, …] USER001-p13
ID PWD NAME
USER001 YES
주요 HANK
주제
자주 내용이 변경되면서, 조회가 빈번하게 발생하는 경우.
ID DEX GOLD ITEMS
USER001 YES HANK [{itemcd : “guntlet”, amount : 2...}]
▶ 질문에 대한 답변 드립니다.
감사합니다.