Home

SCon 컨퍼런스



SCon은 SOPT라는 IT 벤처 창업 동아리 소속의 대학생들이 it정보를 공유하기 위해 주최한 컨퍼런스라고 합니다.

이번 컨퍼런스는 빅데이터 시대의 대안책으로 떠오르고 있는 ‘미디어 3.0’과 ‘큐레이션’을 주제로 열릴 예정인데 관심이 가시는 대학생분들은 많은 참여를 부탁드립니다.
IT정보와 ‘미디어 3.0’, ‘큐레이션’에 관심있어하는 대학생들이 귀중한 정보를 접할 수 있는 소중한 기회가 될거 같습니다.
Tags :

Cacti로 MySQL 모니터링 및 튜닝 포인트

모니터링 도구로 Nagios, Zabbix, Ganglia 등 많지만, 저는 Cacti를 사용해 왔고(많이 사용한 건 아니지만) 최근 들어 많은 기능이 고도화(알림, 템플릿, 다루기 쉬움)되어서 나름 괜찮다고 생각해 Cacti를 가지고 MySQL을 모니터링하고 일부 튜닝 포인트도 잡을 수 있는 내용으로 기술해 봅니다.

모니터링하기 위해 Cacti를 설치하고, Plugin을 등록하자.

기존에 Cacti 설치 매뉴얼은 여기를 참조하면 설치가 가능하다. 이번에는 추가적으로 자주 활용되는 Cacti Plugin을 더 설치하였다.
> wget http://www.cacti.net/downloads/cacti-0.8.7i-PIA-3.1.zip
> unzip cacti-0.8.7i-PIA-3.1.zip
> cd /home/k2/www/cacti
> patch -p1 -N < /logs/src/cacti-0.8.7i-PIA-3.1/cacti-plugin-0.8.7e-PA-v2.6.diff

> cd /home/k2/www/cacti
> wget http://docs.cacti.net/_media/plugin:settings-v0.71-1.tgz -O settings.tgz
> tar zxvf settings*.tgz -C /home/k2/www/cacti/plugins
> chown -R apache:apache /home/k2/www/cacti/plugins/settings
> wget http://docs.cacti.net/_media/plugin:clog-v1.7-1.tgz -O clog.tgz 
> tar zxvf clog*.tgz -C /home/k2/www/cacti/plugins 
> chown -R apache:apache /home/k2/www/cacti/plugins/clog
> wget http://docs.cacti.net/_media/plugin:thold-v0.4.9-3.tgz -O thold.tgz 
> tar zxvf thold*.tgz -C /home/k2/www/cacti/plugins 
> chown -R apache:apache /home/k2/www/cacti/plugins/thold
> wget http://docs.cacti.net/_media/plugin:monitor-v1.3-1.tgz -O monitor.tgz
> tar zxvf monitor*.tgz -C /home/k2/www/cacti/plugins 
> chown -R apache:apache /home/k2/www/cacti/plugins/monitor
MySQL 모니터링을 위한 Cacti 템플릿으로 사용한 것은 better-cacti-templates(percona-monitoring-plugins)이다.
해당 플러그인을 다운로드 받은 다음 cacti 디렉토리의 ss_get_by_ssh.php, ss_get_mysql_stats.php 파일을 Cacti가 설치된 디렉토리의 scripts디렉토리(/home/k2/www/cacti/scripts)에 카피한다.
그리고 아래와 같이 MySQL의 계정 정보를 수정해 준다.
> vi ss_get_mysql_stats.php
$mysql_user = 'cactiuser';
$mysql_pass = 'cactipassword';
$mysql_port = 3306;
그 다음 다운받은 percona-monitoring-plugins Templates를 Cacti UI를 통해 아래와 같이 Import를 해준다.

Console -> Import Templates -> Import Template from Local File 에 cacti_host_template_percona_mysql_server_ht_0.8.6i-sver1.0.0.xml 파일을 업로드 한다.
그려면 success라는 응답을 내려주면서 정상적으로 Template이 등록이 완료된다.

