Pastebin

User가 일반 text를 저장할 수 있는 웹 서비스를 설계해보자.

Pastebin 이란 무엇인가

Pastebin 서비스는 User가 인터넷을 통해 일반 텍스트나 이미지를 저장하고, 업로드된 데이터에 엑세스 할 수 있는 고유한 URL을 생성할 수 있도록 한다. User들은 다른 User들이 볼 수 있도록 URL을 넘겨주기만 하면 되기때문에 네트워크를 통해 데이터를 빠르게 공유하는데 사용된다.

Go Pastebin

시스템 요구사항 및 목표

다음과 같은 요구사항을 충족해야 한다. :

기능 요구 사항:

  1. User들은 데이터를 업로드하거나 붙여넣기를 할 수 있어야 하며 데이터에 엑세스 할 수 있는 고유한 URL을 얻어야 한다.
  2. User들은 텍스트만 업로드 할 수 있다.
  3. 데이터와 링크는 특정 시간대가 지나면 자동으로 만료된다. User들은 만료 시간도 지정할 수 있어야 한다.
  4. User들은 선택적으로 붙여넣기용 사용자 지정 alias를 선택할 수 있어야 한다.

비기능적 요구 사항:

  1. 시스템은 매우 신뢰할 수 있어야 하며, 업로드 된 데이터는 모두 손실 되어서는 안 된다.
  2. 시스템은 가용성이 높아야 한다. 우리 서비스가 중단되면 User들이 그들의 Pastes에 접근할 수 없기 때문에 이 것은 꼭 필요하다.
  3. User들은 minimum latency로 real-time으로 Pastes에 access할 수 있어야 한다.
  4. Pastes 링크들은 추측할 수 없어야 한다.(예측할 수 없다.)

확장성 요구 사항

  1. 분석(예를들어 얼마나 많이 Pastes에 액세스 하였는가?)
  2. 우리의 서비스는 다른 서비스들이 REST API를 통해 접근할 수 있어야 한다.

설계시 몇 가지 고려 사항

Pastebin은 URL 단축서비스와 몇가지 요구사항이 같지만, 우리가 유념해야 될 추가 설계 고려 사항들이 있다.

User가 한 번에 붙여넣기 할 수 있는 텍스트 양의 제한은 어느정도일까? 우리는 서비스 남용을 막기 위해 user들이 10MB이상의 Paste를 갖지 못하도록 제한 할 수 있다.

사용자 지정 URL에 크기 제한을 적용해야 하는가? 우리 서비스는 사용자 지정 URL을 지원하므로 User가 원하는 URL을 선택할 수 있지만 사용자 지정 URL을 꼭 제공해야 하는 것은 아니다. 단, 사용자 지정 URL에 대한 크기를 제한을 두는 것이 합리적이며(and often desirable) 일관된 URL 데이터 베이스를 갖출 수 있도록 한다.

시스템 APIs

우리는 SOAP 또는 REST API를 통해 서비스의 기능을 노출시킬 수 있다. 다음은 Pastes를 create/retrieve/delete하기위한 API 정의다.

addPaste(apiDevKey,pasteData,customUrl=None,userName=None,pasteName=None,expireDate=None)

Parameters
apiDevKey(String): 등록된 계정의 API 개발자 키, 이것은 무엇보다도 할당된 할당량에 기초하여 사용자를 조절하는것에 사용될 것이다.
pasteData(String):paste 텍스트 데이터
customUrl(String):선택적 사용자 지정 URL
userName(String):URL을 생성하는 데 사용할 선택적 사용자 이름
pasteName(String):Paste 이름(선택사항)
expireDate(String):Paste 만료 날짜(선택사항)

Returns : (String)
Insertion에 성공하면 Paste를 할 수 있는 URL이 반환되고 그렇지 않으면 오류코드가 반환된다.

마찬가지로 Paste API를 검색할 수 있다.

getPaste(apiDevKey,apiPasteKey)

여기에서 apiPasteKey는 검색할 Pastes 키를 나타내는 문자열이다. 이 API는 Paste 텍스트 데이터를 반환한다.

deletePaste(apiDevKey,apiPasteKey)

삭제를 성공하게 되면 ‘true’를 반환하고 그렇지 않으면 ‘false’를 반환한다.

Database 설계

저장 중인 데이터의 특성에 대한 몇 가지 주시

  1. 우리는 수십억 개의 기록을 보관해야 한다.
  2. 우리가 저장하고 있는 각 metadata object는 크기가 작을 것이다(1KB 미만)
  3. 우리가 저장하고 있는 각 Paste object는 중간 크기 일 수 있다.(few MB일 수 있다.)
  4. 어떤 User가 Pastes를 만들었는지 저장하려는 경우를 제외하고, 레코드 사이에는 relationships가 없다.
  5. 우리 서비스는 read가 많다.

