mockResolvedValue

  • 값을 자동으로 Promise.resolve()로 감쌉니다
  • 내부적으로 Promise.resolve(mockResult)로 처리

 

mockReturnValue

  • 값을 그대로 반환
  • 호출자가 Promise를 기대할 경우 직접 Promise.resolve()로 감싸야 한다.

목차

 

컨테이너가 IT 세상을 점령한 이유

 

깃 허브에 있는 소스코드를 다운받아서 소스코드에 사용되는 환경에 맞추기 위해서 버전에 맞는 도구를 설치해야한다.

 

만약 이것이 큰 프로젝트라면 새로운 개발팀과 운영팀이 인계 받을 때 소스코드를 빌드하고 실행하기위해서 여러가지 도구를 버전에 맞게 설치해야 한다. 

 

하지만, 컨테이너를 이용하면 소스코드를 내려받고 나서 명령 한 줄로 배포 및 실행이 가능하다.

 

레거시 애플리케이션 현대화 하기

 

컨테이너를 활용하면 거의 모든 애플리케이션을 클라우드에서 실행할 수 있다.

그러나, 기존 애플리케이션의 구조를 낡은 모놀리식(monolithic) 설계로 방치한다면 도커 혹은 클라우드 플랫폼의 진가가 발휘되기 어렵다.

 

이유는 기민성에 제약이 따르기 때문이다. 모놀리식에서 새 기능을 추가하여 출시하려면 기존의 기능이 망가지지 않았늦니 확인하는 회구 테스트에만 적어도 2주가 걸릴 것이다.

 

도커로 이주하는 과정을 애플리케이션의 낡은 설계를 탈바꿈하는 첫걸음이다. 애플리케이션을 전면적으로 재구현하지 않고도 새로운 패턴을 도입할 수 있다.

 

이 그림은 통짜 애플리케이션을 분할해 기능별로 별도의 컨테이너에 배치하여 여러 개의 컨테이너로 분할된 분산 애플리케이션을 만드는 과정을 나타낸것이다.

그림 1-3 모놀리식 설계를 가진 통짜 애플리케이션을 재구현 없이 분산 애플리케이션으로 재편하는 과정. 각 컴포넌트는 도커 컨테이너에서 실행되며, 라우팅 컴포넌트가 요청 처리를 기존 통짜 애플리케이션에 맡길지 아니면 새로운 마이크로서비스 설계를 따르는 컴포넌트에 맡길지 결정한다.

 

이렇게 설계를 하면 변경내용에 해당되는 컨테이너만이용하여 빠르게 테스트할 수 있다.

 

클라우드 환경에 적합한 새로운 애플리케이션 개발하기

 

도커는 기존 애플리케이션을 클라우드로 이주하는데 유용하다.

 

통짜 애플리케이션이라면 도커를 통해 컴포넌트를 분할하고 새로운 설계를 적용해 클라우드나 데이터센터 어디든 원하는 곳에서 애플리케이션을 운영할 수 있다.

 

클라우드 환경을 고려한 완전히 새로운 애플리케이션 개발이라면 도커를 통해 더 빠른 개발이 가능하다.

 

아래 그림은 전형적인 마이크로 서비스 아키텍처의 애플리 케이션을 나타낸 것이다.

그림 1- 4 클라우드 애플리케이션은 각 컴포넌트가 컨테이너에서 동작하는 마이크로서비스 아키텍처로 설계된다.



  • 각 컴포넌트는 자신만의 데이터를 가지며 API를 통해서 이 데이터를 외부에 제공한다.
  • 프런트 앤드는 이 API를 이용하는 웹 애플리케이션 형태
  • 도커는 여러가지 프로그래밍 언어로 구현하거나 서드 파티 소프웨어를 도입하여 애플리케이션을 구현하는데 유용하다.

기술 혁신: 서버리스와 그 너머

 

현대 IT 기술을 주도하는 요소 중 하는 일관성이다.

 

특히, 개발 팀은 모든 프로젝트에서 같은 도구, 같은 프로세스, 동일한 런타임을 사용하기를 원한다.

 

도커를 이용하면 어떠한 형태의 애플리케이션이라도 모든 제품의 빌드, 배포, 운영을 같은 도구와 같은 방법으로 수행할 수 있다.

