Sunday, 9 December 2018

[번역] 보상 시스템 설계의 숨겨진 힘

보상 시스템 설계의 숨겨진 힘


어떻게 효과적이고 책임 있는 보상을 설계할 것인가

보상은 강력하다

당신은 새로운 앱을 깔고 얼마 지나지 않아 지우거나, 다시는 열지 않습니다. 당신은 별 다른 이유 없이 몇 시간 동안 인스타그램 피드를 스크롤링 하며 빠져있기도 할 겁니다. 다른 제품들은 한, 두번 사용하지 않는 것 같은 반면에 특정 디지털 제품들은 어떻게 우리의 일상 생활에 뿌리 깊게 내리는지 잘 아는 것은 분명합니다. 

강력한 앱들은 매일 사용된다. 다른 것들은 지워지거나 잊혀진다.

가장 인기있는 앱들은 보상 시스템을 사용하여 사용자를 유지하고 참여시키고 사용자 간 공유를 증가시킵니다. 보상 시스템은 디자이너에게 제품으로부터 사용자들이 가치를 얻어내도록 하는데 보장하는 아주 강력한 도구입니다.

여러 보상 전달 방법들

알아차리지 못하고 있을지라도 우리는 매일 디지털 제품을 사용하면서 보상받습니다. 이러한 보상들은 항상 명확한 것은 아니며 가장 미묘한 것이 보통 가장 효과적입니다.

보상은 다양할 수 있지만 대부분 아래의 4가지 중 하나로 전달됩니다.

1. 정보 보상

2. 사회적 보상

3. 게임화 보상

4. 현금화 보상

어떤 제품이 이 모든 전달 방법을 사용할지라도 보상은 효과적일 수 있도록 사용자의 감정 레벨에 맞게 울려퍼져야 합니다. 감정이 더 강력할수록 보상은 더 강력한 경향이 있습니다.

1. 정보 보상

정보 보상은 피드를 통해 사용자에게 전달되는 이미지, 글, 컨텐츠입니다. 이러한 컨텐츠는 사용자가 만든 작은 아이템이거나 겉보기에 끝없이 보이는 컨텐츠가 많은 사이트입니다. 컨텐츠가 어떤 종류이건 상관 없이 정보 보상은 사용자의 호기심을 만족시킵니다.

미디엄, 트위터, 버즈피드가 정보 보상을 사용하는 앱의 좋은 예

 

슬롯 머신 메커니즘

2008년 소프트웨어 개발자 Loren Brichter가 트위터 앱 클라이언트 트위티를 설립합니다. 얼마 지나지 않아, 트위터는 트위티를 인수하고 그 서드 파티 앱을 공식 아이폰 앱으로 바꿨습니다. 결과적으로, 트위터는 앱스토어에서 자신의 영역을 공고화했고 대중에게 "당겨서 새로고침" 기능을 선보였습니다.


약 10년 전 트위티의 UI (이미지: InformationWeek)

트위터 앱이 출시 이후 많은 UI 변경이 있었지만 당겨서 새로고침 기능은 아직도 핵심 인터랙션 중 하나입니다. 인스타그램, 링크드인, 미디엄 같은 다른 앱들이 이 기능을 채택했고 가장 흔히 볼 수 있는 제스처 기능 중 하나로 만들었습니다.

트위터, 인스타그램, 링크드인, 미디엄은 당겨서 새로고침 기능을 사용하는 많은 앱 중 아주 소수다.

전 구글러이자 디자인 윤리학자인 Tristan Harris는 당겨서 새로고침 기능을 슬롯 머신에 비유했습니다. 그의 에서, "모든 기술 설계자가 해야할 것은 레버를 내리는 것 같이 사용자 액션을 변하는 보상과 연결시키는 것이다. 레버를 당기면 즉시 매혹적인 보상을 받거나 아무것도 받지 못한다."라고 했습니다. 새로운 정보와 컨텐츠를 받기를 희망하며 우리는 앱 피드를 새로고침합니다. 흥하든 망하든 슬롯 머신을 하는 것 처럼.

염두에 두는 디자인

정보 보상은 더 많은 컨텐츠가 즉시 제공 가능해지면서 우리의 일상에 평범한 것이 되었습니다. 정보 보상을 설계할 때, 모든 사용자에게 모든 타입의 컨텐츠가 중요하지는 않다는 것을 기억하는게 중요합니다.

인스타그램에서 "You're All Caught Up"는 사용자가 중복 컨텐츠를 보는 것을 피할 수 있도록 도와주는 스마트한 기능이다. 

인스타그램의 "You're All Caught Up"는 사용자가 중복 컨텐츠를 피할 수 있도록 도와줍니다. 정보 보상이 보다 보편화됨에 따라, 사용자가 중복 컨텐츠를 볼 때 이를 알 수 있도록 기능을 설계하는 것이 중요합니다.

2. 사회적 보상

대부분의 앱에서 사회적 보상을 제공하는 경향이 있기 때문에 사회적 보상은 디지털 제품에서 찾기 가장 쉬운 것 중 하나입니다. 인스타그램의 하트, 미디엄의 박수갈채, 드리블의 뷰는 유명한 앱의 보편적인 사회적 보상의 완벽한 예입니다.

페이스북은 좋아요, 공유하기, 댓글 버튼을 편리하게 포스트 아래에 두었다.


사회적 보상은 허영심, 자기 가치, 그리고 유효성 이 3가지 강력한 감정을 충족시킵니다. 부적절하게 사용하면 사회적 보상은 사용자에게 역효과를 주고 사용자와 당신의 제품에 모두 부정적으로 영향을 줍니다.

'좋아하지 않아요'가 뭘까

2007년, 페이스북 소프트웨어 프로그래머 저스틴 로젠슈타인은 기술팀에게 상징적인 "좋아요 버튼"을 기술팀에게 만들도록 지시했습니다. 가디언지의 이 글 속 로젠슈타인에 따르면 이 기능은 '몹시' 성공적이었습니다. 사람들이 단기간에 늘어난 사회적인 지지를 주고 받으면서 참여가 치솟았습니다.

좋아요 버튼은 오늘날 소셜 미디어 플랫폼의 제일 즉각적으로 알아볼 수 있는 기능 중 하나이다.

