티스토리 뷰

Relational DB

ACID

ACID란 원자성, 일관성, 고립성, 지속성의 약자로 DB 트랜잭션이 안전하게 수행됨을 보장한다.

트랜잭션(Transaction) : DB의 상태를 변환시키는 하나의 논리적 기능을 수행하기 위한 작업의 단위 또는 일련의 연산

1. Actomicity (원자성)

  • 각 트랜잭션이 완전히 성공하거나 완전히 실패함을 보장한다. 이는 DB의 부분 업데이트를 방지한다.
  • 입금 프로세스를 예로들자면 A가 B에게 입금을 하는데 A에서 돈이 빠져나오는 action, B에 돈을 입금하는 action이 모두 이루어 져야 원자성을 지킬 수 있으며, A에서 돈을 빼고 B에 입금이 되지 않는다면 그대로 돈이 유실되어버린다.

2. Consistency (일관성)

  • 트랜잭션의 수행 전/후의 DB는 항상 일관된 상태여야 한다.
  • mainDB A와 replica인 B가 있다고 할 때, A라는 DB에 데이터가 쌓였다면, B에도 동일한 데이터가 쌓여야 한다.

3. Isolation (고립성)

  • 트랜잭션 수행 시 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 보장한다.
  • A, B, C, D 트랜젝션이 있는데 각 트렌젝션의 작업은 서로 영향을 주면 안된다.
  • 은행 관리자는 이체 작업이 진행되는 도중에 Query를 실행하더라도 이체 작업을 볼 수 없고, 실행시킨 Query는 이체 작업이 종료 된 이후에 실행된다.

4. Durability (지속성)

  • 성공적으로 수행된 트랜잭션은 영원히 반영되어야 한다.
  • RAM 메모리마냥 휘발성이 되면 안된다.

 

NoSQL

Document DB

  • 테이블의 스키마가 유동적이며, 각 레코드 마다 다른 스키마를 가질 수 있다.
  • JSON과 같은 Document를 이용하여 레코드를 저장할 수 있다. (하나의 Giant Object)
  • Key value pair 형태로 저장할 수 있다.
  • ex) Mongo DB
{
  'name': 'user1',
  'address': {
    'localCode': '02',
    'country': 'Kr'
  }
}
{
  'name': 'user2',
  'age': 1,
  'address': {
    'localCode': '032',
    'country': 'Kr'
  }
}
id name age
1 user1 null
2 user2 1

위와 같이 컬럼에 해당하는 데이터가 없으면 저장이 되지 않는 SQL과 다르게 1번의 age가 없어도 저장이 된다.

  • 장점
    • 값이 없더라도 무조건 공간이 필요하던 RDB와는 달리, 저장하지 않을 수 있으므로 공간을 덜차지한다.
    • 여러개의 테이블을 하나의 Document에 모아둘 수 있으므로, 조회 시 한 번의 조회로 필요한 데이터를 획득할 수 있다. (join 대체) 그래서 데이터 접근 속도가 빠르다.

Blob Storage DB

  • 비디오, 이미지, 대량의 text 바이너리 데이터 형식을 Blob 데이터 타입이라고 한다.
  • ex) S3, GCS(Google Cloud Storage), Azur Blob Storage

 

Time series DB (시계열 DB)

  • 하나 이상의 시간과 하나 이상의 value pair를 통해 시계열(일정 산격으로 배치된 데이터의 수열)을 저장하고 서비스하는데 최정화 된 소프트웨어 시스템이다.
  • log 데이터를 쌓을 때 많이 사용한다.
  • purchase order, employee activity등 대량의 데이터를 저장하는 Amazon과 같은 대형 기업에서 사용할 수 있다.
  • ex) influxDB, prometheusDB

 

GDB (Graph DB)

  • 데이터를 그래프(node, edge)로 저장하고 표현하는 DB이다. 
  • GDB는 edge를 통해 데이터에 해당하는 node간 관계를 직접 정할 수 있으며, 데이터의 관계를 그래프를 통해 직관적으로 시각화 할 수 있다.
  • 데이터 간 관계를 표현할 필요가 있을경우 사용할 수 있다. (사람간 관계를 표현할 SNS 서비스 등)
  • 한 User와 팔로우를 맺은 User List를 조회한다고 할 때 DB에 저장된 모든 회원을 순회하여 검색해야 되므로 어마어마하게 느리다.
  • 이러한 불합리적인 구조는 Graph DB를 사용하여 개선할 수 있다.
  • 한 User에 대한 관계도는 edge로 연결되므로 관계없는 User는 순회하지 않는다. (관련 없는 Node는 고려하지 않음)
  • ex) netflix, google, naver 등에서 사용한다.