즉, 아키텍쳐나 기술 기반과 무관하게 이들 애플리케이션의 빌드, 배포, 관리를 일원화 할수 있다.

 

*서버리스 기술은 곧 컨테이너 기술이다. 서버리스 기술의 목표는 모든 일이 플랫폼이 처리하도록 하는 것이다.

 

데브옵스 도입하기

 

데브옵스(DevOps)는  개발과 운영을 합친 이름으로, 애플리케이션의 전체 생애주기를 담당하는 전담 팀을 둔다.

 

운영자와 개발자는 다른 도구를 다루는데 이 사람들끼리 하나의 팀을 이룰수 있도록 도와주는 것이 도커이다.

Dockerfile 과 도커 컴포드 스크립트를 사용하면 같은 기술과 도구로 팀을 통일할 수 있다.

 

CALMS 라는 데브옵스를 위한 프레임워크가 있다.

  • cluture (문화)
  • automation (자동)
  • lean (린)
  • metric(측정)
  • sharing(공유)

의 머리 글자를 딴 것이다. 도커는 이들 개념 모두와 밀접한 관련이 있다.

 

자동화는 컨테이너 환경의 핵심,

분산 애플리케이션은 린 원칙에 따라 만들어진다.

배포 프로세스와 운영 로그로부터 얻은 측정치를 쉽게 사용할 수 있다.

도커 허브는 이미 있는 것을 공유의 장이다.

 

 

 

목차

toBe

방식 : 엄격한 동일성 검사(strict equality)

  • Object.is를 사용하여 검사
    • +0-0을 구분
    • NaN === NaN 은 false 지만 Object.is(NaN, NaN) 은 true

용도

  • 원시 값(primitive value) 비교 - 숫자, 문자열, null, undefined 등
  • 동일한 객체 참조 확인 - 객체나 배열이 같은 메모리 주소를 가리키는지 확인
  • 배열의 요소들이 순서와 내용까지 동일한지 확인

특징 : 값이 같더라도 서로 다른 객체나 배열인 경우 실패

 

예시

 expect(10).toBe(10); // 통과
 expect('hello').toBe('hello'); // 통과

 const obj1 = { a: 1 };
 const obj2 = { a: 1 };
 expect(obj1).toBe(obj2); // 실패 (서로 다른 참조)
 
const obj3 = obj1;
expect(obj3).toBe(obj1) // 통과 (서로 같은 참조)