요약하면, 좋아요 버튼은 혁명적이었습니다. 이 기능은 사용자들에게 글을 쓰는데 보상을 주고 사람들이 온라인에서 상호작용하는 방식을 바꿨습니다. 로젠슈타인과 다른 사람들이 이제는 사회적 보상이 제공하는 "중독 피드백 루프"를 경고함에 따라 최근 몇년 동안 조사 대상이 되었습니다.

양날의 검

사회적 보상이 강력해지고 사용자들과 아주 깊은 감정적인 단계에 반향을 일으키면서 사회적 보상은 논란거리가 되었습니다. 이것이 더 높은 참여를 낳고, 사용자들이 너무 이것에 의지하면 짜증나거나 상처가 될 수 있습니다. 소셜 미디어가 유아기와 성숙 단계에서 멀어지면, 사회적 보상이 어떻게 진화하는지 알게될 것입니다.

3. 게임화

게임화는 게임이 아닌 앱에서 점수 시스템, 업적, 그리고 게임 같은 기능들을 말합니다. 최근 몇 년 동안 트리하우스, 듀오링고, 코드아카데미 같은 회사들이 그들의 코스에 어느 정도게임화를 사용했습니다.

트리하우스에서 코스를 완료하면 사용자가 받는 업적들

포스퀘어의 스웜, 피트니스 앱 스트라바 같은 소셜 앱들도 그들의 핵심 제품 가치와 본질적으로 연결된 게임화된 경험을 제공합니다. 스웜은 장소를 자주 방문하는 데 뱃지를 주는 반면 스트라바는 이전 보다 더 빠르게 수행한 것에 대한 "업적"을 보상합니다.

진행 측정

게임화는 완료된 작업과 아직 해결되지 않은 작업을 시각화하여 제품의 지속적인 사용을 유도합니다. 게임화는 사용자가 각 이정표에 도달한 후 성취감을 얻을 때 사용자가 상호작용할수록 제품의 가치가 더 높아지게 합니다.

스트라바는 운동에서 이정표에 도달한 달리기 선수와 자전거 선수들에게 업적을 준다.

항상 작동하지는 않는다

최근 몇년간 게임화라는 유행어가 더 많은 관심을 끌면서 이 용어가 많이 사용되었습니다. 비록 당신의 제품에 추가되는 훌륭한 특징처럼 보일 수 있지만 모든 제품이 게임화될 필요는 없다는 것을 기억하는 것이 중요합니다. 게임화를 제품에 도입하기 위해 서두르기 전에, 제품 핵심 가치와 본질적으로 연결되어 있을 때 제일 잘 작동한다는 것을 기억해야 합니다. 사용자는 자신의 진행 상황을 시각적으로 측정해 만족감을 느껴야 합니다. 만약 제품이 제공된 게임화된 경험과 동떨어져있다면 제품이 공허하고 솔직하지 못한 느낌이 들 수 있습니다.

4. 현금화

현금화는 사용자가 주요 작업을 완료할 때 물리적인 제품이나 현금을 제공합니다. HQ Trivia는 현금화 보상을 사용한 가장 최근의 바이러스성 앱입니다. 이 앱은 사용자들로 하여금 돈이나 다른 물리적 보상을 위해 라이브 게임 쇼에서 경쟁하게끔 장려합니다. 1.5 백만의 사용자들이 한번에 특정 방송에 채널을 맞추고 있고 타임지는 이 앱을 2017년 올해의 앱으로 선정했습니다.

HQ Trivia는 사용자들이 얻은 돈을 볼 수 있는 리더보드도 만들었다.


소셜 미디어 앱들도 프리미엄 컨텐츠를 생산하는 크리에이터를 장려하기 위해 현금성의 보상을 사용합니다. 유튜브는 동영상에 광고를 달면 사용자들에게 돈을 제공하고 미디엄은 작가들이 글을 쓰고 돈을 받을 수 있는 파트너 프로그램을 가지고 있습니다.


미디엄은 파트너 프로그램에 참여하는 것을 독려하기 위해 통계를 제공한다.

투명해져라

HQ Trivia, 유튜브의 지불 방식 모두 최근 몇 년 동안 비판의 대상이었습니다. 일부 사람들은 HQ가 90일 이내에 20달러라는 한계점에 도달했을 때만 지불하도록 허용하는 조항 때문에 "글리치로 가득찬 사기"인지 의문을 제기했습니다.(이 최소 현금 인출 규칙은 2018년 1월에 제거되었습니다.) 그리고, 유튜브가 광고주들을 달래기 위해 2017년 광고 정책을 바꾸었을 때, 크리에이터들은 동영상이 악마화되고 있는 것처럼, 때로는 아무 이유 없이, "Adpocolypse"라고 불렀습니다.

지불이 언제 그리고 어떻게 사용자에게 분배되는지 명확하게 하는 것은 불만을 예방하기위해 필수적입니다. 금전적 보상은 (문제 없이 주어질 때) 파워 유저들을 이용하고 제품의 지속 사용을 장려하는 좋은 방법입니다.

결론

디지털 제품은 당신이 좋아하는 앱에서 많은 전달 방법을 사용하는 것처럼 오직 하나의 보상에 제한되어 있지 않습니다. 책임감 있게 사용하면, 보상은 사용자들에게 당신의 제품에 있는 가치를 보게하고 결과적으로 깊은 수준의 참여를 추가하는 아주 좋은 방법입니다.

이 글은 The Hidden Power of Reward Systems In Design를 파파고의 도움을 얻어 번역한 글입니다.

Saturday, 8 December 2018

[번역] Bash 명령어 가이드

Bash는 상호적인 라인 인터프리터 또는 쉘입니다. 저는 간단한 쉘 명령어 사용법과 그것들이 무엇인지 공유하려고 합니다. 저는 시간 절약을 위한 목적으로 이 목록을 작성했습니다. 왜냐하면, GUI 없이는 모든 트랜잭션은 마우스 사용없이 빠르게 움직이기 때문입니다. 이 글은 제 다음 글 iOS 개발자를 위한 Bash 스크립트 가이드를 위한 가이드입니다.

ls

현재 작업 중인 디렉토리의 폴더와 파일 이름을 나열합니다.