그 다음 MySQL 서버가 Cacti 서버와 분리되어 있다면 Create Devices를 통해 호스트 등록을 하면서 Template과 함께 등록한다.
저는 Cacti 서버에 설치된 MySQL을 모니터링하기 때문에 기존 등록된 localhost에 template을 반영하도록 했다.

  • Console -> Devices -> Associated Graph Templates 에서 percona 템플릿 추가한다.
  • Console -> Data Sources Add 버튼을 클릭해서 데이터 소스 등록한다.
  • Console -> Graph Management Graph Add 하고 해당 Data Source 등록한다.

MySQL 성능 모니터링 관련 지표들을 몇가지 살펴보면

프로젝트 오픈 전에는 log-slow-queries, log_queries_not_using_indexes 등을 설정하여 인덱스를 사용하지 않는 쿼리, 인덱스를 사용해도 전체 Scan하는 쿼리를 모두 기록하고 그것을 튜닝한다. 그런데 전수 조사하기에는 분명 빠지는 부분이 있을 것이다.
그러나 오픈 후에는 성능상의 이유로 이런 기능을 disable시켜 놓게 된다. 하지만 문제되는 쿼리들은 분명 나오게 되는데 이를 해결하기 위해서는 모니터링 도구를 통해 즉각 대응할 수 있어야 한다. 그래서 Template에 사용되는 MySQL의 모니터링 도구에 표시되는 그래프를 통해 튜닝 포인트를 찾아내는 방법에 대해서 알아본다.

1) 트랜잭션 상황을 파악하는 MySQL Transaction Handler 이 그래프는 트랜젝션 완료 갯수와 롤백 개수를 나타낸다.


롤백의 현황을 통해 쿼리의 오류 정도를 확인 가능하고 Deadlock을 예측해 볼 수도 있다.

2) SQL의 종류를 확인하는 MySQL Command Counters
이 그래프는 어떤 종류의 SQL 문장이 실행되었는지를 나타내주는 그래프다. 단위 간격(기본 5분)마다 횟수이다 m는 밀리, 즉 1/1000이다. 예를 들면 100m라는 것은 5분 동안 발생 횟수가 0.1회하는 것으로, 50분만에 1번 발생했다는 것을 나타낸다.


Com은 Command의 약자로 Com Select/Delete/Insert/Update/Replace는 이름 그대로 SQL 실행 횟수이다. Com xxx Multi는 여러 테이블을 일괄적으로 Update하는 수를 나타낸다.
Questions은 MySQL 서버 시작 후 지금까지 요청된 쿼리 수.

3) SELECT의 실행 계획을 확인하는 MySQL Select Types
이 그래프는 개별 쿼리에 대해 EXPLAIN을함으로써 어떤 실행 계획을 사용하는지 알 수 있다.


인덱스가 없는 칼럼을 조회하는 Select Full Join에 표시되고 범위 지정도 역시 인덱스를 타지 않고 Join을 했을 경우 Select Full Range Join을 보면 된다.
이런 값들이 발생할 경우 튜닝의 대상으로 삼아야 한다.

4) 쿼리의 I/O 동작을 알수 있는 MySQL Handlers
MySQL 쿼리 실행 후 스토리지 엔진 API를 통해 일어나는 파일이나 디스크 I/O를 볼 수 있게 해 준다. show session status 값.


- Handler Read First : 테이블이나 인덱스의 Full Index Scan 시의 먼저 첫 번째 레코드 수. -> 튜닝 대상.
- Handler Read Key : 인덱스 키값에 따라 점프하여 읽는 횟수.
- Handler Read Next : 키 값에 따라 레코드를 확인한 후 후속 행을 읽은 횟수.
- Handler Read Prev : 키 값에 따라 이전 레코드 읽는 횟수.
- Handler Read Rnd : Random Read 값.
- Handler Read Rnd Next : Random Read 후속 읽기 횟수. -> 튜닝 대상.

5) 쿼리 캐시 감시하는 MySQL Query Cache
이 그래프는 캐시의 사용 변화 추이를 살펴 보면서 캐시를 효율적으로 사용하는지 파악하는 데 도움을 준다.


- Qcache_hits : 캐시에서 질의를 가져올 때마다 값이 증가.
- Qcache_inserts : 질의가 들어올 때마다 증가. inserts를 hits로 나누면 비적중률을, 1에서 비적중률을 빼면 적중률 계산이 가능함.
- Qcache_lowmem_prunes : 캐시를 위한 메모리가 부족해져 더 많은 질의를 위한 공간을 확보하기 위해 정리되어야 하는 횟수. 증가 추세에 있다면 단편화가 심각하거나 메모리가 부족하다는 징후.
- Qcache_not_cached : 일반적으로 SELECT 구문이 아니기 때문에 캐시 후보에서 제외된 질의 숫자.

