블로그 이미지
평범하게 살고 싶은 월급쟁이 기술적인 토론 환영합니다.같이 이야기 하고 싶으시면 부담 말고 연락주세요:이메일-bwcho75골뱅이지메일 닷컴. 조대협


Archive»


 
 

딥러닝을 이용한 숫자 이미지 인식 #2/2


앞서 MNIST 데이타를 이용한 필기체 숫자를 인식하는 모델을 컨볼루셔널 네트워크 (CNN)을 이용하여 만들었다. 이번에는 이 모델을 이용해서 필기체 숫자 이미지를 인식하는 코드를 만들어 보자


조금 더 테스트를 쉽게 하기 위해서, 파이썬 주피터 노트북내에서 HTML 을 이용하여 마우스로 숫자를 그릴 수 있도록 하고, 그려진 이미지를 어떤 숫자인지 인식하도록 만들어 보겠다.



모델 로딩

먼저 앞의 예제에서 학습을한 모델을 로딩해보도록 하자.

이 코드는 주피터 노트북에서 작성할때, 모델을 학습 시키는 코드 (http://bcho.tistory.com/1156) 와 별도의 새노트북에서 구현을 하도록 한다.


코드

import tensorflow as tf

import numpy as np

import matplotlib.pyplot as plt

from tensorflow.examples.tutorials.mnist import input_data


#이미 그래프가 있을 경우 중복이 될 수 있기 때문에, 기존 그래프를 모두 리셋한다.

tf.reset_default_graph()


num_filters1 = 32


x = tf.placeholder(tf.float32, [None, 784])

x_image = tf.reshape(x, [-1,28,28,1])


#  layer 1

W_conv1 = tf.Variable(tf.truncated_normal([5,5,1,num_filters1],

                                         stddev=0.1))

h_conv1 = tf.nn.conv2d(x_image, W_conv1,

                      strides=[1,1,1,1], padding='SAME')


b_conv1 = tf.Variable(tf.constant(0.1, shape=[num_filters1]))

h_conv1_cutoff = tf.nn.relu(h_conv1 + b_conv1)


h_pool1 =tf.nn.max_pool(h_conv1_cutoff, ksize=[1,2,2,1],

                       strides=[1,2,2,1], padding='SAME')


num_filters2 = 64


# layer 2

W_conv2 = tf.Variable(

           tf.truncated_normal([5,5,num_filters1,num_filters2],

                               stddev=0.1))

h_conv2 = tf.nn.conv2d(h_pool1, W_conv2,

                      strides=[1,1,1,1], padding='SAME')


b_conv2 = tf.Variable(tf.constant(0.1, shape=[num_filters2]))

h_conv2_cutoff = tf.nn.relu(h_conv2 + b_conv2)


h_pool2 =tf.nn.max_pool(h_conv2_cutoff, ksize=[1,2,2,1],

                       strides=[1,2,2,1], padding='SAME')


# fully connected layer

h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*num_filters2])


num_units1 = 7*7*num_filters2

num_units2 = 1024


w2 = tf.Variable(tf.truncated_normal([num_units1, num_units2]))

b2 = tf.Variable(tf.constant(0.1, shape=[num_units2]))

hidden2 = tf.nn.relu(tf.matmul(h_pool2_flat, w2) + b2)


keep_prob = tf.placeholder(tf.float32)

hidden2_drop = tf.nn.dropout(hidden2, keep_prob)


w0 = tf.Variable(tf.zeros([num_units2, 10]))

b0 = tf.Variable(tf.zeros([10]))

k = tf.matmul(hidden2_drop, w0) + b0

p = tf.nn.softmax(k)


# prepare session

sess = tf.InteractiveSession()

sess.run(tf.global_variables_initializer())

saver = tf.train.Saver()

saver.restore(sess, '/Users/terrycho/anaconda/work/cnn_session')


print 'reload has been done'


그래프 구현

코드를 살펴보면, #prepare session 부분 전까지는 이전 코드에서의 그래프를 정의하는 부분과 동일하다. 이 코드는 우리가 만든 컨볼루셔널 네트워크를 복원하는 부분이다.


변수 데이타 로딩

그래프의 복원이 끝나면, 저장한 세션의 값을 다시 로딩해서 학습된 W와 b값들을 다시 로딩한다.


# prepare session

sess = tf.InteractiveSession()

sess.run(tf.global_variables_initializer())

saver = tf.train.Saver()

saver.restore(sess, '/Users/terrycho/anaconda/work/cnn_session')


이때 saver.restore 부분에서 앞의 예제에서 저장한 세션의 이름을 지정해준다.

HTML을 이용한 숫자 입력

그래프와 모델 복원이 끝났으면 이 모델을 이용하여, 숫자를 인식해본다.

테스트하기 편리하게 HTML로 마우스로 숫자를 그릴 수 있는 화면을 만들어보겠다.

주피터 노트북에서 새로운 Cell에 아래와 같은 내용을 입력한다.


코드

input_form = """

<table>

<td style="border-style: none;">

<div style="border: solid 2px #666; width: 143px; height: 144px;">

<canvas width="140" height="140"></canvas>

</div></td>

<td style="border-style: none;">

<button onclick="clear_value()">Clear</button>

</td>

</table>

"""


javascript = """

<script type="text/Javascript">

   var pixels = [];

   for (var i = 0; i < 28*28; i++) pixels[i] = 0

   var click = 0;


   var canvas = document.querySelector("canvas");

   canvas.addEventListener("mousemove", function(e){

       if (e.buttons == 1) {

           click = 1;

           canvas.getContext("2d").fillStyle = "rgb(0,0,0)";

           canvas.getContext("2d").fillRect(e.offsetX, e.offsetY, 8, 8);

           x = Math.floor(e.offsetY * 0.2)

           y = Math.floor(e.offsetX * 0.2) + 1

           for (var dy = 0; dy < 2; dy++){

               for (var dx = 0; dx < 2; dx++){

                   if ((x + dx < 28) && (y + dy < 28)){

                       pixels[(y+dy)+(x+dx)*28] = 1

                   }

               }

           }

       } else {

           if (click == 1) set_value()

           click = 0;

       }

   });

   

   function set_value(){

       var result = ""

       for (var i = 0; i < 28*28; i++) result += pixels[i] + ","

       var kernel = IPython.notebook.kernel;

       kernel.execute("image = [" + result + "]");

   }

   

   function clear_value(){

       canvas.getContext("2d").fillStyle = "rgb(255,255,255)";

       canvas.getContext("2d").fillRect(0, 0, 140, 140);

       for (var i = 0; i < 28*28; i++) pixels[i] = 0

   }

</script>

"""


다음 새로운 셀에서, 다음 코드를 입력하여, 앞서 코딩한 HTML 파일을 실행할 수 있도록 한다.


from IPython.display import HTML

HTML(input_form + javascript)


이제 앞에서 만든 두 셀을 실행시켜 보면 다음과 같이 HTML 기반으로 마우스를 이용하여 숫자를 입력할 수 있는 박스가 나오는것을 확인할 수 있다.



입력값 판정

앞의 HTML에서 그린 이미지는 앞의 코드의 set_value라는 함수에 의해서, image 라는 변수로 784 크기의 벡터에 저장된다. 이 값을 이용하여, 이 그림이 어떤 숫자인지를 앞서 만든 모델을 이용해서 예측을 해본다.


코드


p_val = sess.run(p, feed_dict={x:[image], keep_prob:1.0})


fig = plt.figure(figsize=(4,2))

pred = p_val[0]

subplot = fig.add_subplot(1,1,1)

subplot.set_xticks(range(10))

subplot.set_xlim(-0.5,9.5)

subplot.set_ylim(0,1)

subplot.bar(range(10), pred, align='center')

plt.show()

예측

예측을 하는 방법은 쉽다. 이미지 데이타가 image 라는 변수에 들어가 있기 때문에, 어떤 숫자인지에 대한 확률을 나타내는 p 의 값을 구하면 된다.


p_val = sess.run(p, feed_dict={x:[image], keep_prob:1.0})


를 이용하여 x에 image를 넣고, 그리고 dropout 비율을 0%로 하기 위해서 keep_prob를 1.0 (100%)로 한다. (예측이기 때문에 당연히 dropout은 필요하지 않다.)

이렇게 하면 이 이미지가 어떤 숫자인지에 대한 확률이 p에 저장된다.

그래프로 표현

그러면 이 p의 값을 찍어 보자


fig = plt.figure(figsize=(4,2))

pred = p_val[0]

subplot = fig.add_subplot(1,1,1)

subplot.set_xticks(range(10))

subplot.set_xlim(-0.5,9.5)

subplot.set_ylim(0,1)

subplot.bar(range(10), pred, align='center')

plt.show()


그래프를 이용하여 0~9 까지의 숫자 (가로축)일 확률을 0.0~1.0 까지 (세로축)으로 출력하게 된다.

다음은 위에서 입력한 숫자 “4”를 인식한 결과이다.



(보너스) 첫번째 컨볼루셔널 계층 결과 출력

컨볼루셔널 네트워크를 학습시키다 보면 종종 컨볼루셔널 계층을 통과하여 추출된 특징 이미지들이 어떤 모양을 가지고 있는지를 확인하고 싶을때가 있다. 그래서 각 필터를 통과한 값을 이미지로 출력하여 확인하고는 하는데, 여기서는 이렇게 각 필터를 통과하여 인식된 특징이 어떤 모양인지를 출력하는 방법을 소개한다.


아래는 우리가 만든 네트워크 중에서 첫번째 컨볼루셔널 필터를 통과한 결과 h_conv1과, 그리고 이 결과에 bias 값을 더하고 활성화 함수인 Relu를 적용한 결과를 출력하는 예제이다.


코드


conv1_vals, cutoff1_vals = sess.run(

   [h_conv1, h_conv1_cutoff], feed_dict={x:[image], keep_prob:1.0})


fig = plt.figure(figsize=(16,4))


for f in range(num_filters1):

   subplot = fig.add_subplot(4, 16, f+1)

   subplot.set_xticks([])

   subplot.set_yticks([])

   subplot.imshow(conv1_vals[0,:,:,f],

                  cmap=plt.cm.gray_r, interpolation='nearest')

plt.show()


x에 image를 입력하고, dropout을 없이 모든 네트워크를 통과하도록 keep_prob:1.0으로 주고, 첫번째 컨볼루셔널 필터를 통과한 값 h_conv1 과, 이 값에 bias와 Relu를 적용한 값 h_conv1_cutoff를 계산하였다.

conv1_vals, cutoff1_vals = sess.run(

   [h_conv1, h_conv1_cutoff], feed_dict={x:[image], keep_prob:1.0})


첫번째 필터는 총 32개로 구성되어 있기 때문에, 32개의 결과값을 imshow 함수를 이용하여 흑백으로 출력하였다.




다음은 bias와 Relu를 통과한 값인 h_conv_cutoff를 출력하는 예제이다. 위의 코드와 동일하며 subplot.imgshow에서 전달해주는 인자만 conv1_vals → cutoff1_vals로 변경되었다.


코드


fig = plt.figure(figsize=(16,4))


for f in range(num_filters1):

   subplot = fig.add_subplot(4, 16, f+1)

   subplot.set_xticks([])

   subplot.set_yticks([])

   subplot.imshow(cutoff1_vals[0,:,:,f],

                  cmap=plt.cm.gray_r, interpolation='nearest')

   

plt.show()


출력 결과는 다음과 같다



이제까지 컨볼루셔널 네트워크를 이용한 이미지 인식을 텐서플로우로 구현하는 방법을 MNIST(필기체 숫자 데이타)를 이용하여 구현하였다.


실제로 이미지를 인식하려면 전체적인 흐름은 같지만, 이미지를 전/후처리 해내야 하고 또한 한대의 머신이 아닌 여러대의 머신과 GPU와 같은 하드웨어 장비를 사용한다. 다음 글에서는 MNIST가 아니라 실제 칼라 이미지를 인식하는 방법에 대해서 데이타 전처리에서 부터 서비스까지 전체 과정에 대해서 설명하도록 하겠다.


예제 코드 : https://github.com/bwcho75/tensorflowML/blob/master/MNIST_CNN_Prediction.ipynb


저작자 표시 비영리
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

노트7의 소셜 반응을 분석해 보았다. 


#3 제플린 노트북을 이용한 상세 분석