$ ls -a # 숨겨진 파일을 포함한 모든 파일을 나열합니다.
$ ls -A # 숨겨진 파일을 포함하고 최상위 디렉토리를 제외한 모든 파일을 나열합니다.
$ ls -F # 항목에 인디케이터(*/=>@| 중 하나)를 추가합니다.
$ ls -S # 파일 크기에 따라 정렬합니다.
$ ls -al # 같은 디렉토리에 있는 모든 파일의 목록을 제공합니다.
$ ls -l # 긴 형태를 사용합니다.
$ ls -nl # 사용자 ID가 포함된 긴 형태를 사용합니다.
$ ls -c # ctime(마지막 변경 시간)으로 정렬합니다.
view raw ls.sh hosted with ❤ by GitHub

man

시스템 참고 메뉴얼을 보기 위해 사용되는 인터페이스입니다.

$ man ls # 명령을 실행하는데 사용할 수 있는 모든 옵션을 보여줍니다.
$ man -V --version # 버전 정보를 표시합니다.
$ man -c # ~/.manpath 파일의 기본 설정이 아닌 설정 파일을 사용합니다.
$ man -d # 디버깅 정보를 표시합니다.
view raw man.sh hosted with ❤ by GitHub

env

현재 사용자의 환경 변수 목록을 반환합니다.

$ env
view raw env.sh hosted with ❤ by GitHub

chmod

파일이나 디렉토리의 권한을 변경합니다.

$ chmod 777 # 모든 사용자가 읽고, 쓰고, 실행할 수 있습니다. 예) chmod 777 my_file
$ chmod 755 # 다른 사용자가 읽고 실행할 수 있지만 변경은 주 사용자만 가능합니다.
$ chmod 777 # 주 사용자만이 읽고, 쓰고, 실행할 수 있습니다.
view raw chmod.sh hosted with ❤ by GitHub

chwon

파일과 디렉토리의 소유권을 변경합니다.

$ chown --help && chown --version
view raw chown.sh hosted with ❤ by GitHub

PATH

콜론으로 구분된 디렉토리 목록을 저장합니다.

$ echo $PATH
view raw path.sh hosted with ❤ by GitHub

grep

파일에서 패턴과 매칭되는 라인을 찾고 결과를 반환합니다.

$ grep "keyword" file.tx # 하나의 파일에서 주어진 문자열로 찾습니다.
$ grep -i "keyword" file.tx # 대소문자 구별없이 찾습니다.
$ grep -R "keyword" file.tx # 디렉토리의 모든 파일을 찾고 찾은 결과를 포함한 라인과 파일 이름을 결과로 반환합니다.
view raw grep.sh hosted with ❤ by GitHub

awk

특정 라인을 추출합니다.

$ awk {keyword} file.tx
view raw awk.sh hosted with ❤ by GitHub

open

파인더에서 현재 폴더를 엽니다.

$ open .
view raw open.sh hosted with ❤ by GitHub

chgrp

파일과 디렉토리의 그룹을 변경합니다.

$ chgrp groupname file.txt
view raw chgrp.sh hosted with ❤ by GitHub

pwd

작업 중인 디렉토리 이름을 출력합니다.

$ pwd
view raw pwd.sh hosted with ❤ by GitHub

cd

현재 작업 중인 디렉토리를 변경합니다.

$ cd / # 루트 디렉토리로 이동합니다.
$ cd .. # 부모 디렉토리로 이동합니다.
$ cd # 파라미터 없이 사용하는 경우에 사용자 홈 디렉토리로 이동합니다.
$ cd ~root # '~' 뒤에 사용자 이름이 주어지면 그 사용자의 홈 디렉토리로 이동합니다.
view raw cd.sh hosted with ❤ by GitHub

HOME

홈 디렉토리 경로를 보여줍니다.

$ echo $HOME
view raw home.sh hosted with ❤ by GitHub

nano

키보드 입력만 받는 커맨드 라인 에디터입니다.

$ nano myscript.sh
view raw nano.sh hosted with ❤ by GitHub

find

파일과 디렉토리를 검색합니다.

$ find directory -name filename # 이름으로 파일을 찾습니다.
$ find directory -cnewer file # 파라미터로 준 파일 보다 더 최근에 수정된 파일들을 검색합니다.
$ find directory -amin n # n분 전 마지막 접근한 파일을 찾습니다.
$ find directory -cmin n # n분 전 마지막 변경된 파일을 찾습니다.
$ find directory -atime n # n일 전 마지막 접근한 파일을 찾습니다.
$ find directory -mtime n # n일 전 마지막 변경된 파일을 찾습니다.
$ find directory -ctime n # n일 전 마지막 변경된 파일을 찾습니다.
$ find directory -print # 찾은 파일의 경로를 표시합니다.
$ find directory -exec # 검색 결과에 따라 명령어를 실행합니다.
# mtime vs atime vs ctime : https://www.quora.com/What-is-the-difference-between-mtime-atime-and-ctime
view raw find.sh hosted with ❤ by GitHub

mkdir

명령어로 디렉토리를 생성합니다.

$ mkdir folder # folder라는 이름을 가진 디렉토리를 생성합니다.
view raw mkdir.sh hosted with ❤ by GitHub

mv

파일이나 디렉토리를 이동시킵니다.

$ mv -i source # 이미 존재하는 파일을 덮어쓰기 전에 안내를 해줍니다.
$ mv -f source # 안내 없이 이미 존재하는 파일은 덮어씁니다.
$ mv -n source # 이미 존재하는 파일은 절대 덮어쓰지 않습니다.
$ mv -v source # 옮기기 전 경로와 옮긴 후 경로를 출력합니다.
view raw mv.sh hosted with ❤ by GitHub

rm

파일이나 디렉토리를 삭제합니다.

$ rm -f file # 삭제하는데 묻지 않습니다. 또한 존재하지 않는 파일에 대한 정보도 제공하지 않습니다.
$ rm -i file # 파일을 삭제하기 전에 안내합니다.
$ rm -r directory # 디렉토리와 하위 디렉토리의 모든 내용물을 삭제합니다.
$ rm -v file # 삭제 과정에 대한 정보를 제공합니다.
view raw rm.sh hosted with ❤ by GitHub