6) 키 효율성 확인하는 MyISAM Indexes
키 버퍼는 MyISAM 테이블을 위한 인덱스 블록을 저장한다. 이상적인 경우 이 블록에 대한 요청은 디스크가 아니라 메모리에서 일어나야 한다는점을 알아두자.


- Key_reads : 디스크에서 요청한 숫자.
- Key_read_requests : 전체 숫자. Key_reads를 Key_read_requests로 나누면 비적중률 계산 가능. 비적중률이 높다면 키 버퍼를 늘려야 하는 등의 튜닝을 가해야 함.


[참조 사이트]

디스크 IO 성능 - I/O 스케줄러

I/O Scheduler

I/O 스케줄러는 디스크 I/O 를 효율화하기 위한 기능이다. Kernel 2.6.10에서 deadline, noop, cfq, anticipatory 4 종류가 있으며, 기본은 cfq.
OS 내에 있는 I/O scheduler 디자인을 결정하는 핵심 요소가 'throughput vs. latency(response time)'이다.
그리고 우리가 운영하는 서비스에서 특히 File I/O가 맞은 아키텍처에서는 튜닝 포인트 중에 하나라는 것도 알아두어야 한다.


I/O Elevator?

I/O Scheduler는 Request Queue를 적절히 조작하여 seek time을 최소화하면서 global throughput을 최대화하는 것인데, 여기엔 merging과 sorting의 두개의 기본 동작이 쓰인다.
즉 request가 들어왔을때 큐에 이미 그 request가 있거나 이웃한 block에 대한 request가 있을때 두개의 request를 합치는 것이다. 또한 디스크의 seek를 줄이기 위해서 새로 들어온 request를 FIFO 방식으로 뒤에 붙이는것이 아니라 이미 기다리고 있는 request들 사이에 block번호에 따라 sorting된 상태가 되게끔 삽입해 넣는것이다.
이렇게 함으로써 디스크의 seek를 최소화하고 disk의 arm은 디스크를 왕복 횡단하면서 서비스를 할수 있게 된다. 그렇다고 해서, "굶고 있는(starving)" I/O request가 많아도 안된다. 적당히 공정성(fairness)을 유지해서, latency도 줄여주어야 한다. 이러한 모습은 마치 Elevator와 비슷하기 때문에 I/O Scheduler는 Elevator라고도 불린다.


블록 I/O Request 일단 Elevator에 넣어져, 예약된 후 Dispatch된다. Dispatch되는 Request는 RequestQueue에 넣어져 장치 드라이버가 I/O를 수행해 간다.


I/O Elevator 종류는?

1. noop 스케줄러
- No Operation. 아무것도 하지 않는 스케줄러.
- 주로 지능형 RAID 컨트롤러있거나, SSD사용하거나, 반도체 디스크 등 성능 좋은 디스크를 사용할 경우 선택되어지는 스케줄러로 커널은 아무것도 하지 않는 것이 부하를 줄일 수 있다는 생각이 기저에 있다.

2. anticipatory(as) 스케줄러
- 발생되는 I/O 요청에서 향후 발생되는 I/O 요청의 위치를 예측하고 위치 떨어진 I/O 요청 처리를 중지하고 위치 가까운 I/O 요청을 처리하는 방식이다.
- 지연 시간을 줄이고 처리량을 향상하는 것.
- 전통적인 하드 디스크와 비슷한 구조이다.
- 입출력을 기다려 모아서 처리하는 성질이 있어 지연 시간은 나쁘게 될 가능성도 있다.

3. deadline 스케줄러
- I/O 대기 시간의 한계점(deadline)을 마련하고, 그것이 가까워 온 것부터 먼저 처리한다.
- 처리량보다 지연에 최적화된 스케줄링을 한다.
- 읽기 및 쓰기를 모두 균형있게 처리한다.
- 몇몇 프로세스가 많은 수의 I/O를 발생시키는 환경에 적합하다.
- 데이터 베이스의 파일 시스템에 많이 사용된다.