expect([1,2,3].toBe([1,3,2]) // 실패
expect([1,2,3].toBe([1,2,3]) // 성공

 

toEqual

방식: 깊은 비교 (Deep Equality)

  • 객체나 배열의 구조와 내용을 비교
  • 부모 클래스에서 상속된 속성은 무시

용도

  • 객체나 배열의 구조와 내용을 비교할 때
  • 부모 클래스에서 상속된 속성은 무시해도 괜찮을 때.

특징

  • 참조를 무시하고 값만 비교
  • 객체 내부에 중첩된 값도 비교

 

const obj1 = { a: 1 };
const obj2 = { a: 1 };
expect(obj1).toEqual(obj2); // 통과 (내용이 같음)

const array1 = [1, 2, 3];
const array2 = [1, 2, 3];
expect(array1).toEqual(array2); // 통과 (배열의 내용이 같음)

const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { a: 1, b: { c: 2 } };
expect(obj1).toEqual(obj2); // 통과 (내용이 동일)

toStrictEqual

방식 : 객체의 구조(프로퍼티와 값) 그리고 타입(클래스 여부) 가 동일한지 비교 검사, 객체가 직접 소유한 프로퍼티만 비교

용도 

  • 더 엄격한 객체 검증이 필요할 때
    • 객체의 키와 값이 같고, 구조가 완전히 동일한지 확인
    • 명시되지 않은 속성(undefined)까지 검사해야 할때
    • 단순히 {} 생성된 객체인지 클래스 인스턴스인지 비교가 필요한 경우
    • 배열의 요소들이 순서와 내용까지 동일한지 확인

특징

  • 객체의 추가적인 프로퍼티나 순서의 차이도 확인
  • 상속받은 프로퍼티도 비교 대상에서 제외
  • 상속받은 프로퍼티를 포함하려면 객체를 복사하거나 평탄화(flatten)필요

 

예시

const obj1 = { a: 1, b: 2 };
const obj2 = { a: 1, b: 2 };
expect(obj1).toStrictEqual(obj2); // 통과 (내용 동일)

const obj3 = { a: 1, b: 2, c: 3 };
expect(obj1).toStrictEqual(obj3); // 실패 (추가된 프로퍼티 c)

const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3];
const arr3 = [1, 3, 2];
expect(arr1).toStrictEqual(arr2); // 통과 (배열 내용 동일)
expect(arr1).toStrictEqual(arr3) // 실패


/* 상속 프로퍼티 */
// 부모 클래스 정의
class Parent {
  constructor() {
    this.parentProp = 'parent';
  }
}

// 자식 클래스 정의
class Child extends Parent {
  constructor() {
    super();
    this.childProp = 'child';
  }
}

const obj1 = new Child();
const obj2 = { childProp: 'child', parentProp: 'parent' };

// `toStrictEqual`은 obj1의 상속 프로퍼티(parentProp)를 비교하지 않음
expect(obj1).toStrictEqual(obj2); // 실패

// obj1의 모든 프로퍼티를 명시적으로 포함한 객체와 비교
const obj1Flattened = Object.assign({}, obj1);
expect(obj1Flattened).toStrictEqual(obj2); // 통과

 

* 평탄화 추가 설명

원래 obj1 객체 (상속 포함):

Child {
  childProp: 'child',
  __proto__: Parent {
    parentProp: 'parent',
    __proto__: Object
  }
}

 

Object.assign({}, obj1)로 평탄화한 객체

{
  childProp: 'child',
  parentProp: 'parent'
}

 

 

차이점 요약

  toBe toEqual toStrictEqual
비교 방식 Object.is를 사용하여 참조와 값을 비교 구조와 내용의 깊은 비교
- toEqual의 기능 + 더 엄격한 검증
- 객체의 타입(인스턴스 여부)까지 검증
- 스파스 요소까지 포함
원시 값 비교 값이 같으면 true 값이 같으면 true 값이 같으면 true
객체 비교 참조가 같아야 true 객체의 내용이 같으면 true 객체의 내용 + 타입이 같아야 true
배열 비교 참조가 같아야 true 배열의 내용과 순서가 같으면 true 배열의 내용, 순서, 스파스 요소가 같아야 true
클래스 인스턴스 비교

동일 참조일 때만 true 구조가 같으면 true 구조와 클래스 타입이 같아야 true

스파스 요소 비교하지 않음 스파스 요소와 undefined를 동일하게 간주 스파스 요소와 undefined를 다르게 간주
사용 사례 - 원시 값 비교
- 객체 참조 확인
- 동일한 메모리 위치인지 확인
- 객체의 구조나 내용을 검증할 때
- 배열, 객체의 내용 확인
- 객체의 구조와 타입까지 검증해야 할 때
- 배열의 스파스 요소 확인

 

목차

 

작업큐(Job-Queue) 시스템

 

작업큐 시스템의 필요성

 

웹 서비스에는 기본적으로 요청이 동기적으로 실행된다.

따라서, 계속 성장해가는 웹 서비스에서는 데이터가 누적되면서 데이터를 추가하고 갱신하는 처리가 점점 무거워진다.

이 때문에, 양호했던 성능도 시간이 지남에 따라 악화되고 서비스 사용자 경험에 영향을 주게 된다.

→ 작업큐 시스템을 이용하여 나중으로 미루어도 되는 작업을 비동기로 실행 가능

  사용자 경험개선 가능

 

(하테나  경우)

사용자가 URL을 북마크했을 때의 처리를 작업큐 시스템에서 처리

 

작업큐 시스템 입문

가장 간단하게 비동기화하는 방법

  • 비동기화하고자 하는 처리를 독립된 스크립트로 해서 해당 스크립트를 애플리케이션 내부에서 호출하는 방법
    • 단점
      • 스크립트 시작과 초기화의 오버헤드가 크다.
      • 대량의 비동기 처리를 실행시키려 하면 그 수만큼의 프로세스를 실행해야 한다.
    • 프로토타입이나 소규모 애플리케이션에만 적용하는 것을 추천

많은 양의 비동기 처리를 안정적으로 하는 방법

  • 작업큐(job-queue)와 워커(worker)를 세트로 한 작업큐 시스템을 사용
    • 작업큐에 실행하고자하는 처리를 등록 ▶ 워커가 큐에서 작업을 추출하여 처리

클라이언트 ( 웹 애플리케이셔) - 작업을 투입. 작업을 투입한 다음 처리를 계속 진행할 수 있다.

작업큐 - 작업을 쌓는다.

워커 - 작업큐를 참조, 미실행된 작업을 추출해서 작업을 실행

 

하테나에서의 작업큐 시스템

Perl로 구현된 시스템

 

TheSchwartz - 작업큐

  • MySQL과 같은 RDBMS를 사용하는 작업큐 시스템 
  • 비동기로만 가능

Gearman - TheSchwartz 보다 가벼운 작업큐

  • RDBMS 가 아닌 독자적인 데몬을 사용해서 작업의 정보를 메모리에 저장
  • 동기적으로 순번대로 처리
  • 동기적으로 병렬로 처리
  • 비동기적으로 백드라운드로 처리

WorkerManager에 의한 워커 관리

  • 워커 프로세스를 좀더 세세하게 제어하기 위한 시스템 (하테나에서 개발)
  • TheSchwartz 와 Gearman을 래핑해서 최소한의 변경으로 양쪽에 대응
  • 설정파일로 워커 클래스 정의. 설정파일만 수정해서 워커로서 사용할 클래스를 변경 가능
  • 워커 프로세스의 라이프사이클 관리. 프로세스 관리. 데몬화 수행
  • 워커 프로세스의 프로세스 개수 관리. 프로세스 개수를 관리하고 병행처리가 가능한 작업수를 제어
  • 로그 출력. 작업을 처리한 타임스탬프 등을 로그에 기록

로그분석

처리시간과 지연시간을 측정함으로써 투입된 작업 종류와 양에 대해 워커의 처리능력이 충분한지여부 확인 가능하다.

 

(예) 지연시간이 길어지는 경우 ▶ 아무리 비동기 처리라고 하더라도 사용자 경험상 문제가 되는 경우 발생

→ 이 경우 워커의 튜닝과 보강을 생각해야 할 시점

스토리지 선택

웹 애플리케이션에 있어서 "증가하는 데이터를 어떻게 저장할까?" 라는 문제는 영원한 과제다.

웹 애플리케이션과 스토리지

스토리지?

애플리케이션 데이터를 영속적으로 혹은 일시적으로 저장하기 위한 기능

 

원본데이터

애플리케이션에 업로드된 사진, 블로그 본문과 같이 영속적으로 저장되어야 하는 데이터

가장 중요해서 서비스의 근본적인 신뢰성과 관계있다  비용을 들여서라도 최상급 신뢰성 확보

 

캐시

액세스 랭킹이나 검색용 인덱스 데이터와 같이 재생성 가능한 가공데이터

신뢰서은 그다지 중요하지 않음 → 비용을 줄일 필요 있음

 

애플리케이션에 필요한 데이터의 예

  필요한 신뢰성 크기 갱신빈도 종류
블로그 본문 원본 데이터
디지털카메라 사진 원본 데이터
검색용 인덱스 가공 데이터
HTML 처리 후 본문 캐시

 

적절한 스토리지 선택의 어려움

 

적절한(저장하고자 하는 데이터의 특성에 맞는) 스토리지 선택의 중요성

  • 비용과 성능, 안정성의 균형을 높은 차원으로 달성하기 위한 열쇠
  • 스토리지를 잘못 선택한 채로 서비스를 시작하게 되면 나중에 알아차리더라도 스토리 변경은 보통 방법으로는 뜻대로 이룰 수 없다.
  • 가능한 한 특성에 맞는 스토리지를 선택하여 하나의 스토리지를 오래도록 사용하는 것이 바람직하다.

하지만,  서비스 성장을 예측하는 것은 어려우며 기술도 진화해가므로 스토리지 설계를 전혀 갱신하지 않고 가는 것은 어렵다.

 

스토리지 선택의 전제가 되는 조건

애플리케이션에서의 액세스 패턴을 이해하기 위한 지표

  • 평균크기
  • 최대크기
  • 신규추가 빈도
  • 갱신빈도
  • 삭제빈도
  • 참조빈도

추가) 크기에 요구되는 신뢰성, 허용할 수 있는 장애 레벨, 사용할 수 있는 하드웨어나 쓸 수 있는 예산 도 중요한 포인트

 