rmdir

디렉토리를 삭제합니다. 폴더가 비어 있을 경우에만 작동합니다.

$ rmdir -p directoryname
view raw rmdir.sh hosted with ❤ by GitHub

touch

파일 내용에 아무런 변화 없이 파일을 생성하거나 엽니다.

$ touch -a file # 접근 시간을 업데이트합니다.
$ touch -c file # 파일이 존재하지 않으면 생성합니다.
$ touch -m file # 변경 시간을 업데이트합니다.
$ touch -t file # 주어진 시간대로 접근 시간을 변경합니다.
view raw touch.sh hosted with ❤ by GitHub

cat

파일의 내용물을 보여줍니다.

$ cat -n file # 화면에 주어진 숫자의 라인만큼 파일 내용물을 보여줍니다.
view raw cat.sh hosted with ❤ by GitHub

wc

파일의 개행, 단어, 바이트 수를 출력합니다. 파일이 여러개일 경우 합쳐서 출력합니다.

$ wc -l file # 행의 수를 반환합니다.
$ wc -m file # 문자 수를 반환합니다.
$ wc -w file # 단어 수를 반환합니다.
view raw wc.sh hosted with ❤ by GitHub

head

파일의 첫부분을 출력합니다.

$ head file # 첫 몇 줄을 보여줍니다.
view raw head.sh hosted with ❤ by GitHub

tail

파일의 뒷부분을 출력합니다.

$ tail file # 마지막 몇 줄을 보여줍니다.
view raw tail.sh hosted with ❤ by GitHub

more

화면 단위로 파일의 내용물을 출력합니다.

$ more file
view raw more.sh hosted with ❤ by GitHub

less

위아래 방향 뿐 아니라 아래위 방향 이동도 지원합니다.

$ less file
view raw less.sh hosted with ❤ by GitHub

nl

라인마다 번호를 추가해서 보여줍니다.

$ nl file
view raw nl.sh hosted with ❤ by GitHub


끝입니다. 읽어주셔서 감사합니다. 당신의 생산성을 높이는데 도움이 되었으면 좋겠습니다.

이 글은 Bash Commands Guide를 번역했습니다.

Friday, 7 December 2018

[번역] 어떻게 마이크로 서비스가 인터넷을 구했을까?

도입


오늘날 분산 시스템이 얼마나 영향력 있는지, 적어도 대학 수준에서는 가장 간과되는 주제 중 하나로 남아있습니다. 컨테이너화(containerization)와 폴트 톨러런스(falut tolerance)와 같은 개념을 이해하는 학생들은 많지 않고 시스템 프로젝트가 해커톤에서 이기는 것을 볼 수 없을 겁니다. 그럼에도 불구하고, 저는 적어도 오늘날의 대규모 시스테이 어떻게 작동하는지 간단하게 이해하는 것이 매우 중요하다고 생각합니다.

이 이야기는 1~2년 동안 일반적인 컴퓨터 과학 교육을 받은 사람이나 웹 개발을 넓게 독학한 사람과 같이 초보자를 대상으로 하는 시리즈 중 첫번째 글입니다. 처음 몇 개의 글은 주요 개념에 대한 높은 수준의 소개와 기술적 세부 사항에 대한 몇 가지 심층적인 설명을 할 것입니다. 나중에 네트워킹, 쿠버네티스나 쿨한 것들에 관한 주제를 탐험해보고 싶습니다. 이번 첫번째 글은 매우 간단하고 마이크로 서비스 이면의 기본 개념과 동기부여를 설명하는 것을 목표로 합니다.

분산 시스템이 인터넷을 돌아가게 한다.

옛날 옛적에, 애플리케이션은 모놀리식하게 만들어졌습니다. 애플리케이션은 웹 서버 자체와 어떤 종류의 데이터 스토리지 시스템으로 구성되었을 가능성이 높고, 하나 또는 두 개의 바이너리에 구축되어 패키지되었습니다. 이 바이너리는 서버 랙에 업로드 되어 기계 위에서 직접 실행되었습니다. 이것이 80년대와 90년대 인터넷에는 괜찮았지만 오늘날 구글은 35억 개의 검색 쿼리를 매일 받고 있고, 아무리 큰 서버라할지라도 그것을 다 처리하기는 어렵습니다.

예전에는 엔지니어가 더 나은 서버, 더 나은 케이블 등을 구입함으로써 수직적으로 확장했습니다. 인터넷의 성장과 무어의 법칙의 종식과 함께, 기존 확장 방식이 빠르게 지속할 수 없게 되었고 수평적 확장의 필요성은 고통스러울 정도로 분명했습니다. 더 좋고, 더 비싼 하드웨어를 사는 대신에, 단순히 싼 서버를 아주 많이 구입하고 모든 서버에 부하를 분산시키는 것입니다.

최초의 수평적 확장은 웹 서버를 중복 실행하는 것이었습니다. 그러나 최근 클라우드 발전과 함께 마이크로 서비스 아키텍처가 빠르게 도입되기 시작했습니다. 이 아이디어는 거대한 애플리케이션을 서비스라고 불리는 개별 컴포넌트로 나누어 각자 전문화된 작업을 수행하는 것입니다. 그러므로 개발자들은 처음부터 끝까지 요청을 처리하는 대신에, 사용자 인증기, 페이지 서버, api 서버, 데이터베이스 모델 서비스 같은 서비스들로 애플리케이션을 분리합니다.


모놀리식 애플리케이션 쪼개기 (출처)

각 마이크로 서비스는 하나 이상의 레플리카로 구성됩니다. Django에서 실행되는 백엔드를 가진 웹사이트의 경우, Django 서버의 복사본 수를 늘리으로써 수평적으로 확장할 수 있습니다. 이 복사본들이 레플리카입니다. 데이터베이스를 사용하는 경우, 데이터베이스의 복사본인 샤드(shard)라는 레플리카의 수를 늘리는 것으로 확장할 수 있습니다. 샤드를 개별로 실행하고 전체 데이터의 일부를 저장할 수 있는 전체 데이터 베이스를 생각해보시기 바랍니다. 샤드의 수를 늘림으로써 데이터베이스를 수평으로 확장할 수 있습니다. 이 복제품들은 다른 기계에서 실행 될 수 있습니다. 그래서 만약 100대의 컴퓨터에서 거대한 웹 서버를 실행하길 원한다면, 100개의 레플리카를 만들어 각각의 컴퓨터에서 실행할 수 있습니다.