4. cfq(Completely Fair Queuing) 스케줄러
- 프로세스마다 I/O 대기열을 가지고 최대한 균등하게 예약을 한다.
- 많은 프로세스들이 세세한 I/O를 많이 발생시킬 때 사용하면 좋다.
- Fedora Core 커널 패키지의 기본이다.


설정 방법은?

1. grub.conf 수정
> vi /boot/grub/grub.conf
title Red Hat Enterprise Linux Server (2.6.18-8.el5)
root (hd0, 0)
kernel / vmlinuz-2.6.18-8.el5 ro root = /dev/vg0/lv0 elevator = deadline
initrd / initrd-2.6.18-8.el5.img 
2. scheduler 지정
> echo 'deadline'> /sys/block/<device>/queue/scheduler

참고로 RHEL 5.3 on Xen에서 grub.conf에서 I/O 스케줄러에 무엇을 지정해도 noop가 되어 버린다. 그래서 설정할 경우 2번 방식으로 처리해야 한다.


MySQL Benchmark Write 테스트 결과

1. 테스트 서버 환경
- H/W 정보
CPU : Intel Xeon Quad-Core X3440(2.53GHz)
Memory : DDR3 PC3-10600 (1,333MHz) 2GB x 2
OS : Centos 5.7 x86_64
DISK : SATA2 500GB (7200.ES) - PC급

- I/O Scheduler
cfq와 deadline을 번갈하 셋팅하고 리붓해서 테스트 진행.

- /etc/security/limits.conf
mysql soft nproc  8192
mysql hard nproc  16384
mysql soft nofile 8192
mysql hard nofile 65536

- /etc/sysctl.conf
net.ipv4.tcp_fin_timeout = 5
net.ipv4.tcp_keepalive_time = 10
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1

- my.cnf 설정(나머전 디폴트)
innodb_buffer_pool_size = 2G
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
max_connections=500
open-files-limit = 65535

- Memory Allocator
export LD_PRELOAD="/usr/local/lib/libtcmalloc.so"

- 테스트 테이블 레코드 사이즈 : 1024 bytes (insert 한 레코드 기준)

2. BMT 결과
현재 설치한 서버의 디폴트 I/O Scheduler는 cfq와 DB 서버에서 많이 설정해 사용하고 있는 deadline을 비교하여 Insert를 BMT 한 결과 deadline 조금 앞선 결과를 보여주었다.

근데 위 BMT는 스토리지가 어떻게 구성되었는지 등의 환경에 따라 성능치가 다르게 나올 수 있다는 점은 알아두었으면 한다.

요약 하자면..

환경에 따라 차이가 있을 수 있으니, 무엇이 최고라고 말하기 어렵다. 4가지 설정에 대해서 테스트해 보고 최적의 스케줄러를 설정하는 것이 가장 바람직하다.

  • 간략한 팁이라면, 디스크 I/O 성능이 좋다면(SSD 등-SSD 의 경우 디스크 헤드의 탐색이 없기 때문에) noop를 권장한다.
  • DB서버에는 주로 deadline과 noop를 사용하는 사례가 많다고 하니 참고만 하시라.
  • RAID로 구성된 DBMS 서버의 스케줄러는 cfq 보다 deadline을 권장한다.
  • KVM은 deadline 스케줄러가 권장되고 있다.

[참조 사이트]

JavaScript/HTML/CSS로 코딩 내용을 실시간 확인 가능한 Meteor에 대해

Meteor란? 그리고 설치 방법..

Meteor는 Web응용 프로그램을 개발하기위한 프레임 워크와 실행 환경을 제공해서 JavaScript/HTML/CSS 코딩 내용을 바로 확인해 주는 플랫폼이라고 이해하면 된다.

설치 방법은?
빠른 설치 방법도 있지만, 여기서는 컴파일 설치 방법으로 진행한다.

> git clone git://github.com/meteor/meteor.git
> cd meteor
> ./admin/generate-dev-bundle.sh
> ./install.sh
> meteor create --example leaderboard
> cd leaderboard
> meteor
[[[[[ ~/meteor/leaderboard ]]]]]

Initializing mongo database... this may take a moment.
Running on: http://localhost:3000/


내부 dependencies는 node.js, npm, mongodb 등의 패키지들이 엮여 있다.