RDBMS

RDBMS(Realtional Database Management System) 

  • 표 형식으로 데이터를 저장하고 대부분은 SQL 언어로 데이터 조작을 수행하는 시스템
  • 다양한 데이터를 저장한다거나 강력한 질의를 할 수 있어서 범용성이 높은 스토리지

 

MySQL

  • 특징: SQL을 해석해서 실행하는 기능 블록과 실제로 데이터를 보관하는 기능 블록이 분리되어 있음

MySQL 아키텍처

스토리지 엔진

MyISAM

  • 1 개의 테이블이 실제 파일 시스템 상에 3개의 파일(정의, 인덱스, 데이터)로 표현
  • 장점
    • 시작과 정지가 빠름
    • 테이블 이동이나 이름변경을 직접 가능
  • 단점
    • DB 프로세스가 비정상 종료하면 테이블이 파손될 가능성 높음
    • 트랜잭션 기능이 없음
    • update, delete, insert가 테이블 락으로 되어 있어 갱신이 많은 용도로는 성능적으로 불리

InnoDB

  • 스토리지 엔진 전체에서 사전에 정의한 소수의 파일에 데이터를 저장.
  • 장점
    • 트랙잭션 지원
    • 비정상 종료시 복구기능 존재
    • 데이터 갯인이 로우 락(Row Lock)으로 되어 있음
  • 단점
    • 데이터량에 따라 시작, 정지가 수 분 정도 걸린다.
    • 테이블 조작을 모두 DB를 경유해서 수행해야 한다.