집단 스타일 마이크로 서비스 아키텍쳐 (출처)
마이크로 서비스 아키텍쳐 패턴에 대한 더 많은 정보를 원한다면 Arun Gupta 블로그를 방문해보세요. 그는 AWS의 주요 기술자입니다.

장점

아래 항목들은 마이크로 서비스를 사용하는 가장 큰 장점을 나열한 것 입니다. 더 많은 장점이 있지만 이 4가지가 가장 중요합니다.
  • 마이크로 서비스 프레임워크의 가장 크고 부인할 수 없는 장점은 어떤 컴포넌트라도 수평으로 확장할 수 있다는 것입니다. 하나의 서비스(예:신경망)가 과부하 상태라면, 간단하게 특정 서비스의 더 많은 레플리카를 실행하면 됩니다.
  • 서비스들이 독립적입니다. 각 컴포넌트는 별도의 저장소로 저장할 수 있고 전담 엔지니어 팀에 의해 관리됩니다. 컴포넌트는 용도에 가장 적합한 언어로 작성되므로 데티어베이스 서비스는 C로 작성되고 웹 서버는 Python으로 작성될 수 있습니다. 이러한 서비스는 업데이트될 수 있고 파이프라인의 나머지 부분에 영향을 미치지 않고 새로운 컴포넌트가 만들어질 수 있습니다.
  • 이 아키텍처는 플러거블합니다. 서비스의 독립성을 기반으로 하지만 완전히 새로한 단계로 나아갑니다. 회사는 모든 서비스를 쓸 필요도 없습니다. MySQL, Elasticsearch, Redis와 같은 타사 애플리케이션은 모두 시스템에 쉽게 통합될 수 있는 마이크로서비스입니다.
  • 폴트 톨러런스. 이 장점은 시스템이 제대로 설계되지 않은 경우에만 존재합니다. 하나의 서비스 레플리카가 실패해도 전체 파이프라인 또는 해당 서비스에 오류가 발생해서는 안 됩니다. 마찬가지로 특정 서비스의 버그는 다른 비 관련 서비스의 가동 시간에 영향을 미치지 않습니다. 이것이 항상 쉬운 것은 아니며, 폴트 톨러런스는 산업과 연구 모두에서, 특히 분산 데이터베이스나 네트워크와 같은 주제에 대해 야기되는 문제입니다.
그리고 물론 모든 것과 마찬가지로 약간의 단점도 있습니다. 한 서비스에서 다른 서비스로 요청을 보내는 것이 오버헤드가 있고 복잡합니다. 분산 시스템은 종종 의존성, 레플리케이션, 공유 운명 문제를 가질 수 있습니다. 구축과 디버깅의 어려움은 마이크로 서비스의 수와 복잡성에 따라 기하급수적으로 증가합니다.

좋은 소식은 수많은 연구원, 기업, 그리고 스타트업이 이 문제의 모든 측면을 연구합니다. Jenkins, Spinnaker, Jegertraacing과 같은 프로젝트는 산업과 학계에서 매일 새로운 혁신이 이루어지고 있는 오늘날 가장 인기 있는 오픈 소스 솔루션 중 하나입니다.

그래서 분산 시스템은 여전히 상대적으로 새로운 반면 그 영향은 매일 지속적으로 느껴질 수 있습니다. 제 말은, 이 글을 당신이 어떻게 읽고 있는지 생각해보시기 바랍니다.

이 글은 How Microservices Saved the Internet파파고의 도움을 얻어 번역한 글입니다.

Tuesday, 20 November 2018

[번역] 웹 아키텍처 101

웹 아키텍처 101


웹 개발자로서 시작했을 때 알았으면 좋았을 기본 아키텍처

최신 웹 애플리케이션 아키텍처 개요

위 다이어그램은 스토리블록(Storyblocks)의 아키텍처를 꽤 잘 나타낸 것 입니다. 숙련된 웹 개발자가 아닐지라도 꽤 복잡해보인다는 것을 알 수 있을 것 입니다. 각각의 구성 요소들의 자세한 정보들을 알아보기 전에 아래의 짧은 글은 아키텍처를 좀 더 이해하기 쉽게 도와줄 것 입니다.

한 사용자는 구글에 "Strong Beautiful Fog And Sunbeams In The Forest"를 검색한다. 첫번째 결과는 스토리블록에서 나온다. 사용자 브라우저가 이미지 상세 페이지로 리다이렉트하는 결과를 클릭한다. 그 아래에서는 사용자의 브라우저DNS에 스토리블록에 어떻게 접근할 수 있는지 검색하고 스토리블록에 요청을 한다.

그 요청은 그 요청을 처리하기 위해서 동시에 운영하는 10개 정도의 웹 서버들 중 하나를 랜덤으로 선택하는 로드 밸런서에 이른다. 이제 웹 서버는 이미지에 대한 정보를 캐싱 서비스에서 찾아보고 나머지 데이터는 데이터베이스에서 가져온다. 우리는 이미지에 대한 색상 프로필 정보가 아직 계산되지 않은 것을 알아 차리고 "color profile" 작업작업 큐에 넣는다. 작업 서버들이 이제 이 작업들을 결과를 적절히 데이터베이스에 업데이트하면서 비동기적으로 처리한다.

다음으로, 풀 텍스트 서치 서비스에 사진의 제목을 입력으로 요청하면서 비슷한 사진들을 찾기를 시도한다. 사용자가 스토리블록에 멤버로 로그인하면 계정 서비스에 사용자의 정보를 검색한다. 마지막으로, 클라우드 스토리지 시스템에 기록될 페이지 뷰 이벤트를 데이터 파이어호스에 보낸다. 결국 데이터 웨어하우스에 저장되어 분석가가 비즈니스에 대한 질문에 대답하는데 사용한다.

