<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title>파란 개발자 블로그</title>
	
	<link>http://dev.paran.com</link>
	<description>개발자가 행복한 회사 kth</description>
	<lastBuildDate>Wed, 23 May 2012 05:51:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/devparan" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="devparan" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">devparan</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>MySQL에서 테이블 스키마를 “무중단”으로 변경해보자!!</title>
		<link>http://dev.paran.com/2012/05/23/mysql-table-schema-update-without-service-stop/</link>
		<comments>http://dev.paran.com/2012/05/23/mysql-table-schema-update-without-service-stop/#comments</comments>
		<pubDate>Wed, 23 May 2012 05:47:39 +0000</pubDate>
		<dc:creator>sdchan1</dc:creator>
				<category><![CDATA[Tech Note]]></category>
		<category><![CDATA[Alter Table]]></category>
		<category><![CDATA[Migration]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://dev.paran.com/?p=7656</guid>
		<description><![CDATA[kth 데이터지능팀 성동찬 &#160; Overview MySQL은 단순 쿼리 처리 능력은 탁월하나 테이블 스키마 변경 시에는 상당히 불편합니다. 일단 테이블 스키마 변경 구문을 실행하면 임시 테이블 생성 후 데이터를 복사하고, 데이터를 복사하는 동안에는 테이블에 READ Lock이 발생하여 데이터 변경 작업을 수행하지 못합니다. (Table Lock이 걸리죠.) 이 같은 현상은 인덱스, 칼럼 추가/삭제 뿐만 아니라 캐릭터셋 변경 시에도 [...]]]></description>
			<content:encoded><![CDATA[<h3>kth 데이터지능팀 성동찬</h3>
<p>&nbsp;</p>
<h1 id="MySQLIsolationLevel에따른SQL사용주의사항-Overview"><strong>Overview</strong></h1>
<p>MySQL은 단순 쿼리 처리 능력은 탁월하나 테이블 스키마 변경 시에는 상당히 불편합니다.<br />
일단 테이블 스키마 변경 구문을 실행하면 임시 테이블 생성 후 데이터를 복사하고,<br />
데이터를 복사하는 동안에는 테이블에 READ Lock이 발생하여 데이터 변경 작업을 수행하지 못합니다. (Table Lock이 걸리죠.)</p>
<p>이 같은 현상은 인덱스, 칼럼 추가/삭제 뿐만 아니라 캐릭터셋 변경 시에도 동일하게 발생합니다.<br />
(최근 5.5 버전에서는 인덱스 추가/삭제에서는 임시 테이블을 생성하지 않습니다.)</p>
<p>얼마 전 서비스 요구 사항 중 테이블 칼럼을 무중단으로 변경하는 것이 있었는데, 이에 관해 정리 드리겠습니다.^^</p>
<h1><strong>요구사항</strong></h1>
<p>서비스 요구사항과 개인적인 요구 사항은 다음과 같습니다.</p>
<ol>
<li><strong>최대한 서비스 중단 없이 가능해야 함</strong></li>
<li><strong>테이블에 Lock이 발생하지 말아야 함</strong></li>
<li><strong>빠르게 구현해야 함(개인 요구 사항)</strong></li>
<li><strong>재사용 가능해야 함(개인 요구 사항)</strong></li>
<li><strong>문제 발생 시 복구가 쉬워야 함</strong></li>
</ol>
<p>개인적으로 빠르게 적용하는 것과 이와 같은 이슈가 추후 재 발생 시 재사용할 수 있도록 모듈화하자는 것이 목표였습니다.</p>
<h1><strong>대상 테이블 분석</strong></h1>
<p>대상 테이블은 다음과 같은 특징이 있었습니다.</p>
<ol>
<li><strong>Auto_increment 옵션이 적용되었으며, Primary Key가 존재함</strong></li>
<li><strong>데이터 변경에는 Insert와 Delete만 발생(Update 없음)</strong></li>
<li><strong>연관된 프로시저 및 트리거는 없음</strong></li>
</ol>
<p>무엇보다 Update가 없기 때문에 조금 더 생각을 심플하게 가져갈 수 있었습니다.</p>
<h1><strong>작업 시나리오</strong></h1>
<p><img class="alignnone size-full wp-image-7668 colorbox-7656" src="http://dev.paran.com/wp-content/uploads/2012/05/how_to_migrate_data1.png" alt="How to migrate data to different table" width="399" height="270" /></p>
<p>트리거로 기존 테이블에 Insert및 Delete 시 변경 분을 별도 테이블에 저장을 합니다.<br />
그리고 임시 테이블을 만들고 해당 테이블에 기존 테이블 데이터를 이관합니다. 물론 임시 테이블에는 원하는 스키마로 변경된 상태겠죠.<br />
Import가 마무리되면 트리거에 쌓인 데이터로 변경 분을 적용하고 최종적으로 테이블을 Rename함으로써 프로세스가 마무리됩니다.</p>
<p>조금더 상세하게 풀자면 다음과 같습니다.</p>
<ol>
<li><strong>임시 테이블 생성</strong>
<ul>
<li>Insert/Delete 시 변경 사항을 저장할 테이블<br />
(TAB01_INSERT, TAB01_DELETE)</li>
<li>데이터를 임시로 저장할 테이블</li>
</ul>
</li>
<li><strong>트리거 생성</strong>
<ul>
<li>원본 테이블에 Delete 발생 시 해당 ROW를 임시 테이블에 저장</li>
<li>원본 테이블에 Insert 발생 시 해당 ROW를 임시 테이블에 저장</li>
</ul>
</li>
<li><strong>원본 테이블 export/import</strong>
<ul>
<li>export -&gt; 테이블명 변경 -&gt; import</li>
<li>SED로 테이블 명을 임시 테이블 명으로 변경</li>
</ul>
</li>
<li><strong>원본 테이블과 임시 테이블 RENAME</strong>
<ul>
<li>원본 테이블 : TAB01 -&gt; TAB01_OLD</li>
<li>임시 테이블 : TAB01_TMP -&gt; TAB01</li>
</ul>
</li>
<li><strong>테이블 변경 분 저장</strong>
<ul>
<li>TAB01_INSERT에 저장된 데이터 Insert</li>
<li>TAB01_DELETE에 저장된 데이터 Delete</li>
</ul>
</li>
<li><strong>트리거, 임시테이블 제거</strong>
<ul>
<li>트리거 : Insert트리거, Delete 트리거</li>
<li>테이블 : TAB01_INSERT, TAB01_DELETE</li>
</ul>
</li>
</ol>
<p>모든 작업을 어느정도 자동화 구현하기 위해 &#8220;작업 스크립트&#8221;를 만드는 프로시저와 데이터 이관을 위한 Shell 스크립트를 작성하였습니다.</p>
<p>Shell 스크립트는 Export와 동시에 SED 명령을 통해 자동으로 테이블 이름을 변경하여 Import하도록 구현하였습니다.</p>
<p>DB명, 테이블명,  스키마 변경 내용을 다음과 같이 인자 값으로 넘겨서 프로시저를 호출합니다.<br />
(프로시저 소스는 가장 하단 참조)</p>
<pre>call print_rb_query('dbatest', 'TAB01', 'MODIFY ACT_DESC VARCHAR(100) CHARACTER SET UTF8MB4 COLLATE UTF8MB4_UNICODE_CI DEFAULT NULL;');</pre>
<p>그러면 아래와 같이 결과가 나오는데 Step1, 2, 3을 순차적으로 실행하면 됩니다. 보기 쉽게 주석을 추가하겠습니다.^^</p>
<pre>&gt;&gt; Step 1&gt; Prepare : SQL &lt;&lt;
## 임시 테이블 생성
DROP TABLE IF EXISTS dbatest.TAB01_INSERT;
CREATE TABLE dbatest.TAB01_INSERT LIKE TAB01;
DROP TABLE IF EXISTS dbatest.TAB01_DELETE;
CREATE TABLE dbatest.TAB01_DELETE LIKE TAB01;
DROP TABLE IF EXISTS dbatest.TAB01_TMP;
CREATE TABLE dbatest.TAB01_TMP LIKE TAB01;

## 임시 테이블 스키마 변경
ALTER TABLE dbatest.TAB01_TMP AUTO_INCREMENT = 10660382;
ALTER TABLE dbatest.TAB01_TMP MODIFY ACT_DESC VARCHAR(100) CHARACTER SET UTF8MB4 COLLATE UTF8MB4_UNICODE_CI DEFAULT NULL;
DELIMITER $$

## Delete 트리거 생성
DROP TRIGGER IF EXISTS dbatest.TRG_TAB01_DELETE$$
CREATE TRIGGER dbatest.TRG_TAB01_DELETE
AFTER DELETE ON dbatest.TAB01
FOR EACH ROW
BEGIN
INSERT INTO dbatest.TAB01_DELETE VALUES(
    OLD.ACT_ID,
    OLD.ACT_UID,
    OLD.ACT_USER_NAME,
    OLD.ACT_TIME,
    OLD.TO_UID,
    OLD.TO_USER_NAME,
    OLD.ACT_TYPE,
    OLD.POSTID,
    OLD.TAB01,
    OLD.ACT_DESC,
    OLD.BEFORE_USER_NAME,
    OLD.PHOTO_LINK,
    OLD.THUMB_URL,
    OLD.FROM_SERVICE);
END$$

## Insert 트리거 생성
DROP TRIGGER IF EXISTS dbatest.TRG_TAB01_INSERT$$
CREATE TRIGGER dbatest.TRG_TAB01_INSERT
AFTER INSERT ON dbatest.TAB01
FOR EACH ROW
BEGIN
INSERT INTO dbatest.TAB01_INSERT VALUES(
    NEW.ACT_ID,
    NEW.ACT_UID,
    NEW.ACT_USER_NAME,
    NEW.ACT_TIME,
    NEW.TO_UID,
    NEW.TO_USER_NAME,
    NEW.ACT_TYPE,
    NEW.POSTID,
    NEW.TAB01,
    NEW.ACT_DESC,
    NEW.BEFORE_USER_NAME,
    NEW.PHOTO_LINK,
    NEW.THUMB_URL,
    NEW.FROM_SERVICE);
END$$
DELIMITER ;

&gt;&gt; Step 2&gt; Data Copy : Shell Script &lt;&lt;
## 데이터 마이그레이션
mig_dif_tab.sh dbatest TAB01 TAB01_TMP

&gt;&gt; Step 3&gt; Final Job : SQL &lt;&lt;
## 변경분 적용
INSERT INTO dbatest.TAB01_TMP SELECT * FROM dbatest.TAB01_INSERT;
DELETE A FROM dbatest.TAB01_TMP A INNER JOIN dbatest.TAB01_DELETE B ON A.ACT_ID = B.ACT_ID;

## 테이블 Rename(Swap)
RENAME TABLE dbatest.TAB01 TO dbatest.TAB01_OLD, dbatest.TAB01_TMP TO dbatest.TAB01;

## 트리거 제거
DROP TRIGGER IF EXISTS dbatest.TRG_TAB01_DELETE;
DROP TRIGGER IF EXISTS dbatest.TRG_TAB01_INSERT;

##변경분 재 적용 (확인 사살)
INSERT INTO dbatest.TAB01 SELECT * FROM dbatest.TAB01_INSERT;
DELETE A FROM dbatest.TAB01 A INNER JOIN dbatest.TAB01_DELETE B ON A.ACT_ID = B.ACT_ID;

## 임시 테이블 제거
DROP TABLE IF EXISTS dbatest.TAB01_INSERT;
DROP TABLE IF EXISTS dbatest.TAB01_DELETE;</pre>
<p>임시 테이블에는 Auto_increment 값을 <span style="text-decoration: underline"><strong>기존보다 1% 높게 설정</strong></span>하여 테이블명 Swap 후 Primary Key 충돌이 없도록 하였습니다.<br />
그리고 Insert ignore문을 사용하여 Primary Key 중복으로 발생하는 오류는 무시하도록 하였고, 테이블 Rename 후 변경분을 재 적용하는 확인사살도 하였습니다. ^^;;</p>
<h2>Shell 스크립트</h2>
<p>위에서 Step2에서 사용하는 Shell 스크립트는 다음과 같습니다.</p>
<pre>#!/bin/sh
if [ $# -ne 3 ]; then
echo "Usage: ${0}   "
echo ""
echo "Database Name : snsdb"
echo "Orignal Table : tab01"
echo "Target Table  : tab01_tmp"
echo "==&gt; ${0} snsdb tab01 tab01_tmp"
exit 1
fi
## Declare Connection Info
export DB_CONNECT_INFO="-u계정 -p패스워드"
export REMOTE_DB_HOST="DB호스트URL"
export REMOTE_DB_PORT="3306"
## Exec profile for mysql user
. ~/.bash_profile
## Dump and Insert Data
mysqldump ${DB_CONNECT_INFO}                           \
  --single-transaction                                 \
  --no-create-db                                       \
  --no-create-info                                     \
  --triggers=false                                     \
  --comments=false                                     \
  --add-locks=false                                    \
  --disable-keys=false                                 \
  --host=${REMOTE_DB_HOST}                             \
  --port=${REMOTE_DB_PORT}                             \
  --databases ${1}                                     \
  --tables ${2}                                        \
| sed -r 's/^INSERT INTO `'${2}'`/INSERT INTO `'${3}'`/gi' \
| mysql ${DB_CONNECT_INFO} -h ${REMOTE_DB_HOST} -P ${REMOTE_DB_PORT} ${1}</pre>
<p>Export 값을 파이프(|)로 sed로 넘기고, sed에서는 테이블명만 정규식으로 바꿔서 최종적으로 Import하는 구문입니다.</p>
<p>Create Table As Select 혹은 Insert into Select 구문을 사용하지 않은 이유는 <span style="text-decoration: underline">Redo 로그가 비대해짐에 따라 시스템 부하</span>가 따르기 때문입니다.<br />
tx_isolation 값을 READ-COMMITTED로 설정하여도 데이터가 전체 들어간 시점에 <span style="text-decoration: underline">일시적인 테이블 Lock이 발생</span>합니다.<br />
(트랜잭션을 마무리하는 과정에서 발생하는 Lock입니다.)<br />
&#8220;<a title="Permanent Link: MySQL 트랜잭션 Isolation Level로 인한 장애 사전 예방 법" href="http://gywn.net/2012/05/mysql-transaction-isolation-level/" rel="bookmark">MySQL 트랜잭션 Isolation Level로 인한 장애 사전 예방 법</a>&#8221; 을 참고하세요.^^</p>
<h2>프로시저</h2>
<p>단일 테이블이라면 위에 있는 스크립트를 약간만 수정하면 되겠지만,<br />
제 경우는 변경할 테이블이 꽤 많아서 스크립트를 생성하는 프로시저를 아래와 같이 구현하였습니다.</p>
<p>사실 모든 과정을 Perl 혹은 Java로 구현하면 Step없이 간단했겠지만,<br />
DB 접속 서버에 구성하기 위해서는 절차 상 복잡한 부분이 있어서 프로시저로 작성하였습니다. ㅎㅎ</p>
<pre>DELIMITER $$
DROP PROCEDURE print_rb_query $$
CREATE PROCEDURE print_rb_query(IN P_DB VARCHAR(255), IN P_TAB VARCHAR(255), IN P_ALTER_STR VARCHAR(1024))
BEGIN
## Declare Variables
SET @qry = '\n';
SET @ai_num = 0;
SET @ai_name = '';
SET @col_list = '';

## Get AUTO_INCREMENT Number for Temporary Table
SELECT CAST(AUTO_INCREMENT*1.01 AS UNSIGNED) INTO @ai_num
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = P_DB
AND TABLE_NAME = P_TAB;

## Get auto_increment Column Name
SELECT COLUMN_NAME INTO @ai_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = P_DB
AND TABLE_NAME = P_TAB
AND EXTRA = 'auto_increment';

SET @qry = CONCAT(@qry, '&gt;&gt; Step 1&gt; Prepare : SQL &lt;&lt;\n');
SET @qry = CONCAT(@qry, 'DROP TABLE IF EXISTS ',P_DB,'.',P_TAB,'_INSERT;\n');
SET @qry = CONCAT(@qry, 'CREATE TABLE ',P_DB,'.',P_TAB,'_INSERT LIKE ',P_TAB,';\n');
SET @qry = CONCAT(@qry, 'DROP TABLE IF EXISTS ',P_DB,'.',P_TAB,'_DELETE;\n');
SET @qry = CONCAT(@qry, 'CREATE TABLE ',P_DB,'.',P_TAB,'_DELETE LIKE ',P_TAB,';\n');
SET @qry = CONCAT(@qry, 'DROP TABLE IF EXISTS ',P_DB,'.',P_TAB,'_TMP;\n');
SET @qry = CONCAT(@qry, 'CREATE TABLE ',P_DB,'.',P_TAB,'_TMP LIKE ',P_TAB,';\n');
SET @qry = CONCAT(@qry, 'ALTER TABLE ',P_DB,'.',P_TAB,'_TMP AUTO_INCREMENT = ',@ai_num,';\n');
SET @qry = CONCAT(@qry, 'ALTER TABLE ',P_DB,'.',P_TAB,'_TMP ',P_ALTER_STR,'\n');

## Change Delimiter
SET @qry = CONCAT(@qry, 'DELIMITER $$\n');

## Get Column List for Delete Trigger
select GROUP_CONCAT('\n OLD.',COLUMN_NAME) into @col_list
from INFORMATION_SCHEMA.COLUMNS
where TABLE_SCHEMA = P_DB
and table_name = P_TAB
order by ORDINAL_POSITION;

SET @qry = CONCAT(@qry, 'DROP TRIGGER IF EXISTS ',P_DB,'.TRG_',P_TAB,'_DELETE$$\n');
SET @qry = CONCAT(@qry, 'CREATE TRIGGER ',P_DB,'.TRG_',P_TAB,'_DELETE\n');
SET @qry = CONCAT(@qry, 'AFTER DELETE ON ',P_DB,'.',P_TAB,'\n');
SET @qry = CONCAT(@qry, 'FOR EACH ROW\n');
SET @qry = CONCAT(@qry, 'BEGIN\n');
SET @qry = CONCAT(@qry, 'INSERT INTO ',P_DB,'.',P_TAB,'_DELETE VALUES(');
SET @qry = CONCAT(@qry, @col_list);
SET @qry = CONCAT(@qry, ');\n');
SET @qry = CONCAT(@qry, 'END$$\n');

## Get Column List for Insert Trigger
select GROUP_CONCAT('\n NEW.',COLUMN_NAME) into @col_list
from INFORMATION_SCHEMA.COLUMNS
where TABLE_SCHEMA = P_DB
and table_name = P_TAB
order by ORDINAL_POSITION;
SET @qry = CONCAT(@qry, 'DROP TRIGGER IF EXISTS ',P_DB,'.TRG_',P_TAB,'_INSERT$$\n');
SET @qry = CONCAT(@qry, 'CREATE TRIGGER ',P_DB,'.TRG_',P_TAB,'_INSERT\n');
SET @qry = CONCAT(@qry, 'AFTER INSERT ON ',P_DB,'.',P_TAB,'\n');
SET @qry = CONCAT(@qry, 'FOR EACH ROW\n');
SET @qry = CONCAT(@qry, 'BEGIN\n');
SET @qry = CONCAT(@qry, 'INSERT INTO ',P_DB,'.',P_TAB,'_INSERT VALUES(');
SET @qry = CONCAT(@qry, @col_list);
SET @qry = CONCAT(@qry, ');\n');
SET @qry = CONCAT(@qry, 'END$$\n');

## Change Delimiter
SET @qry = CONCAT(@qry, 'DELIMITER ;\n');
SET @qry = CONCAT(@qry, '\n\n');

## Insert Data
SET @qry = CONCAT(@qry, '&gt;&gt; Step 2&gt; Data Copy : Shell Script &lt;&lt;\n');
SET @qry = CONCAT(@qry, 'mig_dif_tab.sh ',P_DB,' ',P_TAB,' ',P_TAB,'_TMP\n');
SET @qry = CONCAT(@qry, '\n\n');
SET @qry = CONCAT(@qry, '&gt;&gt; Step 3&gt; Final Job : SQL &lt;&lt;\n');

## Insert Data into Temporary Table
SET @qry = CONCAT(@qry, 'INSERT IGNORE INTO ',P_DB,'.',P_TAB,'_TMP SELECT * FROM ',P_DB,'.',P_TAB,'_INSERT;\n');

## Delete Data from Temporary Table
SET @qry = CONCAT(@qry, 'DELETE A FROM ',P_DB,'.',P_TAB,'_TMP A INNER JOIN ',P_DB,'.',P_TAB,'_DELETE B ON A.',@ai_name,' = B.',@ai_name,';\n');

## Swap table names
SET @qry = CONCAT(@qry, 'RENAME TABLE ',P_DB,'.',P_TAB,' TO ',P_DB,'.',P_TAB,'_OLD, ',P_DB,'.',P_TAB,'_TMP TO ',P_DB,'.',P_TAB,';\n');

## Drop Triggers
SET @qry = CONCAT(@qry, 'DROP TRIGGER IF EXISTS ',P_DB,'.TRG_',P_TAB,'_DELETE;\n');
SET @qry = CONCAT(@qry, 'DROP TRIGGER IF EXISTS ',P_DB,'.TRG_',P_TAB,'_INSERT;\n');

## Insert Data
SET @qry = CONCAT(@qry, 'INSERT IGNORE INTO ',P_DB,'.',P_TAB,' SELECT * FROM ',P_DB,'.',P_TAB,'_INSERT;\n');

## Delete Data
SET @qry = CONCAT(@qry, 'DELETE A FROM ',P_DB,'.',P_TAB,' A INNER JOIN ',P_DB,'.',P_TAB,'_DELETE B ON A.',@ai_name,' = B.',@ai_name,';\n');

## Drop Temporary Tables
SET @qry = CONCAT(@qry, 'DROP TABLE IF EXISTS ',P_DB,'.',P_TAB,'_INSERT;\n');
SET @qry = CONCAT(@qry, 'DROP TABLE IF EXISTS ',P_DB,'.',P_TAB,'_DELETE;\n');
SET @qry = CONCAT(@qry, '\n\n');
SELECT @qry;
END$$
DELIMITER ;</pre>
<h1><strong>Conclusion</strong></h1>
<p>결과적으로 서비스 영향없이 무중단으로 테이블 스키마를 변경하였습니다.<br />
만약 Update가 있는 경우라면 &#8220;INSERT INTO .. ON DUPLICATE KEY UPDATE..&#8221; 문을 사용하면 해결 가능하다는 생각이 드네요.^^<br />
물론 Update 트리거에도 Insert와 동일한 액션이 취해져야 하겠죠.</p>
<p>서비스 중단없이 DB 스키마를 변경했다는 점에서 큰 의의가 있었네요.^^</p>
<p>질문은 <strong>@gywndi</strong> 로 트윗을 날려주세요^^</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.paran.com/2012/05/23/mysql-table-schema-update-without-service-stop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Microsoft 의 SNS서비스 So.Cl 은 무엇인가</title>
		<link>http://dev.paran.com/2012/05/22/microsoft-sns-so-cl/</link>
		<comments>http://dev.paran.com/2012/05/22/microsoft-sns-so-cl/#comments</comments>
		<pubDate>Tue, 22 May 2012 07:52:29 +0000</pubDate>
		<dc:creator>junsle</dc:creator>
				<category><![CDATA[퀵 리뷰]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[SNS]]></category>
		<category><![CDATA[so.cl]]></category>

		<guid isPermaLink="false">http://dev.paran.com/?p=7591</guid>
		<description><![CDATA[kth Android 팀 전슬마로 So.cl의 등장 A new research experience for student를 모토로 하는 MS의 SNS 서비스가 출범했습니다. 총평을 먼저 내리자면 확실히 So.cl은 교육 및 리서치 등에 특화된 SNS서비스 입니다. 이번 리뷰를 하면서 느낀것은 So.cl은 소모임이나 과제를 할때 공동의 목표를 가지고 있는 집단에서 여러 혼재되어있는 자료중 필요한 것들만 피드에 정리해서 넣을 수 있는, 확실히 핀터레스트보다 더 훌륭한 개인 큐레이션 서비스가 [...]]]></description>
			<content:encoded><![CDATA[<h3>kth Android 팀 전슬마로</h3>
<p></p>
<h1 id="Socl-Socl의등장"></h1>
<h1>So.cl의 등장</h1>
<p><strong>A new research experience for student를 모토로 하는 MS의 SNS 서비스가 출범했습니다.</strong><br />
<a href="http://dev.paran.com/wp-content/uploads/2012/05/스크린11-1024x6311.jpg"><img class="alignnone  wp-image-7638 colorbox-7591" title="스크린11-1024x631" src="http://dev.paran.com/wp-content/uploads/2012/05/스크린11-1024x6311.jpg" alt="" width="617" height="375" /></a><br />
총평을 먼저 내리자면 확실히 <strong>So.cl은 교육 및 리서치 등에 특화된 SNS서비스</strong> 입니다.<br />
이번 리뷰를 하면서 느낀것은 So.cl은 소모임이나 과제를 할때 공동의 목표를 가지고 있는 집단에서 여러 혼재되어있는 자료중 필요한 것들만 피드에 정리해서 넣을 수 있는, 확실히 핀터레스트보다 더 훌륭한 개인 큐레이션 서비스가 되어진다는 것 입니다.</p>
<h1 id="Socl-Socl에서내세우는3가지특화서비스">So.cl에서 내세우는 3가지 특화 서비스!</h1>
<p><a href="http://dev.paran.com/wp-content/uploads/2012/05/스ED7A1.png"><img class="alignnone size-full wp-image-7608 colorbox-7591" title="스ED7A~1" src="http://dev.paran.com/wp-content/uploads/2012/05/스ED7A1.png" alt="" width="527" height="73" /></a></p>
<p>첫번째 특징인 피드 브라우저는 아래와 같이 페이스북의 뉴스피드와 별반 다를것이 없어 자세한 설명은 생략하겠습니다.</p>
<p>&nbsp;</p>
<p><a href="http://dev.paran.com/wp-content/uploads/2012/05/tumblr_lw7r6dqRR01r2d8a6.png"><img class="alignnone size-full wp-image-7610 colorbox-7591" title="tumblr_lw7r6dqRR01r2d8a6" src="http://dev.paran.com/wp-content/uploads/2012/05/tumblr_lw7r6dqRR01r2d8a6.png" alt="" width="495" height="478" /></a></p>
<p><a href="http://dev.paran.com/wp-content/uploads/2012/05/스크린2.png"><img class="alignnone size-full wp-image-7611 colorbox-7591" title="스크린~2" src="http://dev.paran.com/wp-content/uploads/2012/05/스크린2.png" alt="" width="545" height="434" /></a></p>
<p>두번째 특징은 포스트 작성시 내가 원하는 주제에 대해 검색한 결과에 대해 핀터레스트 + 관련 정보 형식으로 게시할 수 있다는 것입니다.</p>
<p>좀더 자세히 살펴보면 만약 내가 &#8220;한국&#8221;에 대한 주제에 대해 조사하려고 한다고 가정합니다.</p>
<p>그럼 아래와 같은 플로우로 So.cl을 사용할 수 있을 것입니다.</p>
<p>&nbsp;</p>
<p>1. 한국으로 검색을 한다.<br />
<a href="http://dev.paran.com/wp-content/uploads/2012/05/스크린21.png"><img class="alignnone size-full wp-image-7612 colorbox-7591" title="스크린~2" src="http://dev.paran.com/wp-content/uploads/2012/05/스크린21.png" alt="" width="505" height="49" /></a></p>
<p>&nbsp;</p>
<p>2. 검색결과중에 맘에 드는 자료들을 선택한다.</p>
<p>&nbsp;</p>
<p>이미지의 경우 원하는 이미지를 클릭, 웹사이트의 경우 ADD TO POST 버튼을 누르면 나의 게시물에 자동으로 추가되어 집니다.</p>
<p>이때 선택된 이미지의 경우 상단우측에 체크 표시가 나타납니다.</p>
<p><a href="http://dev.paran.com/wp-content/uploads/2012/05/스크린22.jpg"><img class="alignnone  wp-image-7639 colorbox-7591" title="스크린2" src="http://dev.paran.com/wp-content/uploads/2012/05/스크린22.jpg" alt="" width="529" height="781" /></a></p>
<p>3. 게시완료</p>
<p><a href="http://dev.paran.com/wp-content/uploads/2012/05/스크린32.jpg"><img class="alignnone size-full wp-image-7640 colorbox-7591" title="스크린3" src="http://dev.paran.com/wp-content/uploads/2012/05/스크린32.jpg" alt="" width="567" height="568" /></a></p>
<p>게시를 완료했습니다. 벌써 누군가가 댓글을 달았네요!</p>
<p>이런식으로 한 주제에 대해 이미지, 웹사이트를 하나의 피드에 적용하여 좀 더 심도있게 다른사람들과 공유할 수 있게 됩니다.</p>
<p><a href="http://dev.paran.com/wp-content/uploads/2012/05/스크린1.png"><img class="alignnone size-full wp-image-7616 colorbox-7591" title="스크린~1" src="http://dev.paran.com/wp-content/uploads/2012/05/스크린1.png" alt="" width="550" height="413" /></a></p>
<p>세번째 특징은 비디오 파티입니다. 동영상을 같이 보면서 토론을 할 수 있도록한 기능입니다.</p>
<p>어떻게보면 우리나라의 아프리카티비와 흡사하네요.</p>
<ol>
<li><a href="http://dev.paran.com/wp-content/uploads/2012/05/스크린3-1.png"><img class="alignnone size-full wp-image-7651 colorbox-7591" title="스크린3 (1)" src="http://dev.paran.com/wp-content/uploads/2012/05/스크린3-1.png" alt="" width="193" height="26" /></a> 버튼을 클릭합니다.</li>
<li>어떤 주제에 대한 비디오방( ? )인지 방제를 정합니다.<br />
<a href="http://dev.paran.com/wp-content/uploads/2012/05/스크린211.jpg"><img class="alignnone size-full wp-image-7653 colorbox-7591" title="스크린21" src="http://dev.paran.com/wp-content/uploads/2012/05/스크린211.jpg" alt="" width="551" height="92" /></a></li>
<li>방이 생성됩니다.<br />
<a href="http://dev.paran.com/wp-content/uploads/2012/05/스E3091.png"><img class="alignnone  wp-image-7620 colorbox-7591" title="스E309~1" src="http://dev.paran.com/wp-content/uploads/2012/05/스E3091-1024x692.png" alt="" width="573" height="388" /></a></li>
<li>같이 공유할 동영상을 검색합니다. 여기서는 &#8216;UX&#8217;가 되겠지요.<br />
<a href="http://dev.paran.com/wp-content/uploads/2012/05/스크린121.jpg"><img class="alignnone size-full wp-image-7641 colorbox-7591" title="스크린12" src="http://dev.paran.com/wp-content/uploads/2012/05/스크린121.jpg" alt="" width="380" height="588" /></a></li>
<li>가장 적합한 동영상을 선택합니다.</li>
<li>해당 동영상을 친구를 초대하여 함께 이야기하며 봅니다.<br />
<a href="http://dev.paran.com/wp-content/uploads/2012/05/스크린41.jpg"><img class="alignnone  wp-image-7642 colorbox-7591" title="스크린4" src="http://dev.paran.com/wp-content/uploads/2012/05/스크린41.jpg" alt="" width="581" height="396" /></a></li>
<li>주제에 대해 더 좋은 동영상이나 보완할 영상이 있을경우 방을 생성한 본인 혹은 초대된 친구 모두 동영상을 추가할 수 있습니다.<a href="http://dev.paran.com/wp-content/uploads/2012/05/스크린11.png"><img class="alignnone  wp-image-7624 colorbox-7591" title="스크린~1" src="http://dev.paran.com/wp-content/uploads/2012/05/스크린11-1024x719.png" alt="" width="573" height="403" /></a></li>
</ol>
<h1 id="Socl-기타사항">기타사항</h1>
<p>1. 피드번역</p>
<p>별로 놀라울 사항은 아니지만 피드들을 번역하는 기능이 기본으로 들어가 있습니다. 물론 한글도로 번역이 됩니다!</p>
<p><a href="http://dev.paran.com/wp-content/uploads/2012/05/translate-2.png"><img class="alignnone size-full wp-image-7625 colorbox-7591" title="translate-2" src="http://dev.paran.com/wp-content/uploads/2012/05/translate-2.png" alt="" width="571" height="179" /></a></p>
<p>2. <a href="http://blog.fuselabs.org/post/17773913754/introducing-so-cl-riffs">Riff</a></p>
<p>위에서는 언급하지 않았지만 피드 브라우저에서 Riff라는 생소한 기능이 보입니다. 처음에는 트위터의 리트윗, 페이스북의 공유하기 기능과 같은것인줄 알았는데 예상과는 전혀 다른 기능이었습니다.</p>
<p>Riff의 뜻는 재즈에서 사용하는 단어로 &#8220;악절이 끊기는 데서 솔로로 하는 반복적 즉흥 연주&#8221;를 뜻합니다.<br />
이 단어의 뜻 처럼 누군가 특정주제에 대해 글을 올렸을 때 Riff를 누르면<br />
이 주제에 대해 즉흥적으로 피드를 만들어 올리는 역할을 합니다. (음악용어인지라 예를 &#8220;존 콜트레인&#8221;으로 든것 같군요 <img class="colorbox-7591"  src="http://wiki.kthcorp.com/s/ko_KR/3128/13/_/images/icons/emoticons/smile.png" alt="(웃음)" />)</p>
<p>이 처럼 누군가의 피드에서 Riff를 누르면 동일주제에 대한 검색결과가 나오고 거기에서 나에게 맞는 정보를 클릭하여<br />
새로운 피드를 게시합니다. 이렇게 되면 처음 글을 올렸던 사람의 피드에는 누가 나의 피드에 대해서 Riff를 했는지가 나타나게 됩니다.(아래 그림상의 2번)<br />
내가 생성한 게시물 또한 누구의 게시물에서 Riff를 행했는지 나타나게 됩니다.(3번)<br />
이는 결국 일종의 &#8220;대화&#8221;로 여겨질 수 있게되는데 특정주제에 대해서 내가 보는 시각 뿐만 아니라 남이 볼수 있는 시각을 동시에 볼 수 있게해 주는 기회를 부여하기 때문입니다.</p>
<p><a href="http://dev.paran.com/wp-content/uploads/2012/05/riffs1.jpg"><img class="alignnone size-full wp-image-7643 colorbox-7591" title="riffs" src="http://dev.paran.com/wp-content/uploads/2012/05/riffs1.jpg" alt="" width="491" height="842" /></a></p>
<p>&nbsp;</p>
<p style="padding-left: 30px;">3. 페이스북, 윈도우 라이브 로그인</p>
<p style="padding-left: 30px;"><a href="http://dev.paran.com/wp-content/uploads/2012/05/wlid-login1.jpg"><img class="alignnone size-full wp-image-7644 colorbox-7591" title="wlid-login" src="http://dev.paran.com/wp-content/uploads/2012/05/wlid-login1.jpg" alt="" width="489" height="203" /></a><br />
로그인에 성공하면 아래와 같이 서비스에서 사용할 이름을 입력합니다.<br />
<a href="http://dev.paran.com/wp-content/uploads/2012/05/image0021.jpg"><img class="alignnone size-full wp-image-7645 colorbox-7591" title="image002" src="http://dev.paran.com/wp-content/uploads/2012/05/image0021.jpg" alt="" width="484" height="257" /></a></p>
<p style="padding-left: 30px;">4. 특정주제에 대한 페이지 제공</p>
<p style="padding-left: 30px;"><a href="http://dev.paran.com/wp-content/uploads/2012/05/ExploreSocl.png"><img class="alignnone size-full wp-image-7631 colorbox-7591" title="ExploreSocl" src="http://dev.paran.com/wp-content/uploads/2012/05/ExploreSocl.png" alt="" width="500" height="278" /></a></p>
<p style="padding-left: 30px;">5. 아직은 불완전한&#8230;.</p>
<p style="padding-left: 30px;">     이번 리뷰를 진행하는 동안 너무느린 속도, 많은 버그들을 맞닥들이게 되었습니다. 앞으로 개선이 이루어 질 것이라 믿습니다. <img class="colorbox-7591"  src="http://wiki.kthcorp.com/s/ko_KR/3128/13/_/images/icons/emoticons/smile.png" alt="(웃음)" /><a href="http://dev.paran.com/wp-content/uploads/2012/05/스크린311.jpg"><img class="alignnone  wp-image-7646 colorbox-7591" title="스크린31" src="http://dev.paran.com/wp-content/uploads/2012/05/스크린311.jpg" alt="" width="515" height="418" /></a></p>
<h1 id="Socl-에필로그">에필로그</h1>
<p>현대 사회는 트위터, 페이스북과 같은 SNS을 통해 소통하는 시대를 살고 있지만 이것은 반대로 과다정보로 인한 스트레스와 혼란을 일으키고 있습니다.</p>
<p>우리는 이러한 정보의 홍수속에서 원하는 것을 찾을 시간이 여간 많이 걸리는 것이 아닙니다.</p>
<p>올해 유행하는 단어가 있습니다. 바로 &#8220;큐레이션&#8221;이라는 단어입니다. 이 큐레이션이라는 말의 뜻은 큐레이터에서 생격난 말이라고 합니다.</p>
<p>즉, 큐레이션이란 정보를 선별하고 요약해서 제공해주는 사람과 이러한 행위가 합쳐져서 생겨난 말입니다.</p>
<p>이러한 서비스의 장점은 수많은 정보속에서 친구와 나 자신이 큐레이터가 되어 직접 컨텐츠를 고르기 때문에</p>
<p>정보를 접하는 상대방(같은 주제로 고민하는)은 더욱 더 가치있는 정보들을 접할 수가 있는 것이죠.</p>
<p>현재 대표적인 서비스로는 &#8220;핀터레스트&#8221;가 있습니다.</p>
<p>&nbsp;</p>
<p>So.cl은 서두에서 말씀드린것 처럼 교육 및 리서치를 위한 SNS 입니다.<br />
(실제로 MS는 아래와 같은 조사를 토대로 So.cl를 만들었다고 합니다.)</p>
<p><a href="http://dev.paran.com/wp-content/uploads/2012/05/tumblr_lw7kavfp4z1r2d8a61.jpg"><img class="alignnone size-full wp-image-7648 colorbox-7591" title="tumblr_lw7kavfp4z1r2d8a6" src="http://dev.paran.com/wp-content/uploads/2012/05/tumblr_lw7kavfp4z1r2d8a61.jpg" alt="" width="437" height="385" /></a></p>
<p>So.cl은 태생이 학생들을 대상으로 만들어 졌습니다.</p>
<p>&nbsp;</p>
<p>그 결과 &#8221;It started to look like students (and those of us at FUSE Labs) were using it for <strong>self-presentation</strong>, as well as for<strong> information sharing and information discovery</strong>.&#8221;와 같은 태도변화를 얻을 수 있었다고 합니다.</p>
<p>&nbsp;</p>
<p>MS는 So.cl을 통해 학생들 혹은 어떤 주제에 대해 조사하려는 사람에게 좀더 쉽고 심도있는 정보를 조합할 수 있도록 제공함으로서</p>
<p>페이스북과는 다른, 보다 가치있는 정보를 생성하려는 시도를 했다고 생각합니다. 좀더 가다듬어지고 사용자가 늘어난다면</p>
<p>양질의 정보들을 이용할 수 있는 수준놓은 큐레이션 서비스가 되어질 것 입니다.</p>
<p>감사합니다.</p>
<p>&nbsp;</p>
<p>So.cl URL : <a href="http://www.so.cl/" rel="nofollow" target="_blank">http://www.so.cl/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://dev.paran.com/2012/05/22/microsoft-sns-so-cl/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MySQL 성능 죽이는 잘못된 쿼리 습관</title>
		<link>http://dev.paran.com/2012/05/22/mysql-low-performance-query-bad-habit/</link>
		<comments>http://dev.paran.com/2012/05/22/mysql-low-performance-query-bad-habit/#comments</comments>
		<pubDate>Tue, 22 May 2012 01:27:16 +0000</pubDate>
		<dc:creator>sdchan1</dc:creator>
				<category><![CDATA[Tech Note]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Tuning]]></category>

		<guid isPermaLink="false">http://dev.paran.com/?p=7397</guid>
		<description><![CDATA[kth 데이터지능팀 성동찬 Overview 안정적인 서비스 유지를 위해서는 쿼리 작성이 상당히 중요합니다. 잘못된 쿼리 하나가 전체적인 퍼포먼스를 크게 저해하기도 하고 최악의 경우 장애 상황까지 치닫기 때문이죠 단일 코어에서 Nested Loop Join으로 데이터를 처리하는 MySQL 특성 상 쿼리 구문에 큰 영향을 받습니다. (반드시 알아야할 MySQL 특징 세 가지 참고) 그래서 오늘은 쿼리 작성 시 기피해야 하는 사항 세 가지정도 [...]]]></description>
			<content:encoded><![CDATA[<h3>kth 데이터지능팀 성동찬</h3>
<p><strong><br />
<h1>Overview</h1>
<p></strong><br />
안정적인 서비스 유지를 위해서는 쿼리 작성이 상당히 중요합니다.<br />
잘못된 쿼리 하나가 전체적인 퍼포먼스를 크게 저해하기도 하고 최악의 경우 장애 상황까지 치닫기 때문이죠</p>
<p>단일 코어에서 Nested Loop Join으로 데이터를 처리하는 MySQL 특성 상 쿼리 구문에 큰 영향을 받습니다. (<a title="Permanent Link: 반드시 알아야할 MySQL 특징 세 가지" href="http://gywn.net/2011/12/mysql-three-features/" rel="bookmark">반드시 알아야할 MySQL 특징 세 가지</a> 참고)</p>
<p>그래서 오늘은 쿼리 작성 시 기피해야 하는 사항 세 가지정도 골라봅니다.<br />
<strong><br />
<h1>Case 1</h1>
<p></strong></p>
<pre>SELECT @RNUM:=@RNUM+1 AS RNUM, ROW.*
FROM (SELECT @RNUM:=0) R,
(
    SELECT
        M.MASTER_NO,
        M.TITLE,
        MI.PATH,
        M.REGDATE,
        CM.TYPE
    FROM MAIN AS M
    LEFT OUTER JOIN TAB01 AS MI
        ON M.MASTER_NO = MI.MASTER_NO
    INNER JOIN TAB02      AS CM
        ON M.MASTER_NO = CM.MASTER_NO
    WHERE M.DEL_YN = 'N'
    ORDER BY M.MASTER_NO DESC
) ROW
LIMIT 10000, 10</pre>
<p><img class="alignnone size-full wp-image-7400 colorbox-7397" src="http://dev.paran.com/wp-content/uploads/2012/05/SQL_Plan_Case1-1.png" alt="SQL Plan Case1-1" width="493" height="146" /></p>
<p>오라클 쿼리에 익숙하신 분들이 흔히 하는 실수입니다.</p>
<p>오라클 rownum 효과를 내기 위해 (SELECT @RNUM:=0) 로 번호를 붙이다 보니 결과적으로 필요없는 데이터를 스캔합니다.<br />
Nest Loop Join으로 데이터를 처리하기 때문에 퍼포먼스가 상당히 떨어집니다.</p>
<p>Row 번호는 어플리케이션 서버에서 생성하고, 다음과 같이 쿼리를 작성하는 것이 좋습니다.</p>
<pre>SELECT
    M.MASTER_NO,
    M.TITLE,
    MI.PATH,
    M.REGDATE,
    CM.TYPE
FROM MAIN AS M
LEFT OUTER JOIN TAB01 AS MI ON M.MASTER_NO = MI.MASTER_NO
INNER JOIN TAB02      AS CM ON M.MASTER_NO = CM.MASTER_NO
WHERE M.DEL_YN = 'N'
ORDER BY M.MASTER_NO DESC
LIMIT 10000, 10</pre>
<p><img class="alignnone size-full wp-image-7401 colorbox-7397" src="http://dev.paran.com/wp-content/uploads/2012/05/SQL_Plan_Case1-2.png" alt="SQL Plan Case1-2" width="541" height="100" /></p>
<p>변환 전/후 쿼리 프로파일링을 해보면 다음과 같습니다. 변환 후에 필요없는 데이터 스캔에 소요되던 Sending Data가 사라지고, 단순하게 처리됩니다.</p>
<p><img class="alignnone size-full wp-image-7402 colorbox-7397" src="http://dev.paran.com/wp-content/uploads/2012/05/SQL_Profile_Case1.png" alt="SQL Profile Case1" width="478" height="480" /><br />
<strong><br />
<h1>Case 2</h1>
<p></strong><br />
Where 조건 Left Value에 함수 적용하여 결과적으로 Full Scan이 발생하는 경우입니다.<br />
서비스 구현 단계에서는 쉽고 직관적으로 보일지는 몰라도, DB 내부 데이터 처리에서 엄청난 자원을 소모합니다.</p>
<p>이런 습관은 DBMS 상관없이 기피해야 합니다.</p>
<pre>SELECT *
FROM VIEW_MASTER_LOG_GROUP TAB01
WHERE DATE_FORMAT(ST_LAST_DATE, '%Y-%m-%d') LIKE DATE_FORMAT(NOW(), '%Y-%m-%d');</pre>
<p><img class="alignnone size-full wp-image-7403 colorbox-7397" src="http://dev.paran.com/wp-content/uploads/2012/05/SQL_Plan_Case2-1.png" alt="SQL Plan Case2-1" width="457" height="71" /></p>
<p>Where 조건 날짜 검색 로직을 살펴보면 결과적으로 오늘 0시 이후 데이터를 가져오는 구문입니다. 그렇다면 다음과 같이 변환해 봅시다.</p>
<p>인덱스를 타게 Left Value에서 불필요한 Function을 제거하고, Between으로 0시 이후 데이터를 가져옵니다.</p>
<pre>SELECT *
FROM VIEW_MASTER_LOG_GROUP TAB01
WHERE ST_LAST_DATE BETWEEN DATE_FORMAT(NOW(), '%Y-%m-%d') AND NOW();</pre>
<p><img class="alignnone size-full wp-image-7404 colorbox-7397" src="http://dev.paran.com/wp-content/uploads/2012/05/SQL_Plan_Case2-2.png" alt="SQL Plan Case2-2" width="513" height="71" /></p>
<p>Full Scan이 아닌 Range Scan이며 정상적으로 인덱스를 탑니다.<br />
<strong><br />
<h1>Case 3</h1>
<p></strong><br />
데이터 추가 조회를 위한 Outer Join 사용 시 주의할 점입니다. 바로 위 1차 변환된 쿼리를 기준으로 말씀 드리겠습니다.</p>
<p>하단 쿼리는 Outer Join이 조건 검색에 영향을 미치지 않고 추가 정보 조회만을 위한 역할로 사용될 때 입니다.</p>
<pre>SELECT
    M.MASTER_NO,
    M.TITLE,
    MI.PATH,
    M.REGDATE,
    CM.TYPE
FROM MAIN AS M
INNER JOIN TAB01 AS CM
    ON CM.MASTER_NO = M.MASTER_NO
LEFT OUTER JOIN TAB02 AS MI
    ON M.MASTER_NO = MI.MASTER_NO
WHERE M.DEL_YN = 'N'
ORDER BY M.MASTER_NO DESC
LIMIT 10000, 10;</pre>
<p><img class="alignnone size-full wp-image-7405 colorbox-7397" src="http://dev.paran.com/wp-content/uploads/2012/05/SQL_Plan_Case3-1.png" alt="SQL Plan Case3-1" width="332" height="103" /></p>
<p>데이터를 10,000번째 위치부터 10 건을 가져온다면 결과적으로 불필요한 10000번 Outer Join이 발생합니다. 쿼리 성능이 상당이 안좋습니다.</p>
<p>물론 데이터가 적을 경우에는 큰 문제가 없지만, 데이터가 누적됨에 따라 서버에 큰 영향을 미칠 수 있습니다. 아래와 같이 수정을 해보죠.</p>
<pre>SELECT
    A.MASTER_NO,
    A.TITLE,
    MI.PATH,
    A.REGDATE,
    A.TYPE
FROM(
    SELECT
        M.MASTER_NO,
        M.TITLE,
        M.REGDATE,
        CM.TYPE
    FROM MAIN AS M
    INNER JOIN TAB01 AS CM
        ON CM.MASTER_NO = M.MASTER_NO
    ORDER BY M.MASTER_NO DESC
    LIMIT 10000, 10
) A
LEFT OUTER JOIN TAB02 AS MI
    ON A.MASTER_NO = MI.MASTER_NO;</pre>
<p><img class="alignnone size-full wp-image-7406 colorbox-7397" src="http://dev.paran.com/wp-content/uploads/2012/05/SQL_Plan_Case3-2.png" alt="SQL Plan Case3-2" width="372" height="115" /></p>
<p>SQL Plan 정보는 더 안좋은 것처럼 보이지만, SQL을 프로파일링 해보면 다음과 같이 좋은 성능을 확인할 수 있습니다.</p>
<p><img class="alignnone size-full wp-image-7407 colorbox-7397" src="http://dev.paran.com/wp-content/uploads/2012/05/SQL_Profile_Case3.png" alt="SQL Profile Case3" width="660" height="449" /></p>
<p>변환 후 프로파일은 더욱 길어지기는 했지만, Outer Join을 위한 Sending Data 시간만큼 단축되었습니다.<br />
<strong><br />
<h1>Conclusion</h1>
<p></strong><br />
3가지 간단한 사례이기는 하지만, SQL 튜닝 시 확인을 해보면 종종 걸리는 문제들입니다.<br />
쿼리 특성에 따라 성능이 좌우되는 만큼 SQL도 서비스 로직을 정확히 파악하여 작성한다면 서버 자원을 효율적으로 배분할 수 있겠죠.</p>
<p>잊지 마세요. MySQL에서는 <span style="text-decoration: underline"><strong>단일 코어에서 Nested Loop Join 방식으로 데이터를 처리</strong></span>한다는 사실을..</p>
<p>재미있는 사례로 다음에 인사 드리겠습니다. ^^</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.paran.com/2012/05/22/mysql-low-performance-query-bad-habit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>kth 기술뉴스 – 페이스북 앱스토어 App Center 발표외 18건</title>
		<link>http://dev.paran.com/2012/05/21/kth-news-facebook-appcenter/</link>
		<comments>http://dev.paran.com/2012/05/21/kth-news-facebook-appcenter/#comments</comments>
		<pubDate>Mon, 21 May 2012 07:38:58 +0000</pubDate>
		<dc:creator>xguru</dc:creator>
				<category><![CDATA[기술뉴스]]></category>

		<guid isPermaLink="false">http://dev.paran.com/?p=7572</guid>
		<description><![CDATA[2012년 05월 21일, kth 아키텍트 그룹이 발행하는 기술 신동향 &#38; 뉴스 링크입니다. 오늘은 얼마전 발표된 Facebook 의 앱스토어, AppCenter 를 메인뉴스로 선정했습니다. 상세한 내용은 저희 회사 내부 위키에는 이미 분석이 되었는데, 곧 정리해서 개발자 블로그에도 발행하도록 하겠습니다. &#160; [ 웹사이트, 웹서비스, 웹기술 ] 페이스북 앱스토어 App Center 발표 http://t.co/gqVF4wKv 소셜앱에 포커싱하고 유료앱지원. 아이튠스/플레이 랑 대결하기보다 모바일웹까지 [...]]]></description>
			<content:encoded><![CDATA[<p>2012년 05월 21일,  kth 아키텍트 그룹이 발행하는 기술 신동향 &amp; 뉴스 링크입니다.</p>
<p>오늘은 얼마전 발표된 <strong>Facebook 의 앱스토어, AppCenter </strong> 를 메인뉴스로 선정했습니다. 상세한 내용은 저희 회사 내부 위키에는 이미 분석이 되었는데, 곧 정리해서 개발자 블로그에도 발행하도록 하겠습니다. </p>
<p>&nbsp;</p>
<h2>[ 웹사이트, 웹서비스, 웹기술 ]</h2>
<ul>
<li>페이스북 앱스토어 App Center 발표 <a href="http://t.co/gqVF4wKv">http://t.co/gqVF4wKv</a> 소셜앱에 포커싱하고 유료앱지원. 아이튠스/플레이 랑 대결하기보다 모바일웹까지 전체를 포용하는 메타스토어 방식. 10억사용자 대상이라 충분히 파괴력이 있을 듯 합니다. </li>
<li>소셜미디어가 구글검색순위에 어떤영향을 주는가 <a href="http://t.co/NBiCXSIL">http://t.co/NBiCXSIL</a> 작은 시험세트이긴 하지만.. 결과는 구글+가 페이스북/트위터에 비해 구글검색 순위에 대해서는 영향이 높다는 것. 이건 뭔가 잘못 되어가는 것 같다는 생각이..</li>
<li>웹 디자인/개발에 관한 판매자/구매자 가이드 <a href="http://t.co/XTJwZMVk">http://t.co/XTJwZMVk</a> 우리나라랑은 다르겠지만, 해외의 외주 웹개발에 대한걸 여러모로 알 수 있는 재미난 글.</li>
<li>Gmvault – 자신의 Gmail 계정을 전체 백업/리스토어 하는 오픈소스 유틸리티 <a href="http://t.co/lHiH741a">http://t.co/lHiH741a</a> 윈/맥/리눅스 모두 지원</li>
<li>MS가 만든 SNS, So.CL <a href="http://j.mp/JvjMb9">http://j.mp/JvjMb9</a> 컨텐츠 큐레이션에 집중한 것으로 보이는군요. 과연 ?</li>
</ul>
<h2>[ 모바일 - 아이폰/안드로이드 ]</h2>
<ul>
<li>XCode 4.3.2 버전 이후의 iOS Simulator 직접실행 아이콘 만들기 <a href="http://t.co/Y5K1R3io">http://t.co/Y5K1R3io</a></li>
<li>Linkedin 의 새 iPad 앱이 95%가 HTML5로 제작 <a href="http://t.co/UatGaIji">http://t.co/UatGaIji</a> 링크드인 모바일 개발팀장 왈 &#8220;Responsive Design&#8221;은 자기들한테는 잘 맞지 않았다고..</li>
<li>애플이 iOS 지도앱에 구글맵 대신 자사의 새로운 맵으로 교체할 것이며, 상상초월일꺼라고.. <a href="http://t.co/i1enmNxN">http://t.co/i1enmNxN</a>  기인수한 3D지도 업체들의 기술로 6월 WWDC에서 iOS6의 주 기능으로 발표할것 같다는 예상.</li>
<li>Ebay의 새 아이패드앱 <a href="http://t.co/shGoAXop">http://t.co/shGoAXop</a> 정말 잘 만들었군요. 좌상단 메뉴처리도 참신&amp;멋지고, 전체적으로 UI가 깔끔하고 군더더기 없네요.</li>
<li>Luke의 데이터 먼데이 &#8220;모바일 웹 쇼핑&#8221; <a href="http://t.co/iZ1Pyqy8">http://t.co/iZ1Pyqy8</a> 미국 스마트폰/타블렛 사용자중 79%가 모바일쇼핑을 경험. 스마트폰 사용자는 29%, 타블렛 사용자는 42%가 쇼핑을 함으로써 타블렛이 좀더 쇼핑에 적합.</li>
</ul>
<h2>[ 프로그래밍/HTML5/CSS/Javascript ]</h2>
<ul>
<li>Linkedin이 아이패드앱에서 HTML5로 부드러운 무한 스크롤링을 위해 사용한 5가지 기법 <a href="http://t.co/rPXKwtGd">http://t.co/rPXKwtGd</a> 이미지 언로딩/페이지 숨김/페이지 제거/스케일링&amp;박스섀도우 피하기/DOM노드 줄이기</li>
<li>Linkedin 아이패드앱에서 속도개선을 위해 WebSocket을 사용한 이야기 <a href="http://j.mp/K3NfgL">http://j.mp/K3NfgL</a></li>
<li>The Web Platform : Browser Technologies <a href="http://platform.html5.org">http://platform.html5.org</a> html5.org 가 제공하는 한 페이지짜리 기술 레퍼런스 Cheat Sheet. 깔끔하군요</li>
</ul>
<h2>[ DB,클라우드,웹서버 기술 ]</h2>
<ul>
<li>Cassandra at GoDaddy <a href="http://t.co/jZiZgtJ2">http://t.co/jZiZgtJ2</a> ASP 환경에서 카산드라를 세션스토어로 사용한 내용을 기록한 시리즈글</li>
<li>MongoDB at Cragslist <a href="http://j.mp/JvlkSL">http://j.mp/JvlkSL</a> 미국에서 가장 트래픽이 많은 사이트중 하나인 Craigslist의 MongoDB 적용 1주년 회고 발표</li>
<li>DevOps를 위한 추천 책&amp;블로그 10선 <a href="http://t.co/HdDig78d">http://t.co/HdDig78d</a></li>
<li>Goodbye CouchDB <a href="http://j.mp/JvkXHP">http://j.mp/JvkXHP</a> , Goodbye MongoDB <a href="http://j.mp/K3Ml3V">http://j.mp/K3Ml3V</a>  시리즈인것 같지만 그건 아니고.. 각자의 시선으로 본 DB의 장단점 리스트. 이건 특정DB의 문제라기 보다는 각자 상황에 맞는 DB를 선택하는 것이 중요</li>
</ul>
<h2>[ 추천글 ]</h2>
<ul>
<li>출판사 앱-모델의 실패 http://t.co/vb7X9PPL 책의 종류에 따라서 다르긴 하겠지만 단순 앱 형태의 이북은 그다지 메리트가 없는게 사실.</li>
<li>Touché – 디즈니 연구자들이 사물에 터치하는 많은 제스쳐들을 인식하도록 만든 시스템 <a href="http://t.co/vGpNPGLb">http://t.co/vGpNPGLb</a> 정전식으로 전기의 변화를 잡아내는 방식이라 손잡이,책상 심지어 물에까지 가능. 동영상 필감!</li>
</ul>
<p>피드백 환영합니다! </p>
<p>파란 개발자 블로그를  <a href="http://feeds.feedburner.com/devparan" target=_blank>RSS리더에서 구독</a>하시면, 매주간의 기술뉴스와 kth 임직원들이 작성하는 다양한 전문기술 글들을 보실수 있습니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.paran.com/2012/05/21/kth-news-facebook-appcenter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>시각 장애인 웹/모바일 접근성 간담회 후기</title>
		<link>http://dev.paran.com/2012/05/16/web-mobile-app-accessibility/</link>
		<comments>http://dev.paran.com/2012/05/16/web-mobile-app-accessibility/#comments</comments>
		<pubDate>Wed, 16 May 2012 01:45:55 +0000</pubDate>
		<dc:creator>Brad Hong</dc:creator>
				<category><![CDATA[특별 기고]]></category>
		<category><![CDATA[accessibility]]></category>
		<category><![CDATA[app]]></category>
		<category><![CDATA[handicapped]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[접근성]]></category>

		<guid isPermaLink="false">http://dev.paran.com/?p=7465</guid>
		<description><![CDATA[kth Android팀 홍성훈 시각 장애인이 웹 또는 휴대폰을 이용하면서 겪은 애로사항을 공유하기 위한 간담회를 다녀왔습니다. 느낀점을 한마디로 표현하자면 충격 그 자체였습니다. 시각 장애인들이 휴대폰을 이용하는 것도 놀라운데, 웹서핑을 하다니&#8230; 앱을 개발할때 접근성(Accessibility)을 생각해 본 적이 없었던 저는, 이번 간담회를 계기로 많은 생각을 하게 되었습니다. 개발자로써 사회에 공헌하는 방법, 멀리 있지 않은 것 같습니다. 이런 신선한 [...]]]></description>
			<content:encoded><![CDATA[<h3>kth Android팀 홍성훈</h3>
<p><img class="colorbox-7465"  style="float: left;margin-left: 30px;margin-right: 30px" src="http://dev.paran.com/wp-content/uploads/2012/05/220px-Handicapped_Accessible_sign.svg_.png" alt="접근성(accessibility)" width="200" height="200" />시각 장애인이 웹 또는 휴대폰을 이용하면서 겪은 애로사항을 공유하기 위한 간담회를 다녀왔습니다.<br />
느낀점을 한마디로 표현하자면 충격 그 자체였습니다. 시각 장애인들이 휴대폰을 이용하는 것도 놀라운데, 웹서핑을 하다니&#8230; </p>
<p>앱을 개발할때 접근성(Accessibility)을 생각해 본 적이 없었던 저는, 이번 간담회를 계기로 많은 생각을 하게 되었습니다.<br />
개발자로써 사회에 공헌하는 방법, 멀리 있지 않은 것 같습니다. </p>
<p>이런 신선한 충격이 가시기 전에 글을 남겨봅니다.</p>
<ul>
<li><strong>관련자료</strong></li>
<ul>
<li><a href="http://wah.or.kr/_Upload/pds/%EC%9B%B9%20%EC%A0%91%EA%B7%BC%EC%84%B1%EC%9D%84%20%EA%B3%A0%EB%A0%A4%ED%95%9C%20%EC%BD%98%ED%85%90%EC%B8%A0%20%EC%A0%9C%EC%9E%91%20%EA%B8%B0%EB%B2%95%20v2.0(111130).pdf">웹 접근성을 고려한 콘텐츠 제작 기법 v2.0(111130).pdf</a></li>
<li><a href="http://www.mopas.go.kr/gpms/view/jsp/download/userBulletinDownload.jsp?userBtBean.bbsSeq=1039187&amp;userBtBean.ctxCd=1037&amp;userBtBean.orderNo=1">모바일 애플리케이션 접근성 지침(행안부고시2011-38호).pdf</a></li>
</ul>
</ul>
<p>&nbsp;</p>
<h2>간담회 분위기</h2>
<p><strong> &#8221;웹 애로사항&#8221;, &#8220;모바일 애로사항&#8221;, &#8220;개선 또는 개발해주었으면 하는 아이디어&#8221;</strong>라는 주제로 3시간 동안 진행되었습니다. </p>
<p>이번 간담회에 장애인 분들은 시각 장애인들만 참석 하였으며, &#8220;전혀 보이지 않는 시각 장애인&#8221;과 &#8220;아주 약간 보이는 시각 장애인&#8221; 이렇게 두 부류로 나눌 수 있었습니다. </p>
<p>네이버, 네이트, 다음, KTH와 같은 포탈사와 LG, 삼성 같은 제조사가 꽤 적극적으로 참여, 대응하고 있는 모습이 인상적이었습니다. </p>
<p>진행 방식은 장애인들의 애로사항들과 그 애로사항들에 대해 기업들이 어떻게 대응하고 있는지 자유롭게 공유하는 방식으로 진행되었습니다.</p>
<ul>
<li><strong>참석자</strong></li>
<ul>
<li>시각장애인(11명)</li>
<li>학계(1명)</li>
<li>기업(20여명)</li>
<li>정부 : 한국정보화진흥원 관계자 3-4명</li>
</ul>
</ul>
<p>&nbsp;</p>
<h2>웹(Web) 애로사항</h2>
<ul>
<li><strong>Captcha 관련</strong></li>
<ul>
<li>기본적인 Captcha 형태인 Text 방식 외에, Audio Captcha도 지원해주었으면 한다.</li>
<li>Audio Captcha를 지원해주더라도 변형된 소리를 제대로 듣고 입력하기 너무 힘들다.</li>
</ul>
<li><strong>Sense Reader</strong></li>
<ul>
<li>읽기 커서가 접근이 안되는 경우가 많다.</li>
<li>예) 마우스 오버 Dropdown 팝업 등등</li>
</ul>
<li><strong>광고</strong></li>
<ul>
<li>마우스 오버 광고 재생: 갑자기 재생이되어 놀라는 경우가 많음.</li>
<li>광고로 인해 마우스 커서 찾기 힘들다.</li>
<li>광고 스킵을 눌렀는데, 또 다른 광고로 이동되어 목적했던 Contents 접근이 힘들었던 경험이 있다. 한번 포커스를 잃어 버리면 찾기 힘들다.</li>
</ul>
<li><strong>프레임 등의 테두리</strong></li>
<ul>
<li>웹에서 테두리 너무 얇아 구분이 안된다.</li>
<li>특히 약관의 경우 그러하며 체크박스, 라디오 박스 찾기 힘들다.</li>
<li>마우스 오버시 테두리가 진해졌으면 좋겠다.</li>
</ul>
<li><strong>대체 텍스트</strong></li>
<ul>
<li>없는 부분이 많다.</li>
<li>대체 텍스트는 가장 기본적인 접근성이다. 꼭 누락되지 않았으면 한다.</li>
</ul>
<li><strong>키보드 접근</strong></li>
<ul>
<li>키보드로 접근이 안되는 경우가 있다.</li>
<li>예) 다음팟, 네이버 동영상 등의 동영상 재생기</li>
</ul>
<li><strong>확대</strong></li>
<ul>
<li>테스크탑 페이지에는 확대기능이 있어 편리하게 사용하고 있다. 모바일 페이지 확대 기능이 빠져서 어렵다.</li>
<li>확대기능을 위해, &#8220;PC 화면으로 보기&#8221; 같은 기능을 써서 데스크탑 페이지를 보다가 링크를 누르면 다시 모바일 페이지로 이동된다. 불편하다.</li>
</ul>
</ul>
<p>&nbsp;</p>
<h2>앱(App) 애로사항</h2>
<ul>
<li><strong>UX</strong></li>
<ul>
<li>아이폰 앱들은 통일된 사용자 경험을 제공해주는 경우가 많아 좋다.</li>
<li>안드로이드 앱들은 제공해주는 사용자 경험이 서로 다른 경우가 많아 어렵다.</li>
</ul>
<li><strong>접근성 제공</strong></li>
<ul>
<li>접근성을 고려하지 않고 개발된 경우가 많다.</li>
<li>특히, 모바일 뱅킹 앱들은 접근성을 제공해주지 않는 경우가 대부분이다.</li>
<li>그나마 미약하게라도 접근성을 제공해 주었는데, 업데이트 후에 없어지는 경우가 있다. 접근성 관련 내용이 체크리스트에 포함되어 이런 경우가 없었으면 좋겠다.</li>
</ul>
<li><strong>하드웨어 버튼</strong></li>
<ul>
<li>아이폰은 홈버튼이 하드웨어 버튼으로 되어 있어 쓰기 편리하다.</li>
<li>반면 안드로이드는 ICS의 경우 화면 버튼으로 들어가서 화면 영역과 테두리 영역이 구분이 안되어 버튼 찾기가 힘들다.</li>
</ul>
<li><strong>포커스 이동</strong></li>
<ul>
<li>순서가 직관적이지 않다.</li>
<li>한번 시각적인 초점를 잃어버리면 찾기 힘들다.</li>
</ul>
<li><strong>색대비</strong></li>
<ul>
<li>색대비가 작은 경우가 있어 고대비 기능을 사용하지 못하는 경우가 많다.</li>
<li>글자가 작을 수록 높은 색대비가 필요하다.</li>
</ul>
<li><strong>UI</strong></li>
<ul>
<li>아이폰의 보이스오버 기능을 위해 세 손가락을 이용하여 삼중 클릭을 하는 경우가 있는데, UI 구조상 클릭하기 어려운 경우가 많다.</li>
<li>예를 들어 카카오톡의 사용자 프로필 팝업이 그런 경우인데, 바깥영역이 클릭되어 프로필 팝업이 사라지는 경우가 있다.</li>
</ul>
</ul>
<p>&nbsp;</p>
<h2>개선 또는 개발해주었으면 하는 아이디어</h2>
<ul>
<ul>
<li><strong><a href="http://itunes.apple.com/kr/app/vizwiz/id439686043?mt=8">VizWiz</a> 같은 앱</strong></li>
<ul>
<li>사진을 찍고 음성 녹음해서 전송하면, 자원 봉사자들이 사진과 녹음 내용을 듣고 도움을 주는 앱</li>
</ul>
<li><strong>보행자용 네비게이션</strong></li>
<ul>
<li>사고 발생할 경우, 법적인 문제 등으로 난처한 일이 발생할 수 있다.</li>
<li>기술적인 특성상 오차범위가 크다.</li>
</ul>
<li><strong>버스 탈때 정차한 버스의 위치를 알려주는 앱</strong></li>
<ul>
<li>시각장애인은 가급적 버스 이용안한다. 자력으로는 원하는 버스를 탈방법이 거의 없다.</li>
<li>안내 방송으로 나오는 도착 순서와 실제로 도착하는 버스 순서가 틀린 경우가 많다.</li>
<li>약시의 경우 버스 번호를 보려면 가까이 다가가야하는데, 위험하다. 보기가 너무 힘들다.</li>
</ul>
<li><strong>옵티컬 줌 (하드웨어)</strong></li>
<ul>
<li>장애인용 옵티컬 줌 기능이 필요하다.(예: 포터블 확대 독서기)</li>
</ul>
</ul>
</ul>
<p><img class="aligncenter colorbox-7465" src="http://dev.paran.com/wp-content/uploads/2012/05/pic32.gif" alt="포터블 포켓 뷰어" width="205" height="200" /> <strong> </strong></p>
<h2>참고: 접근성 관련 국내 법률</h2>
<p>이번 간담회에서 받아온 <a href="http://wah.or.kr/_Upload/pds/%EC%9B%B9%20%EC%A0%91%EA%B7%BC%EC%84%B1%EC%9D%84%20%EA%B3%A0%EB%A0%A4%ED%95%9C%20%EC%BD%98%ED%85%90%EC%B8%A0%20%EC%A0%9C%EC%9E%91%20%EA%B8%B0%EB%B2%95%20v2.0(111130).pdf">&#8220;웹 접근성을 고려한 콘텐츠 제작 기법 &#8211; 한국형 웹 콘텐츠 접근성 지침 2.0(행정안전부, 한국 정보화 진흥원)&#8221;</a>자료에서 보면 아래와 같이 관련 법률이 제정되어 있습니다.</p>
<ul>
<li>2008년 4월 11일부터 시행되고 있는 <strong>&#8216;장애인 차별 금지법&#8217; 제12조 (정보 통신, 의사 소통에서의 정당한 편의제공의무)</strong></li>
<li>2009년 5월 22일 공포된 <strong>&#8216;국가 정보화 기본법&#8217; 제32조 (장애인,노인 등의 정보 접근 및 이용 보장)</strong></li>
<li><strong>&#8216;장애인 차별 금지법 시행령&#8217;</strong> : 대통령령으로 정한 공공기관은 1년 이내, 즉 2009년 4월 11일 까지, 그 외 대상은 1년에서 5년내, 즉 2013년 4월 11일 까지 단계적으로 웹 접근성을 준수하도록 하고 있으며, 장애인에게 정당한 편의 제공 규정을 위반할 경우 <strong>최고 3000만원의 과태료</strong>가 부가되고, 행위가 악의적인 경우 <strong>3년 이하 징역이나 3000만원 이하의 벌금</strong>을 부과할 수 있도록 규정</li>
</ul>
<p>웹 접근성까지만 언급되어 있지만, 앱도 대응이 필요하지 않을까 생각됩니다. 하지만, 법을 피해가기 위한 슬픈(?) 작업은 안하고 싶네요. <strong> </strong></p>
<h2>정리&#8230; User = 다양한 사람들&#8230;</h2>
<p>놀라웠습니다. 시각장애인들이 웹서핑을 하고 스마트폰을 사용한다는 것 자체가 놀라웠습니다. 그리고, 내가 그렇게 놀랐다는 것에 또 놀랐습니다. 그들도 나와 같은 정보와 지식에 메마른 지식인이라는 것을 왜 망각했을까요? </p>
<p>UX는 모두 알다시피 User experience 의 약자입니다. 간담회에 참석한 장애인 중 한분이 이런 이야기를 하더군요.<br />
<strong><em>&#8220;우리 나라에서 말하는 UX에서 User에는 장애인은 포함되지 않는것 같다.&#8221;</em></strong> </p>
<p>IT 기업에서 User라고 생각하는 대상은 좋게 말해서 &#8220;서비스를 통해 어떤 유/무형의 가치(Contents)를 만들어낼 수 있는 사람&#8221;이라고 표현할 수 있을 것 같습니다. 결국, 최소의 비용으로 최대의 이윤을 얻어야하는 기업 입장으로는 선뜻 <strong>*돈 안되는*</strong> 작업, <strong>*돈 안되는*</strong> User에게 투자를 결정하기가 힘들겁니다. </p>
<p>이해됩니다.<br />
그렇지만 그 이상 이야기하면 도덕적으로 창피해 질 듯합니다. </p>
<p><strong>접근성(Accessibility)은 장애인을 위한 것이 아니라 사람을 위한 것입니다.</strong> 접근성(Accessibility)이라는 단어에 어디에도 장애인이란 말은 없습니다. 일반인이 느끼는 편리함과 장애인이 느끼는 편리함은 결코 배타적이지 않다고 생각합니다. 접근성이 좋아지면 일반인들도 편해집니다. 접근성을 높이면 UX, UI가 더 직관적으로 표현될 수 밖에 없습니다. </p>
<p>작은것 부터 시작해야겠습니다. 우선, 머리속에서 배제하지 않는 것부터&#8230; </p>
<p>접근성 관련 <a href="http://android-developers.blogspot.com/2012/04/accessibility-are-you-serving-all-your.html">Android 개발자 블로그</a>와 <a href="http://developer.android.com/guide/topics/ui/accessibility/index.html">Android 개발자 사이트의 접근성 관련 부분</a>부터 살펴보아야겠습니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.paran.com/2012/05/16/web-mobile-app-accessibility/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[kth 모바일 리포트] 연령 낮을수록 ‘스크린샷’, 높을수록 ‘앱설명’ 보고 앱 선택</title>
		<link>http://dev.paran.com/2012/05/16/customer_story/</link>
		<comments>http://dev.paran.com/2012/05/16/customer_story/#comments</comments>
		<pubDate>Wed, 16 May 2012 00:11:28 +0000</pubDate>
		<dc:creator>kejully</dc:creator>
				<category><![CDATA[특별 기고]]></category>

		<guid isPermaLink="false">http://dev.paran.com/?p=7419</guid>
		<description><![CDATA[kth CVI팀 조사/분석파트 이경은 CVI(Customer Value Innovation)팀 내 조사/분석파트는 시장동향분석, 고객리서치,  고객데이터 분석 등을 통해 고객 Needs 및 Unmet Needs를 발굴하여 서비스 개선과 활성화를 위해 노력하는 조직입니다. 이번 조사의 목적은 이미 멋진 아이디어와 실력을 가진 개발사 또는 인디 개발자 분들께서 이용자가 원하는 서비스를 만들기 위해 이용자관점에서 생각하고, 이용자 관점에서 고민하는 기회를 가졌으면 하는 바램으로 기획되었습니다. 향 후에도 개발자 입장이 아닌 이용자 [...]]]></description>
			<content:encoded><![CDATA[<h3>kth CVI팀 조사/분석파트 이경은</h3>
<p>CVI(Customer Value Innovation)팀 내 <strong>조사/분석파트</strong>는 <strong>시장동향분석, 고객리서치,  고객데이터 분석</strong> 등을 통해<br />
<span style="text-decoration: underline">고객 Needs 및 Unmet Needs를 발굴하여 서비스 개선과 활성화를 위해 노력하는 조직</span>입니다.</p>
<p>이번 조사의 목적은 이미 멋진 아이디어와 실력을 가진 개발사 또는 인디 개발자 분들께서 <strong>이용자가 원하는 서비스를 만들기 위해<br />
이용자관점에서 생각하고, 이용자 관점에서 고민하는 기회를 가졌으면 하는 바램</strong>으로 기획되었습니다.</p>
<p><span style="text-decoration: underline">향 후에도 개발자 입장이 아닌 이용자 입장에서 고민하는 내용으로 많이 찾아 뵙도록 노력</span>하겠습니다<br />
그럼 아래의 2012년 1분기 스마트폰 이용자조사에 대한 리뷰를 시작해 보겠습니다.</p>
<p>&nbsp;</p>
<h2><strong>2012년 1분기 스마트폰 이용자 조사</strong></h2>
<p align="left"><strong>▶ 조사제목 : </strong>2012년 1분기 스마트폰 이용자 조사<br />
<strong>▶ 조사대상 : </strong>스마트폰(팟게이트)이용자 총 7,815명 (아이폰 5,175명+안드로이드폰2,027명) 응답<br />
<strong>▶ 조사기간 : </strong>2012년 3월29일 ~ 4월13일<br />
<strong>▶ 신 뢰 도 : </strong>95% 신뢰수준의 오차범위 ± 1.11%</p>
<p>참고) 용어의 정의 : 구글 플레이는 쉬운 이해를 위해 안드로이드 마켓으로 표시하였습니다.(구글플레이=안드로이드마켓)</p>
<p>&nbsp;</p>
<p><strong><span style="text-decoration: underline">1.  모바일 어플리케이션!  레드오션에에서 가능성을 찾아라.</span></strong></p>
<p>아래 결과에 따르면 한달 평균 어플 설치수는 아이폰 6.6개, 안드로이드폰 5.2개로 아이폰이 안드로이드폰 이용자보다 1.4개 높은 설치개수가<br />
나타났고<strong>[참조-그래프1]</strong>, 한달 평균 실제 이용하는 어플 수는 아이폰 13개 안드로이드폰 11개로 2개 차이가 있었는데<br />
달리 말하면 <span style="text-decoration: underline">한 달에 출시되는 수 많은 어플 중 실제 스마트폰에 설치되는 어플은 애플 앱스토어에서는 6.6개, 안드로이드 마켓에서는 5.2개 밖에 </span><br />
<span style="text-decoration: underline">안 되는 치열한 레드오션 시장</span>이기도 하다.</p>
<p>그러나 유선Web과 같이 1등이 고착화되어 있는 시장과는 달리 앱스토어이든, 안드로이드마켓이든 <span style="text-decoration: underline">1등 유지기간이 일주일이 </span><span style="text-decoration: underline">넘기 힘들 정도로<br />
유연함이 있고, 그 유연함에서 오는 기회</span>는 분명 있다. <strong>[</strong><strong>참조:그래프2]</strong></p>
<p><strong>[그래프1] 한달 평균 설치 어플 수                                                                     [그래프2] 한달 평균 실제 이용하는 어플 수<br />
</strong> <a href="http://dev.paran.com/wp-content/uploads/2012/05/gh12.gif"><img class="alignnone size-full wp-image-7425 colorbox-7419" src="http://dev.paran.com/wp-content/uploads/2012/05/gh12.gif" alt="" width="412" height="206" /></a> <a href="http://dev.paran.com/wp-content/uploads/2012/05/gh2.gif"><img class="alignnone size-full wp-image-7426 colorbox-7419" src="http://dev.paran.com/wp-content/uploads/2012/05/gh2.gif" alt="" width="412" height="206" /></a></p>
<p>&nbsp;</p>
<p><strong><span style="text-decoration: underline">2.  어플 성공을 위해서는 대형마트 시식코너가 되어야 한다.</span></strong></p>
<p>이용자들이 <span style="text-decoration: underline">어플 설치 시 가장 많은 영향을 미치는 요소 3가지</span>를 물어본 결과, 아이폰/안드로이드폰 이용자 모두 “유료/무료”를 고려한다는 항목이<br />
1위를 차지했다. <span style="text-decoration: underline">이용자가 유료 어플에 대한 장벽을 얼마나 높게 생각하는지 알 수 있는 결과</span>다.<br />
이 결과에 따르면 아무리 잘 만든 어플이라도 무조건 돈을 지불해야 사용할 수 있다면 이용자들이 최초 선택에서 아예 배제 될 확률이 높다는 것이다.</p>
<p>엄청난 마케팅 비용을 가지고 있는 대기업 개발사가 아닌 이상 처음부터 유료화로 접근하여 이용자에게 선택 받을 확률을 스스로 낮추는 것 방법보다,<br />
<span style="text-decoration: underline">대형 마트의 시식코너와 같이 적절한 양을 선정하여 ‘무료버전’ 또는 ‘어플 내 구입’ 방식을 통한 매출 발생이 바람직</span>할 것으로 보인다. <strong>[</strong><strong>참조:그래프3~4]</strong></p>
<p> <strong>[그래프3] 아이폰 어플 설치 시 영향요인 3가지                                       [그래프4] 안드로이드폰 어플 설치 시 영향요인 3가지<br />
<a href="http://dev.paran.com/wp-content/uploads/2012/05/gh3.gif"><img class="alignnone size-full wp-image-7427 colorbox-7419" src="http://dev.paran.com/wp-content/uploads/2012/05/gh3.gif" alt="" width="413" height="206" /></a> <a href="http://dev.paran.com/wp-content/uploads/2012/05/gh4.gif"><img class="alignnone size-full wp-image-7428 colorbox-7419" src="http://dev.paran.com/wp-content/uploads/2012/05/gh4.gif" alt="" width="413" height="206" /></a></strong></p>
<p>&nbsp;</p>
<p><strong><span style="text-decoration: underline">3. 젊은 스마트폰 이용자를 잡으려면 스크린샷/미리보기에 올인해라.</span></strong></p>
<p>어플 설치에 영향을 미치는 요소 중 아이폰/안드로이드폰 이용자 모두 연령별로 공통 특성이 나타나는데 연령대가 높을수록 앱설명(아이폰이용자)<br />
/어플설명(안드로이드폰이용자)이 연령대가 낮을수록 스크린샷(아이폰이용자)/미리보기(안드로이드폰이용자)가 어플설치에 큰 영향을 받는다고 답했다.</p>
<p>이 결과에서 <span style="text-decoration: underline">높은연령 이용자에게는 쉽고 자세한 어플설명을 제공</span>하고, <span style="text-decoration: underline">젊은 연령층에게는 스크린샷/미리보기를 통해 한정된 스크린샷 갯수에서<br />
어플의 특장점을 어떻게 넣을지 전략</span>이 필요하다. 이 결과를 미루어 볼 때  많은 개발자들이 스크린샷 중에서도 가장 중요한 첫번째 스크린샷을 등록할 때<br />
어플 실행 시 로딩화면을 등록 하는것에 대해서는 큰 고민이 필요한 할 것으로 보인다. <strong>[</strong><strong>참조:그래프5~6]</strong></p>
<p><strong>[그래프5] 아이폰 어플 설치 시 영향요인 3가지-연령별                       [그래프6] 안드로이드폰 어플 설치시 영향요인 3가지-연령별<br />
<a href="http://dev.paran.com/wp-content/uploads/2012/05/gh5.gif"><img class="alignnone size-full wp-image-7429 colorbox-7419" src="http://dev.paran.com/wp-content/uploads/2012/05/gh5.gif" alt="" width="408" height="204" /></a> <a href="http://dev.paran.com/wp-content/uploads/2012/05/gh6.gif"><img class="alignnone size-full wp-image-7430 colorbox-7419" src="http://dev.paran.com/wp-content/uploads/2012/05/gh6.gif" alt="" width="411" height="204" /></a></strong></p>
<p>&nbsp;</p>
<p><strong><span style="text-decoration: underline"><strong><strong><strong>4. </strong></strong></strong>디테일이 곧 높은랭킹을 보장한다.</span></strong></p>
<p>이용자들이 어플 설치 시 가장 많이 찾는 메뉴가 <span style="text-decoration: underline">애플 앱스토어는 인기25</span>, <span style="text-decoration: underline">안드로이드 마켓은 인기무료 메뉴</span>로 나타났다. 어플 성공을 위해서는<br />
<span style="text-decoration: underline">우리가 만든 어플을 어떻게든 인기25, 인기무료메뉴에 상위에 랭크</span> 시켜야 한다. 이유는 상위에 랭크 되면 다시 다운로드가 되고, 다운로드 되면<br />
다시 상위로 올라가는 선 순환이 일어나기 때문이다.</p>
<p>따라서 이용자들은 어떤 내용을 보고 우리 어플을 설치하는지? 이용자들이 보고 있는 접점에서 우리어플이 얼마나 효과적으로 노출되고 있는지?<br />
디테일을 고민해야 한다. 그 디테일이란?  [그래프5][그래프6]에서 보듯이 <span style="text-decoration: underline">앱스토어에서는 리뷰/스크린샷/별점/앱설명</span>, <span style="text-decoration: underline">안드로이드 마켓에서는<br />
사용후기/어플설명/미리보기</span><span style="text-decoration: underline">/별점/어플이름</span>이 이에 해당할 것이다. <strong>[</strong><strong>참조:그래프7~8]</strong></p>
<p><strong>[그래프7] 아이폰 어플 설치 시 많이 찾는 메뉴                                        [그래프8]안드로이드마켓에서 어플설치 시 많이 찾는 메뉴<br />
<a href="http://dev.paran.com/wp-content/uploads/2012/05/gh7.gif"><img class="alignnone size-full wp-image-7431 colorbox-7419" src="http://dev.paran.com/wp-content/uploads/2012/05/gh7.gif" alt="" width="410" height="206" /></a> <a href="http://dev.paran.com/wp-content/uploads/2012/05/gh8.gif"><img class="alignnone size-full wp-image-7432 colorbox-7419" src="http://dev.paran.com/wp-content/uploads/2012/05/gh8.gif" alt="" width="410" height="205" /></a><br />
</strong></p>
<p>&nbsp;</p>
<p><strong><span style="text-decoration: underline">5. <strong><strong><strong><strong> </strong></strong></strong></strong>이용자의 언어로 말하라~ 검색되지 않으면 존재하지 않는다. </span></strong></p>
<p>이용자들이 어플 설치시 가장 많이 찾는 메뉴에 대해 연령별 분석을 해 본 결과 아이폰/안드로이드폰 모두 <span style="text-decoration: underline">낮은 연령층에서는 </span><br />
<span style="text-decoration: underline">트랜드를 반영하는 인기메뉴의 선호</span>가 나타나고, <span style="text-decoration: underline">높은 연령일수록 검증된 추천메뉴에 대한 선호</span>가 나타났다.</p>
<p>여기에서 아이폰의 검색 메뉴가 눈에 띄는데<br />
만약 시간이 갈수록 어플 수가 많아진다고 가정 한다면, 내가 필요한 어플을 앱스토어에서 찾는 게 더욱 어려워 질 것이고, 결국 검색의 중요성이<br />
부각될 것이다.</p>
<p>이는 우리의 과거 십수년간 PC Web에서의 이용행태를 보면 알 수 있는데 PC Web의 초창기 때 인터넷 사용방법은 도메인을 외워서 홈페이지에<br />
접근 했었고(URL직접입력), 정보량이 조금 늘었을 때에는 잘 정리된 카테고리 홈페이지 사이트를 이용 했었고(야후), 정보량이 엄청난  현재에는<br />
검색사이트(구글) 이용할 수 밖에 없는 이유와 같다.</p>
<p>따라서 개발자는 <span style="text-decoration: underline">어플 등록 시 이용자들이 검색으로 쉽게  찾을 수 있게 이용자의 언어로 어플 이름을 만들고 어플을 등록할 때 입력하는<br />
키워드 또는 태그를 충분히 고려하여 입력</span>해야 한다. <strong> [</strong><strong>참조:그래프9~10]</strong></p>
<p><strong>[그래프9] 아이폰 어플 설치 시 많이 찾는 메뉴-연령별                         [그래프10] 안드로이드마켓에서 어플설치시 많이 찾는 메뉴-연령별<br />
<a href="http://dev.paran.com/wp-content/uploads/2012/05/gh9.gif"><img class="alignnone size-full wp-image-7433 colorbox-7419" src="http://dev.paran.com/wp-content/uploads/2012/05/gh9.gif" alt="" width="411" height="206" /></a> <a href="http://dev.paran.com/wp-content/uploads/2012/05/gh10.gif"><img class="alignnone size-full wp-image-7434 colorbox-7419" src="http://dev.paran.com/wp-content/uploads/2012/05/gh10.gif" alt="" width="411" height="206" /></a></strong></p>
<p><strong></strong> </p>
<p><strong><span style="text-decoration: underline"><strong><strong><strong><strong><strong>6. </strong></strong></strong></strong></strong>타이밍과 완성도는 고객의 입장에서 생각하라</span></strong></p>
<p>모든 서비스 담당자는 런칭시점이 다가오면서 항상 같은 고민에 부딪 치는데, 그것은 타이밍과 완성도에 대한 고민이다.<br />
보통 우리가 타이밍과 완성도의 우선순위를 정하는 방법은 <span style="text-decoration: underline">진입장벽이 낮으며 아이디어가 핵심인 어플인 경우는 </span><br />
<span style="text-decoration: underline">선점의 우위를 점하기 위해 타이밍이 우선</span>이고, <span style="text-decoration: underline">유사 어플이 이미 출시 되었거나 경쟁이 치열한 어플인 경우는 완성도가 우선</span>이다.는 결정이 힘을 받는다.<br />
그럼 무엇이 정답일까? 아래 조사항목에서 확인해 보자</p>
<p>아래 결과에서 보듯이 어플 삭제 후 재 설치경험의 58.6%이다,<br />
58.6%의 수치를 긍정적으로 본다면 약 10개중 6개는 재설치가 가능하고 우리어플도 6개에 해당될 수 있다는 것이고,<br />
58.6%의 수치를 부정적으로 본다면 약 10개중 4개는 재설치는 불가능하고 우리어플은 4개에 해당되고, 순간의 판단 착오로<br />
몇개월의 노력이 날라갈 수도 있다는 것이다.</p>
<p>따라서, <span style="text-decoration: underline">만약 완성되지 않은 채 어플을 출시해야 한다면 사업자의 입장이 아니라 고객의 입장에서</span><br />
<span style="text-decoration: underline">타이밍과 완성도를 충분히 고민해야</span> 한다.<strong>[참조:그래프11~12]</strong></p>
<p><strong>[그래프11] 어플삭제 후 재 설치경험                                                     [그래프12] 어플 삭제 후 재설치경험 &#8211; OS별<br />
<a href="http://dev.paran.com/wp-content/uploads/2012/05/gh111.gif"><img class="alignnone size-full wp-image-7435 colorbox-7419" src="http://dev.paran.com/wp-content/uploads/2012/05/gh111.gif" alt="" width="384" height="307" /></a> <a href="http://dev.paran.com/wp-content/uploads/2012/05/gh121.gif"><img class="alignnone size-full wp-image-7436 colorbox-7419" src="http://dev.paran.com/wp-content/uploads/2012/05/gh121.gif" alt="" width="384" height="307" /></a></strong><strong></strong></p>
<p><strong></strong> </p>
<p><strong><span style="text-decoration: underline"><strong><strong><strong><strong><strong><strong>7.</strong></strong></strong></strong></strong></strong> 게임은 타겟별 선호가 분명한 장르이므로 타겟별로 전략을 세워야 한다.</span></strong></p>
<p>국내 이용자들의 선호게임장르를 알아본 결과 전체 선호게임장르는 퍼즐/보드로 나타났고, 성별구분으로는 <span style="text-decoration: underline">남성은 RPG/스포츠/디펜스게임</span>,<br />
<span style="text-decoration: underline">여성은 퍼즐보드/아케이드/SNG로 그 선호가 분명</span>하게 나타났다.<br />
신규 게임 장르 진출을 고민하는 개발자인 경우 타겟 이용자의 선호 장르를 고려해 접근해야 하낟.<strong>[</strong><strong>참조:그래프13~16]</strong></p>
<p><strong>[그래프13] 선호게임 장르                                                                          [그래프14] 선호게임장르 &#8211; OS별<br />
<a href="http://dev.paran.com/wp-content/uploads/2012/05/gh13.gif"><img class="alignnone size-full wp-image-7438 colorbox-7419" src="http://dev.paran.com/wp-content/uploads/2012/05/gh13.gif" alt="" width="384" height="307" /></a> <a href="http://dev.paran.com/wp-content/uploads/2012/05/gh14.gif"><img class="alignnone size-full wp-image-7439 colorbox-7419" src="http://dev.paran.com/wp-content/uploads/2012/05/gh14.gif" alt="" width="384" height="307" /></a></strong></p>
<p><strong>[그래프15] 선호게임 장르 &#8211; 성별                                                             [그래프16] 선호게임 장르 &#8211; 연령별<br />
<a href="http://dev.paran.com/wp-content/uploads/2012/05/gh15.gif"><img class="alignnone size-full wp-image-7440 colorbox-7419" src="http://dev.paran.com/wp-content/uploads/2012/05/gh15.gif" alt="" width="384" height="307" /></a> <a href="http://dev.paran.com/wp-content/uploads/2012/05/gh16.gif"><img class="alignnone size-full wp-image-7441 colorbox-7419" src="http://dev.paran.com/wp-content/uploads/2012/05/gh16.gif" alt="" width="384" height="307" /></a></strong></p>
<p> <strong> </strong></p>
<p><strong><span style="text-decoration: underline">7. 어플의 가장 중요한 시점은 출시 후 한 달이다.</span></strong></p>
<p>실제 이용자 게임을 설치한 후 집중 플레이 시간을 알아 본 결과 일주일 정도 집중적으로 플레이 한다는 이용자가 36.3%로 가장 많았고,<br />
<span style="text-decoration: underline">약 84.7%가 한달이내 플레이 한다고 한다</span>. 이는 디바이스별/성별/연령별로 상관없이 공통적으로 나타나는 현상이다.<br />
(단, 게임장르에 따라 SNG 게임 같은 경우는 집중플레이 기간이 2달을 넘게 한다는 내용이 상위에 있음)</p>
<p>게임을 한 달간 집중적으로 플레이 한 후 더 이상 이용하지 않는다는 결론을 봤을 때, <span style="text-decoration: underline">개발사 입장에서는 한달 이내 투입비용을 모두 회수해야 </span><br />
<span style="text-decoration: underline">손익분기을 맞출 수 있다는 결론</span>이 나온다. 달리 말하면 그 만큼 모바일 게임이 트랜드에 민감하고 수명이 짧기 때문에 앞선 기획을 해야하며<br />
적절한 투입자원 고려가 게임 어플 수익창출의 큰 변수가 된다는 것을 알 수 있다.</p>
<p> <strong>[그래프17]설치 후 집중 플레이 기간                                                   [그래프18] 설치 후 집중 플레이 기간 &#8211; OS별<br />
<a href="http://dev.paran.com/wp-content/uploads/2012/05/gh17.gif"><img class="alignnone size-full wp-image-7442 colorbox-7419" src="http://dev.paran.com/wp-content/uploads/2012/05/gh17.gif" alt="" width="384" height="307" /></a> <a href="http://dev.paran.com/wp-content/uploads/2012/05/gh18.gif"><img class="alignnone size-full wp-image-7443 colorbox-7419" src="http://dev.paran.com/wp-content/uploads/2012/05/gh18.gif" alt="" width="384" height="307" /></a><br />
</strong><strong>[그래프19]설치 후 집중 플레이 기간 &#8211; 성별                                       [그래프20] 설치 후 집중 플레이 기간 &#8211; 연령별<br />
<a href="http://dev.paran.com/wp-content/uploads/2012/05/gh19.gif"><img class="alignnone size-full wp-image-7444 colorbox-7419" src="http://dev.paran.com/wp-content/uploads/2012/05/gh19.gif" alt="" width="384" height="307" /></a> <a href="http://dev.paran.com/wp-content/uploads/2012/05/gh20.gif"><img class="alignnone size-full wp-image-7445 colorbox-7419" src="http://dev.paran.com/wp-content/uploads/2012/05/gh20.gif" alt="" width="384" height="307" /></a></strong></p>
<p>이번 조사를 진행하면서  짐작으로 알고있는 내용을 확인하는 내용도 있고, 생각지도 못했던 내용을 알 수 있는 기회도 되었지만<br />
가장 중요한 것은 이 자료가 공유되면서 동일한 데이터를 보면서 다양하게 해석 될 수 있는 기회가 생겼다는 것인 것 같습니다.</p>
<p>혹시 <span style="text-decoration: underline">의견 및 제안 내용이 있으시면 언제라도 댓글로 작성해 주시고,</span><br />
<span style="text-decoration: underline">주신 의견은 다음 조사 진행 시 적극 반영</span>하도록 하겠습니다.</p>
<p>대단히 감사합니다.~~^^ </p>
<p>&nbsp;</p>
<p align="left"><strong>▶ 조사제목 : </strong>2012년 1분기 스마트폰 이용자 조사<br />
<strong>▶ 조사대상 :</strong> 스마트폰(팟게이트)이용자 총 7,815명 (아이폰 5,175명+안드로이드폰2,027명) 응답<br />
▶ <strong>조사기간 : </strong>2012년 3월29일 ~ 4월13일<br />
<strong>▶ 신 뢰 도 : </strong>95% 신뢰수준의 오차범위 ± 1.11%</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.paran.com/2012/05/16/customer_story/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MySQL 테이블과 인덱스 설계시 주의해야 할 13 가지</title>
		<link>http://dev.paran.com/2012/05/15/mysql-table-index-design-tip/</link>
		<comments>http://dev.paran.com/2012/05/15/mysql-table-index-design-tip/#comments</comments>
		<pubDate>Tue, 15 May 2012 00:46:53 +0000</pubDate>
		<dc:creator>sdchan1</dc:creator>
				<category><![CDATA[Tech Note]]></category>
		<category><![CDATA[Data Architect]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://dev.paran.com/?p=7329</guid>
		<description><![CDATA[kth 데이터지능팀 성동찬 안녕하세요. 오늘은 MySQL을 사용할 때 지켜야할 사항 몇 가지 정리합니다. 나름 혼자서 정리를 해 본 것들인데, MySQL로 서비스를 준비 중이라면 한 번쯤은 고려를 해봤으면 하는 내용입니다.^^ 테이블 설계 시 유의 사항 1. 반드시 Primary Key를 정의하고 최대한 작은 데이터 타입을 선정한다. 로그 성 테이블에도 기본적으로 PK 생성을 원칙으로 함 InnoDB에서 PK는 인덱스와 [...]]]></description>
			<content:encoded><![CDATA[<h3>kth 데이터지능팀 성동찬</h3>
<p>안녕하세요. 오늘은 MySQL을 사용할 때 지켜야할 사항 몇 가지 정리합니다.</p>
<p>나름 혼자서 정리를 해 본 것들인데, MySQL로 서비스를 준비 중이라면 한 번쯤은 고려를 해봤으면 하는 내용입니다.^^</p>
<h1><strong>테이블 설계 시 유의 사항</strong></h1>
<h4>1. 반드시 Primary Key를 정의하고 최대한 작은 데이터 타입을 선정한다.</h4>
<ul>
<li>로그 성 테이블에도 기본적으로 PK 생성을 원칙으로 함</li>
<li>InnoDB에서 PK는 인덱스와 밀접한 관계를 가지므로 최대한 작은 데이터 타입을 가지도록 유지</li>
</ul>
<h4>2. 테이블 Primary Key는 auto_increment를 사용한다.</h4>
<ul>
<li>InnoDB에서는 기본 키 순서로 데이터가 저장되므로, Random PK 저장 시 불필요한 DISK I/O가 발생 가능</li>
<li>InnoDB의 PK는 절대 갱신되지 않도록 유지<br />
(갱신 시 갱신된 행 이후 데이터를 하나씩 새 위치로 옮겨야 함)</li>
</ul>
<h4>3. 데이터 타입은 최대한 작게 설계한다.</h4>
<ul>
<li>시간정보는 MySQL데이터 타입 date/datetime/timestamp 활용</li>
<li>IP는 INET_ATON(‘IP’), INET_NTOA(int) 함수를 활용</li>
<li>정수 타입으로 저장 가능한 문자열 패턴은 최대한 정수 타입으로 저장</li>
</ul>
<h4>4. 테이블 내 모든 필드에 NOT NULL 속성을 추가한다.</h4>
<ul>
<li>NULL을 유지를 위한 추가 비용 발생<br />
(NULL 허용 칼럼을 인덱싱 할 때 항목마다 한 바이트 씩 더 소요)</li>
</ul>
<h4>5. Partitioning을 적절하게 고려하여 데이터를 물리적으로 구분한다.</h4>
<ul>
<li>데이터 및 인덱스 파일이 커질수록 성능이 저하되므로Partitioning 유도</li>
<li>PK 존재 시 PK 내부에 반드시 Partitioning 조건이 포함되어야 함</li>
</ul>
<h1><strong>인덱스 설계 시 유의 사항</strong></h1>
<h4>1. 인덱스 개수를 최소화 한다.</h4>
<ul>
<li>현재 인덱스로 Range Scan이 가능한지 여부를 사전에 체크</li>
<li>인덱스도 서버 자원을 소모하는 자료구조이므로 성능에 영향을 줌</li>
</ul>
<h4>2. 인덱스 칼럼은 분포도를 고려하여 선정한다.</h4>
<ul>
<li>인덱스 칼럼 데이터의 중복이 줄어들수록 인덱스는 최대의 효과를 가짐</li>
<li>하단 쿼리 결과 값이 1에 가까울수록(0.9이상 권고) 인덱스 컬럼으로 적합함
<pre>SELECT count(distinct INDEX_COLUMN)/count(*)
FROM TABLE;</pre>
</li>
</ul>
<h4>3. 커버링 인덱스(Covering Index)를 활용한다.</h4>
<ul>
<li>쿼리 조건이 인덱스 안에 포함된 경우 인덱스에서만 연산 유도</li>
<li>인덱스는 일반적으로 행 전체보다 작으므로 불필요한 Disk I/O 회피 가능<br />
&#8220;<a title="Permanent Link: MySQL에서 커버링 인덱스로 쿼리 성능을 높여보자!!" href="http://gywn.net/2012/04/mysql-covering-index/" rel="bookmark">MySQL에서 커버링 인덱스로 쿼리 성능을 높여보자!!</a>&#8221; 편 참고</li>
</ul>
<h4>4. 스토리지 엔진 별 INDEX 특성을 정확히 인지한다.</h4>
<ul>
<li>InnoDB에서 데이터는 PK 순서로 저장되고, 인덱스는 PK를 Value로 가짐</li>
<li>MyISAM은 PK와 일반 인덱스의 구조는 동일하나, Prefix 압축 인덱스를 사용<br />
(MyISAM 엔진에서 ORDER BY 시 DESC는 가급적 지양)</li>
</ul>
<h4>5. 문자열을 인덱싱 시 Prefix 인덱스 활용한다.</h4>
<ul>
<li>긴 문자열 경우 Prefix 인덱스(앞 자리 몇 글자만 인덱싱)를 적용
<pre>CREATE INDEX IDX01 ON TAB1(COL(4), COL(4))</pre>
</li>
<li>Prifix Size는 앞 글자 분포도에 따라 적절하게 설정<br />
(하단 결과가 1에 가까울 수록 최적의 성능 유지, 0.9이상 권고)</p>
<pre>SELECT count(distinct LEFT(INDEX_COLUMN,3))/count(*)
FROM TABLE;</pre>
</li>
</ul>
<h4>6. CRC32함수 및 Trigger를 활용하여 인덱스 생성한다.</h4>
<ul>
<li>URL/Email같이 문자 길이기 긴 경우 유용</li>
<li>INSERT/UPDATE 발생 시 Trigger로 CRC32 함수 실행 결과 값을 인덱싱</li>
<li>CRC32 결과값을 저장할 칼럼 추가 및 인덱스 생성
<pre>alter table user_tbl add email_crc int unsigned not null;
create index idx01_email_crc on user_tbl (email_crc);</pre>
</li>
<li>Insert Trigger 생성
<pre>create trigger trg_user_tbl_insert
before insert on user_tbl
for each row
begin
set new.email_crc = crc32(lower(trim(new.email)));
end$$</pre>
</li>
<li>Update Trigger 생성
<pre>create trigger trg_user_tbl_update
before update on user_tbl
for each row
begin
if old.email&lt;&gt; new.email then
set new.email_crc = crc32(lower(trim(new.email)));
end if;
end$$</pre>
</li>
<li>검색 쿼리
<pre>select *
from user_tbl
where email_crc = crc32(lower(trim('mail@domain.com')))
and email= 'mail@domain.com'</pre>
<p>CRC32 결과가 중복되어도, email값을 직접 비교하는 부분에서 중복이 제거됩니다.</li>
</ul>
<h4>7. 중복 인덱스 생성 회피</h4>
<ul>
<li>MySQL은 동일한 인덱스를 중복 생성해도 에러를 발생하지 않음</li>
<li>Primary Key로 구성된 칼럼과 동일한 인덱스를 생성하지 않도록 주의</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://dev.paran.com/2012/05/15/mysql-table-index-design-tip/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>데이터 수집/검색/조회 서비스 Splunk 퀵리뷰</title>
		<link>http://dev.paran.com/2012/05/10/data-collect-search-indexing-splunk-review/</link>
		<comments>http://dev.paran.com/2012/05/10/data-collect-search-indexing-splunk-review/#comments</comments>
		<pubDate>Thu, 10 May 2012 02:23:14 +0000</pubDate>
		<dc:creator>haegongster</dc:creator>
				<category><![CDATA[퀵 리뷰]]></category>

		<guid isPermaLink="false">http://dev.paran.com/?p=6958</guid>
		<description><![CDATA[분산기술 Lab 조해공, 임도형 Splunk 소개 Splunk 홈페이지에서 제시하는 메인 카피는 “Making Massive Machine Data Accessible, Usable and Valuable to Everyone”입니다. 서버에서 발생하는 거대한 데이터를 쉽게 가져와서, 다룰 수 있게 하고, 그 데이터에서 새로운 가치를 찾을 수 있게 하겠다는 것이네요. 그 흔한 뻥이라 느껴집니다. 게다가 기능 리스트를 보면 그 첫 번 째가 “Universally collect and [...]]]></description>
			<content:encoded><![CDATA[<h3> 분산기술 Lab 조해공, 임도형 </h3>
<p></p>
<h1>Splunk</h1>
<h1>소개</h1>
<p><a href="http://www.splunk.com/">Splunk</a> 홈페이지에서 제시하는 메인 카피는 “Making Massive Machine Data Accessible, Usable and Valuable to Everyone”입니다. 서버에서 발생하는 거대한 데이터를 쉽게 가져와서, 다룰 수 있게 하고, 그 데이터에서 새로운 가치를 찾을 수 있게 하겠다는 것이네요. 그 흔한 뻥이라 느껴집니다. 게다가 기능 리스트를 보면 그 첫 번 째가 “Universally collect and index …”로 시작합니다. ‘universally’랍니다. 얼마나 자신이 있으면 저렇게 과감하게 뻥 칠 수 있을까, 가 첫 대면의 느낌이었습니다.</p>
<p>하여간에 Splunk가 무엇인지 뭔지 파악해 봤습니다. Splunk의 기능들은 다음과 같습니다.</p>
<ul>
<li>서버에서 발생하는 데이터를</li>
<li>다양한 방법으로 가져와서</li>
<li>실시간으로 인덱싱하고</li>
<li>이를 웹 UI를 사용하여</li>
<li>검색하고 조회할 수 있게합니다.</li>
</ul>
<p>사실 요 사항들은 특별하지 않습니다. 기능 목록 자체는 평범합니다. 그런데 살펴보고 사용해 본 느낌은 이렇게 단순하지는 않았습니다. 그렇게 느낀 것들을 중심으로 얘기를 해보겠습니다.</p>
<h1>쓸만한 데이타 수집</h1>
<p>Splunk가 다루는 것은 머신 즉 서버에서 발생한 데이타를 대상으로 합니다. 특정 어플리케이션이 다루는 데이타일 수도 있으나, 어플리케이션이 남기는 로그나 리소스 사용량 등의 데이타도 포함합니다. 또한 어플리케이션이 사용하는 설정이나 메시지, 트랩, 이벤트등도 포함합니다.</p>
<p>Splunk는 다음과 같은 방식으로 데이타를 수집할 수 있습니다.</p>
<ul>
<li>syslog, syslog-ng를 TCP나 UDP로 받기</li>
<li>scp, ftp, tftp, rsync로 파일 복사</li>
<li>JMS와 같은 메시지큐에서 메시지 받기</li>
<li>DBI를 사용하여 DB 데이타 조회</li>
<li>ps, top, vmstat와 같은 명령어 결과 수집</li>
<li>Windows event API를 사용한 이벤트 조회</li>
<li>SPSEC LEA를 사용한 이벤트 조회</li>
</ul>
<p>그리고 다음과 같은 것을 모니터링 할 수 있습니다.</p>
<ul>
<li>파일의 변경</li>
<li>WIndows 레지스트리의 변경</li>
<li>로그파일에서 실시간으로 이벤트 발생</li>
</ul>
<p>이정도면 왠만한 데이터들은 전부 가져올 수 있을 것 같습니다. 거의 빠진 것 없는 것 같네요. 하지만 이것이 놀라울만한 건 아니였습니다.</p>
<h1>실시간 인덱싱</h1>
<p>사실 서버에서 발생되는 데이터들의 포멧은 전부 지맘대로 입니다. 당연할 수 밖에 없습니다. 수많은 어플리케이션들이 있고, 그 들은 자신의 목적에 적합한 데이터를 적합한 형태로 생성합니다. 이들을 전부 처리할 수 있어야 한다고 하면, 그리고 그런걸 개발해야 하는 상황이라면 좀 답답하게 느껴집니다. 그런데 Splunk는 이런 다양한 데이터들을 별도의 파서나 컨넥터 없이 잘 인덱싱 할 수 있다고 합니다. 그것도 실시간으로.</p>
<p>보통 영어로 된 데이터에서라도 일반적인 인덱싱은 쉽지 않습니다. 예를 들어 [2012/03/19 15:33:24] [ERROR] module=some, function=other, some one requested &#8217;please help me&#8217;, CODE=313과 같은 데이터를 처리하려면 검색엔진에서와 같은 단순한 인덱싱은 통하지 않을 것 같네요. 그야말로 데이터를 파싱해야 할 것 같습니다. 그런데 이러한 데이터들을 별도의 파서 없이 잘 인덱싱 할 수 있다고 합니다. 예를 든 메시지의 경우 따로 설정하지 않은 경우라도 조회 조건에 사용될 키로 &#8217;module&#8217;, &#8216;function&#8217;, &#8216;CODE&#8217;가 제시됩니다. 똘돌하게 잘 파싱되네요.</p>
<p>또한 실시간으로 진행됩니다. 여기서 말하는 실시간이라는 것은 2가지 의미가 있을 수 있습니다. 원본 데이타가 변경되었을 때 즉각적으로 Splunk에 적용된다는 것하고, 적용된 바가 사용자 UI에 역시 즉각적으로 반영이 된다는 것. 확인해 보니 2가지 모두 실시간으로 반영되는 것을 확인할 수 있었습니다.</p>
<h1>강력한 사용자 Web UI</h1>
<p>Splunk는 사용자 UI가 Web으로 되어 있습니다. Web은 GUI보다는 어쩔 수 없이 덜 interactive합니다. 대표적으로 실시간으로 값이 바뀌거나, 화면 구성 요소의 동적 변경 등이 그렇습니다. Splunk의 UI는 다음과 같은 모습입니다.</p>
<p><img src="http://dev.paran.com/wp-content/uploads/2012/05/capture-7.jpg" alt="" title="capture-7" width="625" height="352" class="alignnone size-full wp-image-7391 colorbox-6958" /><br />
상단에 조회를 입력할 텍스트 상자가 있고, 바로 아래에 그 조회 결과를 그래프로 보여줍니다. 그리고 하단 좌측에는 파싱된 결과의 키들이 나열되어 있고, 그 우측에는 실제 데이터들이 보여지고 있습니다.</p>
<p>보통 Web으로 된 UI의 경우 조회를 위한 다양한 사항들을 입력하기 위한 별도의 조회 화면이 제공됩니다. 상황에 맞는 다양한 옵션을 제시하기 위해서 입니다. 그런데 Splunk에서는 검색 사이트에서와 같이 검색어를 실시간으로 제시하고 있습니다. 다음 그림은 &#8216;error=&#8217;까지 입력한 상황입니다.</p>
<p><img src="http://dev.paran.com/wp-content/uploads/2012/05/capture-3.jpg" alt="" title="capture-3" width="628" height="292" class="alignnone size-full wp-image-7392 colorbox-6958" /></p>
<p>검색에 사용할 필드 error에 대하여 이미 실시간으로 파싱하여 인덱싱된 값들까지 제시하고 있습니다. 인상깊네요.</p>
<p>&nbsp;</p>
<p>다음은  없는 명령 &#8216;report&#8217;를 입력했을 때의 화면으로 다른 명령어를 제안하고 있습니다.</p>
<p><img src="http://dev.paran.com/wp-content/uploads/2012/05/capture-4.jpg" alt="" title="capture-4" width="626" height="297" class="alignnone size-full wp-image-7393 colorbox-6958" /><br />
&nbsp;</p>
<p>다음은 timechart라는 명령어를 입력한 것인데, 이에 대한 도움말을 보여주고 있습니다. 살펴 보면, 기본 설명외에 사용 예가 있고, 우측에는 이전에 사용했던 히스토리를 보여주고 있습니다.</p>
<p><img src="http://dev.paran.com/wp-content/uploads/2012/05/capture-5.jpg" alt="" title="capture-5" width="626" height="292" class="alignnone size-full wp-image-7390 colorbox-6958" /><br />
실제로 사용해 보니 Web UI의 불편함 혹은 한계를 극복했다 싶습니다. Web의 화면으로 어떻게 그 복잡한 조회와 동작을 할 수 있을까 하는 의혹을 떨칠 수 있습니다.</p>
<h1>Splunk를 다시 정리하면</h1>
<p>서버들이 생성한 데이터를</p>
<ul>
<li>‘<strong>실시간</strong>’으로 ‘<strong>수집</strong>’하고</li>
<li>&#8216;<strong>실시간</strong>&#8216;으로 ‘<strong>인덱싱</strong>’하고</li>
<li>‘<strong>검색</strong>’할 수 있고,</li>
<li>‘<strong>모니터링</strong>’과 ‘<strong>알람</strong>’이 가능하고,</li>
<li>‘<strong>리포팅</strong>’과 ‘<strong>분석</strong>’이 가능합니다.</li>
</ul>
<p>그리고</p>
<ul>
<li>‘<strong>대쉬보드를 사용자 정의</strong>’할 수 있고,</li>
<li>시스템의 ‘<strong>확장성</strong>’이 있으며,</li>
<li>‘<strong>역할기반 접근 제어</strong>’가 가능한 시스템입니다.</li>
</ul>
<p>그런데 꽤나 완성도 있고, 쓸만하고, 실시간으로 처리하고, 업무에 도움이 되겠다 싶은 시스템입니다.</p>
<h1>Splunk를 현 업무에 적용한다고 하면</h1>
<p>2가지를 생각해 봤습니다.</p>
<h2>Hulahoop의 성능 테스트에 활용</h2>
<p>Hulahoop는 kth 분산기술Lab에서 개발 중인 분산 DBMS입니다. 이를 성능테스트 하려면 복수의 서버에서 구동되는 테스트 프로그램에서 생성된 테스트 결과와 각 Hulahoop가 구동되고 있는 서버의 리소스(cpu, mem, disk util)사용 데이터를 수집하여야 합니다. 기존에는 이러한 데이터를 수집하고, 합치고, 분석하는 로직을 하드코딩한 별도의 프로그램을 따로 작성하였습니다. 그리고 결과를 그래프 등으로 시각화하는 별도의 프로그램을 또 작성하여야 했습니다. 그런데 만약 Splunk를 사용한다면 단지 성능 데이터만 파일로 떨구게 하는 작업만 하고, 이외에는 모두 Splunk로 가능할 것 같습니다. 떨군 성능 데이터 파일은 Splunk에서 scp로 가져오면 되고, 각 서버의 리소스 사용 데이터 역시 Splunnk의 기능을 사용하여 수집할 수 있을것이구요.</p>
<h2>GIS 지도 데이터 업로드 프로세스에 적용</h2>
<p>현재 올레맵 상용 지도 서비스는 kth 분산기술랩에서 개발된 분산파일시스템(PFS)에 저장되어 있으며, 지도 데이터 업데이트가 있을 때, 새로운 지도를 PFS에 업로드 하게 됩니다. 수십억 개의 지도 이미지가 업로드가 되는데, 이에 따른 로그의 양이 엄청납니다. 2대 이상의 물리적 장비에 저장되는 많은 양의 로그는 Splunk의 도움으로 다음과 같은 모니터링을 아주 쉽게 할 수 있습니다. 현재 업로드의 진행 상황, 현재 업로드 throughput, 성공/실패한 업로드 수, 부하가 많이 걸리고 있는 PFS front-end, 오류의 형상등을 전부 한 눈에 쉽게 볼 수 있으며, 그로 인해 불필요하게 문제가 발생하는 장비을 찾아내어 콘솔로 직접 접속하는 수고를 없앨 수 있게 됩니다.</p>
<p>뿐만 아니라, Splunk를 이용해 업로드시 발생한 모든 오류의 종류를 추출하여 각 오류의 비중을 보기 위해 pie 그래프를 그려 볼 수도 있고, 만약 어떤 특정 시간대에 업로드 속도가 느려졌다면 생성된 throughput 그래프를 보고 바로 알 수 있습니다. 그 시간대를 잡아내어, 그 시간대에 해당하는 모든 PFS 서버들의 로그에서 error 및 critical 이상의 로그 레벨만을 추출해 내어 재빨리 문제를 파악할 수도 있죠.</p>
<h1>분산시스템에서의 모니터링, 데이터 수집, 분석</h1>
<p>서버가 몇 대 안될 경우에는 서버를 모니터링하거나 데이터를 수집하고 분석하는 것이 크게 어렵지는 않습니다. 콘솔로 로그인하여 몇 명령어를 사용하여 확인할 수 있습니다. 그런데 서버의 수가 늘어나서 몇 백대의 수준이 되고, 각 서버의 환경도 여러가지라면 수잡업은 이미 불가능합니다. 하여간에 관리 시스템이 필요한데, 다양한 환경의 다양한 어플리케이션의 다양한 포멧의 데이터를 처리할 수 있는 시스템은 흔치 않습니다. 게다가 쓸만한 시스템은 더욱. 이러한 도구를 사용하여 작업을 해왔던 담당자는 이런 도구가 없인느 업무를 진행하지 못할 것 같다 싶네요.</p>
<h1>다른 생각들</h1>
<p>저 개인적으로는 이런 류의 제품은 돈 벌기 힘들다고 믿고 있습니다. 이러한 제품을 도입하면 관리가 용이해지고 비용을 절감할 수 있기는 하죠. 하지만 비용 절감에만 도움이 될 분, 매출 증가에는 도움이 되지 않기 때문에 한계가 있다고 생각하기 때문입니다. 그런데 듣기로는 Splunk는 꽤나 대박을 쳤다고 합니다. 그것도 아주 크게. 사실 이런류의 제품은 꽤나 오래전부터 많이 있어 왔습니다. 그런데 Splunk가 그것들과 다른 점은 제대로 쓸만하게 만들었다는 것, 혹은 감동을 줄 수 있다는 것 아닌가 싶습니다. 기능들 리스트만 나열해 본다면 기존의 다른 제품과 그닥 다르지 않습니다. 이러한 제품이 만족하여야 하는 기능을 지원한다는 것은 말 그대로 당연합니다. 이런 기능들은 당연하기 때문에, 제공하지 않으면 고객들이 보지도 않는 것들이죠. 그러나 Splunk는 기존의 제품들에서는 느껴보지 못한 ‘감동기능’이 있습니다. 감동 기능은 기대하지 않았지만, 제공하면 큰 만족을 주는 기능들을 말합니다. 웹 UI의 강력함이나, 데이터 소스의 설정의 편의성이 이에 해당합니다. Splunk가 대박을 칠 수 있었던 것은 이러한 감동기능때문 아닌가 싶습니다. <strong>누구도 요구하지는 않지만(필수 기능이 아니지만), 제대로 만들어 기대치 않았던 감동을 주었기(감동 기능) 때문이라 생각합니다.</strong> 그리고 이러한 감동기능은 차후에는 당연한 필수기능이 됩니다. 이렇게 제품군의 흐름을 바꾸어버리는 제품이 간혹 등장하곤 하는데, 이후에 유사한 제품을 개발하려면 최소한 그 감동기능은 지원해야 하고 어느덧 필수기능이 되어버립니다. 이런 식으로 제품군의 흐름이 바뀌게 됩니다. 대박치기 위해서는 마냥 따라해서는 안되죠. 감동받을 그 가치를 찾아내고 현실화하여야 합니다.</p>
<h1>Reference</h1>
<p>회사 home page: <a href="http://www.splunk.com/">http://www.splunk.com</a></p>
<p>Wikipedia: <a href="http://en.wikipedia.org/wiki/Splunk">http://en.wikipedia.org/wiki/Splunk</a></p>
<p>Guide including feature list: <a href="http://www.splunk.com/web_assets/pdfs/secure/Splunk_Guide_to_Operational_Intelligence.pdf">http://www.splunk.com/web_assets/pdfs/secure/Splunk_Guide_to_Operational_Intelligence.pdf</a></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.paran.com/2012/05/10/data-collect-search-indexing-splunk-review/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CloudStack 으로 자체 클라우드 만들기 – kth 개발자 클라우드를 소개합니다.</title>
		<link>http://dev.paran.com/2012/05/08/cloudstack-kth-developer-cloud/</link>
		<comments>http://dev.paran.com/2012/05/08/cloudstack-kth-developer-cloud/#comments</comments>
		<pubDate>Tue, 08 May 2012 01:37:55 +0000</pubDate>
		<dc:creator>rocky</dc:creator>
				<category><![CDATA[Tech Note]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Cloudstack]]></category>
		<category><![CDATA[Private Cloud]]></category>
		<category><![CDATA[개발자 클라우드]]></category>

		<guid isPermaLink="false">http://dev.paran.com/?p=7249</guid>
		<description><![CDATA[기술전략팀 이석훈 창의적인 발상은 창의적이고 자유로운 공간에서 나온다고 합니다. 일부 회사들은 직원들이 창의적인 아이디어를 끌어낼 수 있도록 사무공간과 환경을 개선하기도 합니다. KTH는 개발자의 창의적이고 자유로운 공간을 개발자 클라우드를 통해 마련하고자 하였고, 그 내용을 상세히 공개합니다. Overview 사내 개발자들에게 전혀 업무와 상관없이 지극히 개인적인 용도의 놀이터로서 개인 서버 장비로 쓸 수 있는 개발자 클라우드를 구축하게 되었습니다. 수년 [...]]]></description>
			<content:encoded><![CDATA[<h3>기술전략팀 이석훈</h3>
<p>창의적인 발상은 창의적이고 자유로운 공간에서 나온다고 합니다. 일부 회사들은 직원들이 창의적인 아이디어를 끌어낼 수 있도록 사무공간과 환경을 개선하기도 합니다. KTH는 개발자의 창의적이고 자유로운 공간을 개발자 클라우드를 통해 마련하고자 하였고, 그 내용을 상세히 공개합니다. </p>
<h1><strong>Overview</strong></h1>
<p>사내 개발자들에게 전혀 업무와 상관없이 지극히 개인적인 용도의 놀이터로서 개인 서버 장비로 쓸 수 있는 개발자 클라우드를 구축하게 되었습니다. 수년 전이였다면 개인 업무용 PC 외에 서버용도의 PC를 던져주고 사무실의 온도와 소음만 높였을 터인데 이제는 Cloud가 대세인 시대가 아닌가요! 또한 저희는 기존 서비스 운영을 위해 사용되던 수백대의 VM(Virtual Machine) 제공 방식처럼 사양 및 OS 환경의 요구사항에 맞게 VM을 제공해 주는 것이 아니라, 사내 개발자들이 자율적으로 VM을 운용하고 커뮤니티 VM Template 들을 서로 공유하고 의견을 나눔으로써 개개인의 기술적인 노하우들이 자연스럽게 Open &amp; Share 할 수 있기를 원했습니다.</p>
<p>저희는 회사내의 다양한 상황을 고려해 아래와 같은 원칙을 세웠습니다.</p>
<p><strong>        1.  VM(Virtual Machine)의  생성 및 자원 할당을 포함한 모든 관리는 개발자 스스로 할 수 있어야 한다.</strong></p>
<p><strong></strong><strong>        2. 일반적인 서비스포트를 제외한 모든 가상화 장비로의 접근은 사내 VPN 을 통해 접근하도록 한다.</strong></p>
<p><strong></strong><strong>        3. 회사내의 서비스 인프라에 영향이 없도록 물리적/ 논리적으로 분리되어야 하며 공개된 서비스 포트 외의 접근을 허용하지 않는다.</strong></p>
<p>위의 원칙을 기준으로 가장 먼저 진행한 것은 개발자들에게 제공될 VM(Virtual Machine) 이 Self-Service Portal 형태로 제공이 가능하게 해줄 수 있는 Open Source 기반의 SW 플랫폼의 선정 이였으며 KT ucloud biz 에서 도입하여 국내 상용 서비스에 적용한 <a href="http://CloudStack.org/">CloudStack</a> 을 적용하기로 결정하고 제공되는 매뉴얼을 기반으로 구축하였습니다.</p>
<p>&nbsp;</p>
<h1><strong>1. About CloudStack</strong></h1>
<p>먼저 CloudStack에 대해 간단히 소개하자면 <a href="http://aws.amazon.com/">AWS</a>(Amazon Web Service)의 EC2와 같은 IaaS 구축을 위한 Open Source 기반의 클라우드 구축 운용 Software Suite (환경 구축 툴) 이며 작년에 <a href="http://www.citrix.com">Citrix</a>사가 인수하였으며 최근 3.X 정식 버전이 릴리즈되어 많은 부분들이 개선되었고, 오픈소스 소프트웨어 프로젝트 지원단체인 <a href="http://www.apache.org/">ASF</a>(Apache Software Fundation)에 기증한다고 발표하였습니다.</p>
<ul>
<li> <strong>CloudStack 특징</strong>
<ul>
<li>Scalable Architecture</li>
<li>Multiple Hypervisor Support (Xenserver, KVM, VMware vSphere,… )</li>
<li>Automatic Configuration Management ( support virtual appliances)</li>
<li>Graphical User Interface ( support Admin/EndUser  Web UI )</li>
<li>Standard API Support</li>
<li>Extensibility (pluggable allocation architecture )</li>
<li>High Availability configurations</li>
<li>Virtual Networking to segment network traffic into VLANs</li>
</ul>
</li>
<li><strong>CloudStack 구축 예</strong>
<ul>
<li>Public Cloud 환경 구축
<ul>
<li>Amazon EC2™ service와 같은 서비스 제공</li>
<li>구축회사 : KT, TATA, IDC Frontier</li>
</ul>
</li>
<li>Private Cloud 환경 구축 (Enterprises)
<ul>
<li>구축 회사: Zynga, KTH(?)</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>&nbsp;</p>
<h1><strong>2. 구축 환경</strong></h1>
<p>우리가 구축했던 시스템 및 SW환경은 아래와 같으며, VM의 Virtual disk Image인 Root Disk 과 Data volume을 저장하기 위한 Primary Storage는 iSCSI Storage 를 사용, Template, ISO images, snapshot 등의 정적 데이터를 저장하기 위한 Secondary Storage는 NFS(Network File System) 을 사용하여 구축하였습니다.</p>
<ul>
<li>Hypervisor  &#8211; Citrix Xen Enterprise 5.6 SP1</li>
<li>Operating system – Red Hat Linux 4.1</li>
<li>CloudStack version 2.2.13</li>
</ul>
<p>&nbsp;</p>
<h1><strong>3. 개발자 클라우드 구성</strong></h1>
<p>CloudStack 에서 제공하는 여러 메뉴얼들은 CloudStack 기반의 Cloud self-service Portal 을 구축하는데 부족함이 없으며 기본적으로 CloudStack의 네트워크 모델에 대한 이해가 필요합니다. 사내 클라우드 인프라팀에서는 이미 우리만의 네트워크 아키텍쳐를 적용하여 가상화 시스템 환경을 구축하고 XenCenter(XenServer Management Client)를 통해 XenServer 기반의 VM을 운영하여 회사내의 여러 서비스를 제공하고 그에 대한 노하우가 있는 상황으로 시작이 두렵지는 않았었습니다. 물론 초기 구축 시에는 전통적인 회사 네트워크 아키텍쳐 기준으로 CloudStack 네트워크 설계를 고려하여 개발자 클라우드 구성에 몇 차례 시행착오가 있기도 했었습니다.</p>
<p><em>현재 구축된 KTH 개발자 클라우드는 CloudStack 네트워크 모델을 기준으로 구성되었으나 Zynga가 CloudStack을 기반으로 Zcloud를 구축하여 AWS의 의존도를 20%수준으로 낮춘것처럼 추후 CloudStack 을 커스터마이징 하여 사내 서비스를 위한 가상화 서버군의 아키텍쳐를 수용 가능하도록 개선하고 기존의 인프라 운영을 위한 Legacy 시스템의 연계를 진행해 보고 싶은 것이 개인적인 욕심입니다. </em></p>
<p>&nbsp;</p>
<h2><strong>3.1 시스템 구성</strong></h2>
<p>CloudStack의 구성은 크게 Management Server와 Cloud Infrastructure로 나눌 수 있으며 Management Server를 통해 Cloud Infrastructure의 관리를 수행합니다.</p>
<p>Cloud Infrastructure는 여러 개의 Zone (datacenter)로 구성되며, 해당 Zone 안에는 VM(Virtual Machine)을 동작시키는 Host Computer 가 존재합니다. 큰 단위 순으로 나열해보면 Zone &gt; Pod &gt; Cluster &gt; Host 순으로 구성이 이루어집니다.  제공되는 메뉴얼에는 규모에 따른 클라우드 구성에 대해 제안을 하고 있으며 구축 용도 및 상황에 따라 참고하여 구성할 수 있습니다.</p>
<p>현재 구축된 KTH의 개발자 클라우드의 시스템 구성은 아래와 같습니다. (<em>네트워크 구성과 관련된 부분은  개발자 클라우드 구축 멤버이신 클라우드기획팀 이장원 팀장님이 첨언 해주셨습니다.</em>)</p>
<p>&nbsp;</p>
<p><a href="http://dev.paran.com/wp-content/uploads/2012/04/1.png"><img class="aligncenter size-full wp-image-7251 colorbox-7249" title="KTH developer Cloud Infrastructure" src="http://dev.paran.com/wp-content/uploads/2012/04/1.png" alt="" width="704" height="528" /></a></p>
<p>&nbsp;</p>
<ul>
<li><strong>Layer 3 스위치</strong>는 C사 제품으로 방화벽과 L3 스위치 모듈이 하나의 블레이드내에 존재합니다. 방화벽 설정의 경우 인바운드 트레픽의 경우는 ACL를 설정하여, 허용된 트래픽만 통신이 가능하며 아웃바운드 트레픽은 차단하지 않았습니다. 라우터의 경우 VRRP(Virtual Router Redundancy Protocol)을 이용하여 고가용성을 구현하였습니다.</li>
<li><strong>Layer 2 스위치</strong>는  각 Pod 와 연결되는 구조로 Pod 구분은 물리적인 스위치를 통한 분리가 아니라 동일 L2스위치내에서 VLAN을 통한 별도의 IP Class 제공을 통한 분리 방식을 채택하였습니다., 또한 스위치의 경우 일반적인 이중화 방식인 INTER-LINK를 이용하여 이중화 하였고, 각 호스트머신은 Bonding 구조로 연결되어 있습니다.</li>
<li><strong>Management Server</strong>에는 Cloud Infrastructure 관리를 위한 Self-Service Portal 과 Mysql DB가 설치되며 되며 각각 Single Node 및 Multi Node 구성과 Single 및 Primary/Backup 형태로 구성이 가능합니다. 저희는 현재 모두 Single로 구축하였으며 접근 허용을 위한 공인망(시스템 자체 방화벽 설정을 통해 사내, VPN을 통해 접근 가능하도록 설정)과 클라우드 자원들을 관리하기 위한 사설망 연결 구성을 하였습니다. (<em>물론 상용으로 서비스를 런칭하였다면 당연히 이중화를 고려했을 것이라는 것을 의심하지 않길 바라는 마음입니다. ^^;</em>)
<ul>
<li>관리자용 EndUser용 WEB UI 제공</li>
<li>API 제공</li>
<li>새로운 VM생성 요청시 Offering 조건에 맞는 Host Computer에 배정</li>
<li>예약된 범위 내에서 Private/ Public  IP 자동 할당</li>
<li>DISK 할당 관리 ( Root Data, Data Volume )</li>
<li>Snapshots, Templates, ISO image 관리</li>
<li><em>user </em><em>권한의 API에서 Portal의 계정 패스워드를 변경 못하게 되어있는 부분에 대해서는 납득이 어려웠습니다. 모든 Self-Service Portal의 제어는 내부적으로 API로 연동이 되기 때문에 실제 내부용 서비스의 오픈 이후에 포털 계정에 대한 비번 변경에 대해서 모두 Admin 권한으로 수정하였습니다.  CloudStack 3.0에서는 LDAP 연동을 지원하여 사내 그룹웨어 시스템과 연동이 가능하게 될 것으로 보여 이 부분에 대해서는 업그레이드로 해결하려고 계획하고 있습니다. </em></li>
</ul>
</li>
<li><strong>Zone</strong>은 하나의 datacenter로 볼 수 있으며 CloudStack 플랫폼상에서 가장 큰 단위의 집합 구성으로 CloudStack은 개념적으로 하나 이상의 Zone을 가질 수 있습니다. Zone은 하나 이상의 Pod와 Secondary Storage로 구성되어 있으며 하나 이상의 Layer3 Switch가 포함될 수 있습니다.  우리의 경우 규모가 크지 않아 현재 한 개의 Zone으로 구성하였습니다.</li>
<li><strong>Pod</strong>는 일반적으로 Rack 하나를 의미하며 Layer-2 스위치와 하나 이상의 Cluster로 구성되며 동일 Pod 내의 Host는 같은 subnet을 사용합니다. 보통은 Pod에 한 개의 Cluster의 관계를 가지고 구성된다고 합니다.</li>
<li><strong>Cluster</strong>는 하나 이상의 Host Machine과 Primary Storage로 구성되며 동일한 Hypervisor 타입 (Xenserver, KVM, vSphere, Oracle VM)이 가능합니다.  우리가 적용한  Xenserver 기준으로는 최대 8개의 Host Machine을 Pool로 구성하여 CloudStack의 Cluster에 연결 시킬 수 있습니다. Citrix Xenserver Hosts의 Pool 구성 및 네트웍 세팅은 관리툴인 Xencenter를 통해서 설정하였고 Xenserver 제어가 가능한 콘솔 명령어들이 있지만 몇몇 정보를 확인하기 위한 용도로만 사용하였습니다. 우리가 적용한 CloudStack 2.2.13 에서 VM의 이동은 동일 Cluster 내에서 가능합니다. (<em>CloudStack 3.X </em><em>부터는 동일 Pod내의 Cluster 간의 VM 이동이 가능하도록 개선되었습니다.</em>)</li>
<li><strong>Host</strong>는 Cluster 내에 있는 Compute Node 이며 VM을 호스팅합니다.
<ul>
<li>CPU, Memory, Storage, 네트워크 리소스를 제공</li>
<li>다양한 CPU 속도와 Memory 구성이 가능하며, Offering 형태로 제공</li>
<li>동일 Cluster 내에는 동일 CPU로 구성</li>
<li>VM의 root disk는 service-offering에서 data volume은 disk-offering에 정의</li>
<li>Offering : Template(OS+Software), Service-offering (Cpu + Memory), Disk-offering으로 구성됨</li>
<li><em>우리 개발자는 모두 평등한 자유시민! 이기 때문에 동일한 사양으로 제공하고 Disk Volume만 다양성을 두었습니다. 만일 신규 도입 및 구축 플랫폼 테스트를 위해 고성능 또는 다수의 리소스를 제공하는 테스트 Cloud 팜을 구성하게 된다면 다양한 Offering 을 제공했으면 합니다. 이런 테스트 Cloud 팜은 개발자들이 임시로 리소스를 할당 받아 구축한 아키텍처를 스스로 검토하기 위해 정말 필요합니다.</em></li>
</ul>
</li>
<li><strong>Secondary Storage</strong>는 Template, ISO images, snapshot 등의 정적 데이터가 저장되며 Zone내에 위치하며 Multiple Storage Server를 등록 가능합니다. Zone내에만 존재하기 때문에 동일 Zone에 있는 VM에게만 서비스 됩니다. Secondary 스토리지의 경우 NFS 프로토콜만 지원하기 때문에 IDC내 운용중인 Scale-out(*가상화 환경에 중요한 포인트) NAS 스토리지를 통하여 1TB 디스크 볼륨에 Template, ISO, Snapshot의 증가를 예측하여 Auto Scale-out 볼륨으로 최대 5TB 제공되도록 구성되었습니다.</li>
<li><strong>Primary Storage</strong>는 VM의 Virtual disk Image인 Root Disk와 Data Volume을 저장하며 Cluster내에 위치하며 Multiple Storage Server를 등록 가능합니다.  iSCSI, NFS지원이 가능하며 VM의 Performance에 많은 영향을 줍니다. Primary Storage 없이 Host Machine의 Local Storage의 사용도 가능하나 VM의 이동 backup 설정이 불가능해져 fault tolerant 한 운영이 힘들어 집니다. 저희는 iSCSI 를 통해 구성하였으며 iSCSI 스토리지도 Secondary Storage와 마찬가지로 Scale-out 구조의 디스크 볼륨의 크기가 <a href="http://en.wikipedia.org/wiki/Thin_provisioning">Thin provisioning</a> 지원이 가능한 스토리지를 통하여 구성되었습니다. 기존 전통적인 SAN 스토리지의 경우 고가용성 측면에서 DBMS 가상화등에 운영하고 있으나 금번 개발자 클라우드환경의 경우 유연한 가상화 인프라 구조의 테스트?(네크워크 통합) 및 효율적인 디스크 볼륨의 사용을 위하여 스토리지 가상화 기술 활용 차원에서 Thin Provisioning을 통한 디스크 볼륨의 제공으로 디스크 리소스 사용요청에 유연하게 대응 할수 있는 환경을 제공하게 되었으며, 실제 서비스 운영환경에도 점진적으로 SAN 구조의 디스크 할당 방식에서 iSCSI 기반으로 Thin Provisioning 구조의 스토리지 사용을 확대할 계획을 가지고 있습니다.</li>
</ul>
<p>&nbsp;</p>
<h2><strong>3.2 네트워크 구성</strong></h2>
<p>CloudStack의 네트워크 아키텍쳐상 여러 유형의 Network가 존재하며 Physical, Virtual 두가지 Type의 네트워크로 분류됩니다. CloudStack 기반의 Cloud 구축시 반드시 이해하고 있어야 할 부분이라서 간단하게 살펴보면 아래 표와 같습니다.</p>
<table width="800" border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td style="text-align: center;" valign="top" bgcolor="#e2ecff" width="158"><strong>Network Type</strong></td>
<td valign="top" bgcolor="#e2ecff" width="300">
<p align="center"><strong>내용</strong></p>
</td>
<td valign="top" bgcolor="#e2ecff" width="300">
<p align="center"><strong>비고</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="158"><strong> </strong><strong>Guest Network</strong></td>
<td valign="top" width="300">- VM이 연결된 Virtual 네트워크</td>
<td valign="top" width="300">Isolation을 지원</td>
</tr>
<tr>
<td valign="top" width="158"><strong> Private Network</strong></td>
<td valign="top" width="300">- VM간 트래픽을 전달하는 Physical네트워크</td>
<td valign="top" width="300">Guest Network : Virtual Networking</td>
</tr>
<tr>
<td valign="top" width="158"><strong> </strong><strong>Link-local Network</strong></td>
<td valign="top" width="300">- Hypervisor Host와 system VM(Virtual Machine) 간 통신을 위한 네트워크 (RFC 3927  Network)</td>
<td valign="top" width="300"> </td>
</tr>
<tr>
<td valign="top" width="158"><strong> </strong><strong>Public Network</strong></td>
<td valign="top" width="300">
<p style="text-align: left;"> - VM, 인터넷간 트래픽을 전달하는 Physical 네트워크<br /> &#8211; Guest Network이 Driect Attached Networking 일 경우 guest 간 트래픽을 전달.</p>
</td>
<td valign="top" width="300">- VM에 Public IP 할당</td>
</tr>
<tr>
<td valign="top" width="158"><strong> Management Network</strong></td>
<td valign="top" width="255"> - 관리서버, Host, Storage 간 Physical 네트워크</td>
<td valign="top" width="246"> </td>
</tr>
<tr>
<td valign="top" width="158"><strong> </strong><strong>Storage Network</strong></td>
<td valign="top" width="300"> - Host와 Storage간의 Optional Physical 네트워크</td>
<td valign="top" width="300">트래픽이 많이 발생하는 링크 분리</td>
</tr>
</tbody>
</table>
<p>※ 하나의 NIC으로 여러 Physical Network 사용이 가능</p>
<p>&nbsp;</p>
<p>CloudStack 의 네트워크 모델은 Basic Mode 와 Advanced Mode 두가지 모드를 지원하며 Zone 구성 시 선택 및 설정이 가능합니다. VM의 인터넷에 직접 연결 여부에 따라 “Direct Attacked”와 “Virtual”로 구분되며 아래 표와 같이 정리할 수 있습니다.</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" bgcolor="#e2ecff" width="165">
<p style="text-align: center;"><strong> </strong><strong>항목</strong></p>
</td>
<td valign="top" bgcolor="#e2ecff" width="149">
<p style="text-align: center;"><strong>Virtual Networking</strong></p>
</td>
<td valign="top" bgcolor="#e2ecff" width="250">
<p style="text-align: center;"><strong>Direct Attached</strong> <strong>tagged Networking</strong></p>
</td>
<td valign="top" bgcolor="#e2ecff" width="250">
<p style="text-align: center;"><strong>Direct Attached</strong> <strong>Untagged Networking</strong></p>
</td>
</tr>
<tr>
<td valign="top" width="165"><strong> </strong><strong> VM, 인터넷간 트래픽</strong></td>
<td valign="top" width="149">- Virtual Router 거침</td>
<td valign="top" width="154">- 직접연결</td>
<td valign="top" width="154">- 직접연결</td>
</tr>
<tr>
<td valign="top" width="165"><strong> </strong><strong> Network Isolation 여부</strong></td>
<td valign="top" width="149">- Virtual Router가 Isolation 지원- Account별 VLAN(zone-wide)</td>
<td valign="top" width="154">- Tag로 Isolation 지원- Account별 VLAN Isolation</td>
<td valign="top" width="154">- 지원안함(Security Group으로 가능)</td>
</tr>
<tr>
<td valign="top" width="165"><strong> </strong><strong> Mode</strong></td>
<td valign="top" width="149">- Advanced</td>
<td valign="top" width="154">- Advanced</td>
<td valign="top" width="154">- Basic</td>
</tr>
<tr>
<td valign="top" width="165"><strong> </strong><strong> Virual Router(VR) 역할</strong></td>
<td valign="top" width="149">- VM에 Private IP 할당- Source NAT, LB, Firewall, VPN, DHCP, DNS</td>
<td valign="top" width="154">- VM에 Public IP 할당</td>
<td valign="top" width="154">- VM에 Public IP 할당</td>
</tr>
<tr>
<td valign="top" width="165"><strong> </strong><strong> 비고</strong></td>
<td valign="top" width="149">- External Network Device 구성가능, 단 DHCP, DNS 기능은 VR에서 수행</td>
<td valign="top" width="154"> </td>
<td valign="top" width="154">- Private Cloud에 유용함</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>저희는 개발자 클라우드의 네트워크 모드로 Basic Mode를 선택하여 구성하였습니다. Advanced Mode 중 Virtual Networking의 경우에는 계정 별로 시스템 관리를 위한 System VM 중에 하나인 Router VM이 생성되며 계정에 연결된 여러 대의 장비의 Router 역할을 하며 Router VM 역시 host 장비의 자원을 사용하며 Amazon EC2와 같은 Public Cloud 환경에 적합합니다. 현재로선 개인당 가상서버 1개씩만을 나눠 주는 우리 개발자 클라우드의 특성 상 부적합하다고 판단하였습니다.</p>
<p>현재 구축된 KTH 개발자 클라우드에 적용된 네트워크 구성은 아래 그림과 같습니다.</p>
<p>&nbsp;</p>
<p style="text-align: center;"><a href="http://dev.paran.com/wp-content/uploads/2012/04/21.png"><img class="aligncenter  wp-image-7257 colorbox-7249" title="KTH developer Cloud Network" src="http://dev.paran.com/wp-content/uploads/2012/04/21.png" alt="" width="674" height="535" /></a></p>
<p>&nbsp;</p>
<p>개발자 클라우드 구성에서 가장 고심한 부분은 네트워크 구성이였습니다. 기존의 클라우드 플랫폼 매니지넌트 솔루션(CloudStack 포함)들의 기본적인 컨셉은 IDC 운영의 전통적인 네트워크 인프라 구조와 많은 차이를 가지고 있습니다. 이 부분에 대해서는 설명이 좀 길어질 수가 있는데 간단히 정리하자면 KTH의 경우 백업, 스토리지,모니터링, 관리등을 위한 별도의 사설 네트워크와 서비스를 위한 공인 네트워크 구조를 가지며 호스트머신은 각각 물리적으로 분리된 별도의 NIC를 사용하도록 구성되어야 할 필요가 있었습니다. 이를 지원하기에는 별도의 IP 클래스를 제공하는 L3~L2 레이어 스위치가 필요한 환경으로 클라우드 매니지먼트 솔루션으로 관리하기 어려운 인프라스트럭처를 가지게 되는 문제를 가지게 됩니다.</p>
<p>유연한 네트워크 구조를 제공하기 위하여 금번 개발자 클라우드에 적용한 방법은 VLAN을 통하여 단일 L2 스위치 상에서 공인, 사설, 스토리지, 관리 네트워크를 VLAN 분리하고, IP Class를 VLAN Tag를 이용하여 구분하도록 구성하였습니다. 물론 단일 채널에 여러 트레픽이 몰리는 부하를 예상하여 스위치와 호스트머신간에 케이블 채널링을 통하여 네트워크 대역의 전송량을 높이고, 일정 부분 QoS 적용을 통한 네트워크 품질을 보장하도록 구성하였습니다.</p>
<p>&nbsp;</p>
<h1><strong>4. 마치면서</strong></h1>
<p>사실 개발자 클라우드를 구축하고 테스트하면서 이렇게 Web기반 Self-Service를 통해서 가상머신들이 원하는 Offering이 적용되어 십여 초 만에 생성되는 것들 지켜보고 있자면 참 경이로웠습니다. 직접 무엇인가 만들어보고 이런 느낌이 드는 것은 참 오랜만 이였던것 같습니다. CloudStack은 그 자체만으로도 Cloud Selft-Service 환경을 구축을 시작하기에 훌륭한 SW 툴킷이라고 개인적으로 생각합니다. (<em>물론 완벽하지는 않지만 지속적으로 개선되고 있는 상황입니다. 우리가 시행착오를 겪으며 Cloud Infrastructure의 생성 및 삭제를 빈번하게 했었는데 Fault가 발생했을 때 정상적으로 데이터가 제거 되지 않는 경우가 많아 DB를 통해 쓰레기 데이터를 삭제하기도 했었습니다.</em>)      <strong> </strong></p>
<p>CloudStack 도입 결정부터 마지막 보안정책 결정 이후, 사내 개발자를 위한 Cloud Self-Service 포털 오픈까지 약 한달 정도 걸린 듯 합니다. 처음 시작할 때는 CloudStack 에서 사용하는 용어도 많이 낮설어서 (<em>이 글을 작성하면서 CloudStack에서 사용하는 용어들을 정리해보니 이제서야 좀 친숙하게 느껴집니다.</em>) 내용을 엉뚱하게 해석하고 진행하다가 시행착오도 있었지만 되돌아보면 꽤 즐거운 시간 이였고 이런 시스템을 구축할 수 있는 기회와 환경이 주어졌던 것에도 고맙게 생각됩니다.</p>
<p>앞으로의 계획은 단기적으로 CloudStack 3.0으로의 업데이트이며 사내 LDAP 서버와 계정을 연동할 계획입니다. 또한 중기적으로는 이번 기회를 통해 Public/Private Cloud 환경의 구축에 관심을 많이 갖게 된 KTH 개발자 클라우드 구축 멤버들과 함께 CloudStack 3.0 코드분석, Network 일반 (<em>같이 작업했던 인프라팀 멤버분과 네트워크 관련해 커뮤니케이션을 하다 보면 개발 쪽에서는 놓치는 부분이 많았었는데 <em>네트워크에 대한 기본지식이 많이 부족하다는 것을 느꼈었습니다.</em></em>) 등에 대해서 COP(Community Of Practice)를 진행하여 사내 상용 인프라에 적용 가능한 Private Cloud 환경 구축에 대한 방안을 찾아 보고자 합니다.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.paran.com/2012/05/08/cloudstack-kth-developer-cloud/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>kth 기술뉴스 – 수평적 조직문화를 가진 Valve 외 27건</title>
		<link>http://dev.paran.com/2012/05/07/kth-news-valve-flatland/</link>
		<comments>http://dev.paran.com/2012/05/07/kth-news-valve-flatland/#comments</comments>
		<pubDate>Mon, 07 May 2012 01:01:47 +0000</pubDate>
		<dc:creator>xguru</dc:creator>
				<category><![CDATA[기술뉴스]]></category>

		<guid isPermaLink="false">http://dev.paran.com/?p=7341</guid>
		<description><![CDATA[2012년 05월 07일, kth 아키텍트 그룹이 발행하는 기술 신동향 &#38; 뉴스 링크입니다. 오늘은 Valve 의 신규입사자용 핸드북 PDF파일을 메인뉴스로 선정했습니다. 수평적 조직문화를 추구하는 회사들은 종종 보이지만, Valve는 정말 특이하군요. &#8220;창업자도/사장도 있긴 하지만 그는 당신의 매니저가 아니다.&#8221; 기회를 찾고 위험을 피하고 프로젝트를 만들고 쉬핑하는건 당신의 권한이다. 게다가 엔지니어가 아닌 직군들에게 하는 조언이 &#8220;Program or be programmed&#8221; [...]]]></description>
			<content:encoded><![CDATA[<p>2012년 05월 07일,  kth 아키텍트 그룹이 발행하는 기술 신동향 &amp; 뉴스 링크입니다.</p>
<p>오늘은 <strong>Valve 의 신규입사자용 핸드북 </strong> PDF파일을 메인뉴스로 선정했습니다. 수평적 조직문화를 추구하는 회사들은 종종 보이지만, Valve는 정말 특이하군요. &#8220;창업자도/사장도 있긴 하지만 그는 당신의 매니저가 아니다.&#8221; 기회를 찾고 위험을 피하고 프로젝트를 만들고 쉬핑하는건 당신의 권한이다. 게다가 엔지니어가 아닌 직군들에게 하는 조언이 &#8220;Program or be programmed&#8221; 네요. &#8220;Valve’s core competency is making software&#8221; 이기 때문에 코드를 이해하는 능력을 가지는게 도움될 것이라고 핸드북에서 직접적으로 이야기 하는게 놀랍습니다. </p>
<p>&nbsp;</p>
<h2>[ 추천글 ]</h2>
<ul>
<li>게임회사 이면서 플랫폼회사인 Valve ( 게임 포털/플랫폼 Steam을 만들고 운영하는 회사죠 ) 의 신규입사자용 핸드북 56페이지 PDF파일 <a href="http://t.co/mUXGO8TM">http://t.co/mUXGO8TM</a> 정말 대단한 회사이면서 멋진 문화. 수평적 기술중시 조직문화의 극단을 보여주는군요.</li>
<li>Choose your Adventure <a href="http://t.co/IqWc8V6U">http://t.co/IqWc8V6U</a> GitHub의 디자인디렉터 Kyle이 얘기하는 개발자&amp;디자이너 이야기. &#8220;멋진 소프트웨어를 만들고 싶다면 디자인&amp;코드 둘 다 배워야 한다&#8221; 멋지네요.</li>
<li>만화서비스 개발후기 by @lqez <a href="http://t.co/n6e0Nzan">http://t.co/n6e0Nzan</a> 국내에서 보기 힘든 디테일하고 멋진 소프트웨어 스택 사용기네요. 귀한 지식 공유해주셔서 고맙습니다. (__)</li>
<li>잃어버렸던 스티브 잡스의 테이프 <a href="http://t.co/bP7rjumX">http://t.co/bP7rjumX</a> 애플을 떠나 넥스트와 픽사를 만들던 시절의 이야기들</li>
<li>The Hack Day Manifesto <a href="http://t.co/Fhvimehl">http://t.co/Fhvimehl</a> 해커쏜/개발자컨퍼런스 제대로 준비하기. 깔끔하군요. GitHub에 올라와 있으니 포크해서 한글판으로 만들어도 좋을듯.</li>
</ul>
<p>&nbsp;</p>
<h2>[ 웹사이트, 웹서비스, 웹기술 ]</h2>
<ul>
<li>아파치용 SPDY 지원모듈 mod_spdy <a href="http://t.co/vQdvabIl">http://t.co/vQdvabIl</a> 속도를 중시하는 웹사이트들이라면 이제 설치를 고려해보셔야..</li>
<li>wkhtmltopdf – 웹페이지를 PDF로 변환해주는 깔끔한 쉘 유틸리티. WebKit 렌더링엔진+QT 사용 <a href="http://t.co/Y6WDJ9fy">http://t.co/Y6WDJ9fy</a> php 및 python 바인딩도 있어서 웹서비스에서 사용하기 좋을 듯</li>
<li>크롬용 SSH 확장 <a href="http://t.co/UZgfZm7F">http://t.co/UZgfZm7F</a> Native-Client 를 이용해서 브라우저 창에서 SSH 서버에 직접 접속. 간단히 접속해서 서버에 이런저런 확인할 때 편리합니다.</li>
<li>ImageOptim – 다양한 옵션조정을 통해 이미지를 최적화해서 크기를 줄여주는 툴. PNG/JPEG/애니메이션GIF 지원 <a href="http://t.co/DjFdNcOs">http://t.co/DjFdNcOs</a> 오픈소스인데.. 맥 전용</li>
<li>Making the Web Faster <a href="http://t.co/8kBWStFT">http://t.co/8kBWStFT</a>  깔끔하게 정리된 웹페이지 최적화 관련팁</li>
<li>Speed Tracer &#8211; 웹앱의 퍼포먼스를 측정하고 분석하는 크롬용 확장 <a href="http://t.co/VonGu93P">http://t.co/VonGu93P</a> 나온지 꽤 오래된듯 한데.. YSlow/Firebug 같은것들에 밀려서 그런지 이제서야 알았네요</li>
</ul>
<p>&nbsp;</p>
<h2>[ 모바일 - 아이폰/안드로이드 ]</h2>
<ul>
<li>RubyMotion – Ruby 언어를 이용해서 iOS어플리케이션을 개발할수 있게 하는 툴체인 <a href="http://t.co/yMVfeyjR">http://t.co/yMVfeyjR</a> $199인데 $149로 할인중</li>
<li>프로젝트 HiJack &#8211; 모바일폰의 3.5mm 이어폰잭을 전력/데이터 전송용으로 사용하여 다양한 센서들을 연결할수 있는 오픈소스 프로젝트 <a href="http://t.co/Ul6ofMTX">http://t.co/Ul6ofMTX</a> 모바일결제 솔루션 Square와 같은 방식</li>
<li>아이패드에서 더 쉬운 커서 이동/선택을 위한 키보드 기능 제안 <a href="http://t.co/">http://t.co/b4mAknRs</a> 이거 꽤 좋네요. 애플보고 가져가서 써달라고 하는데.. 안드로이드쪽에 구현하기가 더 쉬울듯</li>
<li>Android 와 iOS 앱에서 페이스북의 Requests 기능을 연결하는 방법 <a href="http://t.co/B9iUQzZD">http://t.co/B9iUQzZD</a> 소셜기능이 있는 앱들은 필수로 확인해봐야할듯</li>
</ul>
<p>&nbsp;</p>
<h2>[ 프로그래밍/HTML5/CSS/Javascript ]</h2>
<ul>
<li>News from GIT in Java Land <a href="http://t.co/m8IlGqzb">http://t.co/m8IlGqzb</a> Java 에코시스템 상에서 Git 관련 컴포넌트의 현재상태. 이클립스콘 2012 발표자료</li>
<li>EclipseCon 2012 전체 슬라이드 모음 <a href="http://t.co/jPENaulk">http://t.co/jPENaulk</a> 총 80개 세션</li>
<li>Gaskit – Git 기반의 오픈소스 이슈트래커 <a href="http://t.co/tuTtxrkr">http://t.co/tuTtxrkr</a> PoC 수준이지만 이렇게 Git 을 어플리케이션의 내부 데이터베이스로 사용하는 시도가 많아지는듯.</li>
<li>Frontend 개발자들이 알아둬야할 Baseline 정리 <a href="http://t.co/PviCuQex">http://t.co/PviCuQex</a></li>
<li>git-sweep – Git 사용시 Master 로 머지된 모든 리모트 브랜치 한방에 지우는 툴 <a href="http://t.co/jK029gIb">http://t.co/jK029gIb</a></li>
<li>inbox.py &#8211; 앱내에 매우 간단한게 붙여쓸수 있는 SMTP서버 <a href="http://t.co/gd3PopYS">http://t.co/gd3PopYS</a> Python계의 유명인 Kenneth Reitz (Requests 제작자)의 신작 오픈소스</li>
<li><a href="http://t.co/tPUmvQTH">http://t.co/tPUmvQTH</a> 어도비의 HTML랜딩 페이지. 웹표준 / 오픈소스 관련해서 어도비가 하고 있는것들을 깔끔하게 정리했네요. 정말 HTML5 관련해서 열심히 하고 있다는게 눈에 확 보이는듯</li>
<li>stroll.js &#8211; CSS3를 이용한 스크롤 이펙트 <a href="http://t.co/d5rbCnMZ">http://t.co/d5rbCnMZ</a> 괴물 웹개발자 Hakim El Hattab 의 신작. 정말 대단한 친구</li>
<li>Screenqueri.es &#8211; 반응형 디자인 테스팅 사이트 <a href="http://t.co/RLK4uCVj">http://t.co/RLK4uCVj</a> 격자모드가 아주 깔끔하군요 ;)</li>
<li>Responsive News &#8211; BBC 뉴스 웹사이트를 반응형 디자인으로 만든 개발팀이 운영하는 블로그 <a href="http://t.co/1WEjJ5rN">http://t.co/1WEjJ5rN</a> 반응형디자인의 실무적용에 관한 팁들이 계속 올라오고 있습니다</li>
</ul>
<p>&nbsp;</p>
<h2>[ DB,클라우드,서버 기술 ]</h2>
<ul>
<li>Superfastmatch – 오픈소스 텍스트 비교툴 <a href="http://t.co/s9ew3YV6">http://t.co/s9ew3YV6</a> plagiarism(표절)/Churnalism(베껴쓴 기사) 를 손쉽게 찾아줍니다. 숙제검사/표절검색용으로 딱일듯합니다.</li>
<li>CartoDB – 클라우드를 위한 오픈소스 Geospatial DB <a href="http://t.co/nAhTXVbg">http://t.co/nAhTXVbg</a> PostgreSQL/PostGIS 기반. 구글 Fusion Tables 와의 비교자료 <a href="http://t.co/T5fTuALQ">http://t.co/T5fTuALQ</a></li>
<li>Fake S3 &#8211; 아마존 S3 사용하여 개발시 가짜 S3 서버를 로컬에 두고 개발할 수 있게 해주는 오픈소스 <a href="http://t.co/toge4vo6">http://t.co/toge4vo6</a> 마지막에 정리된 S3 대체품들 Ceph/ParkPlace/Boardwalk/RiakCS 도 유용</li>
</ul>
<p>피드백 환영합니다! </p>
<p>파란 개발자 블로그를  <a href="http://feeds.feedburner.com/devparan" target=_blank>RSS리더에서 구독</a>하시면, 매주간의 기술뉴스와 kth 임직원들이 작성하는 다양한 전문기술 글들을 보실수 있습니다.</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.paran.com/2012/05/07/kth-news-valve-flatland/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