정리

  • 추가처리만 한다 → MyISAM가 적합한 스토리지 엔진
  • 갱신빈도가 높고 트랜잭션이 필요하다 → InnoDB가 적합한 스토리지지 엔진

분산 key-value 스토어

  • key-value 스토어 : key와 value 쌍을 저장하기 위한 심플한 스토리지
  • 분산 key-value 스토어 : key-value 스토어에 네트워크를 지원함으로써 다수의 서버로 확장시키는 기능을 지닌 스토리지

memcached (key-value 스토어)

  • 메모리 상에서 동작
  • 서버 증감의 영향을 받지 않음
  • 분산 알고리즘을 클라이언트 라이브러리로 구현
  • 원본 데이터 및 가공 데이터 저장에는 부적합
  • RDBMS 등에서 읽어들인 데이터를 일시적으로 저장해 두어 참조하는 용으로 적합

    → memcached 의 특성을 가장 잘 활용할 수 있는 데이터는 캐시 데이터

    → 캐시로 한정할 경우 서버에는 메모리만 충분히 탑재해두면 된다.

 

TokyoTyrant (key-value 스토어)

  • 로컬에서 동작하는 key-value 스토어인 TokyoCabinet에 네트워크를 지원하도록한 구현
  • 다중성을 높이기 위한 레플리케이션 기능을 내장
  • 성능면에서는 디스크 액세스가 발생하여 memcached 보다는 약간 떨어진다. 하지만 RDBMS 와 비교하면 상당히 빠름

분산 파일시스템

어느 정도 이상인 크기의 데이터를 저장하는데 적합

작은 데이터가 대량으로 존재하는 용도에는 부적합?

 

MogileFS

용도

  • 비교적 작은 대량의 파일을 다룰 목적으로 Perl로 구현된 분산 파일시스템 (수KB ~ 수십MB의 이미지 파일)
  • 이미지 파일과 같이 추가된 다음 갱신되지 않고 참조하기만 하는 용도에 적합(업로드 이미지 파일을 접수받는 웹 앱)

특징

  • 스토리 서버 상에서 개개의 파일은 실제 파일 시스템 상에서도 하나의 파일로 저장 
  • 통상 하나의 파일은 3중으로 다중화되어 일부 스토리지 서버가 고장나서 데이터가 손실되더라도 시스템 전체로서는 계속 정상적으로 동작할 수 있도록 설계되어 있다.
  • 파일을 참조할 때 WebDAV 프로토콜로 얻게되므로, 애플리케이션 측에 구현 필요
  • 미디어 위주의 서비스에서 수십TB 영역이 필요한 미디어 파일을 위한 스토리지로서 충분히 대응할 수 있는 확장성
  • 파일 저장소와 파일을 특정 짓기 위한 키와 대응관계는 메타데이터로 RDBMS에 저장