서버는 HTML로 뷰를 렌더링하고 로드 밸런서를 통해 먼저 전달되는 사용자의 브라우저에 돌려 보낸다. 그 페이지는 CDN에 연결된 우리의 클라우드 스토리지 시스템에 있는 javascript와 css를 포함하고 있다. 그래서 사용자의 브라우저CDN을 통해 그 내용물을 획득한다. 마지막으로, 브라우저는 사용자가 볼 수 있게 페이지를 렌더링한다.

다음으로는 각 구성 요소를 살펴보면서 "101"의 각 구성 요소를 소개하고자 합니다. 각 구성 요소에 대한 소개는 앞으로 웹 아키텍처를 통해 생각할 수 있는 훌륭한 멘탈 모델을 줄 것 입니다. 추후에 스토리블록에서 배운 내용을 바탕으로 구체적인 구현 권장 사항을 제시하는 또 다른 글을 다룰 것 입니다.

1. 도메인 네임 시스템 DNS

DNS는 Domain Name System의 약어이고 월드 와이드 웹을 가능하게 만드는 뼈대 기술입니다. 가장 기본적인 단계의 DNS는 도메인 이름(예. google.com)으로 IP 주소(예. 85.129.83.120)를 얻을 수 있는 키/값 검색 기능을 제공합니다. 그리고 이러한 과정은 당신의 컴퓨터가 적절한 서버로 요청을 보내기 위해 꼭 필요합니다. 전화번호에 빗대어 보면, domain name과 IP 주소의 차이는 "John Doe에게 전화 걸기"와 "201-867-5309에 전화 걸기"의 차이와 같습니다. 옛날에 John에게 전화걸기 위해서 주소록을 뒤져보았던 것 처럼 domain name으로 IP 주소를 찾기 위해 DNS가 필요합니다. DNS를 인터넷을 위한 주소록으로 생각해도 되겠습니다.

더 자세히 다룰 주제가 있지만 101-레벨 인트로에서는 중요하지 않으니 생략하겠습니다.

2. 로드 밸런서 Load Balancer

로드 밸런싱에 대한 상세한 정보에 뛰어들기 전에, 수평적 애플리케이션 확장 vs 수직적 애플리케이션 확장에 대해 알 필요가 있습니다. 이것들이 무엇이고 무엇이 다를까요? 이 StackOverFlow 글에서는 아주 간단하게 이렇게 말했습니다. "수평적" 애플리케이션 확장은 기계를 더 추가하는 것으로 확장하는 것을 말하고 "수직적" 애플리케이션은 있는 기계에 CPU나 RAM 같은 것을 업그레이드하는 것으로 확장하는 것 의미합니다.

웹 개발에서는 대부분 간단함을 유지하기 위해서 수평적으로 확장하길 원합니다. 서버는 랜덤으로 망가질 수 있습니다. 네트워크가 안 좋을 수도 있고 전체 데이터 센터가 오프라인 상태가 될 수도 있습니다. 서버를 하나 이상 갖는다는 것은 애플리케이션이 계속 돌아가는 것을 가능케 합니다. 다르게 말하면 애플리케이션이 "고장에 내성이 있다"라고 할 수 있습니다. 두번째로, 수평적 애플리케이션 확장은 백엔드 애플리케이션의 구성 요소인 웹 서버, 데이터베이스, 서비스 같은 것 들이 각각 다른 서버에서 동작하게 해서 최소량으로 결합하는 것을 가능케합니다. 마지막으로, 수직적으로 확장으로 불가능한 정도를 수평적으로는 확장할 수 있습니다. 세상에는 모든 계산을 다 처리할만한 큰 컴퓨터는 없습니다. Google의 검색 플랫폼은 비록 훨씬 작은 규모의 회사들에게 적용되지만 전형적인 예라고 할 수 있습니다. 예를 들어, 스토리블록은 특정 시점에 150~450개의 AWS EC2 인스턴스를 실행합니다. 수직적 확장을 통해 전체 컴퓨팅 성능을 제공하기는 어렵습니다.

이제 로드 밸런서로 돌아갑시다. 로드 밸런서가 바로 수평적 확장을 가능하게 하는 마법의 소스입니다. 로드 밸런서는 들어오는 요청들을 수 많은 복제된 애플리케이션 서버들 중 하나로 보내고 애플리케이션 서버의 응답을 클라이언트로 다시 보냅니다. 모든 서버들이 동일한 방식으로 요청을 처리해야 합니다. 그래서 서버들 중 어느 하나에 몰리지 않게 요청들을 분배하는 것이 문제입니다.

바로 그겁니다. 개념적으로는 로드 밸런서는 상당히 간단합니다. 그 아래에는 분명 복잡한 것이 있지만 101 버전에서는 알 필요가 없습니다.

3. 웹 애플리케이션 서버 Web Application Servers

고수준의 웹 애플리케이션 서버는 상대적으로 설명하기 쉽습니다. 사용자의 요청을 다루고 핵심 비즈니스 로직을 수행하여 사용자의 브라우저에 HTML을 돌려 보냅니다. 이런 작업을 하기 위해서는 데이터베이스, 캐싱 레이어, 작업 큐, 서칭 서비스, 다른 마이크로서비스, 데이터/로깅 큐 와 같은 백엔드 인프라와 통신해야 합니다. 위에서 언급했듯이, 웹 애플리케이션 서버는 적어도 2개나 그보다 많게 사용자의 처리를 처리하기 위해 로드 밸런서에 연결되어 있습니다.

