Cloud/AWS

[AWS] Amazon DynamoDB로 유연한 NoSQL 개발

loia 2021. 10. 17. 23:56

#Amazon #아마존 #DynamoDB #NoSQL #Amazon DynamoDB

 

 

DynamoDB

DynamoDB는 AWS의 완전 관리형 DB중 하나로 분산형 NoSQL Database 솔루션입니다.

  • Table : 데이터가 테이블에 저장된다.
  • 파티션(필수) : SSD로 백업되는 테이블용 스토리지 할당, 테이블의 항목을 파티션키 값이 따라 여러 파티션으로 나눈다.
    • 파티션 기본 키 : 단일 속성으로 정렬되지 않은 인덱스를 생성한다. 테이블의 항목을 고유하게 식별됨
    • 파티션 정렬 기본 키 : 정렬되지 않은 인덱스를 정렬 키 속성을 기반으로 정렬된 인덱스를 생성함. 테이블 항목은 파티션 키 값과 정렬 키 값의 조합으로 고유하게 식별된다.
  • 정렬키 : 파티션키 값이 동일한 항목을 서로 물리적으로 가까이 저장하고 정렬하도록 정의함.
  • 로컬 보조 인덱스
    • 테이블의 파티션 기본 키를 동일하게 사용하고 정릴 키를 다른 항목으로 사용하여 인덱스를 생성
    • 테이블이 생성될 때만 생성이 가능하고 삭제가 불가
    • 테이블 용량을 기존 테이블과 병행하여 사용함
  • 글로벌 보조 인덱스
    • 테이블의 파티션 기본 및 정렬 키와 다른 항목을 파티션 키로 생성할 수 있다.
    • 생성, 추가, 삭제가 가능하고 테이블과 별도의 용량을 선정해야 합니다.
  • DynamoDB Stream
    • 테이블의 변경사항을 순서대로 기억하여 글로벌 테이블에 복제한다.

EC2, S3, DynamoDB를 활용한 아키텍트

 

테이블 및 글로벌 보조 인덱스 생성

테이블의 속성을 정의하고 파티션 키를 정의한다.

// Create attribute definitions for the primary key attributes of the table and indexes
ArrayList<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>();
attributeDefinitions.add(new AttributeDefinition().withAttributeName("CustomerId").withAttributeType("S"));
attributeDefinitions.add(new AttributeDefinition().withAttributeName("City").withAttributeType("S"));
attributeDefinitions.add(new AttributeDefinition().withAttributeName("Date").withAttributeType("S"));

// Create key schema element for the table's primary key attribute
KeySchemaElement tableKeySchemaElem = new KeySchemaElement().withAttributeName("CustomerId")
		.withKeyType(KeyType.HASH);

테이블의 RCU(Read Capacity Unit), WCU(Write Capacity Unit) 프로비저닝을 정의한다.

// Create object to specify table's provisioned throughput
ProvisionedThroughput tableProvisionedThroughput = new ProvisionedThroughput(5L, 10L);

글로벌 보조 인덱스를 정의한다.

// Create global secondary index object
GlobalSecondaryIndex gsi = new GlobalSecondaryIndex().withIndexName(CITY_DATE_INDEX_NAME)
		.withKeySchema(new KeySchemaElement("City", KeyType.HASH), new KeySchemaElement("Date", KeyType.RANGE))
		.withProvisionedThroughput(new ProvisionedThroughput(5L, 5L))
		.withProjection(new Projection().withProjectionType(ProjectionType.ALL));

AWS DynamoDB 인스턴스를 생성하고 정의된 테이블, 인덱스, 글로벌 보조 인덱스를 생성한다.

// Instantiate DynamoDB client and object
AmazonDynamoDB dynamoDBClient = AmazonDynamoDBClientBuilder.standard().build();

// Create an instance of DynamoDB class
DynamoDB dynamoDB = new DynamoDB(dynamoDBClient);

// Define a request to create a table
CreateTableRequest request = new CreateTableRequest().withTableName(tableName).withKeySchema(tableKeySchemaElem)
		.withAttributeDefinitions(attributeDefinitions).withProvisionedThroughput(tableProvisionedThroughput)
		.withGlobalSecondaryIndexes(gsi);
        
// Wait for the table to become active
table.waitForActive();

AWS Management Console에 접속하여 생성된 테이블을 확인한다.

 

 

테이블에 데이터 업로드

DynamoDB 인스턴스를 생성하고 테이블 정보를 가져온다.

Reservation.csv파일을 읽어 예약정보를 Item에 담고 putItem() 메서드를 호출하여 데이터를 입력한다.

// Instantiate DynamoDB client and object
AmazonDynamoDB dynamoDBClient = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(dynamoDBClient);

// Retrieve the Table object for the reservations table
Table table = dynamoDB.getTable(RESERVATIONS_TABLE_NAME);

br = new BufferedReader(new InputStreamReader(new FileInputStream("Reservation.csv")));
while ((line = br.readLine()) != null) {
	// Split line into values using comma as the separator
	String[] reservationsDataAttrValues = line.split(",");

	// Create Item object
	Item item = new Item().withPrimaryKey("CustomerId", reservationsDataAttrValues[0])
    	.withString("City", reservationsDataAttrValues[1])
        .withString("Date", reservationsDataAttrValues[2]);

	// Add item to table
	table.putItem(item);
	}
}

AWS Management Console에 접속하여 업로드된 데이터를 확인한다.

 

테이블에 쿼리 실행하여 데이터 조회

DynamoDB 테이블 정보(getTable)를 가져온 다음 글로벌 보조 인덱스(getIndex) 정보를 가져온다.

메서드를 호출(query)하여 정렬키 값의 정보를 반환한다.

// Instantiate DynamoDB client and object
dynamoDBClient = AmazonDynamoDBClientBuilder.standard().build();
dynamoDB = new DynamoDB(dynamoDBClient);

// Get the object corresponding to the reservations table
Table reservationsTable = dynamoDB.getTable(reservationsTableName);

// Retrieve global secondary index
Index index = reservationsTable.getIndex(cityDateGlobalSecondaryIndexName);

// Invoke the query
ItemCollection<QueryOutcome> items = index.query("City", inputCity);

도시정보가 Reno인 178건의 예약정보가 조회된다.

 

테이블에 쿼리 실행하여 데이터를 업데이트

DynamoDB 테이블 정보를 가져온 다음 UpdateItemSpec 객체의 인스턴스를 생성한다.

UpdateItemSpec 객체는 파티션키 속성 이름 및 값, 새로 추가되는 속성 이름 및 값, ReturnValue.ALL_NEW를 지정한다.

자세한 사항은 UpdateItem 함수를 참고하자.

// Instantiate DynamoDB client and object
dynamoDBClient = AmazonDynamoDBClientBuilder.standard().build();
dynamoDB = new DynamoDB(dynamoDBClient);

// Get the table object for the table to be updated
Table table = dynamoDB.getTable(reservationsTableName);

// Create an instance of the UpdateItemSpec class to add an attribute called
UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey("CustomerId", customerId)
		.withUpdateExpression("set #purl = :val1").withNameMap(new NameMap().with("#purl", "CustomerName"))
		.withValueMap(new ValueMap().withString(":val1", "joon")).withReturnValues(ReturnValue.ALL_NEW);

 

 

마무리

Amazon DynamoDB를 활용한 개발 방법에 대해 확인해 보았습니다.

DynamoDB는 AWS 비관계형 DB로 완전 관리형 서비스입니다.

관계형 DB로는 Amazon Aurora, SQL Server, MariaDB, Oracle, PostgreSQL, mySQL등 다양한 DB 엔진이 있다.