*WebDAV 서버: HTTP를 기반으로한 프로토콜로 애플리케이션 계층에서 구현되는 경우가 많아서 NFS(커널계층에 구현) 보다 안정적인 시스템을 구축 가능

아키텍처

그 밖의 스토리지

NFS 계열 분산 파일시스템

  • NFS 는 특정 서버의 파일시스템을 다른 서버에서 마운트해서 해당 서버의 로컬 파일시스템과 마찬가지로 조작할 수 있도록 하는 기술.

DRBD(Distributed Replicated Block Device)

  • 네트워크 계층에서 RAID라고 할 수 있는 기술, 블록 디바이스 레벨에서 분산, 다중화 할 수 있는 기술

HDFS(Hadoop Distributed file system)

  • Hadoop 용으로 설계된 분산 파일시스템

 

스토리지의 선택전략

 

캐시 시스템

웹 애플리케이션의 부하가 서서히 증가해서 시스템 용량이 부족한 경우

  1. AP 서버 증설
  2. DB 서버 증설
  3. HTTP 레벨의 캐싱을 수행하는 HTTP 가속기를 사용( 낮은 비용 으로 효과가 높은 대책)

HTTP 가속기

  • 포워드 프록시 - 클라이언트가 외부 서버에 액세스할 때 그 사이에 두는 프록시
  • 리버스 프록시 - 외부 클라이언트가 내부 서버에 액세스할 때 그 사이에 두는 프록시
  • 프록시 : 요청에 대한 응답을 캐싱해두어 같은 요청이 전달됐을 때 캐싱해둔 응답을 반환

리버스 프록시 캐시 서버

구현 툴

  • Squid
  • nginx
  • pound
  • Varnish

계산 클러스터

대량으로 쌓인 로그 데이터의 처리(ex 120gb) ▶ HDD에서 읽어 들이는데만 5 시간 이상

→빠르게 수행하기 위해서 병렬처리가 가능한 계산 클러스터 필요

 

MapReduce의 계산모델

Hadoop 이라는 MapReduce의 오픈소스

MapReduce - 2004년 Google 에서 발표한 계산 모델

 

방식

- key 와 value 쌍의 리스트를 입력 데이터로 해서 최종적으로 value의 리스트를 출력

- map 단계와 reduce 단계로 구성

 

계산모델 사진

  • Map 단계
    1. 먼저 마스터 노드에서 입력 데이터를 잘게 분할해서 각 노드로 분산
    2. 각 노드에서는 분할된 입력 데이터를 계산하고 계산결과를 key 와 value 쌍으로 구성된 중간 데이터로 출력
      • Map 단계의 처리 예시 : (k1, v1) → list(k2, v2)
  • Reduce 단계
    1. Map 단계에서의 출력 데이터를 key(k2) 별로 정리해서 key(k2)와 key에 대응하는 값의 리스트( list(v2) ) 로 재구성
    2. 각각의 key를 각 노드로 분산 ( shuffle phase)
    3. 각 노드에 있는 key(k2)와 key에 대응하는 값의 리스트( list(v2) )를 입력 데이터로 해서 각 리스트( list(v3) )를 최종적인 출력 데이터로 처리를 수행
      • Reduce 단계의 처리 예시 : ( k2, list(v2) ) →  ( k2, list(v3) )
  • 최종
    • 각 노드에서  값의 리스트 list(v3) 를 집약하면 계산이 완료

응용범위

  • 로그 분석, 검색엔진의 인덱스 생성

MapReduce 계산모델

  • Map과 Reduce라는 두가지 처리를 수행하는 함수를 준비하는 것만으로 대량의 데이터를 빠르게 처리 가능
  • 대량의 입력 데이터를 읽어들이는 부분이 성능의 병목이 되는 경우 많다.
    • 분산 파일시스템과 병용하는 것이 중요
      • DVD 1 장 분량의 데이터에 대한 grep 을 2초 만에 끝낼 수 있는 성능을 구현 가능

Hadoop

Hadoop은 Apache 프로젝트 중 하나로 MapRedue의 오픈소스 구현 중 하나(java 로 구현)