앱 서버를 만들기 위해서는 언어(Node.js, Ruby, PHP, Scala, Java, C#, .NET 등), 웹 MVC 프레임워크(Express, Ruby on Rails, Play for Scala, Laravel for PHP 등)를 선택해야 합니다. 이러한 언어들과 프레임워크를 상세하게 다루는 것은 이 글의 범위를 벗어납니다.

4. 데이터베이스 서버 Database Servers

모든 최신 웹 애플리케이션은 정보를 저장하기 위해 1개 혹은 그 이상의 데이터베이스를 사용합니다. 데이터베이스는 데이터 구조를 정의하고 데이터를 저장하고 검색하고 업데이트하고 삭제하는 등의 방법을 제공합니다. 대부분의 웹 애플리케이션 서버는 하나의 데이터베이스와 직접 통신합니다. 그리고 작업 서버 또한 그렇습니다. 추가적으로 각각 백엔드 서비스는 다른 애플리케이션으로부터 고립된 자신만의 데이터베이스를 가집니다.

특정한 기술에 깊게 빠져드는 것을 피하고 있지만 SQL과 NoSQL에 대해 다루지 않을 수가 없습니다.

SQL은 "Structured Query Language"의 약어이고 많은 사람들이 접근 가능한 관계 데이터 셋을 질의하기 위한 보편적인 방법을 제공하기 위해서 1970년대에 발명되었습니다. SQL 데이터베이스는 보통 정수형 값인 ID로 연결된 테이블에 데이터를 저장합니다. 사용자 주소 정보를 저장하는 예를 살펴보겠습니다. 사용자의 ID로 연결된 users와 user_addresses 2개의 테이블이 있습니다. 아래의 간단한 버전의 이미지를 보세요. user_addresses 테이블에 있는 user_id는 user 테이블에 id의 "외래 키"입니다.


SQL에 대해서 잘 모른다면 Khan Academy 여기에서 튜토리얼을 해볼 것을 추천합니다. 웹 개발에서는 아주 흔하기 때문에 애플리케이션을 잘 설계하기 위해서 기본을 알길 원할 것입니다.

NoSQL은 "Non-SQL"의 약어인데 아주 큰 웹 애플리케이션에서 생산되는 많은 양의 데이터들을 다루기 위해 생겨난 새로운 데이터베이스 기술입니다. 대부분의 SQL은 수평적으로 확장할 수 없어서 어떤 시점에서는 수직적으로만 확장할 수 있습니다. NoSQL에 대해서 잘 모른다면, 아래의 소개글을 읽어보길 권합니다.
그리고 명심해야할 것이 있는데 대체로 업계에서 NoSQL 데이터베이스에 대한 인터페이스로 SQL을 사용하고 있으므로 SQL을 모를 경우 배워야 합니다. 요즘은 피할 방법이 거의 없습니다.

5. 캐싱 서비스 Caching Service

캐싱 서비스는 O(1) 시간에 데이터를 저장하고 조회할 수 있는 간단한 키/값 데이터 저장소를 제공합니다. 캐시에서 비싼 비용이 드는 결과를 저장해 두어서 다음에 필요할 때 데이터를 재계산하는 대신에 캐시에서 결과값을 얻는 식으로 캐싱 서비스를 활용합니다. 애플리케이션은 데이터베이스 쿼리, 외부 서비스호출, url로 주어진 html 등 다양한 정보를 캐시에 저장합니다. 실세계의 예를 살펴봅시다.
  • 구글은 "dog", "Taylor Swift"와 같은 쿼리에 대한 결과를 매번 계산하기보다 캐시에 저장합니다.
  • 페이스북은 당신이 보는 많은 데이터들(포스트, 친구들 등)을 캐시에 저장해둡니다. 페이스북의 캐싱 기술에 대한 자세한 것은 이 글을 읽어보세요.
  • 스토리블록은 React server-side rendering의 HTML 결과물, 검색 결과, typeahead 결과 등을 캐시에 저장합니다.
2가지 가장 널리 알려진 캐싱 서버기술은 레디스멤캐시드입니다. 이것들은 다른 글에서 자세히 다루겠습니다.

6. 작업 큐 & 서버 Job Queue & Servers

대부분의 웹 애플리케이션은 사용자의 요청과 직접적으로 관련된 것이 아니어서 비동기적으로 뒤에서 처리해야할 것이 필요합니다. 예를 들어, 구글은 검색 결과를 제공하기 위해서 인터넷 전체를 크롤링하고 인덱싱해야 합니다. 이러한 과정은 검색할 때 마다 하진 않습니다. 대신에, 비동기적으로 웹을 크롤링하고 검색 인덱싱을 업데이트 합니다.

비동기적으로 작업을 가능하게 하는데 많은 아키텍처들이 있지만 가장 흔히 쓰이는 것은 "작업 큐" 아키텍처입니다. 2가지로 구성되어 있는데 실행되어야 할 "작업"들의 큐와 이 큐안에 있는 작업들을 실행하는 한개 이상의 작업 서버들입니다. 작업 서버는 workers라고도 합니다.

작업 큐는 비동기적으로 실행해야할 작업들을 저장합니다. 대부분의 애플리케이션은 우선순위를 가진 큐 시스템을 필요로 하지만 가장 간단한 것은 first-in-first-out (FIFO) 큐입니다. 앱이 실행되어야할 작업이 필요할때 마다(정기적인 스케쥴이던 사용자의 액션으로 결정된 것이던) 큐에 적절한 작업을 추가합니다.

예를 들어, 스토리블록은 마켓 플레이스를 지지하는데 필요한 많은 양의 뒷 작업에 작업 큐를 활용합니다. 영상과 사진을 인코딩하고 CSV 파일을 메타데이터 태깅을 위해 처리하고 유저 통계를 모으고 비밀번호 초기화 메일을 보내는 등에 쓰입니다. 처음에는 간단한 FIFO 큐로 시작했지만 나중에는 비밀번호 초기화 메일을 보내는 것과 같이 빠르면 빠를수록 좋은 시간에 민감한 작업들을 보장하기 위해 우선순위 큐로 업그레이드 했습니다.

작업 서버는 작업들을 처리합니다. 작업 큐를 폴링하여 할 작업이 있는지 만약 있다면 큐에서 작업을 꺼내어 실행합니다. 웹 서버에 대해 말하자면 기반하는 언어나 프레임워크의 선택은 너무나 많아서 이 글에서는 다루지 않겠습니다.

7. 풀 텍스트 서치 서비스 Full-text Search Service

대부분의 웹 앱들은 사용자들이 "쿼리"라고 불리는 텍스트를 입력하면 앱이 "관련된" 결과를 반환하는 검색 기능을 지원합니다. 이러한 기능을 제공하는 기술은 일반적으로 "풀 텍스트 서치(full-text search)"라고 합니다. 이 기술은 반전된 색인(Inverted Index)을 활용하여 쿼리 키워드가 포함된 문서를 빠르게 검색합니다. 
예시 : 3개의 문서 제목이 제목에 있는 키워드로 특정한 키워드가 있는 문서를 빠르게 검색하기 위해 반전된 색인으로 변환된 것 입니다. 주목할 것은 "in", "the", "with" 와 같은 정지 단어라고 불리는 단어들은 일반적으로 반전된 색인에 포함되지 않습니다.
풀 텍스트 서치는 데이터베이스로부터 직접 사용가능하기도 하지만(MySQL은 지원합니다), 반전된 색인을 계산하고 저장하며 쿼리 인터페이스를 제공하는 "서치 서비스"를 분리해서 운영하는게 일반적입니다. 최근 가장 유명한 풀 텍스트 서치 플랫폼은 엘라스틱 서치입니다. 다른 선택지로는 스핑크스아파치 솔라가 있습니다.

8. 서비스 Services

앱이 특정 규모에 도달하면 별도의 애플리케이션으로 실행되도록 분할된 특정 "서비스"가 있을 수 있습니다. 그들은 외부 세계에 노출되지 않지만 앱과 다른 서비스들은 그들과 상호작용합니다. 예를 들어, 스토리 블록에는 몇 가지 운영 중이거나 계획된 서비스들이 있습니다.
  • 계정 서비스는 더 통일된 사용자 경험을 만들고 교차 판매의 기회를 쉽게 제공하기 위해서 우리의 모든 사이트에 걸친 사용자 데이터를 저장합니다.
  • 컨텐츠 서비스는 비디오, 오디오, 이미지 컨텐츠에 대한 메타 데이터를 저장합니다. 그리고 컨텐츠를 다운로드 받거나 다운로드 기록을 보여주는 인터페이스도 제공합니다.
  • 지불 서비스는 고객에게 비용을 지불하는 인터페이스를 제공합니다
  • HTML → PDF 서비스는 HTML을 받아서 PDF로 변환하는 간단한 인터페이스를 제공합니다.

9. 데이터 Data

오늘날 데이터를 얼마나 잘 이용하느냐에 따라 회사는 살거나 죽습니다. 대부분의 요즘 앱들은 특정 크기에 이르면 데이터를 모으고 저장하고 분석할 수 있는 데이터 파이프라인을 활용합니다. 일반적인 파이프라인은 3가지 단계를 가집니다.
  1. 앱이 파이어호스로 데이터(일반적으로 사용자 상호작용에 대한 이벤트)를 보냅니다. 파이어 호스는 데이터를 제공 받고 처리하는 스트리밍 인터페이스를 제공합니다. 종종 미가공 데이터가 변형되거나 증가되고 다른 파이어 호스로 전달됩니다. AWS 키네시스카프카는 이러한 목적에 가장 흔한 기술입니다.
  2. 미가공 데이터와 최종 변형/증가된 데이터들이 클라우드 스토리지에 저장됩니다. AWS 키네시스는 미가공 데이터를 클라우드 스토리지(S3)에 매우 쉽게 저장할 수 있도록 "파이어호스"라는 설정을 제공합니다.
  3. 변형/증가된 데이터들은 종종 분석을 위해 데이터 웨어하우스에 저장됩니다. 우리는 AWS 레드시프트를 사용하고 있고 스타트업 세계에서는 점점 커지고 있습니다. 반면 큰 기업들은 오라클이나 기타 독점적인 웨어하우스 기술을 사용합니다. 데이터셋이 충분히 크면 하둡과 유사한 NoSQL 맵리듀스 기술이 분석에 필요할 수도 있습니다.
아키텍처 다이어그램에 있지 않은 다른 단계가 하나 더 있습니다. 앱과 서비스의 운영 데이터베이스로부터 데이터를 불러와 데이터 웨어하우스에 저장하는 것입니다. 예를 들어 스토리 블록은 비디오블록, 오디오블록, 스토리블록, 계정 서비스, 기부자 포탈 데이터 베이스를  레드시프트에 매일 밤 불러옵니다. 유저 상호 작용 이벤트와 핵심 비즈니스 데이터를 함께 모아놓아서 전체적인 데이터셋을 분석가에게 제공합니다.

10. 클라우드 스토리지 Cloud storage

"클라우드 스토리지는 인터넷을 통해 데이터를 저장, 검색, 공유할 수 있는 간단하고 확장가능한 방법입니다."라고 AWS가 말하고 있습니다. HTTP를 이용한 RESTful API를 통해서 로컬 파일 시스템에 저장했어야할 것에 더 많이 혹은 덜 접근하거나 저장할 수 있습니다. 아마존의 S3 오퍼링은 오늘날까지 가장 널리 사용되는 클라우드 스토리지이며, 여기서는 비디오, 사진, 및 오디오 자산, CSS 및 Javascript, 사용자 데이터 등을 저장하는 데 광범위하게 사용하고 있습니다.

11. 컨텐츠 딜리버리 네트워크 CDN 

CDN은 "Content Delivery Network"를 의미하며, 이 기술은 웹 상에서 단일 원본 서버에서 제공하는 것보다 훨씬 빠르게 정적 HTML, CSS, Javascript 및 이미지와 같은 자산을 서비스하는 방법을 제공합니다. 이 기능은 전 세계 여러 "엣지" 서버에 컨텐츠를 배포하여 사용자가 원본 서버가 아닌 "엣지" 서버에서 자산을 다운로드하게 됩니다. 예를 들어 아래 이미지에서 스페인 사용자는 뉴욕에 원본 서버가 있는 사이트의 웹 페이지를 요청하지만 해당 페이지의 정적 자산은 영국의 CDN "엣지" 서버에서 로드되어 많은 느린 대서양을 건너는 HTTP 요청을 방지합니다.


더 자세한 내용은 이 글에서 확인해보길 바랍니다. 일반적으로 웹 앱은 항상 CDN을 이용하여 CSS, Javascript, 이미지, 비디오 및 기타 자산을 서비스해야 합니다. 일부 앱은 CDN을 활용하여 정적 HTML 페이지를 제공할 수도 있습니다.

마무리

이것이 웹 아키텍처 101 마무리입니다. 이 글이 유용하기를 바랍니다. 내년이나 2년 후에 여기에 나오는 구성 요소들을 다루는 201 시리즈를 포스팅하길 희망합니다.

이 글은 Web Architecture 101를 번역한 글입니다.