조대협 (http://bcho.tistory.com)



데이타 스튜디오는 편리하게 사용할 수 있지만, 쿼리 사용등이 불가능하기 때문에, 원본 데이타를 이용한 상세 분석에는 어려움이 있다. 원본 데이타를 이용해서 상세 분석을 하려면 노트북 계열의 애플리케이션이 효과적인데, 빅쿼리를 연동할 수 있는 노트북으로는 이전에 소개한 주피터 노트북 기반의 데이타랩 (datalab)과, 스파크나 다른 빅데이타 솔루션과 함께 많이 사용되는 제플린 노트북(zeppelin.apache.org) 이 있다.


지난 글에서 데이타랩에 대한 연동 방법은 이미 소개하였으니, 이번에는 제플린을 통하여, 빅쿼리의 데이타를 분석해보도록 한다.


제플린 설치

제플린을 설치 하는 방법은 간단하다. Zeppelin.apache.org 에서, 설치 파일을 다운로드 받는다.

빅쿼리 연동 인터프리터는 제플린 버전 0.61 버전 이상에 포함되어 있기 때문에, 0.61 버전 이상을 다운로드 받는다.  이 때 모든 인터프리터가 포함된 버전을 다운 받아야 한다. (아니면 별도로 인터프리터를 설치해야 하는 번거로움이 따른다.)


다운 로드 받은 파일의 압축을 푼다. 다음으로 제플린 설치 디렉토리로 들어가서 다음 명령어를 수행한다.

% ./bin/zeppelin.sh

윈도우의 경우에는 %./bin/zeppelin.cmd 를 실행하면 된다.

자바 애플리케이션이기 때문에 별도의 설치 과정이 필요없고, 제플린 애플리케이션을 실행하기만 하면 된다.

제플린이 기동되었으면 브라우져에서 http://localhost:8080 으로 접속하면 다음과 같이 제플린 콘솔을 볼 수 있다.

노트북 생성

제플린 콘솔에 들어왔으면 초기화면에서 Create new note 라는 메뉴를 이용하여 새로운 노트북을 생성하자. 여기서는 편의상 “BQ 노트북" 이라는 이름으로 노트북을 생성하였다.


분석 쿼리 작성

이제 분석할 내용은 수집된 트윗의 명사들에 대해서, 시간 단위로 그룹핑을 한 다음에, 각 단어에 대해서 발생한 횟수를 카운트해서 보여주는 내용을 구현하려고 한다.

예를 들어서 9월20일에는 “유행" 이라는 단어가 200회 발생하였고, “패션" 이라는 단어가 100회 발생하였다. 라는 식으로 조회를 하려고 한다.


현재 테이블 구조는 다음과 같다.

Date (발생 시간)

Noun (명사)

count (발생 횟수)


SQL 문장을 작성해보자

select date,noun,sum(count) from 테이블명

group by date,noun


이렇게 쿼리를 하면, 시간대 별로, 명사와 그 명사의 발생 횟수를 리턴을 해주는데, 우리는 앞의 데이타 플로우 프로그램에서 30초 단위로 통계를 집계하도록 하였기 때문에, 30초 단위로 결과가 리턴된다. 우리가 원하는 결과는 30초 단위가 아니라 1시간 단위의 결과 이기 때문에, 다음과 같이 쿼리를 수정한다.


select  DATE(date) as ddate,HOUR(date) as dhour,noun,sum(count) from 테이블명

group by ddate,dhour,noun


DATE와 HOUR라는 함수를 사용하였는데, DATE는 타임 스탬프 형태의 컬럼에서 날짜만을 추출해주는 함수 이고, HOUR는 타임 스탬프 형태의 컬럼에서 시간만을 추출해주는 함수 이다.

이렇게 날짜와 시간만을 추출한 다음에, group by 절을 이용하여, 날짜와,시간 그리고 명사로 그룹핑을 하게 되면 우리가 원하는 것과 같이 각 날짜의 시간대별로 명사별 발생횟수 ( sum(count)) 값의 통계를 얻을 수 있다.


제플린에서 빅쿼리 명령을 수행하려면 다음과 같이 %bigquery.sql 이라고 첫줄에 선언을 한 다음에 SQL 문장을 수행하면 된다.




결과는 디폴트로 테이블 형태로 나오는데, 아래 아이콘 중에서 그래프 아이콘을 누르면 그래프 형태로 볼 수 가 있는데, 이 때 X,Y축의 변수를 지정할 수 있다.

아래 그림과 같이 Keys (X축을) ddate,dhour를 선택하고 Values(Y축)을 dhour SUM을 선택하면, 시간별 나타난 단어수를 볼 수 있다.



그런데 이 쿼리를 수행하면, 각 시간별로 발생한 명사 단어의 수가 매우 많기 때문에, 보기가 매우 어렵다.

그렇다면 시간대별로 발생한 명사중에서 각 시간대별로 많이 발생한 명사 5개씩만을 볼 수 없을까? 즉 group by를 전체 데이타 구간이 아니라, 각각 시간대 별로 계산을 해줄 수 는 없을까 하는 필요가 발생한다.

빅쿼리 파티셔닝

데이타를 구간 별로 나눠서 연산할 수 있는 기능으로 빅쿼리에는 파티션이라는 기능이 있다.

예를 들어서 group by를 전체 결과에 대해 그룹핑을 하는 것이 아니라, 앞에서 언급한 요건 처럼 일 단위로 짤라서 그룹핑을 하는 것이 가능하다.




파티션을 이용해서 할 수 있는 것은 파티션별로 합계나, 통계를 내거나, 파티션의 각 로우의 값의 백분율(%)나 또는 소팅한 순서등을 볼 수 있다. 여기서는, 시간으로 파티션을 나누고  파티션내에서 명사의 수가 많은 수 순서대로 소팅을 한후에, RANK라는 함수를 이용하여 그 파티션에서 그 명사가 몇번째로 많이 나타났는지를 출력하도록 해보겠다.


파티션의 사용법은 다음과 같다.

“파티션 함수 OVER (PARTITION BY 파티션을할 키 목록)”

여기서는 일/시간 별로 파티션을 나눈 후에, 그 순위별로 소팅을 할 것이기 때문에, 다음과 같은 식을 쓴다.

RANK() OVER (PARTITION BY ddate,dhour ORDER BY ncount DESC  ) as rank


이를 쿼리에 적용하면 다음과 같다.

   SELECT

       DATE(date) as ddate,HOUR(date) as dhour

       ,noun

       ,sum(count) as ncount

       , RANK() OVER (PARTITION BY ddate,dhour ORDER BY ncount DESC  ) as rank

   FROM [useful-hour-138023:twitter.noun]

   group by noun,ddate,dhour

   order by ddate,dhour,ncount desc


그러면 다음과 같이 일/날짜 파티션별로 많이 발생한 명사 순으로 발생횟수와 순위(rank)를 출력해준다.



그런데 쿼리를 돌려보면 알겠지만, 시간대별로 수집한 명사의 종류가 많기 때문에, 일자별 데이타가 매우 많다. 그래서 파티션별로 많이 등장하는 단어 5개만을 보려고 하면 rank <5 인것만 걸러내면 된다. 이는 중첩 쿼리를 이용해서 수행이 가능하다

다음은 이를 적용한 예이다.


SELECT ddate,dhour

   ,noun

   , rank

from (

   SELECT

       DATE(date) as ddate,HOUR(date) as dhour

       ,noun

       ,sum(count) as ncount

       , RANK() OVER (PARTITION BY ddate,dhour ORDER BY ncount DESC  ) as rank

   FROM [useful-hour-138023:twitter.noun]

   where noun != "note7" and noun != "samsung" and noun !="galaxy"

   group by noun,ddate,dhour

   order by ddate,dhour,ncount desc

   )

where rank < 6


이렇게 하면, 각 시간대별로 자주 등장하는 단어 6개만을 보여준다.


이 쿼리를 이용하여 데이타를 어떻게 분석하는지는 예전글 http://bcho.tistory.com/1136 을 참고하세요.


간단하게나마 트위터 피드에서 특정 키워드를 기반으로 하여, 명사와 형용사를 추출하여 소셜 반응을 분석하는 애플리케이션 개발과 데이타 분석 방법에 대해서 설명하였다.

아이폰7을 분석해보니, 명사 분석도 의미가 있었지만, 아이폰7에 대한 기대를 형용사 분석을 통해서도 많은 인사이트를 얻을 수 있었다. Awesome, excellent와 같은 기대치가 높은 형용사가 많이 검출되었고 bad, fuck 과 같은 부정적인 의미의 형용사는 다소 낮게 검출되었다. (아마 이즈음이 노트7 폭발로 인하여 반사 이익을 얻은게 아닐까 추정되는데.)


이외에도, 이모콘티만 추출하여 분석을 한다거나, 부사등을 통해서 분석을 하는 것도 가능하고, 구글 자연어 처리 API는 글을 통해서 사람의 감정을 분석해주는 기능도 있기 때문에 응용 분야는 훨씬 더 넓다고 볼 수 있다.

저작자 표시 비영리
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

구글 클라우드 로드밸런서 소개

조대협 (http://bcho.tistory.com)


클라우드 플랫폼에서 가장 필요한 기능중의 하나가 로드밸런서이다.

그중에서 구글 클라우드의 로드밸런서는 L7 스위치 이상의 기능을 가지면서 로드밸런서와 api gateway의 일부 기능을 수행할 수 있는데, 어떤 특징이 있는지 살펴보자. (개인적인 생각이지만 이게 정말 물건이다..)

HTTP 프로토콜 지원

TCP,UDP 뿐 아니라 HTTP 레이어의 로드밸런싱을 지원한다. HTTPS Termination을 당연히 지원하고 HTTP 모드로 부하분산을 할 경우 HTTP URI에 따라 다양한 라우팅을 할 수 있다.

No warming

다른 클라우드 로드밸런서와는 달리 트래픽이 갑자기 많이 들어오더라도 별도의 워밍업작업 없이 트래픽을 받을 수 있다. 클라우드 로드밸런서의 경우에는 종종 수십분간 워밍(부하를 지속해서 넣어서 로드밸런서의 용량을 늘려주는 행위)을 해주지 않으면 큰 대역폭의 트래픽을 못 받는 경우가 있다.

리전간 부하 분산과 서버 그룹간 부하 분산

여기 부터가 재미있는 기능인데, 들어오는 트래픽에 따라서 특정 리전(국가)로 라우팅을 하도록 설정할 수 있고, 별도의 설정이 없으면 자동으로 클라이언트가 가까운 데이타 센터로 트래픽을 라우팅해줄 수 있다.


아래 그림은 HTTP 요청을 US와 EU 리전에 있는 각각의 서버 그룹으로 분산하고, HTTPS요청도 US와 EU에 있는 각각의 리전으로 분산하는 구조를 설명한 그림이다.


(출처 : https://cloud.google.com/compute/docs/load-balancing/http/cross-region-example#overview)


리전간 부하 분산을 하면 리전 단위의 장애 대응이 가능할 뿐만 아니라, 가장 가까운 데이타 센터로 부터 호출을 할 수 있기 때문에 네트워크 구간 시간을 줄일 수 있다.


위의 그림에서 봐야 할것중 하나가 서버 그룹간의 부하 분산인데, 같은 애플리케이션이라도 “인스턴스 그룹" 이라는 개념으로 서버들을 묶을 수 있다. 위에 HTTP 를 지원하는 애플리케이션은 두개의 그룹으로 정의되어 있는데, 이렇게 서버를 여러개의 그룹으로 묶으면 좋은 점이 롤링 업그레이드가 가능하다는 것이다. 즉 그룹 A,B가 있을때, A를 로드 밸런서에서 떼어서 업데에트 한 후 다시 붙이고, 그 다음은 그룹 B를 로드밸런서에서에서 떼어서 업데이트 한 후 다시 붙여서 서버 배포나 업데이트시에 무장애로 진행이 가능하다.

HTTP URI 기반의 부하 분산

매우 흥미로운 기능중 하나가 HTTP의 URI를 기반으로 특정 서버 그룹으로 요청을 라우팅 할 수 있는 기능이다. 일반적인 네트워크 장비인 L4등에서는 구현이 불가능한 기능인데 원리는 단순하다.

아래 그림처럼 /static URL를 갖는 요청은 “static-resources” 라는 서버 그룹으로 라우팅 하고, /video URL을 갖는 요청은 “video-resources”라는 서버 그룹으로 라우팅 하는 식이다.



출처 : https://cloud.google.com/compute/docs/load-balancing/http/content-based-example#overview


매우 간단한 기능이기는 하지만 그 활용도가 매우 높다.

웹서버, 스트리밍 서버등으로 컨텐츠 타입에 따라 서버를 나눌 수 도 있지만,

마이크로 서비스 아키텍쳐 (MSA)로 되어 있는 경우, 각 서비스 컴포넌트가 다른 URL을 가지기 때문에, 앞단에 API Gateway와 같이 URL에 따라 라우팅을 해주는 프록시 계층이 필요한데, 구글의 로드밸런서는 이 기능을 지원하기 때문에, 백앤드 서비스가 MSA로 구성되어 있을 경우 이 기능을 유용하게 사용할 수 있다.

글로벌 엣지 서버와 통합을 통한 네트워크 가속

다른 글에서도 설명했던 내용인데, 구글 클라우드 로드 밸런서를 사용하게 되면 전세계에 흩어져 있는 약 70여개의 엣지 노드를 통해서 요청 트래픽을 받는다. 가장 가까운 엣지 노드로 트래픽을 받은 후, 엣지노드에서 서버까지 구글의 광케이블을 통해서 트래픽을 전달해줘서, 글로벌 서비스의 경우 네트워크 지연 시간을 절약할 수 있다.



자세한 내용은 http://bcho.tistory.com/1109 를 참고


저작자 표시 비영리
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

구글 클라우드 MySQL서비스의 흥미로운 가격 정책

조대협 (http://bcho.tistory.com)


구글 클라우드의 MySQL 서비스인 CloudSQL을 보다보니, 신기한 가격 정책이 있어서 정리해놓고자 한다.

1세대와 2세대의 가격 정책이 다른데, 1세대의 가격 정책이 재미있는점이 있다.


기본 가격 정책


1,2세대 모두 기본 적인 가격 정책은 다음과 같다


저장량 + 인스턴스 기동 비용 + 네트워크 비용

  • 저장량은 말 그대로 저장된 데이타의 양에 따라 과금이 된다
  • 네트워크 비용은 outbound로 나가는 트래픽만 과금이 되는데, 이것도 같은 리전 안의 구글 클라우드에서 호출하는 경우에는 과금이 되지 않는다. 과금이 되는 경우는 구글 클라우드를 쓰더라도 다른 대륙의 인스턴스가 호출을 하거나 또는 다른 클라우드 서비스에서 호출을 하는 경우에만 과금이 되기 때문에, 일반적인 상황에서는 거의 네트워크 트래픽 비용이 과금이 되지 않는다.
  • 인스턴스 기동 비용은 인스턴스가 떠있는 동안데 받는 비용인데 이 부분이 흥미롭다.
인스턴스 가동 비용

1세대 CloudSQL 경우 Package plan 과 Pay per use plan 두가지가 있다.
Package Plan은 일단위 과금이며, 인스턴스가 기동이 되어 있는 일 기준으로 과금이 된다. 이건 모 일반적인 것이고
흥미로운 가격 정책이라고 하는것은 Pay per use plan이다. Pay per use plan은 인스턴스가 떠 있는 시간동안 분당 과금을 하는 것이다. 일반적인 분당 과금 처럼 보일 수 있지만 재미 있는 것은 Cloud SQL 인스턴스 생성시 activation policy (활성화 정책) 이라는 것을 설정할 수 있는데, 이 활성화 정책을 ALWAYS(항상) 으로 해놓으면, 인스턴스를 수동으로 내리지 않는 이상은 항상 떠 있는 케이스이다. 여기까지가 일반적인것이고
활성화 정책중 ON DEMAND(요청시)로 해놓으면, MySQL이 15분 동안 아무 Request가 없으면 해당 MySQL 인스턴스는 자동으로 비활성화 되고 인스턴스 비용이 과금되지 않는다. 비활성화 상태에서 요청이 들어오면 자동으로 활성화 상태가 된다. ON DEMAND는 활성화 상태에서 사용량을 분당으로 과금한다.

아래 그림은 CloudSQL 인스턴스를 생성할때, ON DEMAND 활성화 정책 + 사용량에 따른 청구 방식으로 설정하는 화면이다.




쉽게 설명하면, 서버에 요청이 없으면 자동으로 대기 상태로 들어가면서 데이타 저장 비용만 과금이 되고, 인스턴스 비용은 과금이 되지 않는다는 이야기이다.

이는 항상 서버가 돌아도 되지 않는 일 배치나 또는 개발 환경등에 유용하게 사용될 수 있다. 
물론 이렇게 인스턴스가 될때만 과금하게 하는 것은 수동으로 데이타를 백업 받고 인스턴스를 내렸다가 사용할때 인스턴스를 새로 올리고 데이타를 부어도 되고 또는 수동으로 일일이 인스턴스를 껐다 켰다 해도 유사한 효과를 볼 수 는 있지만, AWS의 경우 시간당 과금이기 때문에, 개발 환경처럼 수분을 쓰고 마는 환경에서는 분당 과금인 CloudSQL에 비해서 금액 절약효과를 보기가 어렵고, 무엇보다 귀찮다.

아래는 20GB 용량을 하루에 4시간 정도 D32 인스턴스로(32GB 메모리 머신) , 300만 IO가 발생하는 일배치를 돌리는 시나리오에서 추가 IO가 없다고 가정할때 가격 시뮬레이션 한 케이스인데 Package plan을 이용할 경우 약 한달에 1116$, Pay per use plan을 사용할 경우 약 338$ 로 약 3.4배 정도의 가격 차이가 있는 것을 확인할 수 있다. 
(참고, Package Plan의 D32 인스턴스는 300만 IO까지는 무료이며, Pay Per Plan의 경우 무조건 100만건당 0.1$가 과금된다. 아래 계산 결과는 Pay per use는 모든 IO 가 과금이 되기 때문에 # of IO를 300만으로 입력하였고, Package Plan은 무료 IO를 넘는 부분에 대해서만 입력하기 때문에, 현재 계산에서 300만 IO는 D32 인스턴스 크기에서는 무료이기 때문에 별도 입력하지 않았다.)




1세대의  Pay per use plan을 사용하면 딱 트렌젝션을 돌릴때만 분당 과금을 할 수 있기 때문에 가격이 저렴해진다.
단 주의 할점은 오랜 시간 서버를 돌리는 경우에는 Pay per use plan 보다는 당연히 Package plan이 저렴하기 때문에 일정 시간 이상 인스턴스를 사용하는 경우는 Pay per use 보다는 package plan을 사용하기 바란다.

가격 정책에 대한 자세한 내용은 https://cloud.google.com/sql/pricing 에 있다. 
어떤 정책이 유리한지는 가격 시뮬레이션을 해보면 되는데 시뮬레이션용 계산기는 https://cloud.google.com/products/calculator/ 를 사용하기 바란다.



저작자 표시 비영리
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

구글 CloudSQL(MySQL) 접속하기

조대협 (http://bcho.tistory.com)


개요 


구글 클라우드에서는 MySQL의 매니지드 서비스 형태로 CloudSQL 서비스를 제공한다. 

이 글에서는 CloudSQL을 서버에서 접근하는 방법과, 일반적인 MySQL 클라이언트로 접근하는 방법에 대해서 설명하고자 한다.


몇가지 배경


CloudSQL은 매니지드 MySQL서비스이다. 아마존에 RDS서비스와 같다고 보면 되는데 현재는 1세대를 서비스하고 있고, 곧 2세대가 서비스 예정이다.

1세대는 500GB까지의 용량까지 지원하고 있지만 2세대는 10테라까지 지원을 한다.

현재 지원되는 MySQL버전은 5.5와 5.6 지원하고, 내부 엔진으로는  InnoDB만을 제공한다.


2 세대에 기대되는 기능으로는 On Prem(호스팅 센터에 있는) MySQL과 복제 구성이 가능하다. On Prem에 있는 서버를 마스터로 할 수 도 있고, 반대로 마스터를 CloudSQL로 사용하고 읽기 노드를 On Prem에 구성하는 등 다양한 하이브리드 구성이 가능하다. (기대되는 부분)


자동 백업, 확장을 위한 읽기 전용 노드 (Read replica)등 필수적인 기능을 제공하고 있다.


연결 방식


CloudSQL은 RDS와는 다르게 private ip (10.x.xx)를 아직 지원하지 않고 public ip만을 지원한다. 그래서 서버에 접근하려면 이 public ip를 통해서 접근하면 된다. 보안을 위한 접근 통제 방법으로 특정 IP 주소에서 들어오는 트래픽만을 받아드리도록 설정이 가능하다.


또는 PaaS서비스인 구글 앱앤진을 사용하는 경우에는 구글 앱앤진의 인스턴스나 그룹 단위로 접근 통제가 가능하다.

다음 그림은 콘솔상에서 접근이 가능한 IP 주소를 지정하는 화면이다.



MySQL 클라이언트를 이용하여 접속을 할때 mysqlclient를 이용하여 직접 ip등을 입력하고 접속을해도 되지만 이 경우에는 CloudSQL에서 Ip를 허용해줘야 하기 때문에 개발이나 기타 운영 환경등에서 IP 주소가 바뀌면 그때 마다 설정을 해줘야 하기 때문에 불편할 수 있다.

이를 조금 더 편하게 하려면 mysqlclient를 사용하지 않고 구글에서 제공하는 "gcloud" 라는 도구를 이용하면, 별도로 접속 IP를 열지 않더라도 접속이 가능하다.

접속 방법은 먼저 gcloud  명령어를 인스톨 한 후에 


$ gcloud config set project [클라우드 프로젝트 이름]

$ gcloud beta sql connect [CloudSQL 인스턴스이름] —user=root

(여기서 --user=root 에서 root 사용자는 MySQL 인스턴스내의 사용자이다)


으로 접속하면 MySQL 클라이언트와 동일한 툴로 접속이 된다.


gcloud 툴킷을 이용한 자세한 접속 방법은 https://cloud.google.com/sql/docs/mysql-client#connect-ssl 를 참고하기 바란다.


참고

  • Toad, MySQL Workbench 등에서 안전하게 연결하는 방법 https://cloud.google.com/sql/docs/admin-tools#squirrel


저작자 표시 비영리
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

Heroku에서 Metrics 메뉴를 이용하여 애플리케이션 모니터링 하기


조대협 (http://bcho.tistory.com)


heroku에서는 Metrics이라는 메뉴를 통해서 기본적인 시스템 모니터링을 지원한다. 기본 지원 항목으로는

응답시간 (Response time), 메모리 사용률 (Memory Usage), 분당 처리량 (Throughput-TPM), CPU 사용률 (Dyno Load)을 볼 수 있다. 이 항목들은 Heroku 대쉬보드에서 모니터링하고자 하는 애플리케이션을 선택한 후, 상단의 Metrics라는 탭을 선택하면 된다.  

 

아래는 Metrics 메뉴를 통해서 helloherokuterry 애플리케이션의 주요 지표를 모니터링 한 화면이다.



한가지 주의할점은 Metrics 모니터링 기능은 무료 dyno로는 사용이 불가능하며 최소 standard-1x dyno 부터 지원이 된다.

저작자 표시 비영리
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

Heroku에서 logentries를 이용하여 node.js 로그 모니터링 하기


조대협 (http://bcho.tistory.com)

 

Heroku에서 제공하는 로깅은 heroku logs –tail 명령을 이용해서 모니터링 할 수 있는데, 이 로그의 경우 최대 1500줄만 저장을 지원한다. 실제 운영 환경에서 1500줄의 로그란 부족해도 많이 부족한 양이다. 그래서 추가적인 서비스를 이용하는 것이 좋은데, 많은 로깅 서비스가 있지만, 간단하게 사용할 수 있는 로깅 서비스로 logentries 라는 서비스가 있다.

 



Figure 1 http://www.logentries.com

 

무료로 사용이 가능하고, 무료 사용시 최대 7일간의 로그를 저장해주고, 일 최대 33M 까지 로그를 저장할 수 있다.

가장 저렴한 Entry 플랜은 한달에 9$로 일 133M 로그를 최대 7일간 저장하고, 가장 비싼 Platium 플랜은 월 1399$로 일 최대 40GB의 로그를 최대 7일간 저장할 수 있게 해준다. (에러나 일반적인 시스템 로그라면, 왠만한 시스템이면 40GB정도면 충분하지 않나 싶다.)

 

그러면 앞서 작성하여 heroku에 배포한 node.js 애플리케이션에 이 logentires를 적용해 보자.

적용은 매우 간단하다. 명령창에서 간단하게 다음 명령을 실행하자

heroku addons:create logentries

 

명령을 실행하면 다음과 같이 logentries 가 설치되었다고 나온다.



Figure 2 logentries 설치

 

설치가 완료되었으면 이제 사용을 해보자. Heroku  대쉬 보드로 접속해서, 생성한 애플리케이션을 선택한다.



Figure 3 heroku dashboard에서 애플리케이션 선택

 

애플리케이션을 클릭해서 들어가면 하단 add-on 리스트에 logentries가 아래 그림과 같이 활성화가 되어 있는 것을 확인할 수 있다.



Figure 4 heroku 애플리케이션에서 add-onsLogentries가 설치된 화면

 

logentries를 클릭해서 들어가면, logentries를 이용한 로그 모니터링 화면이 나온다.

아래 그림과 같이 좌측에 “heroku”라는 Log set이 나오는데, 이를 클릭하고, 우측 상단에 “Live tail” 이라는 버튼을 누르면 현재 node.js의 로그를 실시간으로 보여준다. 실제로 해보면 heroku logs –tail 보다 약 1초 정도 지연이 발생한다.



Figure 5 logentries를 이용한 실시간 로그 모니터링

 

다음 화면은 node.js의 로그를 heroku logs –tail로 모니터링한 화면으로 위의 logentrieslive tail과 동일함을 확인할 수 있다.



Figure 6 heroku logs를 이용한 실시간 로그 모니터링

 

heroku 기본 로깅 시스템에 비해서 더 많은 로그를 볼 수 있는 것은 물론이고, 로그에 대한 검색이 가능하고, 특정 데이타를 기반으로 한 그래프등 다양한 기능을 지원한다.

저작자 표시 비영리
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

Heroku 스케일링 (scaling)에 대해서


조대협 (http://bcho.tistory.com)

 

스케일링이란, 더 큰 다이노(더 많은 CPU와 메모리)를 사용함으로써 각 다이노의 성능을 올리거나, 더 많은 다이노를 추가함으로써 여러 다이노로 부하를 분산해서 전체 성능을 올리는 방법을 이야기 한다.

 

더 큰 다이노를 사용하는 것을 수직 스케일링 (vertical scaling), 더 많은 다이노를 사용하는 것을 수평 스케일링 (horizontal scaling)이라고 한다.

 

그러면 Heroku에서 스케일링을 어떻게 하는지 알아보자

스케일링은 다음과 같이

 

heroku ps:scale 다이노타입=다이노개수:다이노크기

 

 지정하면 된다. 이 스케일링은 무료 티어에서는 사용이 불가능 하기 때문에, 과금을 위한 신용 카드 정보를 등록해야 한다. 대쉬보드에서 “Manage Account > Billing” 메뉴에서 아래와 같이 신용 카드 정보를 추가한다.

 



Figure 1 계정 정보에 신용카드 정보 추가

 

수직 스케일링

 

수직 스케일링에서 다이노의 크기를 늘리는 것을 스케일 업 (scale up), 줄이는 것을 스케일 다운 (scale down)이라고 한다.

현재 하나의 Free 타이의 웹 다이노가 돌고 있을 때, 이를 standard-1x 한개로 스케일 업을 하고자 하면

 

%heroku ps:scale web=1:standard-1x

 

로 하면 간단하게 스케일 업을 할 수 있다.

반대로 스케일 다운을 하려면 더 작은 다니오 타입을 지정하면 된다. 다음은 현재 다이노를 free 타입으로 스케일 다운 하는 명령어 이다.

 

%heroku ps:scale web=1:free

 

수평 스케일링

 

수평 스케일링에서 다이노를 추가 하는 것을 스케일 아웃, 다이노를 빼는 것을 스케일 인이라고 한다.

스케일 아웃과 인은 heroku ps:scale 명령에서 다이노의 개수만 조정해주면 된다.

 

%heroku ps:scale web=2:standard-1x

 

아래는 standard-1x 다이노 2개로 스케일 아웃을 한후 ps 명령을 이용하여 2개의 다니노가 기동된것을 확인 한후, 다시 1개의 free 다이노로 스케일인 & 다운을 한 화면이다.

 



Figure 2 스케일링 테스트 결과

 

스케일 아웃이나 스케일 인이 되면, 자동으로 웹 로드밸런서에 붙어서 부하가 분산된다.

참고로, freehobby의 경우에는 1개의 웹 다이노만 사용이 가능하다. (스케일 아웃이 불가능하다)

 

제약 사항


스케일링에는 몇가지 제약 사항이 있다.

·         free hobby 1개의 웹다니오만 사용이 가능하기 때문에, 스케일 아웃이 불가능하다.

·         같은 타입의 다이노는 같은 크기의 다이노만을 사용해야 한다. 즉 웹은 standard-1x를 사용하면 모든 웹 다이노는 standard-1x만 사용해야 한다. Freehobby, standard-2x 등은 섞어 쓸 수 없다.

·         전체 다이노를 합쳐서 최대 100개의 다이노까지만 스케일링이 가능하다. (고객지원센터에 연락하면 이 한계를 풀 수 있다.)

·         perofmance 다이노의 경우 10개만 사용이 가능하다.

 

과금 방식


헤로쿠의 과금 방식은 초당 과금이다. (아마존의 경우 시간당 과금으로 1시간 1초를 사용해도 2시간 사용분이 과금된다.)  이 부분은 참 좋은듯.

 

오토 스케일링


 서버 부하에 따라서 자동으로 다이노를 늘리고 줄여주는 오토 스케일링은 헤로쿠에서 지원하지 않고, 추가 add-on을 설치해야 한다. 주로 사용되는 오토스케일링 add-on으로 adept (https://www.adeptscale.com/) hirefire (https://www.hirefire.io/) 등이 있다.

 

저작자 표시 비영리
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

Heroku 클라우드에 node.js 애플리이션을 배포하기


조대협 (http://bcho.tistory.com)



가장 빠르게 이해하는 방법은 직접 해보는 것이다. Heorku 클라우드에 대한 이해를 위해서 express를 이용해 구현된 node.js 애플리케이션을 직접 배포해서 실행해보자

이 예제는 node.js 4.3.1 버전과 express 4.13.4 버전을 기준으로 작성되었다.


Heroku 가입

Heroku사용을 위해서 Heroku계정을 만들자. http://www.heroku.com 에 접속해서 Sign up 메뉴로 들어가면, 간단하게 이름과 이메일 정도의 정보만 넣으면 간단하게 계정을 만들 수 있다.



Figure 1 Heroku 가입 화면


다른 클라우드의 경우 향후 유료 사용을 위해서 회원 가입시 처음부터 신용카드 정보를 요구 하는 경우가 있어서 신용카드가 없는 학생등은 가입이 안되는 경우가 있지만, Heroku의 경우 별다른 부담없이 무료로 계정을 생성해서 사용할 수 있다. 지금부터 진행할 예제는 무료 계정에서 한개의 웹 서버를 기동하여 node.js 애플리케이션을 기동하는 예제로 별도의 비용이 필요없다.


계정이 생성되었으면 Heroku 웹 콘솔에 로그인해보자




Figure 2 Heroku 대쉬 보드


첫 대쉬보드에서는 각 개발플랫폼에서 개발을 시작하는 방법에 대한 가이드를 제공한다.


node.js 애플리케이션 준비


Heroku 계정이 준비되었으면, Heroku에 배포할 node.js 애플리케이션을 준비해보자. 

“Hello Heroku”를 출력하는 간단한 node.js 애플리케이션을 작성하자.

다음과 같이 express generator를 이용해서 node.js 애플리케이션을 생성한다.


% express -–session --ejs --css stylus helloheroku

% cd helloheroku

% npm install


애플리케이션을 설치한 후에, 애플리케이션 디렉토리로 들어가서 npm install 명령을 이용하여, 애플리케이션에서 사용되는 의존성을 가지고 있는 모듈들을 설치한다.


다음으로 /routes/index.js를 다음과 같이 수정한다.


var express = require('express');

var router = express.Router();


/* GET home page. */

router.get('/', function(req, res, next) {

  res.render('index', { title: 'Heroku' });

  console.log(' hello heroku ');

});


module.exports = router;


Heroku에 배포하는 node.js 애플리케이션을 개발할때, 주의할점 중의 하나가 package.json이다.

보통 로컬 개발환경에 npm 패키지들이 이미 설치 되어 있는 경우 실행이 제대로 되고, 문제가 없기 때문에, package.json에 필요한 모듈에 대한 정의를 빼먹는 경우가 많다. Heroku에 애플리케이션을 배포할때는 의존 패키지들이 설치되어 있지 않기 때문에 이를 설치 해야 하는데,  Heroku는 자동으로 package.json에 정의된 npm 모듈들을 설치해 준다. 반드시 배포전에 package.json에 필요한 모듈들이 제대로 정의되었는지를 확인해보자


소스코드가 준비되었으면 Procfile 이라는 것을 준비해야 한다. 위에서 만든 애플리케이션의 루트”/” 디렉토리에 다음과 같은 내용으로 Procfile을 작성하자.


web: node ./bin/www


Procfile은 애플리케이션을 Heorku에 배포 해서 실행할때, Heroku 클라우드가 맨 처음 실행하는 명령어를 지정하는 파일이다. 보통 애플리케이션을 기동하기 위한 명령어를 기술한다.

앞서 작성한 Procfile을 보면, “web:” 이라고 기술하였는데, 배포하고자 하는 애플리케이션이 웹 애플리케이션임을 정의한다. web 타입의 애플리케이션만 Heroku의 내부 HTTP 로드밸런서에 연결이 되서 웹 요청을 받을 수 있다.

다음으로 “node ./bin/www” 라고 지정하였는데, node.js 애플리케이션을 기동하기 위한 명령어이다. 우리가 작성한 애플리케이션은 express애플리케이션으로 기동 로직이 ./bin/www 에 들어 있다.


추후에 추가로 설명하겠지만, node.js는 모니터링등을 위해서 forever나 pm2와 같은 추가적인 도구를 이용해서 기동을 하는 경우가 있다. 실행을 할때 forever ./bin/www 식으로 실행하는데, Heroku에서 실행하려면 다음과 같이 실행하면 된다.


web: ./node_modules/.bin/forever ./bin/www


이제 배포를 위한 node.js 애플리케이션 준비가 끝났다. Heorku에 배포해보자.


Heroku 툴벳 설치


계정이 준비되고 애플리케이션 개발이 끝났으면, Heroku에 접속해서 배포를 진행해야 한다. Heroku는 툴벳이라는 커멘트라인 인터페이스 (CLI : Command line interface)를 이용해서 사용한다. 

툴벳은 https://toolbelt.heroku.com/ 에서 다운로드 받을 수 있다.




Figure 3 Heroku 툴벳 다운로드 페이지


툴벳을 인스톨했으면 실행해보자. 프롬프트 상에서 

%heroku 

명령어를 수행하면 간단한 사용법이 나온다.

이 툴벳을 통해서 Heroku에 명령을 내리기 위해서는 자신의 계정으로 로그인을 해야 한다. 로그인은 “heroku login”이라는 명령을 사용해서, Heroku 가입시 생성한 계정으로 로그인을 하면 된다.




Figure 4 툴벳에서 Heroku 로그인


Heroku 배포 준비


로그인이 끝났으면, Heroku내에 앱을 생성한다. Heroku의 앱은 애플리케이션 단위로, 이 앱단위로 배포를 하고 운영을 하게 된다. 

앱 생성 방법은 다음과 같다.


%heroku app:create {앱이름}


이 예제에서는 helloherokuterry 라는 이름의 앱을 생성할것이다.

이 앱 이름은 Heroku 클라우드에 걸쳐서 유일한 이름으로 사용을 해야 하기 때문에, 위의 이름으로 앱을 생성하고자 하면 이미 저자가 해당 이름을 사용하고 있기 때문에, 아마도 에러가 날것이다. 다른 적절한 이름을 이용해서 앱을 생성하자


아래는 helloherokuterry 라는 이름의 앱을 생성하고, “heroku apps” 를 이용하여 현재 생성된 앱 리스트를 확인해서 helloherokuterry 라는 앱이 제대로 생성이 되었는지 확인 하는 화면이다.




Figure 5 Heroku에 애플리케이션을 생성하는 화면


만약에 잘못 앱을 생성하였으면 다음 명령어를 이용해서 앱을 삭제할 수 있다.


%heroku app:delete {앱이름}


앱이 생성되었으면, 작성한 애플리케이션을 배포해야 하는데, heroku의 코드 배포는 git 소스코드 관리 시스템을 사용한다.

앱 디렉토리에서 git 리포지토리를 생성한다.

%git init .

다음, 작성한 애플리케이션들을 git에 추가한다.

%git add *

추가된 애플리케이션 코드들을 commit 한다.

%git commit


이제 로컬 git 리파지토리에 애플리케이션 코드들이 저장되었다. 이 코드들을 Heroku에 전송하자.

git에 Heroku 클라우드 상의 git 저장소를 리모트 저장소로 지정해야 한다.

Heroku의 git 저장소를 리모트 저장소로 지정하는 방법은 다음과 같다. 


%heroku git:remote -a {앱이름}


여기서는 애플리케이션의 이름이 helloherokuterry이기 때문에 다음과 같이 리모트 저장소를 추가하겠다.

% heroku git:remote –a helloherokuterry


heroku의 git 리파지토리가 리모트 저장소로 지정되었다.

아래 명령어를 이용해서 로컬에 저장된 코드를 heroku로 올려보자


%git push heroku master


명령어를 실행하면 소스코드를 Heroku에 배포 하는 것을 확인할 수 있다.




Figure 6 git를 이용하여 Heroku에 앱을 배포하는 화면


배포는 단순하게 소스 코드만을 올리는 것이 아니라 올라간 소스코드를 확인해서, package.json에 지정된 의존성 있는 모듈들을 설치 한다. 아울러 환경변수를 세팅한다.

Heroku의 경우 node.js에 대해서 디폴트 환경 변수를 정의하는데

NPM과 node.js에 대한 환경 변수를 다음과 같이 설정한다. 모드를 운영 모드로 설정하는 부분이다.


remote:        NPM_CONFIG_LOGLEVEL=error

remote:        NPM_CONFIG_PRODUCTION=true

remote:        NODE_ENV=production

remote:        NODE_MODULES_CACHE=true


배포에서 git를 사용하였는데, 혹시나 git에 대해 생소한 분들을 위해서 간략하게 배포 흐름을 정리하고 넘어가자.  




Figure 7 git를 이용한 Heroku 배포 개념도


개발환경에서 작성된 소스코드는 git의 로컬 저장소 (Local repository)로 저장되기전에 git add명령어를 이용하여 스테이징 단계 (stage)로 이동된다. 소스를 저장소에 저장하기 전 단계로, 전체 코드 중에서 어떤 파일들을 저장할지를 선택하고 검토하는 일종의 중간단계이다.

스테이징이 끝나면, git commit 명령을 이용하여 로컬 저장소 즉 내 PC에 있는 git 저장소에 소스 코드를 저장한다.

다음 이 코드를 원격에 있는 Heroku의 git 저장소로 전송을 해야 하는데, 이를 푸쉬(push)라고 한다. git push 명령어를 이용해서 실행하며, 코드가 Heroku의 git 저장소에 저장이 되면, 기동을 하기 위한 환경 변수 설정이나 npm 모듈들을 설치 하는 작업을 수행한다.


이제 애플리케이션 실행을 위한 모든 준비가 끝났다. 배포한 애플리케이션을 기동해 보자


서비스 기동 및 모니터링


서버의 기동은 Heroku에서 web dyno수를 0에서 1로 늘려주면 된다.


%heroku ps:scale web=1


서버가 기동된것을 확인하였으면 웹으로 접속해서 애플리케이션이 제대로 동작하고 있음을 확인하자.

Heroku app의 URL은 http://{heroku app 이름}.herokuapp.com 이다.

우리가 만든 예제는 helloherokuterry라는 앱 이름을 사용했기 때문에, https://helloherokuterry.herokuapp.com/ 가 접속 URL이 된다

또는 간단하게 명령 프롬프트 창 내에서 heroku open 이라는 명령어를 사용하면 해당 URL을 브라우져를 열어서 자동으로 열어준다.


%heroku open




Figure 8 Heroku open 명령어를 이용하여 기동중인 웹사이트를 오픈




Figure 9 Hello Heroku 실행 화면


드디어 Heroku에 node.js 애플리케이션을 배포하고 기동시켰다.

애플리케이션의 구동 상태와 로그를 확인해보자

현재 몇개의 dyno 가 구동되고 있는지를 확인하려면 다음 명령어를 실행하면 된다.


%heroku ps




Figure 10 ps 명령어를 이용하여 동작중인 서버를 확인


현재 web 타입의 1개의 dyno 가 실행되고 있음을 확인할 수 있다.

다음은 애플리케이션 로그를 확인해보자


%heroku logs –tail


이 명령어는 node.js에서 나오는 로그를 모니터링 할 수 있게 해준다



Figure 11 node.js의 로그를 확인


위의 로그를 보면 03:11:32에 서버가 기동 되었음을 확인할 수 있고

03:11:34초에 http://helloherokuterry.herokuapp.com/  URL이 호출되었음을 확인할 수 있다.

그리고 그 아래 애플리케이션에서 console.log(‘hello heroku’)로 출력한 로그도 같이 출력됨을 확인할 수 있다.


테스트가 끝났으면 실행중인 서버를 내려보자.

서버를 내리는 방법은 ps:scale 명령어를 이용하여 web dyno수를 1에서 0으로 변경해주면 된다

%heroku ps:scale web=0

명령을 실행하고 ps 명령어를 이용해서 현재 기동중인 dyno 수를 확인해보면, 아무 서버도 기동되지 않음을 확인할 수 있다.



Figure 12 동작중인 dyno를 종료하는 화면


로그에서도 아래와 같이 dyno를 끄는 로그를 확인할 수 있다.



Figure 13 dyno 종료 로그를 확인



저작자 표시 비영리
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

다르게 생각해볼만한 클라우드 컴퓨팅 활용 전략


조대협 (http://bcho.tistory.com)


근래에 스타트업 기반의 빠른 속도의 개발을 경험하고, 클라우드 컴퓨팅 도입 전략에 대해서 고민할 기회가 생겨서 여러 자료를 검토하던중에 퍼블릭 클라우드 도입 전략에 대해서 기존과 다른 접근 방식이 필요하다고 생각되어 그 내용을 정리합니다.


특정 벤더의 의존성 배제


퍼블릭 클라우드 하면 거의 공식 처럼 AWS 클라우드가 소위 말해서 갑이었으나, 근래에 들어서 구글이나 마이크로소프트가 큰 딜을 잡아나가면서 약간씩 구도가 바뀌고 있는 형상이다.  

 특히 구글의 Spotify와, Quizlet의 사례를 보면 구글 사용사례이기 때문에 구글이 좋다는 이야기지만, 내용을 디테일하게 살펴보면 꽤나 재미 있는 인사이트를 얻을 수 있다.

  • Quizlet의 사례 https://quizlet.com/blog/whats-the-best-cloud-probably-gcp
  • Spotify의 사례 https://news.spotify.com/us/2016/02/23/announcing-spotify-infrastructures-googley-future/




Quizlet의 사례는 가격과 성능에 대한 이야기인데 내용을 요약하면 비슷한 VM이면 구글이 더 싸고 성능 (CPU,메모리, 네트워크)이 훨씬 좋다는 것이다. 아마존은 다양한 가격정책으로 다양한 컴퓨팅 파워를 제공하지만 그만큼 세밀한 가격 정책에 의해서, 높은 성능을 내려면 그만큼 추가 상품을 사야 하는데 비해서, 구글의 경우에는 기본 VM들의 네트워크가 IO 성능들이 높다는 것이다.


여기서 구글의 우수성을 보는것 보다, 이게 왜 좋은지에 대한 인사이트를 얻어야 하는데, 아마존은 다른 클라우드 벤더에 비해서 포트폴리오가 매우 다양하다. 인코딩, IAM, 하드웨어 기반의 키 보안 기술 등 그래서 한번 특정 클라우드에 들어가면 다른 클라우드로 옮기기가 쉽지 않은게 사실인데, 잘 생각해보면, 근래의 클라우드 기반의 아키텍쳐는 다음과 같은 트렌드를 갖는다.


VM위에 직접 설치해서 사용


EC2와 같은 VM만 있으면 그위에 직접 소프트웨어를 설치해서 운영을 하면 된다는 것이다. 아마존에서 제공하는 RDS나 RedShift 와 같은 서비스도 결국은 MySQL이나 Postgres와 같은 오픈 소스 기반이고 대부분이 오픈소스나 기존 제품을 기반으로 되어있기 때문에 교체가 가능하다는 것이다. 강한 기술조직을 가지고 있는 기업의 경우 직접 이러한 제품들을 설치 및 운영이 가능하기 때문에 특정 벤더에 Lock in이 되는것을 최소화할 수 있다.

단 이런 소프트웨어를 설치해서 사용하기 위해서는 VM 자체의 성능과 가격이 중요해진다. 네트워크나 디스크 IO의 속도나 GPU 지원 여부등이 중요한 판단 포인트로 작용을 하게 된다.


즉 이 이야기는 EC2와 같은 컴퓨팅과 S3와 같은 스토리지와 같은 필수 서비스만 제공한다면 어떤 클라우드가 되던지 크게 문제가 없다는 것으로 생각할 수 있다.


매니지드 서비스의 분리


스타트업이나 또는 운영을 자동화하여 개발에 집중하는 조직의 경우 RDS와 같은 클라우드 서비스 제공자가 운영을 대신 해주는 managed 서비스를 이용하는 것을 선호하는데,  근래에 들어서 매니지드 서비스를 전문적으로 제공하는 업체들이 많아졌다. mongoDB나 Redis와 같은 NoSQL의 솔루션을 매니지드 서비스의 형태로 제공하는 compose.io를 보면, 이러한 서비스를 AWS, IBM Softlayer, Digital Ocean등의 몇몇 클라우드 (IaaS)위에서 제공한다는 것이다. 


내가 어떤 IaaS를 사용하건간에, 전문화된 업체를 통해서 특정 솔루션을 매니지드 서비스 형태로 사용이 가능하다. 또 다른 사례중의 하나는 PaaS 플랫폼으로 유명한 Heroku의 경우인데, Heroku는 PaaS 이지만, 사실상 아래 인프라는 AWS로 되어 있다. 현재는 AWS만 지원 하지만, 클라우드 시장이 커감에 따라서 다른 인프라를 충분히 지원이 가능하다고 볼 수 있다. Heroku의 경우 아마존 회사가 아니라 Salesforce.com에 인수되었기 때문에 아마존을 꼭 사용해야 하는 이유가 없다, Cloud Foundary라는 오픈소스를 이용해서 구현이 되었기 때문에 VM만 있다면 큰 문제 없이 다른 인프라에 배포가 가능하다.  (Heroku는 CF를 기반으로 하지 않는다. IBM의 Bluemix가 CF 기반임)





정리해서 말하자면 인프라 클라우드 사업자가 있고 그 위에 매니지드 서비스를 제공하는 전문 사업자들이 점점 더 늘어날 것이고, 이 사업자들은 인프라에 대한 종속성이 없기 때문에, 인프라 클라우드의 차별화가 그다지 크지 않아질 수 있어서 특정 벤더에 대한 종속성이 약해질것이라고 본다.


오픈 API를 통해서 하이브리드 클라우드 기반의 서비스 분산 배치


오픈 소스로 대체가 불가능한 특별한 서비스들이 있는데, AI나 빅데이타에 관련된 것들이 그러하다, 마이크로 소프트나 구글의 경우 머신 러닝 기능을 OPEN API 형태로 제공하고 있고, 알고리즘이 자사의 노하우가 들어가 있는 형태이기 때문에, 다른 오픈소스로 대처가 어렵다 물론 Spark ML과 같은 라이브러리등이 있기는 하지만 개발에 들어가는 노력이나 알고리즘의 품질이 차이가 많이 난다. 얼마전에 구글이 영상 인식을 가능하게 해주는 VISION API를 발표하였고, 마이크로 소프트도 이 보다 많은 기능을 가지고 있는 영상 인식 API를 발표하였다. 흥미로운 점은 이것들이 API로 서비스가 된다는 것이고 이말인 즉, 원격에서 호출이 가능하다는 이야기다. 

이런 API의 특성상 처리 시간이 호출시간에 비해서(네트워크 시간) 길기 때문에, 리모트로 호출한다고 해서 아주 크게 문제가 되지 않고, 근래의 아키텍쳐 특성상 MSA(마이크로 서비스 아키텍쳐)와 같은 분산 서비스 아키텍쳐가 주류를 이루고 있기 때문에, 메인 시스템과 이러한 API 시스템이 꼭 같은 위치에 있지 않더라도 크게 문제가 없다.


클라우드 서비스 제공자 선택은 가격 보다는 부가 서비스와 기술 지원이 관건


Spotify에 사례를 보면 재미있는 것중에 하나가 구글 클라우드를 선택한 주요 이유가 빅데이타 플랫폼과 기술 지원이다.

 Spotify 의 블로그 내용을 보면 가격은 크게 의사 결정 요소로 작용하지 않았다는 것이다. 실제로 요즘 클라우드 시장이 과열이 되면서 디스카운트가 많이 들어가고 있고, 특히 소위 잘나가는 벤더와 잘나가지 못하는 벤더 (조이언트나 랙스페이드 등)가 갈려지면서, 잘 나가지 못하는 벤더들이 레퍼런스를 잡기 위해서 파격적인 할인에 나서고 있다. 클라우드 컴퓨팅의 인프라 가격은 규모의 경제 측면에서 큰 벤더들이 계속해서 시장을 잠식해 나갈 것이고 자체 기술 개발을 통해서 점점 더 가격을 낮춰갈것이다. 아마존의 경우에도 자사의 데이타 센터에 최적화된 CPU를 인텔에 주문했을정도로 이제 인프라 최적화는 점점 더 가속화되어가고 있고, ARM CPU 기반의 서버도 시장에 조금씩 나오는 만큼 가격 경쟁은 가속화 되리라 본다. 특히 통계를 보면 클라우드 가격은 매년 13% 정도씩 감소하고 있다고 한다.


그러면 Spotify가 구글 클라우드 플랫폼을 선택한 이유는 무엇일까?

빅데이타 플랫폼에서 찾을 수 있다. 구글이 경쟁사 대비 더 좋은 빅데이타 플랫폼 서비스를 제공하고 있다는 것인데, AWS의 빅데이타 플랫폼의 하둡이나 스파크, RedShift와 같은 기존의 오픈 소스를 매니지스 서비스로 제공하는 것이 주요 전략이라면, (물론 Dynamo처럼 직접 원천 기술을 만들어서 제공하는 서비스도 있다.) 구글은 기술의 종가답게 이러한 기술들에 대해서 강점을 가지고 있다고 Spotify 블로그에서 전하고 있다.


즉 앞에서 설명한것과 같이 VM 서비스는 평준화 되어 크게 비교 포인트가 되지 못할 것이며, 부가 서비스들 중에서 AI나 빅데이타 영역과 같이 특화되어 대체가 어려운 서비스를 가지고 있는 업체가 강점을 가지게 될것이다.


아울러 기술 지원 부분은 기술 도입에 있어서 중요한데, AWS의 경우 일주일이 멀다하고 계속해서 신기술과 업데이트가 발표되고 있다. 이러한 상황에서 실무 입장에서 새로운 기술을 일일이 찾아보고 자사의 시스템을 클라우드 서비스 제공자에 최적화 하는데는 많은 공부가 필요하고 서비스 제공자에게 서비스 개선등을 요청하기 위해서 원할한 커뮤니케이션 채널이 필요하다. 이를 흔히 프리세일즈(물건을 팔기전에 기술적으로 기술을 설명해주는)와 포스트 세일즈(물건을 판후에, 잘 사용할 수 있도록 지원하는)라고 하는데, 클라우드는 특성상 Self Service의 개념을 가지고 직접 배워서 직접 사용한다는 개념인데, 그러기에는 기술의 속도가 너무 빨라서 이에 대한 지원이 필요하다는 것이다. 실제로 엔터프라이즈 시장에서 성공했던 오라클이나 IBM과 같은 공룡들도 많은 매출이 제품을 판 후에 구현을 도와주는 포스트 세일즈에서 발생을 하였고, 프리세일즈 과정에도 많은 리소스를 투여했던 것이 사실이다.


아직은 클라우드 서비스 제공자의 프리/포스트 세일즈가 강하지는 않지만 (있기는 있다). 이쪽이 성장하면서 좋은 프리/포스트 세일즈 조직을 가진쪽이 비지니스 딜에 좋은 포지션을 가지게 될것이라고 생각해본다.


하이브리드 클라우드 전략


기업의 클라우드 전략을 보면 크게 두가지 갈래로 나뉘어 지는데, 자체 데이타 센터 구축 전략과 클라우드 활용 전략이다.

페이스북과 같은 경우 자체 클라우드를 사용하고, 애플의 경우에도 자체 데이타 센터를 구축하고 있는 것으로 알려지고 있다. http://fortune.com/2016/02/02/apple-data-center-move/

페이스북이나 구글같은 전통적인 테크 기업이면서 서비스 볼륨이 일정 규모 이상되는 경우는 규모의 경제상의 경제상에서 자체 데이타 센터를 구축하고, 자체 서비스에 맞는 인프라를 최적화 해가는 방향으로 집중을 하고 있다. 


반면 Netflix나 Spotify와 같은 서비스 기업은 서비스 개발에 집중을 하고, 인프라는 퍼블릭 클라우드를 사용하는 형태로 방향을 잡아가고 있다. 아무리 인력을 투여해도 퍼블릭 클라우드에서 개발하는 신규 기능을 따라 잡기도 힘들뿐더러, 비용 최적화 면에서도 규모의 경제 특성상 퍼블릭 클라우드가 유리하다는 판단하에서다.





그러면 퍼블릭 클라우드와, 자체 데이타 센터 무엇이 정답일까? 사실은 잘 모르겠다. 

하나 힌트를 얻자면, 애플의 클라우드 전략에서 살펴볼 수 있는데, 애플은 규모의 경제면에서 자체 클라우드를 갖출 정도로 큰 iCloud 서비스를 사용하고 있지만, 자체 클라우드 전략의 이면에서는 데이타 보안에 대한 부분이 있다. 고객의 중요 데이타를 타사의 클라우드에 넣는 것이 계속해서 부담이 되어 왔다. 


그렇다면, 중요 데이타나 중요 시스템은 자사의 클라우드에서 서비스하고, 다른 서비스나 또는 모자른 자원은 퍼블릭 클라우드를 사용하는 하이브리드 클라우드 전략을 갖추지 않을까 조심스럽게 생각해본다.


근래에 얻은 인사이트를 기록해놓고자 정리를 하였지만, 클라우드 컴퓨팅은 이제 거의 필수제가 되어가는것 같다. 특히나 구글,MS,아마존과 같이 규모의 경제를 앞세운 거대 기업들이 이 주도권을 잡아가면서 다른 사업자들은 힘을 잃어가면서 대형 서비스 제공자만 살아 남을것으로 보이고, Digital Ocean과 같은 niche vendor (특정 도메인에 선택과 집중을 통해서 가치를 창출해나가는)들은 특화된 서비스로 특화된 시장을 열어 나갈것이라고 보인다.


서비스 전략이나 시스템 아키텍쳐 설계도 이러한 클라우드 벤더의 변화에 맞춰서 다양화를 해나가야 하지 않을까?

예전 같으면 AWS를 깔고 시스템을 디자인 했다면, 요즘에 다시 시스템을 디자인 한다면 One of IaaS 서비스 + Compose.IO 와 같은 매니지스 서비스 기반의 설계가 조금 더 실용적이 아닐까 생각해본다.

저작자 표시 비영리
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

분산 대용량 큐-Apache Kafka에 대한 검토 내용 정리


실시간 빅데이타 분석 아키텍쳐를 검토하다가 아파치 스톰을 보다보니, 실시간 데이타 스트림은 큐를 이용해서 수집하는 경우가 많은데, 데이타의 양이 많다 보니 기존의 큐 솔루션으로는 한계가 있어서 분산 대용량 큐로 아파치 카프카(Kafka)가 많이 언급된다.

그래서, 아키텍쳐를 대략 보고, 실효성에 대해서 고민을 해봤는데, 큐의 기능은 기존의 JMS나 AMQP 기반의 RabbitMQ(데이타 기반 라우팅,페데레이션 기능등)등에 비해서는 많이 부족하지만 대용량 메세지를 지원할 수 있는 것이 가장 큰 특징이다. 특히 분산 환경에서 용량 뿐 아니라, 복사본을 다른 노드에 저장함으로써 노드 장애에 대한 장애 대응 성을 가지고 있기 때문에 용량에는 확실하게 강점을 보인다.

실제로 마이크로소프트 社의 엔지니어가 쓴 논문을 보면http://research.microsoft.com/en-us/um/people/srikanth/netdb11/netdb11papers/netdb11-final12.pdf

 


카프카의 경우 10만 TPS 이상의 성능을 RabbitMQ는 2만 TPS 정도의 성능을 내는 것으로 나와 있는데, 여기서 생각해볼 문제가 큐는 비동기 처리 솔루션이다. 즉 응답 시간에 그렇게 민감 하지 않다는 것이다.

그리고 일반적인 웹 시스템의 성능이 1500~2000 TPS (엔터프라이즈 시스템의 경우) 내외인 것이 일반적이기 때문에, Rabbit MQ의 2만 TPS의 성능은 충분하다고 볼 수 있지 않을까 한다.

물론 네이버나 해외의 대형 SNS 서비스의 경우에는 충분히 저정도의 용량이 필요하겠지만, 현재로써는 일반적인 시스템에서는 카프카의 용량과 성능은 약간 오버 디자인이 아닌가 하는 생각이 든다.


Rabbit MQ is scalable and




저작자 표시 비영리
신고
크리에이티브 커먼즈 라이선스
Creative Commons License


IBM 블루믹스 소개

 

PaaS

IBM 블루믹스는 IBM에서 제공하는 PaaS(Platform As A Service) 클라우드 서비스이다. 아마존과 같은 서비스가 VM을 제공하는 IaaS(Infra as a service)라면, 블루믹스는 node.js, Java와 같은 런타임을 미리 깔아놓고, 거기에 소스코드를 넣어서 돌리는 구조이다. IaaS의 경우 Linux Windows Server와 같은 OS VM 기반으로 제공하기 때문에 직접 미들웨어를 설치해서 사용해야 하지만, PaaS의 경우 이미 설치된 미들웨어 위에 코드만 돌리면되기 때문에, 아무래도 관리가 편리하다. 

그러면 왜 PaaS인가?

얼마전까지만 해도, 개발 트렌드의 중심은 기업체에서 개발하는 B2C서비스였다. 페이스북이나 네이버와 같은 서비스들이 대표적인데, B2C 서비스들은 대용량의 사용자를 커버해야 하고, 세세한 튜닝이나 설정 변경이 필요하고 다소 복잡한 아키텍쳐 구조를 가지기 때문에, 직접 인프라를 세팅하고 미들웨어를 설치하는 것이 오히려 유리했다. 그래서 IaaS를 많이 사용했는데,

근래에 들어서 개발의 중심이 모바일 앱이 되고 스타트업이 중심이 되면서, 적은 인원으로 빠르게 개발하고 관리할 수 있는 플랫폼이 필요하게되었고, 그로 인해서, Google App Engine이나, Heroku와 같은 PaaS 서비스가 각광받게 되었다.

IBM의 블루 믹스는?

지원 플랫폼

블루믹스는 APPS라는 개념을 가지고 있는데 이는 하나의 서비스로 보면된다. 이 안에, 서비스를 기동하기 위한 node.js mongodb와 같은 미들웨어를 묶어서 배포 할 수 있다. 아래 그림은 실제로 Terry라는 App mongodb 서비스를 추가하는 화면이다.



<App 에 추가할 서비스를 선택하는 화면>

매우 편하다. 클릭 몇번만으로, 내가 원하는 플랫폼을 쉽게 설치할 수 있다.

아래 화면은 node.js mongodb,redis로 구성된 서비스 환경이다.



<node.js mongodb,redis로 구성된 App>

현재 지원되는 플랫폼은 Java, Node.JS, Ruby on rials, Ruby Sinatra등을 지원한다.

부가 서비스 들은, 앞에서 언급한 mongodb, redis이외에도, rabbitMQ, IBM MQ, memcached,Work flow engine, Cloudant (CouchDB 계열) 등의 미들웨어 서비스 이외에도 Single Sign On, IOT (사물인터넷)등의 서비스를 부가로 지원한다. (꽤 많음)


코드 저장 및 반영

런타임에 적용되는 코드들은, 블루믹스에서 제공되는 git 저장소를 사용하면 된다.



<블루믹스 git 저장소>

재미있는 것중의 하나는, 웹브라우져상에서 코드 개발 에디터 기능 자체도 제공한다. 아래는 node.js의 코드를 웹 개발환경에서 편집하는 화면이다.



<블루믹스내에서 코드 편집하는 화면>

그리고, Atlassian JIRA와 같은 이슈 트랙킹 시스템을 제공한다. 공동 프로젝트를 관리하기 위해서는 태스크를 관리할 수 있는 시스템이 필요한데, 블루믹스에서는 IBM Jazz를 기반으로한 태스크 관리 시스템을 제공하고 있다. 개인적으로 예전에 Jazz를 사용했을때 상당히 무겁고 복잡하다는 느낌을 받았는데.. 어떤지는 조금 더 써봐야 알 수 있겠다.



<Jazz를 이용한 Task 정의 화면>

블루믹스는 앞에서 본것과 같이 서비스를 제공하기 위한 플랫폼만을 제공하는 것이 아니라, 형상관리,태스크 관리 및 빌드/배포 까지 자동화한 ALM (Application Life cycle management) End2End 기능을 제공한다.


서비스 관리

아래 화면은 node.js의 인스턴스 수를 조정하는 화면인데, 정말 쉽다. 아래 인스턴스 개수 숫자를 올려주면, 그만큼의 인스턴스가 가동되고, 각 인스턴스별 메모리양을 설정할 수 있다.



<그림. Node.js의 인스턴스 수를 조정하는 화면>

좀 특이한 점이 아마존처럼 VM단위로 과금을 하는게 아니라, 나한테 정해진 메모리 용량에 따라서, 이 안에서 인스턴스를 마음대로 만들 수 있는 개념인데, 구체적인 과금에 개념에 대해서는 향후에 조금 더 테스트를 해보고 올리도록 하겠다.

 

지금까지 간략하게나마 IBM PaaS 클라우드 블루믹스에 대해서 알아보았다. 특징은 무엇보다 쉽다!! 이다. 블루믹스 클라우드는 가입하면 무료 평가기간 동안 사용할 수 있으며 다른 클라우드 처럼 신용카드 번호를 넣지 않아도 된다. (URL : https://ace.ng.bluemix.net)

서버 개발 환경이 필요한 사람이 있으면 꼭 한번 사용해보기를 추천한다.

알림 : 본글은 IBM 블루믹스로 부터, 스폰서를 받는 글이 아닙니다!!! 혹시나 오해하지 마시기를..

저작자 표시
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

Cloud Front

조대협

Cloud Front CDN (Contents Delivery Network) 서비스 이다. 이미지나 동영상 같은 정적인 컨텐츠들을 서비스하는데, 서버가 있는 데이타 센터에서 서비스를 하게 되면, 네트워크 latency 때문에 성능이 저하가 되기 때문에, 전세계의 여러 개의 데이타 센터에 서버(이를 edge node 또는 edge server라고 함) 를 넣고, 클라이언트와 가까운 데이타 센터로 부터 컨텐츠를 제공하는 서비스 이다.

얼마나 많은 지역별 데이타 센터에 edge node를 설치하고 서비스를 제공하느냐, edge node의 네트워크 대역폭이나 용량은 충분하느냐가 서비스의 품질을 결정하는데, 세계적으로 Akamai Limelight 등의 업체가 유명하다.

아마존의 경우에도 얼마전부터 Cloud Front라는 이름으로 CDN 서비스를 제공하는데, 아마존 인프라와 융합되어 몇 가지 특별한 기능들을 제공한다.

아래 http://media.amazonwebservices.com/FS_WP_AWS_CDN_CloudFront.pdf 그림은 Frost & Sullivan 이라는 곳에서 작성한 CDN의 성능 비교표로, 아마존 Cloud Front가 다른 경쟁사에 비해서 성능적으로 우세거나 동등 수준으로 나온다. 물론 테스트 환경이나 시나리오에 따라 다소 다르겠지만, 아마존도 계속 해서 edge node를 증설하고 있는 상황이기 때문에 상용 수준의 CDN 성능을 제공할 수 있을 것이라고 본다.



 

Cloud Front 동작 시나리오

그럼 먼저 Cloud Front가 어떻게 작동하는 지를 살펴보도록 하자.



   Client가 웹사이트에 접속한다. 웹사이트를 www.terry.com이라고 하자.

   Client DNS 서버를 통해서 www.terry.com 의 주소를 look up 한다. 이 때, www.terry.com cloud front URL로 맵핑이 되어있어야 하는데, CNAME 레코드를 이용하여 www.terry.com을 해당 사이트에 대한 Cloud Front URL 로 맵핑 해놓는다. 여기서는 asdf.cloudfront.net이라고 가정하자

   Client asdf.cloundfront.net 의 주소를 다시 look up을 하는데, Route53에 의해서, Client와 가장 가까운 위치에 있는 Cloud Front edge node 주소를 리턴 받게 된다.

   Client는 리턴 받은 ip를 가지고 Cloud Front edge server로 접속을 한다.

   Cloud Front에는 URL에 따라서 resource의 위치를 RULE로 정해놓는데, 위의 예에서는 /image 디렉토리의 파일은 S3에 원본을 두고 Cloud Front에 캐슁하도록 하고, /css/ 아래 파일들은 원격지에 있는 (Amazon이 아닌) 서버에 두고 캐슁을 하도록 하였다. 그리고 *.jsp 파일은 캐슁 없이 직접 원본 서버로 가도록 하였다.

   만약에 /image/ /css/에 있는 파일을 Client가 요청 하였을 경우 edge node의 캐쉬를 체크해보고, 캐쉬에 내용이 없으면 원본 서버로 부터 파일을 읽어서 캐쉬에 저장한 후에, Client에 리턴한다. 캐쉬에 있을 경우에는 바로 리턴을 한다.

Origin Server

앞에서 설명한 시나리오에서 원본 파일이 저장되는 곳을 Origin Server라고 한다.

Origin Server AmazonS3 bucket이나 EC2 인스턴스 또는 Amazon 밖의 서버가 될 수 있다.

서비스가 가능한 컨텐츠의 종류

Cloud Front를 통해서 서비스가 가능한 컨텐츠의 종류는 다음과 같다.

Ÿ   Download Distribution : HTTP 프로토콜을 이용해서 다운로드 받을 수 있는 이미지나 기타 정적인 리소스 파일

Ÿ   Streaming Distribution : HTTP Progressive Down load RTSP(Real Time Streaming Protocol)을 지원하는 동영상 컨텐츠

Cache 동작

CDN은 기본적으로 컨텐츠를 edge node에 캐쉬 해놓는 것을 기능으로 한다. 캐쉬이기 때문에 유지 시간 TTL이 있는데, 기본 TTL 시간은 24시간이고 최대 1시간으로 까지 줄일 수 있다.

그런데 만약 파일을 잘못 올렸거나, 수정이 필요할 때 캐쉬의 TTL 시간에 의해서 수정이 edge node에 반영되는 시간까지 최소 1시간이 소요된다.

이런 문제를 해결하기 위해서 Cloud Frontinvalidation API (특정 파일을 캐쉬에서 지우는 기능)을 제공하는데, 한번에 3개의 invalidation request밖에 실행할 수 없으며, invalidation request는 최대 1000개의 파일까지만 지원한다. 그리고 invalidation request는 모든 edge node에 반영되어야 하기 때문에, 보통 5~10 분 정도의 시간이 소요된다.

그래서 조금 더 빠르게 캐쉬에서 컨텐츠를 업데이트 하기 위해서는 버전을 사용하기를 권장하는데, 쉽게 이야기 해서 파일명을 바꾸도록 하는 것이다. /image/photo.png가 있을때, 이 파일이 변경되기를 원할 경우, HTML 원본에서 해당 이미지 명을 /image/photo_v2.png로 변경하고,새로운 파일명도 photo_v2.png로 저장을 하면 별도의 cache invalidation 작업 없이 바로 변경 내용을 반영할 수 있다.

 

또는 파일명을 바꾸는 게 부담 스러울 경우에는 Query String을 사용할 수 있다.

예를 들어 /image/photo.png?version=1.0 으로 HTML에서 이미지 경로를 걸어 놓으면, Cloud Front "photo.png?version=1.0"을 키로 캐쉬에 파일을 저장한다. Origin server에 이렇게 파일을 요청하게 되면, 이 파일은 정적인 컨텐츠이기 때문에, Query String은 무시 되고, Origin Sever "photo.png" 파일만 리턴한다. 원본 컨텐츠가 바뀌었을 경우, 원본 컨텐츠의 파일명은 변환할 필요가 없이 똑같이 "photo.png" 파일로 저장을 하되, HTML의 참조명을 /image/photo.png?version=2.0으로만 바꿔 주면, Cloud Front입장에서는 resource의 이름이 아까와 다른 이름이기 때문에, Cache에서 찾지 못하고 다시 Origin Server로 요청하게 된다

(Query String을 버전명으로 사용하기 위해서는 Cloud Front설정에서 Query String by pass 기능을 on 해줘야 한다.)

비공개 컨텐츠에 대한 접근 제어

다음으로 이런 정적인 컨텐츠를 다루다 보면 특정 사용자에게만 서비스를 제공해야 하는 경우가 있다. 예를 들어 유료 앱 다운로드나, 유료 동영상 서비스같은 것이 좋은 예가 되는데, Cloud Front Signed URL이라는 기능을 이용해서, CDN 컨텐츠에 대한 접근 제어 기능을 제공한다.

원리는 간단하다. CDN의 특정파일에 대한 접근 권한을 {ip 주소, 다운로드 가능 시간 시작~} (접근 권한의 각 필드는 필수가 아니라 선택 사항이다. 또한 ip 주소는 특정 ip ip 주소 대역으로도 정할 수 있다.) 으로 정하고, URL을 생성한 후 암호화 하여 사용자에게 제공하는 것이다.

그러면 그 URL CDN내의 컨텐츠를 접근하면, 접근 권한에 정의된 조건을 충족하면 다운로드를 할 수 있도록 해준다.

아래는 아마존 웹사이트에서 발췌한 Signed URL 샘플이다.


1) 이 부분의 resource 파일명을 정의한다.

2),3) Query String을 정의 하는 부분이다. 원본 파일(Origin Server)로 전달되는 Query String이다.

4) Policy 로 앞에서 언급한 접근 가능 정책 {ip 주소, 접근 가능 기간} JSON으로 정의한후에 encoding string이다.

5) HMAC과 유사하게 이 URL이 변조되는 것을 막기 위해서 URL에 대한 Signature Base64 encoding을 이용해서 생성해서 붙인 부분이다. (일종의 Hash값으로, URL에 대한 Hash URL이 변조되면 이 Hash 값과 맞지 않는다.)

6) Key로 아마존 Cloud Front 사용을 위해서 발급된 키이다.

Signed URL 이외에 사용자 계정을 통해서 접근을 제어할 수 있는 방법이 있는데, 이 계정은 아마존 계정 서비스인 IAM을 통해서 생성된 계정만을 통해서만 가능하다. 참고로 IAM 계정 서비스는 최대 5000개의 계정만 생성 및 관리가 가능하기 때문에, 대외 서비스에는 적절하지 않고, 소규모 대내 서비스나 또는 내부 관리 용도로 CDN 접근 제어를 할대 유용하게 사용할 수 있다.

부가적인 기능

그 밖에도 몇가지 부가적인 기능들이 있다. SSL을 통해서 컨텐츠를 서비스 하는 기능이나, 또는 컨텐츠 서비스 내용을 HTTP access 로그로 남겨서 S3에 저장하는 기능들이 있다.

성능 향상 방법

Cloud Front를 사용하는데 있어서 몇 가지 성능을 향상 시킬 수 있는 테크닉이 있어서 소개하고자 한다.

1) Domain Sharding : 일반적으로 웹브라우져는 하나의 도메인 주소에 대해서 동시에 열 수 있는 네트워크 Connection 수가 제한이 있다. IE7의 경우에는 한 도메인당 2, Chrome IE8/9 6, Fire Fox의 경우에는 8개이다. 그런데 일반적인 웹 페이지에서 동시에 로딩되는 리소스는 대략 20~50개 정도가 된다.즉 웹브라우져가 여는 Connection 수로는 한꺼번에 모든 리소스 로딩이 어렵다는 것이다. 일반적인 CDN에서도 적용될 수 있는 기법인데, 하나의 시스템에 여러개의 도메인을 적용하는 것이다. 예를 들어 서버의 주소가 210.113.119.210 이라고 하고, 도메인 명이 www.terry.com 이라고 하자.CNAME으로 image.terry.com, resource.terry.com, css.terry.com 등 여러개의 도메인을 같은 URL을 가리키도록 해놓고, HTHL에서도 image url "src="http://image.terry.com/img/myimage.png" 식으로 지정해놓게 되면 브라우져 입장에서는 전혀 다른 사이트로 인식하기 때문에, 별도의 네트워크 Connection을 열 수 있다. 이 방법을 사용하면 브라우져의 Connection을 최대로 열어서 전체적인 웹사이트 Loading Time을 증가시킬 수 있다.

 

2) Compression : CDN은 네트워크에 관련되는 서비스이기 때문에 당연히 원본 컨텐츠의 사이즈가 작으면 성능이 사용하는 대역폭도 작아지고, 성능도 더 잘 나온다. 압축 기능을 사용하기 위해서는 Origin server apache와 같은 웹서버인 경우에는 gzip compression 기능을 웹서버에 적용해주면 되지만, S3 Origin server로 사용하는 경우에는 S3 자체에는 gzip compression 기능을 가지고 있지 않기 때문에, 컨텐츠를 할때 gzip으로 압축해서 올리고 "Content-Encoding" gzip으로 명기해주면 된다.

 

가격 체계

Cloud Front edge node의 위치에 따라서 가격이 다르다. 과금은 Out bound traffic을 기준으로 하는데, 아래 그림과 같이 South Africa가 다른 region에 비해서 가격이 월등하게 비싸다. Cloud Front를 사용하기 전에, 먼저 서비스를 하고자 하는 국가등을 미리 고려한 후에, 가격과 함께 사용지역을 고려하기를 권장한다.



저작자 표시
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

'클라우드 컴퓨팅 & NoSQL > Amazon Web Service' 카테고리의 다른 글

Auto scaling out  (1) 2013.09.11
Amazon의 CDN 서비스 Cloud Front  (0) 2013.09.10
Amazon Route 53 DNS 서비스  (0) 2013.09.09
Amazon Elastic Load Balancer  (2) 2013.09.09
Amazon Direct connect  (0) 2013.09.06
Amazon VPC (Virtual Private Cloud) 소개  (3) 2013.08.18

Amazon Route 53 DNS 서비스

조대협

Route53은 아마존에서 제공하는 DNS 서비스 이다. 일반 DNS와 다르게 몇 가지 아마존에 특성화된 몇 가지 기능을 가지고 있는데, 특화 기능에 앞서서 DNS 의 일반 개념을 먼저 정리해 보자.

DNS domain name (www.example.com) ip 주소로 바꿔 주는 일종의 dictionary 서비스 이다.

이러한 맵핑 정보를 저장해 놓는 파일을 DNS Zone file이라고 한다.

 

이 서비스는 DNS 서버에 저장해놓은 파일을 기반으로 주소를 변환하는데, 여기에 정의되는 레

코드들 중에서 대표적은 레코드는 다음과 같다.

 

   SOA 레코드 : 해당 DNS 서버 자체의 설정 정보를 정의 한다.

Ÿ   DNS 서버는 Primary/Secondary 구조로 장애 대응을 할 수 있는 구조인데, 이를 위해서 SOA 레코드에는 이를 위한 설정이 반영되어 있다.

Ÿ   serial # - revision # Zone 파일이 업데이트 될때 마다 증가하는 일종의 버전

Ÿ   refresh - secondary server primary server로 부터 업데이트를 하는 주기

Ÿ   retry - primary server로 부터의 query가 실패하였을때, 다음 retry 까지 시간.

Ÿ   expire : secondary server에서 zone 파일을 유지 하는 시간

Ÿ   TTL : DNS 응답을 받아가는 서버가 해당 레코드 응답을 얼마나 유지해야 하는 TTL 시간

   NS 레코드 : DNS 서버가 참조하는 다른 DNS 서버이다. DNS 서버 자신에서 domain name에 대한 주소를 알아 내지 못할때, NS 레코드에 정의된 서버로 가서 주소를 알아dhsek.

   CNAME 레코드: 도메인명을 다른 도메인과 맵핑할때 사용 (일종의 alias)

   A 레코드:도메인을 ip로 맵핑

   PTR 레코드 : ip를 도메인으로 맵핑 (Reverse Zone에서 사용)

 

DNS 서버의 특성중에서 주의깊게 봐야 하는 특성은 캐슁이다.

보통 DNS 서버는 클라이언트가 사용하는 로컬 네트워크에 있는 DNS를 사용하게 된다. 회사 네트워크라면 회사내의 DNS 서버,집에서 사용하는 경우 해당 통신사의 DNS서버, 모바일을 사용할 경우, 해당 통신사의 DNS 서버를 사용한다. DNS 서버들은 look up을 요청한 목적 서비스 서버에 대한 ip 주소를 다른 클라이언트가 요청할 때 응답을 빠르게 하기 위해서 자체적으로 캐슁하고 있다.

예를 들어 구글의 A라는 서비스가 있다고 하자. 이 서비스 A는 구글의 DNS 서버에 주소가 정의되었을 것이다. 만약 한국의 사용자가 스마트 폰을 이용하여 이 서비스의 URL을 접근하게 되면, 해당 한국 통신사의 DNS 서버를 통해서 주소를 look up 하게 될 것이고, 이 한국 DNS 서버는 구글의 DNS 서버에 주소를 물어본 후에, 다음 서비스를 위해서 자신의 Cache를 업데이트 한다.

이 캐쉬가 지워지고 다시 업데이트 되는 시간이 TTL 시간인데, TTL은 이후에도 설명하겠지만, 동적으로 DNS 주소를 업데이트하거나 변경하였을때, 로컬의 DNS서버의 캐쉬가 업데이트 되지 않아서 실제 주소가 바뀌더라도 이전 서버의 주소를 리턴하는 경우가 있어서 주소 변경을 어렵게 한다.

이제 Route 53의 고유 기능을 살펴보도록 하자.

Health check & DNS Fail Over

Route53은 자체적으로 Health check 기능을 가지고 있다. 하나의 DNS 명에 대해서 multiple ip address return할 수 있는데, 해당 ip의 서버의 상태를 체크해서 장애 상태인 경우에는 list에서 제외하고, 장애가 복구 되면 다시 리스트에 추가하는 형태이다.

앞에서 언급했듯이 이 기능의 경우 local DNS들의 캐슁 때문에, Route53이 장애를 인지하고 바로 list에서 제외한다 하더라도 local DNS에서 캐쉬가 업데이트 되는 시간이 필요하기 때문에 바로 fail over는 되지 않는다. 되도록 빠른 fail over를 하기 위해서는 Route53에서 TTL 시간을 짭게 주는 것이 좋은데, 아마존의 경우 60초이하 의 값을 권장하고 있다.

Latency based routing

Route53의 기능 중에 상당히 흥미로운 기능중의 하나인데, Route53에 하나의 DNS 주소에 대해서 여러개의 서비스 ip binding 되어 있을 경우, Route53은 클라이언트로 부터 DNS 주소에 대한 look up 요청을 받았을 경우, 클라이언트로 부터 가장 빠른 응답시간을 보장하는 (거리가 가까운) 서버의 ip 주소를 리턴하는 기능이다.

 원리를 설명해보면 다음과 같다. 아마존 인프라는 각 데이타센터로부터 다른 ip주소 대역까지의 네트워크 latency 값을 주기적으로 수집해서 데이타 베이스화 해서 가지고 있다. 예를 들어 미국 아마존 데이타 센터에서 전세계에 대한 latency를 아마존을 가지고 있다. 한국,중국,유럽 등등. 이렇게 latency 자료를 가지고 있다가, DNS look up 요청이 오면, 요청을 한 클라이언트쪽의 ip를 기반으로 내부 데이타 베이스내의 latency를 체크해여 가장 가까운 아마존 데이타 센터의 ip를 리턴하게 되는 원리이다.

이 때 Route 53으로 request를 보내는 클라이언트는 end user browser나 모바일 기기등이 아니라 end user가 접속된 네트워크의 로컬 DNS 서버가 되게 된다.

 Latency based routing의 경우 로컬 DNS가 클라이언트가 접속하는 망내에 있는 것을 전제로 한다.

 

저작자 표시
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

'클라우드 컴퓨팅 & NoSQL > Amazon Web Service' 카테고리의 다른 글

Auto scaling out  (1) 2013.09.11
Amazon의 CDN 서비스 Cloud Front  (0) 2013.09.10
Amazon Route 53 DNS 서비스  (0) 2013.09.09
Amazon Elastic Load Balancer  (2) 2013.09.09
Amazon Direct connect  (0) 2013.09.06
Amazon VPC (Virtual Private Cloud) 소개  (3) 2013.08.18

 

Elastic Load Balancer

 조대협

ELB는 아마존에서 제공하는 일종의 L4와 같은 로드 밸런서이다. 내부적으로 VM위에서 동작하는 소프트웨어 로드밸런서이고, 아마존 환경에 맞춰서 최적화 되어 있다.

 



Multiple zone support

ELB는 기본적으로 multiple zone을 지원한다. ELB 생성시, ELB를 배포할 Amazon Availability Zone을 지정할 수 있다. 여러 개의 zone multiple ELB instance가 배포 되기 때문에 ELB 인스턴스는 기본적으로 ip 주소를 가지지 않는다. 대신 DNS 주소를 가지는데, 테스트를 해보면 알겠지만, ELB DNS 주소는 경우에 따라서 1개 이상의 주소를 리턴하게 된다.

이는 multiple zone을 지원하기 위해서 뿐만 아니라, ELB의 용량이 모자르게 되면 내부적으로 자동으로 scaling을 하는데, 먼저 ELB scale up을 해서 인스턴스 크기를 키우고, 모자르다면 다른 ELB 인스턴스를 만들어서 추가 하는 scaling out 작업을 수행한다.

여러개의 ELB를 하나의 end point로 묶기 위해서 DNS 리스트 방식을 사용하게 된다.

SSL Termination

ELB SSL 기반의 HTTPS 프로토콜을 지원할 수 있다.ELB 설정에 SSL 인증서를 세팅해놓으면 Client --> ELB SSL, ELB --> 백엔드 EC2까지는 HTTP로 통신을 하게 된다.

X-forwarded for Header

ELB EC2 인스턴스 앞에서 로드밸런싱을 하게 되면 EC2 입장에서 incoming address ELB의 주소로 인식하게 된다. 애플리케이션에 따라서 client ip를 알아야 할 경우가 있는데, EC2 입장에서는 ELB request를 하는 주체가 되기 때문인데, 이러한 문제를 해결하기 위해서 ELB는 원래의 client ip X-forwarded-for (XFF) 헤더 안에 실어서 보내준다. EC2에서는 이 XFF HTTP Header를 열어 봄으로써 원본 client ip를 알아낼 수 있다.

Sticky Session

ELB가 추가적으로 제공하는 기능중에 하나가 sticky session이라는 기능이다. 이 기능은 client로 부터 들어오는 http request를 항상 같은 ec2 인스턴스로 라우팅을 해주는 기능인데, ELB sticky session의 원리는 cookie를 사용한다.

Sticky session 기능을 on 해놓으면, http response cookie를 세팅하여, 해당 client가 가는 ec2 instance에 대한 정보를 저장해 놓는 방식이다.

몇 가지 추가 설정이 필요한데, 애플리케이션이 이미 http cookie를 사용하고 있으면, 해당 cookie 명을 넣어서 사용중인 애플리케이션 cookie를 사용하게 하고, 만약에 애플리케이션이 cookie를 사용하지 않으면, 별도로 ELB cookie를 만들도록 한다.



위의 그림과 같이 sticky session 기능은 cookie를 사용하기 때문에, multiple ELB 상황에서도 항상 같은 request를 같은 ec2 인스턴스로 라우팅할 수 있게 해준다.

Health Check

ELB ELB에 연결된 EC2 인스턴스에 대한 자체적인 Health Check 기능을 가지고 있다. 사용자 설정에서 정해진 옵션에 따라서 주기적으로 EC2 인스턴스에 Health Check 메세지를 보내고, 만약에 EC2 인스턴스가 장애로 판단되면, 해당 인스턴스를 로드밸런싱 리스트에서 제외한다.

반대로, 제외되었던 인스턴스라도, 주기적으로 체크해서 정상화가 되면 다시 로드 밸런싱 대상에 추가하게 된다.

DNS Fail Over

다음으로 ELB 간의 HA이다. Load Balancing은 앞에서 언급한 바와 같이 DNS Round Robin 을 사용한다. 마찬가지로 HA 역시 DNS 방식을 사용하는데, Amazon DNS ELB 인스턴스들의 상태를 감시하다가 문제가 생기면, DNS 리스트에서 제외를 한다.

DNS 방식이기 때문에, TTL 시간을 가지고 있고, TTL 시간이 지나야 리스트가 클라이언트에 업데이트 되기 때문에, TTL 시간이 지나기 전까지는 client가 계속 장애가 난 인스턴스로 로드가 밸런스 될 수 있다. 그래서 Load Balancer 기반의 Fail Over 보다는 넘어가는 시간이 느리다.

VPC & ELB

앞서 VPC에 대한 개념에 대해서 설명하였는데, ELB 역시 VPC 안쪽이나 바깥쪽 양쪽에 배포가 가능하다. VPC 바깥쪽에 배포를 하여 public ip를 가지고 VPC 안쪽의 EC 인스턴스에 대해서 로드밸런싱이 가능하며, 또한 VPC 안쪽에 배포를 하여 private ip를 가지고 EC 인스턴스에 대해서 로드 밸런싱이 가능하다.

주의해야할점

마지막으로 ELB 사용 및 테스트시 주의할점을 몇가지 언급해보면 다음과 같다.

ELB로 성능 테스트를 하다 보면, 부하가 일정 수준으로 못 올라가는 경우에 ELB에서 Network In/Out bound 쪽에서 병목이 있는 것을 발견할 수 있는데, 이는 ELB의 용량이 충분하지 않기 때문이다. ELB는 자체적으로 scaling을 하기는 하지만, scaling이 그리 빠르지 않다. 그래서 성능 테스트를 할 경우에는 wramp up 기간을 둬서 충분히 부하를 줘서 인위적으로 ELB scaling하게 해 놓은 후에, 부하 테스트를 해야 ELB 단의 병목을 피할 수 있다.

또는 wramp up 이 되었는지 여부가 확실 하지 않으면 DNS look up으로 몇 개의 ELB 인스턴스가 생성되었는지 확인해보거나, 제일은 Amazon쪽에 부하 테스트 기간을 알려주면 미리 Amazon 쪽에서 ELB scaling 해 준다.

그리고 부하테스트를 하다 보면, 특정 EC2 Instance나 특정 Availability Zone으로 몰리는 현상이 있을 수 가 있다. 특정 Zone으로 부하가 몰리는 현상은 흔히 발생하는 데, ELB 자체가 부하를 골고루 분산해 주지 않는다. 다만 특정 Zone이나 Instance로 몰리는 현상이 아주 심할 경우에는 몇 가지 요인을 생각해볼 수 있는데, 먼저 부하 테스트 쪽의 DNS 캐쉬를 의심해볼 수 있다.

ELB간의 로드밸런싱은 DNS Round Robin을 사용하기 때문에, 클라이언트 쪽의 캐쉬를 지워주지 않으면 그 시간동안 계속해서 특정 ELB 인스턴스에만 부하를 주게 된다.

특정 인스턴스로 몰리는 현상의 경우 Sticky Session을 사용하는 경우, 클라이언트 쪽의 Cookie를 지워 주지 않아서, Cookie를 참조해서 계속 같은 EC2 인스턴스로 부하가 가는 경우가 많다.

 

그래서 ELB 기반의 부하테스트를 할 때에는 고성능 적은 수의 클라이언트 보다는 많은 수의 저성능 클라이언트를 사용하는 것이 부하를 골고루 나눠 지게 할 수 있다.

 

저작자 표시
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

원본 : http://aws.typepad.com/aws/2012/03/amazon-s3-performance-tips-tricks-seattle-hiring-event.html


아마존 S3를 이용하는 시스템에 대한 성능 테스트를 할때, 성능이 Leanear 하게 증가하지 않는데, 그 원인을 보면 다음과 같은 원리가 작용한다.


원인 분석

S3는 내부적으로 여러개의 파일을 저정하기 위해서 물리적으로 파일을 여러개의 디스크에 분할 저장하는데, 이 분할 하는 로직을 파일명을 가지고 해쉬를 사용한다. 그래서 파일명이 유사하게 되면, 같은 파티션(디스크)에 파일이 써지기 때문에, 하나의 파티션에 많은 물리적인 IO를 유발하고 결과적으로 성능이 떨어지게 되는 것이다.


원리

S3는 파일명을 가지고 hashing을 하여 파일을 분산 저장한다고 했다. 더 정확하게 이야기 하면 파일명의 앞부분인 prefix를 가지고 분산 키로 사용한다.

즉 예를 들어 파일명이

server.2012-12-31

server.2012-12-30

server.2012-12-29

server.2012-12-28

과 같이 앞의 prefix가 같다면, 파일은 같은 파티션에 저장될 가능성이 많다.

그래서 앞의 file prefix를 다양한 이름으로 바꿔 주는 것이 좋다.

예를 들어 일정 디렉토리 (디렉토리명으로도 파티셔닝이 된다.)로 다음과 같이 구분한다

a/server.2012-12-31

b/server.2012-12-30

c/server.2012-12-29

d/server.2012-12-28

위와 같은 구조를 취하면, 최소 4개 파티션에 분할 저장된다.
또는 위의 파일명의 경우 맨 마지막이 날짜로 rotation되는 형태이기 때문에, 다음과 같은 파일명으로 저장해도 파티셔닝 효과를 볼 수 있다.
13-21-2102.server
03-21-2102.server
92-21-2102.server
:
S3에서 내부적으로 어떤 원리로 partitioning을 하는지는 정확하게 나와 있지 않다. 단지 prefix를 이용한다고만 나와 있는데, 최소한 파일명(또는 디렉토리명)을 다른 문자로 시작하게 하면, 골고루 파티션에 분산하여 저장할 수 있다고 가이드 하고 있다.

최소한 50 TPS 이상의 S3 IO를 요구할 경우에는 파티션을 권장하고 있다.
이 키 기반의 파티셔닝은 단지 S3 뿐만 아니라, NoSQL이나 HDFS와 같은 분산 파일 시스템에도 동일한 원리로 적용되기 때문에 반드시 참고하기 바란다.


저작자 표시
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

Amazon Opsworks 소개

시스템에 설치와, 애플리케이션을 자동화

배경

얼마전에, Amazon에서 새로운 클라우드 서비스인 Opsworks를 발표하였다.

[출처:Amazon Opsworks 소개 페이지]

비단 클라우드 뿐만 아니라, 서버 시스템을 개발하다보면, 당면 하는 과제중의 하나가, 소프트웨어 설치와, 애플리케이션의 배포이다.

예전에야 큰 서버 한대에, WAS 하나 설치하고, DB를 다른 서버에 설치해서  사용했지만, 요즘 같은 시대에는 x86 서버 여러대에 WAS를 분산 배치하고, 여러 솔루션들 설치해서 사용하고, 시스템의 구조 역시 훨씬 더 복잡해 졌다. 그래서, 이러한 제품 설치를 자동화 하는 영역이 생겼는데, 이를 Configuration Management(이하 CM)이라고 한다. CM의 개념은 Microsoft System Center Configuration Manager의 제품 소개나 White Paper를 보면, 정리가 잘 되어 있다. Unix 진영의 Configuration Management 영역은 오픈소스로 Puppet이나 Chef가 주류를 이룬다. 그중에서 Chef Recipe 라는 것을 제공하여, 특정 제품에 대해서 설치를 자동화 하는 스크립트를 제공한다. 일일이 제품마다 설치 스크립트를 만들지 않아도, Recipe만 입수하면 손 쉽게 제품을 설치할 수 있다. 특히나 클라우드 환경에서는 개발 환경이나 스테이징,QA 환경을 다이나믹하게 만들었다가 없앴다 하기 때문에 더군다나, 이러한 Configuration Management가 아주 중요하다.

 기존에는 Amazon 이미지인 AMI를 이용하여, 솔루션이 미리 설치된 AMI를 만들어 놓고, bootstrap 기능을 이용하여, 서버가 기동 될때, 특정 환경 변수를 설정하게 하거나

CloudFormation을 이용하여 설치를 자동화 할 수 있었다. 그러나 AMI 방식은 너무 단순해서 복잡한 설정이 어렵고 처음에는 반드시 직접 설치해야 하는 부담이 있었고, CloudFormation은 그 복잡도가 너무 높아서 사용이 어려웠다.

이번에 발표된 Opsworks는 이 중간즘 되는 솔루션으로 보면 된다.

Stack, Layer 그리고 Instance의 개념

Opsworks는 기본적으로 오픈소스 Chef를 이용하여 구현되었다. Chef를 이용해서 아마존에 맞게 개념화 해놓았는데, 먼저 Opsworks의 개념을 보자. Opsworks를 이해하려면 3가지 개념, Stack, Layer 그리고 Instance의 개념을 이해해야 한다.

우리가 PHP 웹서버 + MYSQL로 이루어진 웹 애플리케이션을 개발한다고 하자, 그리고 앞단은 HAProxy를 사용해서 로드 밸런싱을 한다고 하면, 이 애플리케이션은 크게, HA Proxy로 이루어진 Load Balancer Layer 그리고, PHP 웹서버를 사용하는 Application Server Layer 그리고, MySQL로 이루어진 DB Layer 3가지 계층으로 이루어진다.

3 가지 계층은 (HAProxy+PHP Web Server+MySQL) 다른 웹 개발에도 반복적으로 사용될 수 있다.


이렇게 각 계층을 Layer라고 하며, 이 전체 계층을 반복적으로 재사용하기 위한 묶음을 Stack이라고 한다. 그리고, 각 계층에 실제 서버를 기동했을 경우 각 서버를 Instance라고 한다. 예를 들어 하나의 HA Proxy 서버를 띄우고, 이 아래 4개의 PHP Web Server를 기동했다면, 이 시스템은 PHP Web Server로 된 Application Server 계층에 4개의 Instance를 갖는게 된다.

Chef & Predefined Cookbook
Opsworks
는 앞에서 언급했듯이 Chef (http://www.opscode.com/chef/기반이다.

Chef에 사용되는 설치 스크립트는 Ruby 언어로 되어 있으며, Opsworks에서는 콘솔에서 편리하게 사용할 수 있도록 Pre-defined Layer를 정해놨다.

Layer

Product

Load Balancing

HAProxy

Applications & Web Server

Node.js RubyOnRails, static web server, PHP

DBMS

MySQL

Cache

Memcached

Monitoring

Ganglia

 이외의 부분은 Custom Layer라고 해서 사용자가 직접 정의해야 하며, Chef를 만든 OpsCode Receipe를 참고하여 설정할 수 있다.

애플리케이션의 배포

이렇게 Stack 구성이 완료되면, 기동후에, 여기에 배포되는 애플리케이션을 배포할 수 있다. 자바로 치면 war, ear 파일등이 된다.

아마존이 충분히 서비스를 고려했다는 점은, 여기서도 나오는데, 애플리케이션 배포중에 중요한 일중 하나가, 배포가 잘못되었을때 기존 버전으로 roll back이 가능해야 한다는 것이다. 이를 지원하기 위해서 보통 배포 서비스를 설계할때는 애플리케이션을 저장할 수 있는 repository를 별도 설계해서, 여러 버전을 저장해놓고, 필요할 경우 Roll Back을 하는데, Opsworks는 이를 지원하기 위해서 다양한 Repository를 지원한다.-AWS S3, 일반 HTTP URL, GitHub ,Subversion

현재 Opsworks에서 지원하는 배포 가능한 앱은 Ruby on rails, PHP, JavaScript(Node.js), Static등을 지원하며, Custom App을 통해서 여러 앱 타입을 지원하도록 할 수 있다.

더 살펴봐야 할것

Opsworks 스크립트를 통해서 할 수 없는 것중 하나는 ELB(Elastic Load Balancer)등의 세팅을 할 수 없다. 오로지 EC2위에 설치하는 것만 가능하다. 설치와 배포를 AWS 인프라와 어떻게 엮어서 할 수 있을까가 과제이다.

아직 베타 서비스이고 사례가 많지는 않지만, 설치와 배포가 중요한 클라우드 환경에서, Chef라는 주요 오픈 소스를 기반으로한 서비스인 만큼 시간을 가지고 지켜볼만한 하다.

 

참고 : http://docs.aws.amazon.com/opsworks/latest/userguide/walkthroughs.html

저작자 표시
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

Dynamo는 새롭게 소개된 AWS의 NoSQL서비스이다.
Key-Value 형태로 대용량의 데이타를 저장할 수 있으며, 고속의 데이타 access를 제공한다.

데이타 모델
먼저 데이타 모델을 살펴보자, RDBMS의 일반적인 테이블 구조와 유사하지만, 조금 더 유연성을 가지고 있다.
RDBMS와 똑같이 테이블이라는 개념을 가지고 있으며, 테이블은 테이블명과 각각의 ROW로 구성된다.
테이블은 Unique한 Primary Key를 가지고 있다. 이를 Key라고 정의한다.
테이블의 ROW에 해당하는 내용은 item이라고 부르는데, 각 item은 key에 의해서 구분된다.
RDBMS와는 다르게, 각 ROW는 똑같은 Column을 갖는 것이 아니라, 각  row 마다 다른 column을 가질 수 있다
그래서, 각 컬럼을 name = value 식으로 정의하는데, 이 각각을 attribute라고 정의한다.



이 개념을 도식화 해보면 위의 그림과 같다.
아마존 웹사이트에 나와 있는 예제를 한번 살펴보자.
ProductCatalog 라는 테이블이 있다고 하자, 이 테이블의 Primary Key는 Id라는 필드를 사용한다. 이 Primary Key 필드는 모든 item들이 가지고 있어야 한다.

Item 1
{ 
   Id = 101                                       
   ProductName = "Book 101 Title"
   ISBN = "111-1111111111"
   Authors = [ "Author 1", "Author 2" ]
   Price = -2
   Dimensions = "8.5 x 11.0 x 0.5"
   PageCount = 500
   InPublication = 1
   ProductCategory = "Book" 
} 
Item 2
{ 
Id = 201
ProductName = "18-Bicycle 201"
Description = "201 description"
BicycleType = "Road"
Brand = "Brand-Company A"
Price = 100
Gender = "M"
Color = [ "Red", "Black" ]
ProductCategory = "Bike"
}

위의 예를 보면 알겠지만, 모든 Item들은 Id라는 Key 필드를 가지고 있지만, 각각의 Column들은 내용이 다르다. Item 1에는 ISBN 필드가 있지만, Item 2에는 ISBN 필드가 없다.

Dynamo는 RDBMS와는 다르게 Index 필드가 없다. (다른 NoSQL도 Index가 없는 경우가 많지만) 대신 range query나 sorting을 지원하기 위해서 range key라는 추가적인 키를 제공한다. Primary Key를 정의시 Unique한 Key 필드 하나만 정의하거나 (이를 Hash Key라고 한다.) 또는 이 range key를 추가로 지정하면, 쿼리 결과가 ascending 순서로 sorting이 되며, 쿼리 역시 이 range key를 기반으로 특정 범위의 데이타만 query 할 수 있다.
이 range key는 table 생성시에 hash key와 함께 정의한다.

성능

내부적으로 SSD 디스크를 이용하기 때문에, 높은 IO 성능을 보장할 수 있으며 read / write 성능을 보장하는 옵션을 가지고 있다.
Read/Write Unit이라는 옵션인데, 1KB item 1개를 1초동안 쓰거나 읽는 단위가 1 Unit이다. 2 Write Unit은 1K 데이타를 1초동안 2개 Write할 수 있는 성능 지표이다.

Units of Capacity required for reads = Number of item reads per second x item size (rounded up to the nearest KB)
Units of Capacity required for writes = Number of item writes per second x item size (rounded up to the nearest KB)
ReadUnit = [초당 읽는 item(row) 수] * [ item 크기 (kb로 반올림) ]
WriteUnit = [초당 쓰는 item(row) 수] * [ item 크기 (kb로 반올림) ]

1 ReadUnit은 초당 1KB짜리 1개의 Item을 읽을 수 있는 성능 단위이다.
예를 들어, 21.5 kb 짜리 item을 초당 100개를 읽는 성능이 필요하다면, Read Unit = 100 * 22 (반올림) = 2200 이 필요하다.
쓰기 성능도, 마찬가지 방식으로 WriteUnit이라는 단위로 지정한다.
각각 최대 10,000 Unit 까지 지원하며, 이 이상을 원할 경우, Amazon Support에 신청하면, 더 높은 Unit으로 올릴 수 있다. (최대 한계는 나와있지 않음)
Unit의 개념은 성능을 보장한다는 개념에서 긍정적이지만, 반대로 성능을 제약한다는 문제를 가지고 있다.
즉 정해진 Unit 보다 많은 read나 write가 발생할 경우, Dynamo는 이를 처리하지 않고 error 처리를 해버린다.
"ProvisionedThroughputExceededException" 그래서 Spike 형태의 request가 들어올 때는 문제가 된다.
프로그램 로직상에서 "ProvisionedThroughputExceededException" 에 대한 처리가 필요한데, 이 에러가 발생하였을 경우에는 프로그램적으로 retry를 하도록 하는 로직을 포함하는 것을 권장한다.

일관성 보장 옵션
Dynamo와 같은 NoSQL 계열의 데이타베이스는 데이타를 여러개의 노드에 나눠서 저장하고, 백업을 위해서 다른 노드로 복제하기 때문에, 복제가 완료되기 전에 클라이언트가 다른 노드에서 데이타를 읽으면 예전의 데이타를 읽을 수 있다. 이런 문제가 일관성 문제인데, 일반적인 NoSQL은 이러한 일관성을 보장하지 않는다. 복제할 때까지 시간이 걸린다는 것을 가정하고, (시간 자체는 짧으나) 그 시간동안은 일관성이 보장이 안되는데, 이러한 일관성 보장 정책을 Eventually Consistent Read라고 한다. 반대로, 데이타를 쓴 다음 모든 노드에서 데이타를 읽었을때, 같은 데이타를 바로 리턴하게 할 수 있는데, 이 경우에는 데이타가 써진 후에, 다른 노드 까지 replicated될때까지 기다려야 한다. 그래서 당연히 Read 응답시간이 Eventually Consistency Read보다 느리다. 이러한 일관성 정책을 Strongly Consistent Read라고 한다. Strong Consistency의 경우 Eventually Contentency와 같은 성능을 보장하려면, 더 빨리 data write를 발생시켜야 하기 때문에, 내부적으로 더 높은 write unit이 필요하게 된다. 그래서, Eventually Consistency의 경우 Strong Consistency에 비해서 가격이 50% 정도 저렴하다.

Query
데이타베이스이기 때문에, 데이타에 대한 Query를 지원한다.
Primary Key를 가지고 get이 가능할 뿐더러, range key를 이용하여, subset을 query하는 range query가 가능하다.
쿼리 후 list(set) 형태의 데이타가 리턴되었을 경우, 한번에 리턴할 수 있는 데이타 set의 최대 크기는 1MB이다.
1MB가 넘을 경우에는 pagenation을 해야 하는데, 1MB 가 넘는 경우 LastEveluatedKey라는 값을 리턴하여, (일종의 DB cursor와 같은 역할) 다음번 read시 부터는 이 키 부터 리드할 수 있도록 pointing을 해준다
또는 명시적으로 Limit 라는 parameter를 이용하여, Query에서 리턴되는 수를 정할 수 있다. (SQL의 "top"과 같은 개념) 전체 쿼리 결과가 1000개라도 Limit 10 으로 하면, 소팅된 순서에서 상위 10개의 item 만 리턴한다.
다음으로는 "Count"라는 parameter가 있는데, 이 Count는 RDBMS의 select count(*)와 같은 개념이다. Query 결과로 리턴되는 총 Item의 수를 리턴한다.
주의할점은 Dynamo는 NoSQL이다. RDBMS와 다르다.
key 기반의 select와, range query는 지원하지만, group by, where, index등의 쿼리 기능은 없다. (데이타 모델 설계 자체를 RDBMS와 다르게 해야 한다.)

Scan
Scan 기능은 테이블의 모든 Item을 순차적으로 읽어오는 기능으로, Query와 마찬가지로, 한번 API call에 1MB까지만 읽어올 수 있고, LastEvaluatedKey 값을 이용해서 다음 데이타를 연속적으로 읽어올 수 있다. 처음부터 테이블을 Scan 하기 때문에, 당연히 많은 시간이 소요된다.

저작자 표시
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

'클라우드 컴퓨팅 & NoSQL > Amazon Web Service' 카테고리의 다른 글

Amazon의 설치 배포 자동화 솔루션 Opsworks  (0) 2013.02.26
간단한 S3 Performance Test  (3) 2013.01.25
아마존의 SSD의 NoSQL 서비스 Dynamo  (0) 2012.12.07
Amazon S3 서비스 소개  (0) 2012.12.06
EMR 특징  (1) 2012.12.06
Dynamo 특징  (0) 2012.12.06

AWS S3 (Simple Stoage Service)는 파일을 저장하기 위한 스토리지이다. 일반적인 파일시스템의 개념과는 약간 다르고, 파일 이름을 대표하는 key와 파일 자체로 구분되는 Object Storage이다.

저장할 수 있는 파일의 크기는 개당 1byte~5TB이고, 총 저장 용량에는 제한이 없다. 디렉토리와 비슷한 개념으로, bucket이라는 개념을 가지고 있다.

S3에 접근하기 위해서는 일반적은 file io api등은 사용할 수 없으며, REST/HTTP 기반의 프로토콜만 지원한다. 그래서, 성능이 다른 파일 시스템에 비해서 느리다.

기본적으로 3 copy를 지원하여, 데이타를 복제하고, 이 복제는 Amazon availability zone (AZ) 단위로 복제가 되기 때문에 데이타 센터 장애에 대한 대응성을 가지고 있다. 단 region 간 복제는 지원하지 않는다. 복제에 관련된 옵션으로는 RRS (Reduced Redundancy Storage)라는 것이 있는데, 이 옵션을 적용하면, 2 copy (원본 + 백업)만을 저장하기 때문에, 가격이 훨씬 더 저렴하다.

3 copy를 저장할 경우, S3에 대한 데이타 신뢰도는 99.999999999% 를 보장하고, 서비스에 대한 가용성은 99.99%를 보장한다.

다른 주목할만한 기능 은 retain 기간을 지정할 수 있다. 즉 파일의 저장 기간을 지정할 수 있고, 그 기간이 지나면 자동으로 삭제가 된다.

또한 파일에 대한 versioning 기능을 가지고 있어서, 잘못되었을 경우, 기존의 파일 내용으로 roll back이 가능하다. S3 서비스는 AWS 내에서 대용량 데이타를 저장하기 가장 알맞은 저장소이다. 그래서 다른 AWS의 서비스 (EMR 나 CloudFront, Glacier 등)에 자연스럽게 연동될 수 있는 기능을 제공하며, 다른 서비스들과 상호보완적인 관계를 갖는다. 예를 들어 SQS와 같은 큐 서비스에는 큰 객체(파일)을 저장할 수 없기 때문에 이벤트 메세지는 SQS에 저장하고, 실제 큰 파일은 S3에 저장해서 레퍼런스를 하던가, Dynamo와 같은 NoSQL DB도 레코드당 데이타 한계로 인해서, 메타 데이타는 Dynamo에 저장하고, 파일과 같은 큰 바이너리 데이타는 S3에 저장하고 레퍼런스를 하게 할 수 있다.

매우 간단한 서비스이기는 하지만, 데이타 손실 가능성이 적고, 사용이 간략하며, 다른 서비스와 연계성이 높기 때문에, 필히 익혀둬야 하는 서비스이다.

저작자 표시
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

아마존의 EC2 서비스는 VM 기반의 컴퓨팅 자원을 제공하는 서비스이다.

클릭 몇 번으로 저기 바다 넘어있는 나라에 내 서버를 만들 수 있으며, 내가 사용한 만큼만 비용을 지불하면 된다.
아마존 EC2에서 제공하는 VM은 성능과 특성에 따라 여러가지 타입을 가지고 있다.

일반적인 인스턴스 
  • 1세대 인스턴스(m1) : m1.* 이름으로 시작하며 아마존에서 일반적으로 제공하는 가상화된 VM 인스턴스 이다.
  • 2세대 인스턴스(m3) : 2012년에 발표한 인스턴스로 m3.* 로 시작하며, 기존에 비해서 50% 이상의 높은 CPU 성능을 가지고 있다.
특수목적 인스턴스 

  • 고용량 메모리 인스턴스(m2) : m2.* 이름으로 시작하며 17,34,68 GB등 많은 용량의 메모리를 가지고 있는 인스턴스이다. (가상코어 역시 그만큼 많이 가지고 있다) 데이타베이스나 메모리 캐쉬 서버등 메모리 사용량이 높은 서비스에 이용할 수 있다. 
  • 고성능 CPU 인스턴스(c1) : c1.* 이름으로 시작하며, 같은 메모리나 디스크를 갖는 m1 시리즈에 비해서 상대적으로  CPU 만 더 많이 가지고 있다.
  • 클러스터링 인스턴스(cc1) : cc1.* 로 시작하며, 아마존 인스턴스 중에서 가장 높은 스펙을 가지고 있다. 많은 CPU와 많은 메모리 그리고 10G 기반의 IO 성능을 가지고 있다. 특히 클러스터링 인스턴스는 placement group이라는 옵션을 지원하는데, 아마존의 VM은 내부에서 생성될때, 어느 위치(Rack)에 생성될지 알 수 가 없다. 그래서 인스턴스간의 네트워크 latency가 예측 불가능 한데, 클러스터링 인스턴스를 placement group으로 묶으면, 인스턴스간의 네트워크 latency를 최소화하고 인스턴스간 10GB 네트웍을 사용한다. 클러스터링된 서비스들은 대부분 인스턴스간의 통신을 하고 그 속도에 많은 영향을 받기 때문에, 클러스터링 된 서비스에 매우 유리하다. Cassandra,MongoDB등과 같이 내부적으로 클러스터링이 되는 NoSQL등에도 사용할 수 있다.
  • 클러스터 GPU 인스턴스(cg) : cg* 로 시작하는 인스턴스로, VM에 GPU (그래픽카드에 들어가는 CPU)가 대거로 포함되어 있다. 우리가 사용하는 그래픽 카드에는 GPU라는 프로세스가 들어 있는데, 이 GPU들은 실수 연산 (floating point)과 같은 수치 연산에 매우 최적화되어 있다. 그래서 수치 해석이나 대규모 병렬처리등에 매우 유리한데, 이러한 GPU들은 CPU와는 다르게 큰 코어를 수개~수십개를 가지고 있는 것이 아니라 수백개의 GPU 코어를 가지고 있기 때문에, 수치 연산에 있어서는 탁월한 성능을 발휘할 수 있다.
  • High IO 인스턴스(hi) : hi*로 시작하며 높은 성능의 네트워크와 디스크 IO성능을 보장한다. 특히 디스크 성능이 탁월하게 높은데 그럴 수 밖에 없는 것이 SSD를 사용한다
EBS(디스크) 성능 옵션

그 외에, 위의 VM을 선택한 후에, VM에 따라 다음과 같은 몇 가지 추가 옵션을 제공한다.
EBS는 나중에 설명하겠지만, iSCSI기반의 SAN 스토리지다. PC로 쉽게 생각하면 외장 하드 정도로 이해하면 된다. (물론 그보다는 훨씬 빠르지만). EC2에서 문제가 되었던게 이 EBS 디스크를 VM에 붙였을때, EBS 디스크에 대한 IO 성능 느리고, 그 성능이 일정하지 않았던 문제를 가지고 있었다. 이를 보와하기 위해서 나온 것이 다음과 같은 두 가지 옵션이다.

Provisioned IOPS (PIOPS)
EBS 디스크 용량에 따라서 IOPS를 보장한다.  보장 가능한 IOPS는 EBS용량에 비례하여 증가한다. GB를 기준으로 N GB사용시, 명시적으로 지정 가능한 최대 IOPS는 N*10 IOPS가 된다. (40GB면 400IOPS, 100GB면 1000IOPS) 현재 최대 1,000 IOPS까지 지원된다.
정확하게는 EC2 VM의 옵션이 아니라 EBS의 옵션으로, Provisioned IOPS를 선택하면, IO 성능을 보장할 수 있는 EBS 디스크 영역에 EBS Volume이 생성된다.

EBS Optimized Instance
EBS Optimized Instance는 EBS와 EC2 인스턴스간에 내부적으로 전용 네트워크를 사용하여 대역폭을 안정적으로 유지해준다. 500Mbps~1000Mbps 사이에 대역폭을 설정할 수 있다.

추가적인 기능
아마존 EC2의 VM 서비스는 몇 가지 추가적인 기능을 가지고 있다.

VM Import/Export
Virtualization 기반의 서비스인 만큼 다른 동작중인 VM에 대한 Snapshot을 뜰 수 있고, 이 Snapshot 파일을 Export할 수 있다. 반대로 Local PC나 자사의 데이타 센터에서 사용하는 VM Image를 Import할 수 도 있다. 현재 지원하는 포맷은 VMDK(VMWare 포맷),VHD(Microsoft), RAW 포맷등을 지원한다.

Amazon Marketplace
Amazon Market Place는 EC2 VM을 생성할때, 미리 소프트웨어가 다 깔려져 있는 VM 이미지를 구매할 수 있는 Market place이다.  예를 들어 VM 생성시 RedHat Enterprise Linux 이미지를 선택하면, RedHat Linux가 깔려 있는 VM이 생성된다. OS 뿐만 아니라 SAP와 같은 패키지 소프트웨어에서 부터 LAMP (Linux + Apache +MySQL + PHP)와 같은 여러 소프트웨어 솔루션의 조합까지 다양한 형태의 이미지들을 구매할 수 있다.



물론 이러한 이미지들은 공짜가 아니다 EC2 시간당 사용 요금에 함께 합쳐서 소프트웨어 라이센스비가 청구된다. 
제품에 따라서는 아마존을 통해서 기술 지원을 받을 수 있는 제품들도 있다. 예를 들어 RedHat Linux의 경우 가격은 일반 Linux VM에 비해서 두배 가량 비싸지만, 아마존을 통해서 기술 지원을 받을 수 있다.

Elastic IP
EC2 VM의 특징중의 하나가, VM이 생성되고 그리고 Restart될 때마다 그 IP 주소가 동적으로 매번 바뀌다는 것이다. 이렇게 IP가 바뀌면 서버간의 통신이나 외부 서비스시에 고정 IP가 없으면 서비스가 어렵기 때문에, 아마존에서는 인터넷 고정 IP 자체를 EIP 라는 이름으로 판매한다. EIP를 구매하면, 인터넷 Public IP가 하나 부여되고, 이를 EC2 인스턴스에 부여하면 고정 IP를 사용할 수 있다.

특성
이외에도 EC2 서비스는 몇 가지 특성을 가지고 있다.

IP 주소 변경
앞의 EIP에서도 설명하였듯이, EC2 인스턴스는 EIP를 배정하지 않는 이상 리스타트 때마다 IP가 변경된다. 고정 IP를 사용하는 방법은 EIP와 VPC (Virtual Private Cloud)를 사용하여 Private IP를 배정하는 방법이 있다. (나중에 설명)

IO 성능
EC2 서비스, 아니 모든 클라우드 서비스에서 가장 신경써야 하는 부분이 IO다. 기본적으로 LOCAL 서버 만큼의 성능이 나오지 않는다. 네트워크 구간 성능, EBS 디스크와 연결된 네트워크 성능 모두 일반 LOCAL 서버에 비해서 낮다.(물론 IO 옵션을 적용하고, 큰 인스턴스를 사용하면 높아진다.) 이 IO 성능은 인스턴스 크기에 비례하고, IO 옵션 (PIOPS, EBS Optimized Instance)에 따라서 높일 수 있다. LOCAL 환경에서 개발한 시스템들이 AWS EC2에 올리면 많은 성능 차이가 나는 이유중의 하나가 이 IO 성능 때문이다. 인스턴스별 IO 성능은  http://aws.amazon.com/ko/ec2/ 를 나와 있다. 주의할점은 EC2의 네트워크는 다른 EC2인스턴스와 공유해서 사용되기 때문에, 그 성능이 일정하지 않다. 큰 인스턴스를 사용하면, 전체적으로 성능은 올라가지만 그 성능에 대한 편차가 크기 때문에 서비스전에 반드시 측정 및 테스트 후에 사용해야 한다.

SLA
SLA는 Service Level Agreement의 약자로, 서비스의 안정성을 백분율로 나타낸 것인데, 100%이면 1년에 장애가 없는 것. 99.95%면 1년에 365일 * 0.05% 만큼 장애가 날 수 있다는 것이다. 그런데 아마존 EC2 서비스의 SLA는 바로 99.95% 이다. 1년에 4.38 시간이 장애가 나도 아마존 책임이 아니라는 이야기. 그래서 AWS에서 설계를 할때는 항상 데이타 센터 자체가 장애가 나거나 region이 장애가 나는 것을 염두 해두고 Zone간 또는 Region 간 Fail over (장애 대응) 시나리오를 고려해서 설계해야 한다.

시간 단위 과금
EC2 사용시 주의해야할 점은 시간 단위의 과금이다. 딱 시간 개념으로만 과금을 한다. 분이나 초의 개념이 없다. 무슨말이냐 하면, 1시간을 사용하던, 1시간00분1초~1시간59분59초는 무조건 2시간으로 과금이 된다. 그래서 EC2 인스턴스의 UP time (기동시간)을 자동화 하거나 스케쥴링 할경우에는 시간을 넘지 않도록 해야 불필요한 시간 과금이 발생하지 않는다.

CPU 단위 ECU
아마존은 EC2 인스턴스의 컴퓨팅 능력 즉, CPU의 단위를 ECU라는 단위로 표현한다.
ECU는 하나의 표현 단위일 뿐이지 1 ECU = 1 vCore나, 1CPU를 뜻 하는 것이 아니다.
아마존 홈페이지의 내용을 인용하면, 1 ECU는 
"
ECU(EC2 컴퓨팅 유닛) 1개는 1.0~1.2GHz 2007 Opteron 또는 2007 Xeon 프로세서와 동일한 CPU 용량을 제공합니다. 이는 원본 설명서에 언급되어 있는 초기 2006 1.7 GHz Xeon 프로세서와도 동일한 수준입니다" 라고 나와 있다. 5~6년전 CPU 성능이다.


인스턴스 과금 방식에 따른 분류
EC2는 계약 방식에 따라 다른 가격 체계를 가지고 있다.
  • Free : 개발이나 테스트를 할 수 있게 일부 인스턴스를 무료로 제공한다. micro 인스턴스의 경우 750시간 무료, 그 이후에는 과금이 되니 주의 바람 (참고 http://aws.amazon.com/ko/ec2/pricing/ )
  • On-Demand Instance : 우리가 일반적으로 사용하는 과금 방식으로, 사용한 시간 만큼 비용을 지불하는 형태이다.
  • Reserved Instance : 일정 기간 인스턴스 사용을 약속하고, 그에 대한 Discount를 받는 방식
  • Spot Instance : 입찰 방식의 사용방법.  사용자가 입찰 가격을 제시해놓으면, 아마존에서 남는 인스턴스들에 대해서 Spot 가격을 책정하는데, 이 가격이 입찰가격 내로 들어오면 인스턴스가 기동되는 방식. 입찰 가격이 넘어가면 자동으로 Spot Instance는 다시 종료 된다. 인스턴스의 가동 시간을 예측할 수 없기 때문에, OLTP식의 일반적인 업무에는 적절하지 않고, Batch 나 분석 업무 같이 대규모의 컴퓨팅 자원을 분산해서 처리 하지만, 항상 인스턴스가 떠 있을 필요가 없는 업무에 적절하다.
아마존을 사용하고, 어느정도 EC2의 볼륨이 확정되면 Reserved Instance를 사용하는 것이 좋다. On-Demand는 가격이 비싸다.
그리고 Map & Reduce와 같은 OLTP용 서비스가 아닌 Batch나 계산 업무는 Spot Instance를 사용하는 것이 좋다.


저작자 표시
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
 

티스토리 툴바