데이터베이스 스키마
우리는 두 개의 테이블이 필요할 것이다. 하나는 Paste에 대한 정보를 저장하기 위한 것이고, 다른 하나는 사용자 데이터를 위한것이다.

URL Shortened Service 참고

High Level design

높은 수준에서, 우리는 모든 읽기 및 쓰기 요청을 처리할 Application layer가 필요하다. Application Layer는 데이터를 저장하고, 검색하기 위해 storage계층과 대화를 할 것이다. 우리는 우리의 storage 계층을 각 paste, user 등과 같은 metadata를 저장하는 하나의 database로 분리 할 수 있고, 다른 하나는 어떤 Object Storage(Amazon s3와 같은)에 Paste contents를 저장할 수 있다. 이런 데이터 분할은 우리가 그것들을 개별적으로 확장할 수 있게 해줄것 이다.

highlevel

Component Design

Application Layer

우리의 Application Layer는 들어오고 나가는 모든 요청을 처리할 것이다. Application server는 요청을 처리하기 위해 backend data store compponents와 대화를 할 것이다.

어떻게 쓰기 request를 처리할 것인가? 쓰기 request를 받으면, 우리 application server는 6자의 임의 문자열을 생성하게 되는데, 이 문자열은 Paste의 Key 역할을 한다. (사용자가 사용자 지정 키를 제공하지 않는 경우). 그런 다음 Application server는 Paste내용과 생성된 키를 database에 저장한다. 삽입에 성공한 후, servser는 user에게 키를 반환할 수 있다. 여기서 발생할 수 있는 한 가지 문제는 중복된 키 때문에 삽입에 실패한다는 것이다. 랜덤 키를 생성하기 때문에 새로 생성된 키가 기존 키와 일치할 가능성이 있다. 그럴 경우 새키를 재생성하고 다시 시도해야한다. 우리는 중복된 키 때문에 실패가 보이지 않을때까지 계속 재시도해야한다. 만약 그들이 제공한 사용자 지정 키가 우리의 데이터베이스에 이미 존재한다면 우리는 사용자에게 오류를 반환해야 한다.

위와 같은 문제의 해결책은 사전에 임의로 6개의 문자열을 생성하여 데이터베이스에 저장하는 독립형 KGS(Key Generation Service)를 실행하는 것이다.(Key-DB) 우리가 새로운 paste를 저장하고 싶을 때마다, 우리는 이미 생성된 키 중 하나를 가지고 그것을 사용할 것이다. 이러한 접근방식은 우리가 중복이나 충돌에 대해 걱정하지 않기 때문에 꽤 간단하고 빠르게 만들어 줄 것이다. KGS는 Key-DB에 삽입된 모든 키가 고유한지 확인할 것이다. KGS는 응용 프로그램 서버에 몇 가지 키를 주는 즉시 이를 사용한 테이블로 옮길 수 있다.
KGS는 항상 일부 키를 메모리에 보관하여 서버가 필요할 때마다 신속하게 제공할 수 있다. KGS는 메모리에 몇 개의 키를 로드하는 즉시, 사용된 키를 옮길 수 있다. 이렇게 하면 우리는 각 서버가 고유한 키를 얻을 수 있는지 확인할 수 있다. 만약 KGS가 메모리에 로드된 모든 키를 사용하기 전에 죽는다면, 우리는 그 키를 낭비하게 될 것이다. 우리는 이 Key들을 엄청나게 많이 가지고 있다는 것을 고려해보는 결과 이것을 우리는 무시할 수 있을 것이다.

KGS는 하나의 실패점이 아닌가? YES,그렇다. 이를 해결하기위해 우리는 KGS의 대기 복제본을 가질 수 있고, 주 서버가 사망할 때마다 key를 생성하고 제공할 수 있다.

각 App 서버가 Key-DB에서 이부 키를 Cache할 수 있는가? Yes, 이것은 확실히 속도를 낼 수 있다. 이 경우, 모든 키를 소비하기 전에 Application server가 종료되면, 우리는 결국 그 키를 잃게 될 것이다. 이것은 우리가 필요로 하는 것보다 훨씬 많은 68억개의 고유한 6자를 가지고 있기 때문에 받아들일 수 있다

어떻게 Paste read 요청을 처리할 수 있을까? paste read 요청을 받으면 application service layer가 datastore에 연결된다. datastore는 key를 검색하여 찾게되면 Paste의 내용을 Return 한다. 그렇지 않으면 오류코드가 반환된다.

Datastore Layer

Datasotre layer는 두개로 나눌 수 있다

Metadata database : MySQL과 같은 관계형 Database나 Dynamo나 Cassandra와 같은 분산형 Key Value 스토어를 사용할 수 있다.

Object Storage : 우리는 아마존의 S3와 같은ㅇ 객체 저장소에 우리의 컨텐츠를 저장할 수 있다. Contents Storage에 전체 용량을 사용하고 싶을 때 마다 서버를 추가하여 용량을 쉽게 늘릴 수 있다.

kgs