naver d2 : https://d2.naver.com/helloworld/8446520

neo4j 예제

Cypher Query를 사용한 Graph Query 서비스를 지원한다.

create(samsung:Company {name: 'Samsung'})
create(SK:Comapny {name: 'SK'})
create(LG:Company {name: 'LG'})

create(employer:employee {name: 'employer'})
create(employee1:employee {name: 'employee1'})
create(employee2:employee {name: 'employee2'})
create(employee3:employee {name: 'employee3'})
create(employee4:employee {name: 'employee4'})

create(employer)-[:WORKFOR {role: 'employer'}] -> (samsung)
create(employee1)-[:WORKFOR {role: 'employer'}] -> (samsung)
create(employee2)-[:WORKFOR {role: 'employer'}] -> (samsung)

create(employee3)-[:STUDYAT] ->(SK)
create(employee4)-[:STUDYAT] ->(SK)

create(employee1)-[:STUDYAT] ->(LG)
create(employee2)-[:STUDYAT] ->(LG)
create(employee3)-[:STUDYAT] ->(LG)
create(employee4)-[:STUDYAT] ->(LG)

node와 edge로 이루어진 DB

 

SpatialDB

  • 공간 데이터를 다루기 위해 특수한 목적으로 사용되는 DB
  • 좌표로 표현할 수 있는 공간 객체들을 데이터화 해서 보다 쉽게 저장
  • 저장한 공간 데이터에 대해 다양하고 손쉬운 연산을 수행
  • ex) QuadTree DB

 

DB 전략

Replication

  • 목적
    • single point of failure
    • read/write 노드를 분리하여 성능 분산을 처한다.
  • backup
    • main db에 장애가 생기더라도 copy db에서 정상적인 서비스를 빠르게 구성하도록 한다.
  • 주의할 점
    • Replication을 할때 데이터 일관성(consistency)가 매우 중요하다.
    • 비동기적으로 데이터를 업데이트해야될 경우가 있다.
    • main db의 내용을 replica(Slave DB)로 replication하는 과정에는 동기/비동기 방식이 있고, 비동기 방식으로 업데이트 할 경우 데이터 일관성이 깨질 수 있다.
    • 블로그 서비스와 같이 변경 사항이 바로 업데이트 되지 않아도 괜찮을 경우 비동기 방식을 사용할 수 있다.

Sharding

  • 단일 논리적 데이터셋을 다수 DB에 나누어 저장하는 방법이다.
  • 데이터를 분산 저장함으로써, 트래픽을 분산시킨다.
  • 방식
    • Vertical Sharding
    • Horizontal Sharding
  • 대부분 Horizontal Sharding 방식을 사용한다.
    • first name의 사전 순서대로 자를 때, 문자열을 A-K, L-S, T-Z로 각각 나눈다.
    • request throughput을 줄이기 위해 나누었지만, A-K보다 T-Z쪽의 데이터가 훨씬 적을 경우 현명한 sharing을 했다고 볼 수 없다. 
    • 요청을 최대한 고르게 나누기 위해 Hashing알고리즘을 사용할 수 있다.

Hashing 알고리즘을 이용하여 Reverse Proxy(로드밸런서) 구현 후 실행

  1. user 데이터를 userDB에 저장할 때, name 문자열의 각 문자를 ASCII 값으로 바꾼 후, 모두 더하고, 서버수 (SHARD_COUNT)로 나눈 나머지 값을 shardIdx로 둔다.
  2. 각 서버에 저장되어 있는 list(SHARD_ADDRESSES)에서 shardIdx를 키값으로 서버를 선택한다.
  3. 해당 서버에 값을 저장한다.
  4. 단순하게 나누었을때 보다 고르게 저장이 된다.

'시스템 디자인' 카테고리의 다른 글

시스템 디자인 7주차  (0) 2021.08.30
시스템 디자인 6주차  (0) 2021.08.26
시스템 디자인 4주차  (0) 2021.07.31
시스템 디자인 3주차  (0) 2021.07.21
시스템 디자인 2주차  (0) 2021.07.18
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함