로그 분석 작업을 실행 할때 유용하다고 함.

예) 47GB의 데이터를 4303개의 Map 태스크로 분할해서 실행하고 1 개의 Reduce 태스크로 집약하여 처리 가능

목차

네트워크 분기점

1 Gbps의 한계 - PC 라우터의 한계

 

리눅스 커널을 사용하면 대략 30만 패킷/초가 한계

평큔 패킷 길이가 300 바이트면 대략 1 Gbps 

 

한계

  • 커널의 성능  = 30만 패킷/초
  • Gigabit Ethernet 레벨 = 1 Gbps

대책

  • PC 라우터를 여러 대 병렬화
  • 박스형 라우터(Cisco 라우터) 사용 - 비싼 가격

 

500 호스트의 한계 - 1 서브넷, ARP 테이블에서의 한계

500 호스트의 한계는 스위치의 ARP 테이블 (Address Resolution Protocol table)과 관련된 한계

*ARP 테이블?  IP 주소(호스트 주소와 서브넷 주소)와 MAC 주소 간 관계를 나타내는 테이블로 스위치가 이 테이블을 지니고 있음

 

1 서브넷에 배치 할 수 있는 호스트수 = 약 500

 

브로드캐스팅 통신에 의존한 처리가 많아지면(트래픽) → CPU 부하가 수십%까지 상승  →  패킷 손실 발생

*브로드캐스팅: 네트워크 상의 모든 장치에 데이터 패킷을 전송하는 통신 방법

  • 브로드캐스트 트래픽이 많아지면 네트워크 장비나 서버의 CPU에 상당한 부하를 줄 수 있고, 이는 처리 능력의 한계로 인해 CPU 사용률이 상승하게 됩니다. CPU 부하가 과도하게 높아지면 패킷 처리가 지연되거나 제대로 이루어지지 않아 패킷 손실이 발생

네트워크 구조 계층화

앞에서 언급된 한계에 대한 대책으로 네트워크를 3단계로 구성하고 있다.

  1. Access 계층(액세스 영역): 서버의 엔드포인트에 접근을 제공하는 계층 
  2. Distrution 계층 : 트래픽을 각 서브넷에 전송하는 계층
  3. Core 계층 혹은 OSPF(Open Shortest Path First) 영역 : 트래픽의 큰 흐름을 담당하는 계층

이 3단 구조로, 가장 작은 서브넷 Access 계층에서 100대 200대 로 억제하고 디스트리뷰션을 1000대 정도 코어 전체로는 10,000대 단위를 다룰 수 있다는 계층구조를 설계한다.

 

글로벌화, CDN

 

세계 각지에서 HTTP로 데이터를 가져가려고 한다면 하나의 나라에 위치하고 있는 데이터 센터에서 전송을 한다는 것은 비현실적이다.

 

이에 대한 대안으로 CDN(Content Delivery Network) 가 있다.

CDN 전문 업체 중 하나가 Amazon Cloudfront 이다.

 

CDN 의 작동원리

세계 각지에 서버를 두고 데이터를 캐싱해서 사용자가 가지고 가려고 할때 사용자와 가장 가까운 서버로 엑세스해서 접근할 수 있게 해주는 원리

 

Amazon Cloudfront 작동 원리

  1. 사용자가 웹사이트나 어플리케이션을 요청할 때 가장 가까운 CloudFront 엣지 로케이션으로 요청이 전송됨.
  2. 요청받은 콘텐츠가 해당 엣지 로케이션에 캐시되어 있지 않은 경우, CloudFront는 원본 서버(예: Amazon S3 버킷 또는 EC2 인스턴스)로부터 콘텐츠를 가져와 사용자에게 전달.
  3. 콘텐츠는 최적화된 네트워크 경로를 통해 사용자에게 전달( 로딩 시간 단축)
  4. 콘텐츠가 업데이트 되었을 경우, 새 콘텐츠로 캐시를 갱신하고, 필요시 무효화 처리를 통해 최신 콘텐츠가 사용자에게 제공됨.

 

 

한층 높은 단계로

10Gbps 이상의 세계

  • AS(Autonomous system) 번호 보유
  • IX(Internet exchange) 에 접속해서 트래픽 교환
  • BGP(Boader Gateway Protoclo)로 라우팅 제어

 

+ Recent posts