위의 설치 과정에서 Leaderboard 샘플 프로젝트를 생성한 다음 meteor를 구동하게 되면 아래와 같은 테스트 결과 화면이 나타난다.호출 URL은 http://localhost:3000/이니 참고하고 화면이 안보인다면 방화벽에 해당 포트를 열어 줘야 한다.



서버의 코드 변경으로 Web 브라우저에서 실시간 확인이 가능하다.

> meteor create helloworld
> cd helloworld
> meteor
[[[[[ ~/meteor/helloworld ]]]]]

Initializing mongo database... this may take a moment.
Running on: http://localhost:3000/

Hello World를 최초 찍는 테스트 화면이다.



왼쪽 터미널에서 서버에서 helloworld.html을 수정해서 Hello World를 Hello Meteor로 수정했는데 아래 그림처럼 자동 웹 브라우저에 반영되는 것을 확인할 수 있다.


HTML뿐만 아니라 JavaScript를 변경하는 경우에도 마찬가지로, 서버에서 JavaScript 코드를 변경하면 코드가 자동으로 Web 브라우저에 전송되어 즉시 반영된다.

Web 브라우저에서 데이터 변경 또한, 서버로 실시간 반영이 가능하다.

다음은 Web 브라우저에서 Blue, Green, Red 등 색상의 이름을 표시하고 원하는 색상으로 투표한느 샘플이다. 샘플 프로그램은 JavaScript, HTML, CSS로 구성되어 있다.

> meteor create firstApp
> cd firstApp/

> cat firstApp.js
Colors = new Meteor.Collection("colors");

if (Meteor.is_client) {
 Template.firstApp.colors = function() {
    return Colors.find({}, {sort: {likes: -1, name: 1}});
 };
}

if (Meteor.is_server) {
  Meteor.startup(function () {
    // code to run on server at startup
  });
}
> meteor

firstApp.js의 첫번째 행은 Colors라는 컬렉션(Collection)을 선언하면 Colors를 저장하는 테이블이 서버 데이터베이스인 MongoDB에 만들어 진다.
세 번째 줄의 if 문은 만약 Web 브라우저에서 코드가 실행되고 있으면, HTML 템플릿 firstApp에 대해 Colors 컬렉션의 내용을 전체 검색(Colors.find)하고 정렬해서 리턴한다. 여기에 사용된 템플릿 엔진은 Handlebars가 사용되고 있다.
최초의 실행 화면은 아래와 같이 된다.


크롬에서 개발 도구를 통해 웹에서 데이터 추가를 아래 커맨드처럼 실행을 한다.

Colors.insert({name: "red"});
Colors.insert({name: "blue"}); 
Colors.insert({name: "green"}); 

그러면 웹에서 실행된 데이터는 Colors 컬렉션(MongoDB)에 데이터가 추가 되고 아래 화면처럼 지속적으로 MongoDB에서 데이터를 가져오기 때문에 세션이 끝나도 다른 브라우저에서도 같은 화면을 보게 된다.


Web 브라우저상에서 이용되는 데이터와 서버 데이터베이스는 항상 실시간으로 동기화하도록 되어 있는 것이 Meteor의 큰 특징의 하나다.

한 Web 브라우저에서 데이터 변경이 다른 Web 브라우저로 실시간 동기화도 가능하다.

데이터가 실시간으로 동기화하는 것을 확인하기 위해서 아래와 같이 Leaderboard 샘플을 참고로 하여 Like 버튼을 코드에 추가한다. 아래는 firstApp.js 코드이다.
<template name="firstApp">
  <div class="firstApp">
  {{#each colors}}
      {{> color_info}}
  {{else}}
    No colors yet.
  {{/each}}
 </div>
    {{#if maybe_selected}}
  <div class="details">
    <input type="button" class="inc" value="Give 1 points" />
  </div>
  {{/if}}

  {{#unless maybe_selected}}
  <div class="none">Click a color to select</div>
  {{/unless}}
</template>
<template name="color_info">
 <div class="color_info {{selected}}">
    <span class="likes">{{likes}} people like </span>
    <span class="name">{{name}}</span>
 </div>
</template>

아래 실행 결과 화면을 보면 왼쪽의 Web 브라우저 Like 버튼을 누르면 선택한 색상의 포인트가 증가와 동시에 다른 Web 브라우저에서 동일하게 포인트가 증가하고 있는 것을 볼 수 있다.



이런 프로그래밍은 개발하는데 특별한 노력없이도 가능하다는데 중요한 의미가 있을 듯 하다.

Troubleshooting

Error: watch EMFILE 오류 메세지가 발생했을 경우
cat /etc/sysctl.conf(root)
# inotify
fs.inotify.max_user_watches = 16384
fs.inotify.max_user_instances = 256
fs.inotify.max_queued_events = 32768

sysctl -a | grep fs.inotify #확인

Error: watch ENOSYS 오류 메세지가 발생했을 경우
node.js의 버그이므로 최신 버전을 설치하세요. v0.6.13 이상.

[참고 사이트]

Pivot Thinking

Pivot Thinking이란?

팀 퍼포먼스 올리는 방법을 검색하다가 나온 Pivot Thinking이라는 게 괜찮아 보여서 나름 이해하려고 정리를 해본 건데 쉽지 않네요.

Pivot Thinking은 문제를 검토하고 새로운 방향으로 나아가기 위한 인지 능력이라고 한다.
많은 사람이 설계 프로세스의 협업 특성에 대해 연구하고 있지만, 개별 팀 멤버의 "설계 사고 스타일'에는 별로 주목 받고 있지 않다고 한다. 그래서 스탠포드 대학의 과학자들은 최근의 과학적 연구에서 흥미로운 패턴을 발견했는데

"Divergers"(확산 사고 형의 사람)는 사실보다는 많은 문제를 좋아하고, 문제의 정의를 바꾸어 여러 답변을 낳는 경향이있다.
이에 대해 "Convergers"(집중적인 사고를 하는 사람)는 문제보다 사실을 좋아하고, 문제를 단지 "최적의 솔루션"으로 푸는 것을 바란다고 한다.



"Divergers"은 빨리 설계 프로세스를 시작하고.
먼저 가장 바람직하지 않은 옵션을 생각하고 과정을 진행 가면서 최종 결정을 내리기 식으로 문제를 해결한다.

"Convergers"는 설계 프로세스를 시작하면
더 신중하게 생각하고 신속하게 최종 결정을 내린다.

만약 "Divergers"며 "Convergers" 차이가 있다면, 행동을 중계해 주는 것이 적절하다. 이것이 과학자들이 'Pivot-Thinking'이라고 부른다.
Divergers는 Convergers방식을, Convergers는 Divergers를 바로 보게하는 것도 한 방법이다.

팀 프로세싱에 반영된다면

기능적으로 다양한 팀 구성원이 팀 상호 작용에 대한 인지 능력의 고유한 집합을 가지고 있으며, 이는 중요한 상호 작용이 필수인 팀 정보의 교환에 미치는 영향은 명확하게 확인되지 않았다.
새로운 제품 설계(NPD)팀의 이러한 인지적 다양성은 업무(Task)와 잠재 솔루션(Solution)의 팀 동료들간의 인식 차이를 낳게하는 것처럼 개개의 팀 멤버들은 팀의 업무를 다르게 인식할 가능성이 높아진다.
개인들의 인식 차이에서 오는 갭을 Pivot-Thinking 기술을 통해 인지 선호도의 가교 역할을 하면서 팀 리더십에 의해 극복될 수 있다고 한다.


H1 : 팀의 개인들은 집중적인지 혹은 확산적인 정보의 인지 선호도에 의해 정의된 트레이딩 존을 통해 정보를 교환게 된다.
H2 : 팀 리더의 행동은 'pivot thinking'이라는 행위를 통해 인지 갭을 상쇄시킨다. 그 'pivot thinking'이라는 행위를 통해 인지 선호도 외에 정보를 평가하여 팀 개개인을 위한 discovery zone을 생성하게 된다.

이해도가 높지 않아서 그런지 어렵네요.

[침고 사이트]

BaaS(Backend as a Service) 에 대하여

BaaS(Backend as a Service)이란 무엇인가?

클라우드 환경의 접속 장치로 PC보다는 iPhone이나 Android 같은 모바일 디바이스가 보편화되고 있다. 앞으로의 클라우드 애플 리케이션의 주역은 모바일 디바이스에서 움직임이 일어날 가능성이 크다는 의미도 포함하고 있는 것이다.
그래서 작은 틈새 시장중에 하나인 모바일 애플 리케이션에 특화된 클라우드 형태로 BaaS(Backend as a Service)라는 서비스가 등장하고 있다. 백엔드 플랫폼을 아웃소싱한다는 생각이 현실화 되고 있는 듯 하다.


BaaS엔 어떤 기능들이 있나?

BaaS에 포함되는 기능들은 일반적으로 모바일 응용 프로그램의 백 엔드로 자주 요구되는 데이터 저장소, 푸시, 사용자 관리/억세스 제어, 자체 인증/소셜 인증 등 소셜 연계, Location 연계, 분석 및 통계 정보, 빌링 등을 포함하고 있다.
BaaS의 목표는 이런 기능들을 모바일 응용 프로그램에서 API를 써 호출하는 서버 측 코드를 작성하지 않고도 클라우드와 연동해 모바일 응용 프로그램을 효율적으로 개발할 수 있는 환경을 제공하는 것이다.


모바일 기반의 클라우드 서비스 개발자들이 연동해서 사용하고 픈 서비스들의 인기도를 나타낸 위 그림을 보면 위치, 노티, 위치 관련 서비스들이 많은 것으로 보아 BaaS의 역할이 중요해 보인다.

속속 등장하는 BaaS

'Appcelerator Acquires Cocoafish' 기사를 통해 BasS 중에 하나인 Cocoafish가 Titanium Mobile을 운영하는 Appcelerator에 인수 되었고, Parse도 공개 베타 종료하고 정식 서비스 오픈한다고 발표했다. Baas의 움직임이 가속화되어 가는 듯 하다. 아래는 Mobile BaaS Ecosystem Map을 나타낸다.



위 BaaS 에코시스템 맵에서 보듯이 많은 BaaS 플랫폼들이 속속 등장하고 있다.
Cocoafish, Parse이외에도 StackMob, Kinvey, Buddy, CloudMine, iCloud, RhoMobile, FeedHenry Astrum Space, CloudyRec, Applicasa, QuickBlox, mobDB, Netmera 등...

일 예로 Parse는 1개의 데이터 저장소, 푸시 통신, 사용자 관리, Twitter 나 Facebook 등 소셜 연계, 위치 서비스와 연계 기능 등을 제공한다. iOS 용과 Android의 SDK를 제공하며, REST API도 제공하고 있다.
요금제 는 월 100만의 API 호출, 100만 푸시, 1GB 이내의 파일 저장 등이라면 무료, 1500 만 회 이내로, 500만 푸시, 10GB 이내의 파일 저장하면 월간 199 달러 지불하게 되어 있다.

apigee.com 처럼 API 종류도 많이 확보하면 더 좋은 무기가 될 듯 하다. 세상은 자신의 자산 확보의 가치보다는 연결의 가치가 더 빛을 발할 수 있는 시대가 되었구나.

[참고 사이트]

Consistent Hashing

NoSQL 관련 기술 중에 하나인 Consistent Hashing의 개념은 1997년에 MIT의 karger가 웹서버의 숫자가 수시로 변경되는 중에 분산 요청을 처리하기 위해 처음 고안했다고 하는데 그 내용을 살펴보고자 한다.
아래의 내용은 'Consistent Hashing' 이라는 아티클을 많이 참조해서 작성했다.

왜 필요한가?

N개의 캐시 시스템(노드)이 있다고 하고 이때 부하 분산에 사용하는 일반적인 방법은 Object o를 hash(o) mod n 번째 캐시 시스템에 저장하는 방식이다. 이런 방식은 캐시 시스템이 추가되거나 제거되기 전까지는 잘 운영된다.
그러나 캐시 시스템이 추가되거나 장애로 제거 되었을 경우, n이 빠뀌게 되면 모든 Object는 새로운 위치에 모두 재할당을 해야하는데 그러기엔 부하 부담이 크다.
이 때 Consistent Hashing 방법을 사용하게 되면 캐시 시스템이 추가되거나 작동이 중단되어도 모든 Object를 할당을 하는 것이 아니라 추가되면 인접한 다른 캐시 시스템에서 적정한 양의 Object 를 받게되고 마찬가지로 제거된다면 남은 캐시 시스템들이 나누는 형태가 되어 일관되게 일부 Object에 대해서 재 할당을 수행하게 된다. 그러므로 기존에 저장된 대부분의 캐시를 사용할 수 있으며 시스템 변동이 히트율에 영향을 미치지 않게 된다.
기본 원리는 Consistent hashing 알고리즘은 Object와 캐시 시스템 둘다 동일한 Hash 함수를 사용해서 해싱하는 것이다. 캐시 시스템은 구간을 정하고 그 구간에는 많은 Object의 해시값을 가지고 있는다. 캐시 시스템이 제거도면 인접한 구간의 캐시 시스템이 제거된 구간을 맞게되고 다른 캐시 시스템은 영향을 받지 않는다.
Performance는 O(log n).

작동 방식은?

Hash 함수는 Object와 캐시 시스템이 일정 구간을 정하게 한다. Java 언어의 예를 보면 Object의 hashCode() 함수는 리턴을 int로 하고 리턴값 int의 구간은 -2^31에서 2^31-1을 가진다.
다음 그림은 네 개의 Object(1,2,3,4)와 3개의 캐시 시스템(A, B, C)가 링에 배치되어 있다.


위의 그림에서 1,4는 캐시 시스템 A에 들어가고 2는 B, 3은 C에 들어 간다. 이때 C가 제거되었다고 가정하면 Object 3은 A에 들어간다. 기타 지원은 변하지 않는다. 다음 그림처럼 캐시 D가 추가되면, 3, 4는 D로 옮긴다. 그리고 1 만 A에 남아있다.


이렇게 함으로써 각 캐시 시스템에 할당된 구간의 사이즈에 예외가 발생해도 잘 동작하게 된다. 한가지 고민해야할 점은 무작위로 분포되기 때문에 캐시 시스템 사이의 Object의 분포는 균일하지 않을 수 있다. 이를 위한 해결책으로 '가상 노드'를 사용하는 방법이 있다. 가상 노드는 캐시 시스템의 링안에서 복제하는데 이는 캐시 시스템 하나 추가할때마다 링에 여러개 배치되게 되는 방식이다.
가상 노드의 효과는 다음 그래프와 같은데 10,000개의 Object를 10개의 캐시 시스템으로 시뮬레이션한 결과이다. X축이 캐시 시스템의 복제수가 되고 Y축은 표준 편차.
복제 수가 작은 Object들의 분산도가 언발란스한데 이는 캐시 시스템의 Object수의 평균의 표준 편차가 크기 때문일 것이다. 이 실험에서 복제를 100이나 200으로 했을 경우 합리적인 균형을 실현할 수 있다고 할 수 있었다고 한다. (표준 편차가 평균 5-10% 정도가 적당함)


시스템마다 다수의 Virtual Nodes(가상 노드)를 만들어서 로드발란싱을 좋게 한 예는 libketema이다.

구현 방법은?

Consistent Hashing 방법이 효력이 발휘하기 위해서는 해싱 함수가 잘 동작해야하는데 Object의 hashCode로는 부족하고 MD5를 추천한다.
public class ConsistentHash {

  private final HashFunction hashFunction;
  private final int numberOfReplicas;
  private final SortedMap circle =
    new TreeMap();

  public ConsistentHash(HashFunction hashFunction,
    int numberOfReplicas, Collection nodes) {

    this.hashFunction = hashFunction;
    this.numberOfReplicas = numberOfReplicas;

    for (T node : nodes) {
      add(node);
    }
  }

  public void add(T node) {
    for (int i = 0; i < numberOfReplicas; i++) {
      circle.put(hashFunction.hash(node.toString() + i),
        node);
    }
  }

  public void remove(T node) {
    for (int i = 0; i < numberOfReplicas; i++) {
      circle.remove(hashFunction.hash(node.toString() + i));
    }
  }

  public T get(Object key) {
    if (circle.isEmpty()) {
      return null;
    }
    int hash = hashFunction.hash(key);
    if (!circle.containsKey(hash)) {
      SortedMap tailMap =
        circle.tailMap(hash);
      hash = tailMap.isEmpty() ?
             circle.firstKey() : tailMap.firstKey();
    }
    return circle.get(hash);
  } 

}

사용 사례는?

- NoSQL
- 오픈 소스

[참조 사이트]