스토리 홈

인터뷰

피드

뉴스

조회수 1552

8퍼센트 '프로덕트' 팀 인터뷰

안녕하세요, 8퍼센트입니다.8퍼센트는 다양한 매체와 콘텐츠로 이야기를 전하고 있습니다. 이번엔 인터뷰를 통해 8퍼센트를 이루고 있는 각 팀들의 이야기를 들어보며 고객에게 더 가까이 다가가고자 합니다. 그 첫 번째 주인공은 서비스 개발을 담당하는 ‘프로덕트’ 팀입니다.Q. 안녕하세요, 인터뷰를 위해 프로덕트 팀 허재영 님과 이호성 CTO님이 자리해주셨는데요. 먼저, 8퍼센트의 제품을 만드는 프로덕트팀은 구체적으로 어떤 일을 하시나요?A. 프로덕트 팀은 8퍼센트의 서비스를 만드는 팀입니다. 고객들이 8퍼센트를 이용하는 데 있어서 불편함이 없도록 서비스를 개선하고 유지하는 역할을 하고 있습니다. 예를 들어 기존의 인터넷 기반 금융 서비스는 공인인증서, Active X를 보면 알 수 있듯이 사용자의 편리함에 초점을 두고 있지 않습니다. 저희의 역할은 사용자들에게 더 편리하고 효율적인 금융 생활을 할 수 있도록 새로운 금융서비스를 시도하는 것입니다.Q. 새로운 금융시스템을 구축하고 운영해나가는 과정이 쉽지 않을 것 같은데, 그것에 대해 어려움과 극복해낸 경험이 궁금합니다.A. 8퍼센트는 이미 만들어진 솔루션을 사용하거나 외주를 통해 시스템을 구축하는 기존의 회사들과 다르게 직접 바닥부터 금융 시스템을 쌓고 있습니다. 금융시스템은 정확함과 안정성을 빼놓을 수 없는데 사용자가 많아지고 시스템이 거대해질수록 생각지 못한 부분에서 오류가 생기게 됩니다. 이러한 오류는 회사의 손실을 발생시키고, 고객들의 신뢰를 잃게 합니다. 위와 같은 일이 발생하지 않게 시스템을 정밀하게 설계하는 것은 기본이고 추가로 발생하는 문제들에 대해 올바르게 대처하는 것이 금융 시스템을 구축하고 운영하는 과정입니다. 물론 힘든 과정이지만 단계별로 시스템을 구축하는 것이 앞으로 남들과 다른 서비스를 제공할 수 있는 기반이 된다고 생각합니다.서비스 초기, 지급 프로세스에 문제가 있었던 적이 있었는데, 이를 인지하고 그에 대한 대응을 진행했습니다. 또한, 대응에 그치지 않고 테스트와 수정한 부분에 대해 제대로 동작하고 있는지 알아보는 QA(Quality Assurance) 프로세스를 갖추는 계기가 되었습니다. Q. 그렇게 만들어지는 8퍼센트 서비스만의 차별화된 점은 무엇인가요?A. 첫 번째는 '자동 투자'입니다. 자동 투자를 선택하게 되면 예치금과 상환된 투자금이 지속적으로 재투자됩니다. 따라서, 고객이 직접 신경 쓰지 않아도 자산을 쉽게 불릴 수 있습니다. 두 번째는 '스페셜딜'입니다. 일부 스페셜딜은 기업이 제공하는 서비스를 투자자가 직접 체험해볼 수 있으며, 이를 통해 고객은 투자 이외의 부수적인 혜택을 누릴 수 있습니다. 소개해드릴 마지막 차별점은 다양한 업체와의 제휴입니다. 8퍼센트는 현재, 기존 금융권에 있는 많은 금융 회사들과 제휴를 맺고 있습니다. 기존 금융 회사가 오랜 시간 쌓아놓은 시스템과 노하우, 그리고 8퍼센트의 서비스를 합쳐 좋은 서비스를 제공하는 것은 저희 서비스의 강점이 된다고 생각합니다. 또한, 기존 금융권뿐 아니라 토스와 같은 스타트업과의 제휴 역시, 토스 플랫폼에서 간편하게 8퍼센트 서비스를 이용할 수 있다는 점에서 이런 다양한 제휴는 저희만의 차별점이 된다고 생각합니다.Q. 8퍼센트 서비스에는 정말 다양한 장점이 있는 것 같습니다. 이렇게 좋은 서비스를 구상할 때 중요하게 생각하는 기준이 무엇인가요?A. 프로덕트 팀에서는 제품을 구상하는 데 있어서 ‘고객들에게 전달될 수 있는 가치’, ‘안정성과 정확성’, ‘사용성’ 이렇게 세 가지 기준을 중요하게 생각하고 있습니다. 금융 서비스는 대부분 돈으로 환산되는 가치를 추구합니다. 프로덕트 팀이 추구하는 금전적인 가치 역시 투자를 했을 때 돈을 벌고, 대출을 통해 돈을 절약하는 것입니다. 이러한 금전적 가치는 개인과 개인들이 서로 연결되어 발생한다는 점에서 사회적 가치에 기여한다 생각합니다. 또한, 핀테크 서비스들이 나오기 이전에 투자와 대출은 상당히 무겁고 다가가기 힘든 면이 있었습니다. 그래서 프로덕트 팀에서는 투자와 대출로 이뤄진 8퍼센트 서비스를 이용자가 손쉽게 쓸 수 있게 만드는 ‘사용성’이 제품을 구상하는 데 있어서 중요한 기준이 됩니다. 예를 들어, 토스 플랫폼을 통해서 저희 투자 서비스를 이용할 수 있게 하는 것도 ‘사용성’을 높이는 것의 일환입니다.Q. 얘기를 들어보니 명확한 기준을 통해 좋은 서비스가 나오는 것 같습니다. 8퍼센트 투자나 대출 서비스를 직접 이용하시나요? A. 모두가 소액부터 거액까지 다양하게 투자 서비스를 직접 체험하고 있습니다. 이는 고객의 입장에서 생각해볼 기회가 되어 일하는데 좋은 자극이 됩니다. ‘개밥 먹기’라고 개 사료를 만드는 회사에서 실제로 먹어보면서 제품이 어떤지 테스트하는 것에서 유래한 말이 있습니다. 8퍼센트 역시 이런 '개밥 먹기' 테스트를 꾸준히 하고 있습니다. 상품 2.0이 처음 출시되었을 때, 직접 소액 대출을 받아 안내, 혹은 연체 문자가 잘 오는지 등 대출 프로세스를 경험하기 위해서 대출 서비스를 이용했습니다. 물론 회사 내부 관계자에게 대출하기 위해 투자자를 모은다는 것은 윤리적인 문제가 있기 때문에 딜을 내부로만 열어서 회사 분들이 투자한 것만으로 모집했습니다. 신용등급은 당연히 떨어지지 않았고 상환하며 아직 잘 쓰고 있습니다.Q. 현재 P2P 금융 법제화에 대한 논의가 활발히 진행되고 있는데, 과거 새로운 규제가 생겼을 때 대처한 경험이 궁금합니다.A. 지금까지 가장 큰 변화는 작년 5월 가이드라인이 시행되면서 일어났습니다. 그전까지 투자자들로부터 모집한 자금은 회사의 소속으로 되어있었는데, 회사가 부도가 나게 되면 그 돈이 압류되어 투자자들의 돈을 못 빼는 현상이 발생할 수 있었습니다. 가이드라인에서 제시한 부분 중 가장 큰 것이 바로 이에 대한 것입니다. 투자자의 돈을 제삼자가 보관하게 해라 즉, 금융기관이 그 돈을 보관하게 하라는 것인데 이를 위해 농협과 함께 설계부터 시작해 지금의 시스템을 만들었습니다. 농협 측에 자금을 보관하고 저희가 시스템상으로 자금의 흐름을 요청하는 식으로 자금이 직접 저희를 통하지 않고 P2P 거래가 이루어지게 되었습니다.Q. 프로덕트 팀의 대처 능력이라면 법제화 같은 변화에서도 흔들림 없는 서비스를 제공할 수 있을 것 같습니다. 마지막으로 프로덕트팀의 목표는 무엇인가요?A. 프로덕트 팀에서는 항상 ‘우리가 바라는 프로덕트가 무엇일까?’ 고민합니다. 개발자로서 가장 안타까운 것은 열 명의 팀원들이 서로 힘내서 만들어내는 서비스가 사라지는 것입니다. 더 나아가, 사라지지 않는다는 것은 사회적인 가치를 인정받는다는 것입니다. 물론 돈을 만들어낸다는 얘기이기도 하지만 우리가 열심히 만든 자식과도 같은 서비스의 사회적인 가치를 인정받고 지속가능하게 하는 것이 최종적인 목표입니다. 특히 이번 18년도 1분기에 8퍼센트의 단기적 성장과 함께 미래 계획이 구체화 되고 그에 대한 긍정적인 확신이 생겨 큰 동기부여가 되었습니다. 8퍼센트 고객들도 더 편리하고 효율적인 서비스를 만들어갈 저희와 끝까지 동행해주셨으면 좋겠습니다.인터뷰는 8퍼센트의 모든 팀을 소개할 때까지 계속되니 많이 기대해주세요:)> 8퍼센트 서비스 보러 가기 #8퍼센트 #에잇퍼센트 #프로덕트팀 #프로덕트 #인터뷰 #팀원소개 #팀소개
조회수 791

HBase Meetup - 비트윈에서 HBase를 사용하는 방법 - VCNC Engineering Blog

비트윈에서는 서비스 초기부터 HBase를 주요 데이터베이스로 사용하였으며 사용자 로그를 분석하는 데에도 HBase를 사용하고 있습니다. 지난 주 금요일(11월 15일)에 HBase를 만든 Michael Stack 씨가 한국을 방문하게 되어 ZDNet 송경석 팀장님의 주최 하에 HBase Meetup Seoul 모임을 가졌습니다. 그 자리에서 VCNC에서 비트윈을 운영하면서 HBase를 사용했던 경험들이나 HBase 트랜잭션 라이브러리인 Haeinsa에 대해 간단히 소개해 드리는 발표 기회를 가질 수 있었습니다. 이 글에서 발표한 내용에 대해 간단히 소개하고자 합니다.비트윈 서비스에 HBase를 사용하는 이유비트윈에서 가장 많이 사용되는 기능 중 하나가 채팅이며, 채팅은 상대적으로 복잡한 데이터 구조나 연산이 필요하지 않기 때문에 HBase 의 단순한 schema 구조가 큰 문제가 되지 않습니다. 특히 쓰기 연산이 다른 기능보다 많이 일어나기 때문에 높은 쓰기 연산 성능이 필요합니다. 그래서 메세징이 중심이 되는 서비스는 높은 확장성(Scalability)과 쓰기 성능을 가진 HBase가 유리하며 비슷한 이유로 라인이나 페이스북 메신저에서도 HBase를 사용하는 것이라고 짐작할 수 있습니다.로그 분석에도 HBase를 사용합니다비트윈은 사용자 로그 분석을 통해서 좀 더 나은 비트윈이 되기 위해서 노력하고 있습니다. 비트윈 사용자가 남기는 로그의 양이 하루에 3억건이 넘기 때문에 RDBMS에 저장하여 쿼리로 분석하기는 힘듭니다. 그래서 로그 분석을 위해 분산 데이터 처리 프레임워크인 Hadoop MapReduce를 이용하며 로그들은 MapReduce와 호환성이 좋은 HBase에 저장하고 있습니다. 또한 이렇게 MapReduce 작업들을 통해 정제된 분석 결과를 MySQL에 저장한 후에 다양한 쿼리와 시각화 도구들로 custom dashboard를 만들어 운영하고 있습니다. 이를 바탕으로 저희 Biz development팀(사업개발팀)이나 Data-driven팀(데이터 분석팀)이 손쉽게 insight를 얻어낼 수 있도록 돕고 있습니다.HBase를 사용하면서 삽질 했던 경험HBase를 사용하면서 처음에는 잘못 사용하고 있었던 점이 많았고 차근차근 고쳐나갔습니다. Region Split과 Major Compaction을 수동으로 직접 하는 등 다양한 최적화를 통해 처음보다 훨씬 잘 쓰고 있습니다. HBase 설정 최적화에 대한 이야기는 이전에 올렸던 블로그 글에서도 간단히 소개한 적이 있으니 확인해보시기 바랍니다.HBase 트랜잭션 라이브러리 해인사Haeinsa는 HBase에서 Multi-Row 트랜잭션을 제공하기 위한 라이브러리입니다. 오픈소스로 공개되어 있으며 Deview에서도 발표를 했었습니다. HBase에 아무런 변형도 가하지 않았기 때문에 기존에 사용하던 HBase 클러스터에 쉽게 적용할 수 있습니다. 비트윈에 실제로 적용되어 하루 3억 건 이상의 트랜잭션을 처리하고 있으며 다른 많은 NoSQL 기반 트랜잭션 라이브러리보다 높은 확장성과 좋은 성능을 가지고 있습니다.발표에서 사용했던 슬라이드를 첨부하였으니 도움이 되었으면 합니다.<iframe class="speakerdeck-iframe" frameborder="0" src="//speakerdeck.com/player/2b8092b02ff90131ef414aa7d272d735?" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true" style="border: 0px; background: padding-box rgba(0, 0, 0, 0.1); margin: 0px; padding: 0px; border-radius: 6px; box-shadow: rgba(0, 0, 0, 0.2) 0px 5px 40px; width: 750px; height: 563px;">
조회수 791

컴공생의 AI 스쿨 필기 노트 ④ 교차 검증과 정규화

지금까지 Linear Regression, Logistic Regression 모델을 만들어보았는데요. 우리가 만든 모델이 과연 잘 만들어진 모델이라고 볼 수 있을까요? 이를 알기 위해서 이번 4주차 수업에서는 우리가 만든 모델의 적합성을 보다 객관적으로 평가하기 위한 방법으로 교차 검증(Cross Validation)과 정규화(Regularization)를 배웠어요. 차례대로 하나씩 알아볼까요?1. Cross Validation교차 검증은 새로운 데이터셋에 대해 반응하는 모델의 성능을 추정하는 방법이에요. 학습된 모델이 새로운 데이터를 받아들였을 때 얼마나 예측이나 분류를 잘 수행하는지 그 성능을 알기 위해서는 이에 대한 추정 방식이 필요해요. 먼저 Whole population(모집단)에서 Y와 f를 구하기 위해 Training Set(모집단에서 나온 데이터셋)에서 f와 똑같지 않지만 비슷한 모델 f^를 만들어요. 그리고 이 모델을 모집단에서 나온 또 다른 데이터 셋인 Test Set을 이용하여 확인해요. 하지만 일반적으로 Test Set이 별도로 존재하는 경우가 많지 않기 때문에 Training Set을 2개의 데이터셋으로 나눠요. 이 Training Set에서 Training Set과 Test Set을 어떻게 나누느냐에 따라 모델의 성능이 달라질 수 있어요. 이런 테스트 방법을 교차 검증(Cross validation)이라고 해요.이번 시간에는 교차 검증 방법으로 LOOCV(Leave-One-Out Cross Validation)와 K-Fold Cross Validation을 알아봤어요. LOOCV(Leave-One-Out Cross Validation)LOOCV는 n 개의 데이터 샘플에서 한 개의 데이터 샘플을 test set으로 하고, 1개를 뺀 나머지 n-1 개를 training set으로 두고 모델을 검증하는 방식이에요.K-Fold Cross ValidationK-Fold CV는 n 개의 데이터를 랜덤하게 섞어 균등하게  k개의 그룹으로 나눠요. 한 개의 그룹이 test set이고 나머지 k-1개의 그룹들이 training set이 되어 k번을 반복하게 돼요. LOOCV도 n-fold CV로 볼 수 있어요!코드로 나타내기Step1. 데이터 생성 & train set과 test set  단순 분리# model selection modulefrom sklearn.model_selection import train_test_splitfrom sklearn.discriminant_analysis import LinearDiscriminantAnalysis# read datadf = pd.read_csv('data/data01_iris.csv')data = df.iloc[:,:-1].as_matrix()target = df['Species'].factorize()[0]LOOCV와 K-Fold CV에 사용할 데이터를 구하는 코드에요. data 파일 안의 data01.csv 파일을 읽어서 데이터 프레임 형태로 가져와요.df(데이터 프레임) 안에는 이와 같은 105개의 데이터 셋이 저장되어 있어요.df(데이터 프레임)의 Sepal.Length부터 Petal.Width의 값들을 매트릭스 형태로 data에 할당해요.Species에는 ‘setosa’, ‘versicolor’, ‘virginica’ 값들이 있는데요. factorize() 을 이용하여 setosa는 0, versicolor는 1, virginica는 2로 바꿔줘요.# random splitX_train, X_test, y_train, y_test = train_test_split(            data, target, test_size=0.4, random_state=0)X_train.shape, y_train.shapeX_test.shape, y_test.shape그다음에는 data와 target 데이터를 가지고 training set과 test set으로 6:4로 나눠요.X_train.shape = (90,4),  X_test.shape = (60, 4)가 돼요.# LDA f = LinearDiscriminantAnalysis() f.fit(X_train,y_train) y_train_hat = f.predict(X_train) table_count(y_train,y_train_hat) f.score(X_train,y_train)LDA(Linear discriminant analysis)는 대표적인 확률론적 생성 모형이에요. 즉 y의 클래스 값에 따른 x의 분포에 대한 정보를 먼저 알아낸 후, 베이즈 정리를 사용하여 주어진 x에 대한 y의 확률 분포를 찾아낸다고 해요.Step2. test set 준비(1) LOOCV으로 test set 준비# leave-one-out  from sklearn.model_selection import LeaveOneOutloo = LeaveOneOut()loo.get_n_splits(X_train)scv = []for train_idx, test_idx in loo.split(X_train):    print('Train: ',train_idx,'Test: ',test_idx)    f.fit(X_train[train_idx,:],y_train[train_idx])    s = f.score(X_train[test_idx,:],y_train[test_idx])    scv.append(s) get_n_splits() 함수를 사용하여 (90,4)의 shape을 가지는 X_train을 90개로 나눠요.test set에 0부터 89까지 하나씩 할당되고 할당된 숫자 외의 나머지 숫자들은 training set으로 모델을 검증해요. 위의 결과에서도 볼 수 있듯이 test set에 0이 할당되면 train set에는 1 ~ 89가 할당되어 모델을 검증하게 돼요!(2) K-fold CV로 test set 준비# K-fold CVfrom sklearn.model_selection import KFoldkf = KFold(5)kf.get_n_splits()scv = []for train_idx, test_idx in kf.split(X_train):    print('Train: ',train_idx,'Test: ',test_idx)    f.fit(X_train[train_idx,:],y_train[train_idx])    s = f.score(X_train[test_idx,:],y_train[test_idx])    scv.append(s) KFold(5) : 위에서 배운 k-fold 교차 검증에서 k를 5로 설정하여 우리가 가지고 있는 데이터 셋을 5개의 그룹으로 나눠서 교차 검증을 할 거예요.kf.get_n_splits()를 사용하여 5번 교차 검증할 것을 정해요.위에서 90개의 데이터셋을 5개의 그룹으로 나눴어요. 그리고 각 그룹 한 개씩 test set으로 정하고 나머지 그룹들은 training set으로 할당하고 모델을 검증해요. 예를 들어 그룹 1이 0~17, 그룹 2가 18 ~ 35, 그룹 3이 36~53, 그룹 4가 54~71, 그룹 5가 72~89라고 할 때, test set에 그룹 1을 할당하면 train set에는 그룹 2, 3, 4, 5가 할당되어 모델을 검증하게 돼요.Step3. 교차 검증 시행CV는 단순히 데이터 셋을 나누는 역할을 수행할 뿐이에요. 실제로 모형의 성능(편향 오차 및 분산)을 구하려면 이렇게 나누어진 데이터셋을 사용하여 평가를 반복해야 해요. 이 과정을 자동화하는 명령이 cross_val_score()이에요.# K-fold CVfrom sklearn.model_selection import cross_val_scoref = LinearDiscriminantAnalysis()s = cross_val_score(f,X_train,y_train,cv=3)cross_val_score(f, X_train, y_train, cv=3) : cross validation iterator cv를 이용하여 X_train, y_train을 분할하고 f에 넣어서 scoring metric을 구하는 과정을 반복해요.2. Regularization앞서 말한 우리의 목적은 우리의 데이터셋에 맞는 Y와 f를 구하는 것이었어요. f를 결정하기 위해서는 먼저 결정해야 하는 요소가 있어요. 아래 다섯 가지가 f를 결정하는 요소들이에요.- Model family : linear, neural 등 방법론 결정- Tuning parameter : 모델에 맞는 파라미터 조절 - Feature selection(특징 선택) : 많은 데이터 중 어떤 데이터를 쓸지 고르는 것 - Regularization(정규화)  - Dimension reduction(차원 축소)f를 결정하는 요소 중 Regularization(정규화)에 대해 알아볼게요!정규화 선형회귀 방법은 선형회귀 계수(weight)에 대한 제약 조건을 추가함으로써 모형이 과도하게 최적화되는 현상(과최적화, overfitting)을 막는 방법이에요. 모형이 과도하게 최적화되면 모형 계수의 크기도 과도하게 증가하는 경향이 나타나요. 따라서 정규화 방법에서 추가하는 제약 조건은 일반적으로 계수의 크기를 제한하는 방법이에요. 일반적으로 Ridge Regression, Lasso, Elastic Net 이 세 가지 방법이 사용돼요.Ridge Regression머신 러닝에서는 모델의 오차를 찾기 위해 보통 최소제곱법(Least squares fitting)을 이용하여 β를 최소화시켜요. 위의 RSS는 잔차제곱식으로 예측값과 실제 값 사이의 차이를 구하는 식이에요. 회귀분석의 계수 값을 RSS을 최소화하는 β값을 찾음으로써 구할 수 있어요.Ridge Regression은 최소제곱법에 가중치들의 제곱합을 최소화하는 것을 추가적인 제약 조건으로 갖는 방법이에요. λ는 기존의 제곱합과 추가적 제약 조건의 비중을 조절하기 위한 하이퍼 파라미터에요. λ가 크면 정규화 정도가 커지고 가중치의 값들이 작아져요. λ가 작아지면 정규화 정도가 작아지며 λ가 0이 되면 일반적인 선형 회귀 모형이 돼요.코드로는 아래와 같이 나타낼 수 있어요.from sklearn.linear_model import Ridgef = Ridge(alpha=0.5)f.fit(xtrain,ytrain)f.intercept_,f.coef_f.score(xtrain,ytrain)f.score(xtest,ytest)LassoLasso는 가중치의 절댓값의 합을 최소화하는 것을 추가적인 제약 조건으로 가져요. 아래와 같이 코드로 나타낼 수 있어요.from sklearn.linear_model import Lassof = Lasso(alpha=1.0)f.fit(xtrain,ytrain)f.intercept_,f.coef_f.score(xtrain,ytrain)f.score(xtest,ytest)Elastic NetElastic Net은 가중치의 절댓값의 합과 제곱합을 동시에 제약 조건으로 가지는 모형이에요. 코드로는 아래와 같아요.from sklearn.linear_model import ElasticNetf = ElasticNet(alpha=0.1,l1_ratio=0.5)f.fit(xtrain,ytrain) f.intercept_,f.coef_f.score(xtrain,ytrain)f.score(xtest,ytest)Lasso와 Ridge Regression의 차이점왼쪽 : Lasso, 오른쪽 Ridge Regression위의 두 그림은 Lasso와 Ridge Regression의  차이점을 잘 나타내는 그림이에요. 초록색 부분은 회귀계수(회귀분석에서 독립변수가 한 단위 변화함에 따라 종속변수에 미치는 영향력 크기)가 가질 수 있는 영역이고 빨간색 원은 RSS가 같은 지점을 연결한 것을 보여주는 것으로 가운데로 갈수록 오차가 작아져요.Lasso와 Ridge Regression 모두 RSS를 희생하여 계수를 축소하는 방법이라는 공통점이 있어요.하지만 Ridge Regression과 Lasso의 가장 큰 차이점은 Ridge 회귀는 계수를 축소하되 0에 가까운 수로 축소하는 반면, Lasso는 계수를 완전히 0으로 축소화한다는 점이에요.Cross validation(교차 검증)과 Regularization(정규화)에 대해 알아보았는데요. 간단히 요약해 볼게요.Cross validation(교차 검증)은 머신러닝 모델의 타당성을 검증하는 방법 중의 하나로, 특정 데이터를 training set과 test set으로 분할한 뒤 training set을 활용해 학습하고 test set으로 테스트하여 학습의 타당성을 검증하는 방법이에요. 교차 검증에는 여러 가지 방법이 있는데 그중에서도 우리는 LOOCV와 K-Fold CV를 배웠어요.Regularization(정규화)는 모델의 일반화 오류를 줄여 과적합을 방지하는 방법을 말해요. 일반적으로 Ridge Regression, Lasso, Elastic Net 이 세 가지 방법을 사용해요.이상적인 머신러닝 모델을 만들기 위해 고려해야 할 점들은 정말 많은 것 같아요. 우리가 만든 모델이 적합한 모델인지 이번 수업시간에 배운 교차 검증과 정규화를 통해 잘 살펴봐요!* 이 글은 AI스쿨 - 인공지능 R&D 실무자 양성과정 4주차 수업에 대하여 수강생 최유진님이 작성하신 수업 후기입니다.
조회수 3200

Apache Spark에서 컬럼 기반 저장 포맷 Parquet(파케이) 제대로 활용하기 - VCNC Engineering Blog

VCNC에서는 데이터 분석을 위해 다양한 로그를 수집, 처리하는데 대부분은 JSON 형식의 로그 파일을 그대로 압축하여 저장해두고 Apache Spark으로 처리하고 있었습니다. 이렇게 Raw data를 바로 처리하는 방식은 ETL을 통해 데이터를 전처리하여 두는 방식과 비교하면 데이터 관리비용에서 큰 장점이 있지만, 매번 불필요하게 많은 양의 데이터를 읽어들여 처리해야 하는 아쉬움도 있었습니다.이러한 아쉬움을 해결하기 위해 여러 논의 중 데이터 저장 포맷을 Parquet로 바꿔보면 여러가지 장점이 있겠다는 의견이 나왔고, 마침 Spark에서 Parquet를 잘 지원하기 때문에 저장 포맷 변경 작업을 하게 되었습니다. 결론부터 말하자면 74%의 저장 용량 이득, 10~30배의 처리 성능 이득을 얻었고 성공적인 작업이라고 평가하지만 그 과정은 간단하지만은 않았습니다. 그 과정과 이를 통해 깨달은 점을 이 글을 통해 공유해 봅니다.Parquet(파케이)에 대해Parquet(파케이)는 나무조각을 붙여넣은 마룻바닥이라는 뜻을 가지고 있습니다. 데이터를 나무조각처럼 차곡차곡 정리해서 저장한다는 의도로 지은 이름이 아닐까 생각합니다.Parquet을 구글에서 검색하면 이와 같은 마룻바닥 사진들이 많이 나옵니다.빅데이터 처리는 보통 많은 시간과 비용이 들어가므로 압축률을 높이거나, 데이터를 효율적으로 정리해서 처리하는 데이터의 크기를 1/2 혹은 1/3로 줄일 수 있다면 이는 매우 큰 이득입니다. 데이터를 이렇게 극적으로 줄일 수 있는 아이디어 중 하나가 컬럼 기반 포맷입니다. 컬럼 기반 포맷은 같은 종류의 데이터가 모여있으므로 압축률이 더 높고, 일부 컬럼만 읽어 들일 수 있어 처리량을 줄일 수 있습니다.https://www.slideshare.net/larsgeorge/parquet-data-io-philadelphia-2013Parquet(파케이)는 하둡 생태계의 어느 프로젝트에서나 사용할 수 있는 효율적인 컬럼 기반 스토리지를 표방하고 있습니다. Twitter의 “Julien Le Dem” 와 Impala 프로젝트 Lead였던 Cloudera의 “Nong Li”가 힘을 합쳐 개발한 프로젝트로 현재는 많은 프로젝트에서 Parquet를 지원하고 컬럼 기반 포맷의 업계 표준에 가깝습니다.Parquet를 적용해보니 Apache Spark에서는, 그리고 수많은 하둡 생태계의 프로젝트들에서는 Parquet를 잘 지원합니다.val data = spark.read.parquet("PATH") data.write.parquet("PATH") Spark에서는 이런 식으로 손쉽게 parquet 파일을 읽고, 쓸 수가 있습니다. 데이터를 분석하기 전에 원본이라고 할 수 있는 gzipped text json을 읽어서 Parquet 로 저장해두고 (gzipped json은 S3에서 glacier로 이동시켜버리고), 이후에는 Parquet에서 데이터를 읽어서 처리하는 것 만으로도 저장용량과 I/O 면에서 어느 정도의 이득을 얻을 수 있었습니다. 하지만 테스트 결과 저장용량에서의 이득이 gz 23 GB 에서 Parquet 18GB 로 1/3 정도의 저장용량을 기대했던 만큼의 개선이 이루어지지는 않았습니다.Parquet Deep Dive상황을 파악하기 위해 조금 더 조사를 해보기로 하였습니다. Parquet의 포맷 스팩은 Parquet 프로젝트에서 관리되고 있고, 이의 구체적인 구현체로 parquet-mr 이나 parquet-cpp 프로젝트 등에서 스펙을 구현하고 있습니다. 그리고 특별한 경우에는 Spark에서는 Spark 내부에 구현된 VectorizedParquetRecordReader 에서 Parquet 파일을 처리하기도 합니다.파일 포맷이 바뀌거나 기능이 추가되는 경우에는 쿼리엔진에서도 이를 잘 적용해주어야 합니다. 하지만 안타깝게도 Spark은 parquet-mr 1.10 버전이 나온 시점에도 1.8 버전의 오래된 버전의 parquet-mr 코드를 사용하고 있습니다. (아마 다음 릴리즈(2.4.0)에는 1.10 버전이 적용될 것으로 보이지만)Parquet 의 메인 개발자 중에는 Impala 프로젝트의 lead도 있기 때문에, Impala에는 비교적 빠르게 변경사항이 반영되는 것에 비하면 대조적입니다. 모든 프로젝트들이 실시간적으로 유기적으로 업데이트되는 것은 힘든 일이기 때문에 어느 정도는 받아들여야겠지만, 우리가 원하는 Parquet의 장점을 취하기 위해서는 여러 가지 옵션을 조정하거나 직접 수정을 해야 합니다.VCNC 데이터팀에서는 저장 용량과 I/O 성능을 최적화하기 위하여 Parquet의Dictionary encoding (String들을 압축할 때 dictionary를 만들어서 압축하는 방식, 길고 반복되는 String이 많다면 좋은 압축률을 기대할 수 있습니다)Column pruning (필요한 컬럼만을 읽어 들이는 기법)Predicate pushdown, row group skipping (predicate, 즉 필터를 데이터를 읽어 들인 후 적용하는 것이 아니라 저장소 레벨에서 적용하는 기법)과 같은 기능들을 사용하기를 원했고, 이를 위해 여러 조사를 진행하였습니다.저장용량 줄이기102GB의 JSON 포맷 로그를 text그대로 gzip으로 압축하면 23GB가 됩니다. dictionary encoding이 잘 적용되도록 적절한 옵션 설정을 통해 Parquet로 저장하면 6GB로, 기존 압축방식보다 저장 용량을 74%나 줄일 수 있었습니다.val ndjsonDF = spark.read.schema(_schema).json("s3a://ndjson-bucket/2018/04/05") ndjsonDF. sort("userId", "objectType", "action"). coalesce(20). write. options(Map( ("compression", "gzip"), ("parquet.enable.dictionary", "true"), ("parquet.block.size", s"${32 * 1024 * 1024}"), ("parquet.page.size", s"${2 * 1024 * 1024}"), ("parquet.dictionary.page.size", s"${8 * 1024 * 1024}"), )). parquet("s3a://parquet-bucket/2018/04/05") 비트윈의 로그 데이터는 ID가 노출되지 않도록 익명화하면서 8ptza2HqTs6ZSpvmcR7Jww 와 같이 길어지기에 이러한 항목들이 dictionary encoding을 통해 효과적으로 압축되리라 기대할 수 있었고, Parquet에서는 dictionary encoding이 기본이기에 압축률 개선에 상당히 기대하고 있었습니다.하지만 parquet-mr 의 구현에서는 dictionary의 크기가 어느 정도 커지면 그 순간부터 dictionary encoding을 쓰지 않고 plain encoding으로 fallback하게 되어 있었습니다. 비트윈에서 나온 로그들은 수많은 동시접속 사용자들의 ID 갯수가 많기 때문에 dictionary의 크기가 상당히 커지는 상태였고, 결국 dictionary encoding을 사용하지 못해 압축 효율이 좋지 못한 상태였습니다.이를 해결하기 위해, parquet.block.size를 default 값인 128MB에서 32MB로 줄이고 parquet.dictionary.page.size를 default 값 1MB에서 8MB 로 늘려서 ID가 dictionary encoding으로만 잘 저장될 수 있도록 만들었습니다.처리속도 올리기저장용량이 줄어든 것으로도 네트워크 I/O가 줄어들기 때문에 처리 속도가 상당히 올라갑니다. 하지만 컬럼 기반 저장소의 장점을 온전하게 활용하기 위해서 column pruning, predicate pushdown들이 제대로 작동하는지 점검하고 싶었습니다.소스코드를 확인하고 몇 가지 테스트를 해 본 결과, Spark에서는 Parquet의 top level field에서의 column pruning은 지원하지만 nested field들에 대해서는 column pruning을 지원하지 않았습니다. 비트윈 로그에서는 nested field들을 많이 사용하고 있었기에 약간 아쉬웠으나 top level field에서의 column pruning 만으로도 어느 정도 만족스러웠고 로그의 구조도 그대로 사용할 예정입니다.Predicate pushdown도 실행시간에 크게 영향을 줄 거라 예상했습니다. 그런데 Spark 2.2.1기준으로 column pruning의 경우와 비슷하게, top level field에 대해서만 predicate pushdown이 작동하는 것을 확인할 수 있었습니다. 이는 성능에 큰 영향을 미치기에, predicate 로 자주 사용하는 column들을 top level 로 끌어올려 저장하는 작업을 하게 되었습니다. 여기에 추가로 parquet.string.min-max-statistics 옵션을 손보고 나서야 드디어 10~30배 정도의 성능 향상을 볼 수 있었습니다.매일 15분 정도 걸리던 "의심스러운 로그인 사용자" 탐지 쿼리가 30여초만에 끝나고, cs처리를 위해 한 사람의 로그만 볼 때 5분 정도 걸리던 쿼리가 30여초만에 처리되게 되었습니다.못다 한 이야기parquet.string.min-max-statistics 옵션과 row group skipping에 관해.Parquet 같은 포맷 입장에서 string 혹은 binary 필드의 순서를 판단하기는 어렵습니다. 예를 들어 글자 á 와 e 가 있을 때 어느 쪽이 더 작다고 할까요? 사전 편찬자라면 á가 더 작다고 볼 것이고, byte 표현을 보면 á는 162이고 e는 101이라 e가 더 작습니다. Parquet 같은 저장 포맷 입장에서는 binary 필드가 있다는 사실만 알고 있고, 그 필드에 무엇이 저장될지, 예를 들어 á와 e가 저장되는지, 이미지의 blob가 저장되는지는 알 수 없습니다. 그러니 순서를 어떻게 정해야 할지는 더더구나 알 수 없습니다.그래서 Parquet 내부적으로 컬럼의 min-max 값을 저장해 둘 때, 1.x 버전에서는 임의로 byte sequence를 UNSINGED 숫자로 해석해 그 컬럼의 min-max 값을 정해 저장했습니다. 이후에 이를 개선하기 위해 Ryan Blue가 PARQUET-686에서 parquet-format에 SORT_ORDER를 저장할 수 있도록 했습니다.여기에서 문제는 이전 버전과의 호환성입니다. SORT_ORDER가 없던 시절의 Parquet 파일을 읽으려 할 때, min-max 값을 사용해 row group skipping이 일어나면 query 엔진에서 올바르지 않은 결과가 나올 수 있으니, binary 필드의 min-max 값을 parquet-mr 에서 아예 반환하지 않게 되어있습니다.하지만 이는 우리가 원하는 동작이 아닙니다. 여기에 parquet.string.min-max-statistics option을 true로 설정하면, 이전처럼 binary필드의 min-max값을 리턴하게 되고 rowgroup skipping이 작동하여 쿼리 성능을 크게 올릴 수 있습니다.마치며Spark과 Parquet 모두 많은 사람이 사랑하는 훌륭한 오픈소스 프로젝트입니다. 또한 별다른 설정이나 튜닝 없이 기본 설정만으로도 잘 돌아가는 편이기 때문에 더더욱 많은 사람이 애용하는 프로젝트이기도 합니다.하지만 오픈소스는 완전하지 않습니다. 좋은 엔지니어링 팀이라면 단지 남들이 많이 쓰는 오픈소스 프로젝트들을 조합해서 사용하는 것에서 그치지 않고 핵심 원리와 내부 구조를 연구해가며 올바르게 활용해야 한다고 생각합니다. 기술의 올바른 활용을 위해 비트윈 데이터팀은 오늘도 노력하고 있습니다.
조회수 3379

개발자 커리어 전환기 2 | 3시간 만의 퇴사 결정, 비전공자로 개발에 뛰어들다.

Q) 안녕하세요 Juan Carlos(환 까를로스)님 자기소개 부탁드려요.네 안녕하세요. 지금 immersive 6기에서 개발자가 되기 위해 열심히 공부하고 있는 환 까를로스라고 합니다. 어쩌다보니 immersive 6기에서 전문 네비게이터로 생활하고 있어요.(웃음) 네비게이터는 페어프로그래밍을 할 때 드라이버가 코딩을 할 수 있도록 큰 그림을 그려주는 거라고 생각하시면 되요. 페어와 같이 코딩을 하면서 Immersive를 헤쳐나가고 있습니다.Q) 코드스테이츠 오시기 전에는 어떤 일을 하셨었나요?해외영업을 했습니다. 이 일을 선택한 이유는 조금 특별해요. 제가 취준생이었을 때 회사를 여러 곳을 지원을 했었습니다. 지원한 기업에서 합격 통보를 받았죠. 근데 막상 그 기업에 입사하려고 보니까 지방에서 근무를 해야 하는 거예요. 그전까지는 이런 것들을 생각도 안 하고 있다가, 막상 닥치니까 곰곰이 생각하게 되었어요.'내가 서울을 떠나서 잘 살 수 있을까?' 지방에서 산다는 거에 대해서 크게 생각하고 있지 않았었는데, 막상 닥치니까 고민이 많이 되더라구요. 제가 서울 토박이인데, 고향을 떠나서 사는 거는 제가 너무 힘들 것 같아서 포기하고 지금 현 직장(지금은 퇴사를 했죠)에 다니게 된 거예요. 그리고 제가 공대 출신인데 공대 출신이 서울에서 직장을 잡으려면 영업 밖에 없더라구요. 그래서 영업직을 선택했었습니다.Q) 그럼 직장을 나오게 된 계기가 있으신가요?새로운 것을 수용할 생각이 없는 경직된 조직문화가 너무 안 맞았어요. 저는 신입을 뽑는 이유는 조직이 시장의 흐름이나 세대의 변화에 맞춰 변하기 위해서라고 생각해요. 근데, 전에 팀은 변할 생각을 안 하더라고요. 야근까지 해가면서 업무개선을 해도 기존 방식을 고수하자는 피드백이 계속되니 열정이 사라지는 것을 느꼈죠. 제가 4년 정도 다녔는데, 퇴사를 고민하고 3시간 만에 결정하고 사표를 내고 나왔어요.저는 뭔가 다양한 경험을 하고 제 스스로가 발전하는 걸 좋아하는데, 발전한다는 느낌이 없었죠. 부서를 여러 곳으로 옮긴 이유도 제가 정확히 뭘 좋아하는지 모르니까 이것저것 해보면 알지 않을까 생각했어요. 영업 파트에서 일하면서도 기획부터 경영지원까지 다양한 일을 맡았었죠.Q) 3시간이면 정말 짧네요! 보통은 여러 번 고민하기 마련인데요. 그럼 퇴사하시고 나서는 무엇을 하셨나요?음... 사실 퇴사하고 나서 제가 맡았던 고객들이 경쟁사로 이직할 수 있게 도와주겠다고 하셔서 고민을 많이 했어요.  근데, 이왕 퇴사했는데 새로운 걸 해보고 싶었어요. 한 군데 계속 있으면 뭐랄까.. 나태해지는 것 같아서요.- 다른 분야의 직장을 잡으신 건가요?일단은 여행 가야지라고 생각해서, 스페인으로 떠났어요.  첫 번째로는 스페인의 순례길을 가기로 했죠. 1000km 정도 되는 길을 걸었던 것 같아요. 순례길을 걸으면서 다양한 사람들을 만나고 생각도 정리도 좀 하고 그랬어요. 거기에는 전 세계 퇴사한 사람이 다 모이는 것 같아요. 숙소에서 만난 친구들에게 물어보면 죄다 회사를 퇴사하고 왔다고 하더라구요(웃음) 그리고 그곳에서 개발자가 돼야겠다는 마음을 먹었습니다.Q) 어떤 경험을 하셨길래 그곳에서 개발자가 돼야겠단 마음을 먹으셨나요?먼저 이 얘기를 해야 하겠네요. 사실 제가 여행경비가 이렇게 많이 들지 몰랐어요. 순례길을 여행하다가 돈도 떨어져 가는데 직업이 있는 채로 순례길을 도는 사람들을 만나게 된 거예요. 세 명을 만났는데, 세 명 다 소프트웨어 엔지니어였습니다. 처음에는 브라질 개발자를 만났어요. 그때까지만 해도 별생각이 없었죠. 다음으로는 러시아 개발자를 만났습니다. 러시아 개발자 친구를 보면서 아 이런 게 디지털 노마드구나라는 생각을 갖게 되었죠. 그리고 마지막으로 스페인 개발자 친구를 만나니까 정말 개발자라는 직업이 부럽게 느껴지더라구요. Q) 디지털 노마드를 보고 개발자가 돼야겠단 결정을 하신 거네요! 그럼 코드스테이츠를 선택해주신 이유가 있으신가요? 아까 제가 생각보다 여행 경비가 많이 드는지 몰랐다고 했잖아요. 순례길만 여행하는데도 여행 경비가 다 떨어진거에요(웃음) 그래서 어쩔 수 없이 세계 여행의 꿈을 접고 한국으로 오게 되었죠. 그리고 한국으로 돌아오는 비행기 안에서 개발자가 되기로 결심을 했습니다. 내가 여행을 다니고 하고 싶은 것을 하면서도 일도 하고 그게 너무 좋아 보이는 거에요. 물론 한국의 현실은 많이 다르겠지만 그래도 개발자라면 가능하지 않을까라고 생각을 했습니다. 그리고 그 비행기에서 핸드폰으로 코딩 관련해서 검색을 하다가 코드스테이츠를 알게 되었어요. 알아보니까 교육철학도 좋고 저에게도 괜찮은 방식을 것 같아서 그 비행기 안에서 바로 결정을 하게 되었습니다. 퇴사할 때와 마찬가지로 일사천리로 결정을 했습니다.- 비행기 안에서 모든 결정이 이루어졌네요! 3시간 만에 퇴사를 결정하신 것 같이요!뭐 망설일 이유가 있나요. 자신감과 결단력 그게 제 장점이니까요(웃음)Q) 그럼 이제 Immersive 얘기를 해볼게요. Immersive에서의 생활은 어떠세요?생각했던 것보다 여유가 있어서 좋아요. 그전에는 되게 불안하고 빡빡하고 그럴 것 같은데 막상 해보니까 할만하더라고요. 그리고 일단 사람들이 너무 좋아요. 같이 지내는 사람들이 좋으니까 Immersive도 할만한 것 같아요.Q) 그러면 지금 Immersive에서는 어떤 것을 배우고 있나요?서버를 배우고 있어요. 프론트 쪽 하구요. 프로젝트를 하고 적용을 해봐야 완전히 내 것으로 만들 수 있을 것 같아요. 역시 직접 적용을 해봐야 정확히 알 수 있을 것 같습니다.서버를 배우고 있어요. 프론트 쪽 하구요. 자바스크립트라는 언어의 다양한 문법을 매일 체험해보고 있어서, 매일매일이 새롭습니다. (뭔가 이해할 만 하면 다른걸 배워서..) 프로젝트를 해봐야 완전히 내것으로 만들 수 있을 것 같아요.Q) 앞으로 어떤 개발자가 되고 싶으세요?거창하게 세상을 바꾸는 개발자! 이런 건 제 스타일은 아니에요(웃음) 저는 제가 하고 싶은 것을 하는 개발자. 만들고 싶은 것을 만드는 개발자가 되고 싶어요. 세상을 바꾸는 개발자도 내가 좋아하는 것, 내가 하고 싶은 것, 내가 만들고 싶은 것을 만드는 개발자가 되었을 때 가능하지 않을까요?Q) 프로젝트를 곧 하게 될 텐데 어떤 프로젝트를 하고 싶으신가요?제 경험에 기반한 프로젝트에요. 우리는 회사에서 주는 돈 그냥 받잖아요. 제가 회사를 나오고 받았던 돈들을 확인해보니 제대로 받지 못했다는 것을 알았어요. 그래서 사람들이 노동의 정당한 보상을 알고 받을 수 있도록 도와주는 프로그램을 만들고 싶어요. 주변만 봐도 대부분의 사람들이 이런 문제로 인해 문제를 가지고 있다고 생각해요.Q) 1년 후에 개발자가 되었다고 생각하면 어떤 모습일까요?개발자가 될 수 있을까요?(웃음) 아마 1년 후엔 야근에 쩔어있지 않을까요? 저는 이게 내 일이다라는 생각을 하면 엄청 파고드는 스타일이거든요. 개발자로 처음 들어간 직장에 남아 있거나 이직을 하고 있을 것 같아요. 사실 저는 계획을 잘 안 세우거든요. 그러니까 아무 준비 없이 퇴사하고 개발을 배우고 있죠. 설마 굶어죽기야 하겠어요?Q) 마지막으로 하고 싶은 말이 있나요?제가 퇴사하면서 방 정리도 같이 하게 됐어요. 정리를 하다 보니까 우연찮게 제 학창시절 생활기록부를 보게 되었습니다. 생활기록부에 장래희망을 적는 칸이 있잖아요. 근데 제가 깜짝 놀란 게 거기에 중학교 때부터 고등학교 때까지 줄곧 프로그래머로 적혀있던 거에요. 그동안 까맣게 잊고 살았는데 신기했어요.그리고 또 생각을 해보니까 대학교 때도 제가 컴공과는 아니지만 공대라서 C++을 해야했는데 그 과목에서 처음으로 A+을 받은 기억이 나더라구요. 이런 생각이 들면서 결국 나는 프로그래머를 선택할 운명이었나? 이런 생각도 들고. 결국에는 돌아돌아 이 길로 온 것 같아요. 그래도 돌아왔다고 해서 늦었다거나 아쉽지는 않아요. 제가 지금까지 걸어온 길이 분명히 프로그래밍을 하는데 도움이 된다고 생각하고 있으니까요.네 지금까지 환 까를로스님과의 인터뷰를 진행했었는데요. 정말 비하인드스토리가 엄청나네요. Immersive 성공적으로 수료하시고 원하시는 개발자가 되기를 바랍니다. 앞으로도 다양한 스토리를 가진 Immersive 수강생분들의 이야기로 찾아뵙겠습니다.
조회수 983

[Tech Blog] Software architecture: The important stuff

마틴 파울러는 Software architecture 를 “무엇이건 간에 중요한 것들(The important stuff whatever it is)” 이라고 정의합니다. 조금은 재미있는 정의지만, 그 정의를 도출하기 위해 제시한 다른 정의를 들어보면 고개를 끄덕이게 합니다.  Software architecture 는 전문 개발자들이 같은 생각을 가지고 이해하는 시스템 디자인입니다. Software architecture 는 이른 시기에 정해져야 하는 디자인 결정들입니다. 혹은 여러분이 “아, 처음부터 좀 더 잘 생각하고 할 껄”이라고 후회하는 바로 그 결정들입니다. Software architecture 는 또한 바꾸기 어려운 결정들의 집합입니다.  결국 무엇을 중요하게 생각할 것인가, 그것이 Software Architecture 라는 의미입니다. Why is it important? 왜 중요한지 설득하지 못한다면 사실 중요하지 않은 것일지도 모르죠. 그래서 왜 Software Architecture 이 중요한지 짚어보고자 합니다. 쿠팡은 Microservice architecture 로 전환하는 여정을 글로 남겼는데요. 블로그 글의 제목을 “행복을 찾기 위한 우리의 여정” 이라고 지었습니다. (좋은 글이니 읽어보시길!) 다시 말해서, Software Architecture는 개발가자 더 좋은 제품을 만들 수 있는 길이기 때문에 중요하다고 말합니다. 그러나 좋은 Software Architecture를 만드는 일은 쉽지 않습니다. 블로그 글을 인용 해보겠습니다: “여기 저렴한 제품과 비싼 제품이 있습니다. 비싼 제품은 software architecture 가 잘 고려되어 있고, 저렴한 제품은 시스템 디자인에 대한 고민 없이 구현되어 있습니다. 하지만 두 제품은 겉으로 보기에 차이가 없습니다. 소비자가 보기에 똑같이 보이고, 똑같은 기능이 있으며, 성능 또한 같습니다. 어떤 제품을 사야할까요?” 소비자는 제품을 만든 개발자의 행복을 위해 더 비싼 제품을 선택하지는 않습니다. 개발자 역시 동료들에게 “내가 행복하려면 시간과 돈이 좀 더 들더라도 좋은 software architecture 를 구성해야 해.” 라고 주장하기엔 설득력이 부족하죠. Software architecture 가 왜 중요한지 모두가 공감하려면 경제적인 입장에서 그 중요성을 설득해야 합니다. “내부 품질을 좀 포기하더라도 이번 릴리즈에 더 많은 기능들이 들어가야 해.” 라는 의견에 “안돼 우리(개발자)는 더 전문적으로 구성해야 해.”라는 의견으로 대응하면 항상 질 수 밖에 없습니다. 장인 정신과 경제 논리 사이의 싸움에서는 경제 논리가 항상 이겨왔거든요.   Cumulative functionality over Time Software architecture 를 고려하지 않으면서 제품을 개발하면 초기에는 기능 추가 속도가 빠를 수 있지만, 시간이 흐름에 따라 제품의 기능 증가 속도는 점차 느려집니다. 이미 구현된 기능들과 코드가 새로운 기능을 추가하는데 걸림돌이 되기 때문입니다. 한편, 좋은 설계를 지속적으로 건강하게 유지하고, 주기적으로 리팩토링을 하고, 코드를 깨끗하게 유지한다면 시간이 흘러도 기능 추가가 느려지지 않을 수 있습니다. 오히려 기능을 추가하기 위해 수정해야 할 곳들이 명확하고 모듈화 또한 잘 되어있기 때문에 시간이 갈 수록 기능 추가가 더욱 빠르게 진행될 수 있습니다. 새로운 개발자가 참여하는 시점에도 시스템을 더욱 빠르게 이해하고, 더 빠르고 안전하게 기능을 추가할 수 있게 됩니다. 결국 장기적으로 더 많은 기능을 생산하고 빠르게 고객에게 전달하기 위해서 개발팀은 좋은 디자인과 설계에 대해 깊게 고민해야 합니다. What is the best software architecture? 옳은 software architecture 는 없습니다. 상황에 따라 해답은 다를 수 있습니다. Microservice architecture 가 좋다고 해서 모든 것에 대한 답이 microservice architecture 인 것은 아니고, 마찬가지로 어떤 시스템이 monolithic architecture 로 구현되어 있다고 해서 뒤쳐져 있는 것도 아닙니다. 모든 선택에는 Tradeoff 가 있기 마련이니까요. 유선 통신 시스템을 구성한다고 생각해 볼까요? 우리 나라처럼 인터넷이 잘 구성된 상황에서 Skype 로 할 수 있는 통화는 무료이고, 품질도 좋고, 영상 통화까지 됩니다. “Skype 만세! 인터넷을 통한 통신이 항상 옳습니다!” 라고 외치려던 시점에 정전이 되었습니다. 방금 외친 외침은 멀리 가봐야 옆집 정도 닿겠죠. 한편 기존 유선 전화 시스템은 느리고 화상 통화도 안되지만, 전화선 자체에 전원이 공급되고 있기 때문에 정전 시에도 통화가 가능합니다. 전쟁 상황이나 기타 재난 등에도 반드시 통신이 가능해야 하는 곳은 유선 전화 시스템이 꼭 필요할 것 같습니다. 은행 시스템도 적절한 예시가 될 수 있습니다. 비밀번호 입력, 전화 인증, OTP 확인하는 등 은행 업무는 왜이리도 복잡할까요? 그냥 비밀번호 기억해주고 로그인 유지해주면 참 편할텐데 말이죠. 안전하기 위해서겠죠. 여러분의 자산은 소중하니까요. 사용성(Usability)과 안전성(Security)은 종종 둘 사이를 조절해야 하는 Tradeoff 입니다. 만들려는 제품과 시스템, 환경, 시기와 조건 등에 따라서 적절한 architecture 는 달라집니다. 좋은 architecture 를 선택할때 개발자는 선택한 것의 대척점에 있는 무언가를 포기 해야합니다. 그렇기에 software architecture 는 기술적인 범주 안에서만 고려되면 안되고, 구현하고자 하는 비지니스를 매우 잘 이해하고 고려해서 적용해야 합니다. What are you going to do? 이미 구성된 software architecture 를 변경하는 것은 굉장히 어렵습니다. 이미 구성되어 있는 것들을 상세하게 알고 있어야 하고, 비지니스의 요구 사항을 수용해야 하며, 이미 존재하는 기능이 변경 도중 문제 없이 동작해야 합니다. 또한 기존 시스템에 기여한 개발자들과 변경 사항에 대한 공감대를 이뤄야 하며, 겉으로 보기에 당장 변화가 없는 것에 대한 비용에 대해 많은 사람들을 설득해야 합니다. 최근 Buzzvil 에서는 Architecture Task Force 팀을 구성하였습니다. 이를 통해 전체적인 설계를 정비하고 모든 개발팀이 구조적으로 같은 이해를 할 수 있도록 분석, 조사, 계획 수립, 실행에 옮길 예정입니다. 지속적인 공유를 통해 전사적인 공감대를 유지하고 체계적인 문서화와 가이드라인을 통해 모든 팀원이 함께 실행하며 성장할 수 있는 기반을 준비하게 될 것입니다. 궁극적으로 전사 프로젝트와 모든 팀이 더욱 빨리 움직일 수 있는 software architecture 를 구성하고, 이를 통해 더 많은 기능을 더 빠르게 전달할 수 있게 할 것입니다. 아직 해야할 일들이 많이 남아있지만 제대로 계획하고 빠르게 움직인다면 충분히 좋은 결과를 만들 수 있을 것 같습니다. 당장은 눈에 보이는 변화가 없을지라도, 좋은 디자인에 대한 고민과 실행이 우리가 궁극적으로 바라는 비전과 목표에 한 걸음 더 빠르게 다가가는 올바른 길이라고 믿습니다.   *버즈빌에서 개발자를 채용 중입니다. (전문연구요원 포함)작가소개 Whale, Chief Architect “Keep calm and dream on.”
조회수 1497

독서모임 스타트업에 개발자나 디자이너가 필요한가요?

트레바리는 독서모임을 운영하는 회사다. 멤버들이 책을 읽고, 독후감을 쓰고, 아지트에서 여러 사람들과 다양한 대화를 나눌 수 있도록 만들어준다. 아날로그적이려면 한없이 아날로그 할 수 있는 회사가 바로 트레바리다. 그러다 보니 트레바리의 첫 빌트인(?) 개발자 겸 디자이너인 나는 가끔 이런 질문을 받기도 한다. "트레바리에 개발자나 디자이너가 필요한가요?" 작년 11월과 12월, 개발과 디자인을 총동원해서 멤버십 신청 페이지의 UI/UX 개선 작업을 진행했다. 원래의 홈페이지보다 편하게 신청하도록 토스 결제를 연동하는 등 프로세스를 재편하였고, 판매할 프로덕트가 의도대로 보이도록 레이아웃을 다시 구성하였다. 컨텐츠의 가독성을 위해 컴포넌트들의 디자인도 깔끔하게 변경했다. 개선된 프로세스와 인터페이스라면 멤버십에 신청하는 사람들이 늘어날 거라고 확신했다. 홈페이지를 방문만 하고 멤버십에 신청하지 않은 이유는 '홈페이지가 불편하고 안 예뻐서'라고 생각했기 때문이었다.결론부터 말하자면 내 가설은 완전히 틀렸다. 개선된 홈페이지를 런칭했지만 방문 유저 대비 신청한 유저의 비율에는 큰 변화가 없었다. 다급히 주변에 조언을 구하기 시작했고 마켓컬리의 이지훈 님이 해주신 조언이 한참을 머릿속에 멤돌았다. "트레바리는 오프라인 경험이 메인이므로 홈페이지의 변화가 큰 효과가 없을 수 있음을 인정하고 시작해야 해요. 홈페이지는 광고를 보고 온 유저들이 독서모임에 가기 전까지 거쳐 가는 곳이에요."그렇다. 트레바리 홈페이지는 오프라인 독서모임에 참여하기 위한 건널목일 뿐이였다. 건널목이 아무리 좋다 한들 목적지가 탐탁지 않으면 사람들이 건너가지 않을 것이었다. 마찬가지로 홈페이지가 아무리 편하고 예뻐도 아지트에 와서 나누는 대화가 무의미하고 재미없다면 사람들이 트레바리를 찾지 않을 것이다.덕분에 트레바리 특성상 홈페이지를 위한 개발자나 디자이너 크루(=직원)가 필요한지 자문하게 되었다. 건널목 역할을 수행하는 홈페이지가 필요한 것이라면 이미 충분하다고 생각했다. 추가로 필요한 기능이 있다면 그때그때 적당한 프리랜서를 고용하는 게 합리적일 수도 있었다. 그렇다면 맨 위의 질문에 대한 대답은 "아니요. 필요 없어요. 프리랜서면 충분해요."가 되는 것이었다.내가 크루로서 잘 쓰일 수 있는 일은 무엇일까?얼핏 생각하기에 프리랜서면 충분해 보이지만 분명 내가 크루로서 잘 쓰일 수 있는 일이 있을 거라 생각했다. 그리고 그것을 오프라인 트레바리와 온라인 트레바리 사이에 간극이 있다는 점에서 찾았다.오프라인 트레바리는 꽤나 매력적이다. 한 시즌을 경험한 두 명의 멤버 중 한 명은 다음 시즌에도 멤버십을 신청한다. 물론 나머지 한 명까지 신청하게 만들게끔 개선할 부분들이 남아있지만 그래도 60%가 넘는 리텐션은 트레바리가 다시 올 만한 서비스라고 말해준다.온라인 트레바리는 사정이 다르다. 많은 사람이 방문하지만 금세 나가버린다. 지금의 트레바리 홈페이지는 트레바리가 뭐 하는 곳인지, 트레바리를 하면 어떤 사람이 될 수 있는지, 트레바리에서는 어떤 사람들을 만날 수 있는지 잘 알려주고 있지 않다. 미리 지인이나 미디어를 통해 트레바리의 매력을 알고 온 사람들만이 홈페이지를 샅샅이 뒤져본 후에나 어떤 곳인지를 엿볼 수 있다.이 불협화음을 잘 조율하는 일을 내가 잘 할 수 있겠다는 생각이 들었다. 나는 원래 작년 초까지 멤버였다가 트레바리 매력에 빠져 입사까지 하게 된 진성 유저였다. 덕분에 트레바리가 얼마나 좋은지, 어떻게 트레바리를 통해 예전보다 멋진 사람이 될 수 있는지, 트레바리에서 얼마나 좋은 사람들을 만날 수 있는지를 알고 있었다. 그리고 이것들을 동네방네 열심히 소문을 내고 싶은 사람이었다.트레바리 홈페이지가 오프라인 트레바리에 오기 위한 건널목이라면 건널목 입구에 삐까뻔쩍한 간판도 크게 달고, 안내판도 만들어 건널목 너머에 얼마나 멋진 곳이 있는지 넘어오고 싶게끔 기대감을 심어주고 싶다. 우리의 비전인 '세상을 더 지적으로 사람들을 더 친하게'처럼 내가 트레바리에 온다면 더 지적이고 멋진 사람이 될 수 있고, 사람들과 더 친하게 지낼 수 있음을 잘 설명해주고 싶었다. 사람은 자기가 정말 좋아하는 것을 설명할 때 지치지 않고 그 어느때보다 열심히 목소리를 높일 수 있다고 생각한다.물론 나 혼자서는 힘들 것이다. 그래서 다른 크루들과 같이 어떻게 잘 전달할 수 있을지 치열하게 고민해보기로 했다. 그 일례로 최근에 영훈님과 같이 사내 스터디를 시작했다. 이런 점들이 단순히 시키는 일만 해내는 프리랜서보다 훨씬 더 잘 쓰일 수 있는 크루로 만들어 줄 것이라고 믿는다. 아직 '그래서 구체적으로 어떻게?'까지는 고민을 끝마치지 못했지만, 드디어 어떤 방향으로 무슨 역할을 하는 사람인지를 결정하였다. 이 결정을 시작으로 올해는 '회사에 더 많은 기여를 할 수 있는 크루가 될 수 있지 않을까'하는 설렘과 '그러려면 훨씬 더 잘해야겠다'는 부담이 가득한 채로 일 년을 맞이하게 되었다.올 한 해 '세상을 더 지적으로 사람들을 더 친하게' 만들어줄 우리 크루들!#트레바리 #기업문화 #조직문화 #스타트업 #인사이트
조회수 2282

비트윈의 멀티티어 아키텍처를 위한 프레젠터 이야기 - VCNC Engineering Blog

블로그 첫 글에서 비트윈의 시스템 아키텍처에 대해 다룬 적이 있습니다. 시스템 구성의 미래에 대한 계획으로 멀티티어 아키텍처에 대해 언급했었는데, 이는 프로토콜을 단순화시키고 배포 자동화를 가능하게 하기 위해서 클라이언트와 비즈니스 로직을 담당하는 서버 사이에 일종의 게이트웨이를 두는 것이었습니다. 그 외에도 여러 가지 필요성이 생겨 해당 역할을 담당하는 프레젠터라는 것을 만들게 되었고 비트윈의 채팅 시스템에 적용하게 되었습니다. 만드는 과정 중에 여러 기술적인 문제들이 있었고 이를 해결하기 위한 노력을 하였습니다. 이 글에서는 비트윈 시스템에서의 프레젠터에 대해 이야기 하고자 합니다.프레젠터프레젠터는 일종의 게이트웨이 입니다. 기존의 시스템에서는 클라이언트들이 ELB를 통해 채팅 서버에 직접 TCP 연결을 하였습니다. 하지만 비트윈 PC버전과 자체 푸시 서버를 만들면서 ELB로는 해결할 수 없는 부족한 점들이 생겼고, ELB의 부족한 점을 채워줄 수 있는 시스템이 필요하게 되었습니다. ELB를 대체하는 역할 외에도 다른 여러 필요했던 기능들을 제공하는 프레젠터를 만들기로 하였습니다.프레젠터는 ELB의 역할을 할 뿐만 아니라 여러 다른 기능들도 제공합니다.프레젠터의 기능패킷을 적절한 샤드로 중계비트윈에서는 커플 단위로 샤딩하여 같은 커플의 채팅 요청에 대해서는 같은 채팅 서버에서 처리하고 있습니다. Consistent Hash를 통해 커플을 여러 채팅 서버로 샤딩하고 ZooKeeper를 이용하여 이 정보를 여러 채팅 서버 간 공유합니다. 프레젠터 또한 ZooKeeper와 연결을 하여 어떤 채팅 서버가 어떤 커플을 담당하는지에 대한 정보를 알고 있도록 설계되어 있습니다. 따라서 프레젠터는 첫 연결 시 보내는 인증 패킷을 보고 해당 채팅 연결에서 오는 요청들을 어떤 채팅 서버로 보내야 할지 판단할 수 있습니다. 어떤 채팅 서버로 보낼지 판단하는 과정은 처음 한 번만 일어나며, 이후 패킷부터는 자동으로 해당 채팅 서버로 중계합니다.프레젠터의 이런 기능 덕분에 클라이언트는 더 이상 어떤 채팅 서버로 붙어야 하는지 알아내는 과정 없이 아무 프레젠터와 연결만 맺으면 채팅을 할 수 있게 되었습니다. 기존에는 클라이언트들이 여러 채팅 서버 중 어떤 서버에 붙어야 하는지 확인하는 작업을 한 후에 할당된 채팅 서버로 연결 맺어야 했습니다. 그래서 클라이언트가 채팅 서버와 연결을 맺기 위해 다소 복잡한 과정을 거쳐야 했지만, 이제는 클라이언트가 프레젠터의 주소로 연결 요청만 하면 DNS Round Robin 통해 아무 프레젠터와 연결하는 방식으로 프로토콜을 단순화할 수 있었습니다. 덕분에 새로운 채팅 서버를 띄울 때마다 ELB를 Warm-Up 시켜야 했던 기존 시스템의 문제가 없어졌습니다. 그래서 비트윈 개발팀의 오랜 염원이었던 채팅 서버 오토스케일의 가능성도 열렸습니다.많은 수의 연결을 안정적으로 유지PC버전과 푸시 서버를 만들면서 기존의 채팅 연결과 다르게 많은 수의 연결이 장시간 동안 유지 되는 경우를 처리할 수 있어야 했습니다. 기존에는 TCP 릴레이를 하도록 설정된 ELB가 연결들을 받아주었습니다. 한 머신당 6만 개 정도의 Outbound TCP 연결을 맺을 수 있는데, ELB도 트래픽에 따라 여러 대의 머신에서 돌아가는 일종의 프로그램이므로 이 제한에 걸린다고 생각할 수 있습니다. 따라서 많은 수의 연결을 맺어놓고 있어야 하는 경우 ELB에 문제가 생길 수 있다고 판단했습니다. (과거 ELB가 연결 개수가 많아지는 경우 스케일아웃이 안되는 버그 때문에 문제가 된 적이 있기도 했습니다) 또한 클라이어트 연결당 내부 연결도 하나씩 생겨야 하면 클라이언트가 연결을 끊거나 맺을 때마다 서버 내부 연결도 매번 끊거나 연결해야 하는 오버헤드가 발생합니다.이를 해결하기 위해 프레젠터에서는 TCP 연결을 Multiplexing하는 프로토콜을 구현하여 적은 수의 내부 연결로 많은 수의 클라이언트 연결을 처리할 수 있도록 하였습니다. 서버 내부에서는 고정된 개수의 몇 개의 연결만 맺어 놓고 이 연결들만으로 수많은 클라이언트 연결을 처리할 수 있습니다. 이처럼 TCP Multiplexing을 하는 것은 Finagle과 같은 다른 RPC 프로젝트에서도 지원하는 기능입니다.TCP Multiplexing 프로토콜을 통해 많은 수의 클라이언트 연결을 소수의 서버 내부 연결로 처리합니다.또한, 프레젠터는 많은 수의 SSL 연결을 처리해야 하므로 암복호화 로직을 실행하는데 퍼포먼스가 매우 중요하게 됩니다. 채팅 서버 한 대를 제거하거나 하는 경우 많은 연결이 한꺼번에 끊어지고 연이어 한꺼번에 연결을 시도하게 되는 경우가 있을 수 있는데, 이 때 대량의 SSL Handshaking을 하게 됩니다. 기존 서버들로 대량의 SSL Handshaking을 빠른 시간안에 처리하기 위해서는 높은 퍼포먼스가 필요합니다. Java로 작성된 프로그램만으로 이런 퍼포먼스 요구사항을 달성하기 어려우므로, 클라이언트와의 연결을 담당하는 부분은 OpenSSL, libevent를 이용한 C++로 코드로 작성하였습니다. 인증 패킷을 파싱하거나 패킷들을 릴레이 하는 등의 로직을 담당하는 부분은 Alfred라는 Netty를 이용하여 만든 인하우스 RPC 라이브러리를 이용해 작성되었습니다. 연결을 담당하는 부분은 TCP 연결을 유지하는 역할과 들어온 패킷들을 Netty로 작성된 모듈로 릴레이 하는 역할만 담당하므로 매우 간단한 형태의 프로그램입니다. 짧은 시간 안에 어럽지 않게 구현할 수 있었습니다.클라이언트의 연결을 받아주는 역할을 하는 부분은 C++, 실제 로직이 필요한 부분은 Java로 작성하였습니다.여러 네트워크 최적화 기술의 지원ELB에는 여러 네트워크 최적화 기술들을 아직 제공하지 않는 경우가 있습니다. 대표적으로 HTTP/2 혹은 SPDY, QUIC, TCP Fast Open 등이 있습니다. 특히 모바일 환경에서는 SSL Handshaking 등 부가적인 RTT로 인한 지연을 무시할 수 없으므로 이런 기술들을 이용한 초기 연결 시간 최적화는 서비스 퀄리티에 중요한 부분 중 하나입니다. ELB는 AWS에서 관리하는 서비스이므로 AWS에서 이런 기능들을 ELB에 적용하기 전에는 이용할 수 없지만, 프레젠터는 직접 운영하는 서버이므로 필요한 기능을 바로바로 적용하여 서비스 품질을 높일 수 있습니다. ELB에서 이미 제공하는 최적화 기술인 SSL Session Ticket이나 다른 몇몇 기술은 이미 적용되어 있고 아직 적용하지 않은 기술들도 필요에 따라 차차 적용할 예정입니다.프레젠터의 구현C++ 연결 유지 모듈프레젠터는 퍼포먼스를 위해 C++로 작성되었습니다. 이는 Pure Java를 이용한 암복호화는 프레젠터에서 원하는 정도의 퍼포먼스를 낼 수 없기 때문입니다. 처음에는 OpenSSL과 libevent를 이용해 작성된 코드를 JNI를 통해 Netty 인터페이스에 붙인 event4j라는 인하우스 라이브러리를 이용하려고 했으나, 코드가 복잡하고 유지보수가 어렵다는 점 때문에 포기하였습니다. 그 후에는 netty-tcnative를 이용해보고자 했으나 테스트 결과 연결당 메모리 사용량이 큰 문제가 있었고, 이를 수정하기에는 시간이 오래 걸릴 것 같아 포기하였습니다. 결국, 페이스북에서 오픈소스로 공개한 C++ 라이브러리인 folly를 활용하여 프레젠터를 작성하게 되었습니다. folly의 네트워크 API들이 OpenSSL과 libevent를 이용해 구현되어 있습니다.릴레이 로직프레젠터는 첫 인증 패킷을 파싱하여 릴레이할 채팅 서버를 판단하며, 이후의 패킷부터는 실제 패킷을 까보지 않고 단순 릴레이 하도록 설계하였습니다. 처음의 Netty 파이프라인에는 Alfred 프로토콜을 처리할 수 있는 핸들러들이 설정되어 있어 인증 패킷을 파싱 할 수 있으며 인증 패킷에 있는 정보를 바탕으로 어떤 채팅 서버로 패킷을 릴레이 할지 결정합니다. 그 이후 파이프라인에 있던 핸들러를 모두 제거 한 후, 읽은 byte 스트림을 Multiplexing Protocol 프레임으로 감싸서 그대로 릴레이 하는 매우 간단한 로직을 담당하는 핸들러 하나를 추가합니다. 덕분에 로직 부분의 구현도 매우 간단해질 수 있었으며, 채팅 서버에 API가 추가되거나 변경되어도 프레젠터는 업데이트할 필요가 없다는 운영상 이점도 있었습니다.Multiplexing Protocol프레젠터의 Multiplexing Protocol은 Thrift를 이용하여 직접 정의 하였으며, 비트윈 개발팀 내부적으로 사용 중인 RPC 라이브러리인 Alfred에 이 프로토콜을 구현하였습니다. Thrift를 통해 C++과 Java로 컴파일된 소스코드를 각각 프레젠터의 연결 처리 부분과 로직 처리 부분에서 이용하여 통신합니다. 프레젠터에서는 Multiplexing된 TCP 연결들을 Stream이라고 명명하였으며 이는 SPDY나 HTTP/2에서의 호칭 방법과 유사합니다. SPDY나 HTTP/2도 일종의 Multiplexing 기능을 제공하고 있으며, 프레젠터의 Multiplexing Protocol도 SPDY 프레임을 많이 참고하여 작성되었습니다.수 많은 클라이언트와의 TCP연결을 Stream으로 만들어 하나의 내부 TCP연결을 통해 처리합니다.Alfred에서는 Multiplexing 된 TCP 연결을 Netty의 Channel 인터페이스로 추상화하였습니다. Netty에서 TCP 연결 하나는 Channel 하나로 만들어지는데, 실제 Stream도 Channel 인터페이스로 데이터를 읽거나 쓸 수 있도록 하였습니다. 이 추상화 덕분에 비트윈 비즈니스 로직을 담당하는 코드에서는 Stream으로 Multiplexing 된 TCP 연결을 마치 기존의 TCP 연결과 똑같이 Channel을 이용해 사용할 수 있었습니다. 그래서 실제 비즈니스 로직 코드는 전혀 건드리지 않고 프레젠터를 쉽게 붙일 수 있었습니다.로드 밸런싱클라이언트는 Route53에서 제공하는 DNS Round Robin 기능을 이용하여 아무 프레젠터에 연결하여 채팅 요청을 날리게 됩니다. 하지만 무조건 동등하게 Round Robin 하게 되면 새로 켜지거나 하여 연결을 거의 맺지 않고 놀고 있는 프레젠터가 있는데도 연결을 많이 맺고 있는 기존 프레젠터에에 연결이 할당되는 문제가 생길 수 있습니다. 충분한 시간이 흐르면 결국에는 연결 개수는 동등하게 되겠지만, 처음부터 놀고 있는 프레젠터에 새로운 연결을 가중치를 주어 할당하면 로드를 분산되는 데 큰 도움이 될 것입니다. 그래서 Route53의 Weighted Routing Policy 기능을 이용하기로 하였습니다. 현재 연결 개수와 CPU 사용량 등을 종합적으로 고려하여 Weight를 결정하고 이를 주기적으로 Route53의 레코드에 업데이트합니다. 이런 방법으로 현재 로드가 많이 걸리는 서버로는 적은 수의 새로운 연결을 맺게 하고 자원이 많이 남는 프레젠터로 더 많은 새로운 연결이 맺어지도록 하고 있습니다.스케일 인/아웃AWS에서는 트래픽에 따라 서버 개수를 늘리기도 하고 줄이기도 하는 AutoScaling 이라는 기능이 있습니다. 프레젠터가 스케일 아웃될때에는 프레젠터가 스스로 Route53에 레코드를 추가하는 식으로 새로운 연결을 맺도록 할 수 있습니다. 하지만 스케일 인으로 프레젠터가 제거될 때에는 Route53에서 레코드를 삭제하더라도 함부로 프레젠터 서버를 종료시킬 수 없습니다. 종종 클라이언트의 DNS 캐싱 로직에 문제가 있어, Route53에서 레코드를 삭제되었는데도 불구하고 이를 업데이트하지 못해 기존 프레젠터로 연결을 시도하는 경우가 있을 수 있기 때문입니다. 따라서 프레젠터 클러스터가 스케일 인 될 때에는 기존의 모든 연결이 끊어지고 충분한 시간 동안 새로운 연결이 생기지 않은 경우에만 서버를 종료시켜야 합니다. AutoScaling Group의 LifeCycleHook을 이용하여 위와 같은 조건을 만족 시켰을 때에만 프레젠터 서버를 완전히 종료시키도록 하였습니다.못다 한 이야기프레젠터라는 이름이 이상하다고 생각하시는 분들이 있을 것으로 생각합니다. 멀티티어 아키텍처를 이야기할 때 프레젠테이션 티어, 어플리케이션 티어, 데이터베이스 티어로 구분하곤 하는데 이 프레젠테이션 티어에서 나온 이름입니다. 지금은 실제 프레젠터가 하는 역할과 프레젠테이션 티어가 보통 맡게 되는 역할에는 많은 차이가 있지만, 어쩌다 보니 이름은 그대로 가져가게 되었습니다.프레젠터에서 AutoScaling을 하기 위해 LifeCycleHook을 이용합니다. 이때 프레젠터를 위해 LifeCycleHook 이벤트를 처리하는 프로그램을 직접 짠 것이 아니라 비트윈 개발팀이 내부적으로 만든 Kharon이라는 프로그램을 이용하였습니다. Kharon은 인스턴스가 시작되거나 종료될 때 실행할 스크립트를 작성하고 인스턴스의 특정 위치에 놓는 것만으로 LifeCycleHook을 쉽게 이용할 수 있게 하는 프로그램입니다. Kharon 덕분에 비트윈 내 다양한 시스템에서 별다른 추가 개발 없이 LifeCycleHook을 쉽게 활용하고 있습니다. 후에 Kharon에 대해 자세히 다뤄보도록 하겠습니다.정리비트윈 개발팀에서는 오랫동안 유지되는 수많은 채팅 서버 연결들을 처리하고 클라이언트와 서버 간 프로토콜을 단순화시키는 등 여러 이점을 얻고자 ELB의 역할을 대신하는 프레젠터를 만들었습니다. 프레젠터를 만드는 과정에서 여러 기술적 문제가 있었습니다. 이를 해결하기 위해 C++로 연결 유지 모듈을 따로 작성하였고 Multiplexing Protocol을 따로 정의하였으며 그 외 여러 가지 기술적인 결정들을 하였습니다. 이런 과정에서 시행착오들이 있었지만 이를 발판 삼아 더 좋은 기술적 결정을 내리기 위해 고민하여 결국 기존 시스템에 쉽게 적용할 수 있고 쉽게 동작하는 프레젠터를 만들어 이용하고 있습니다.
조회수 1287

EOS Token 생성과 발행, 전송

이번시간에는 배포한 Contract를 통해 Token 발행과 전송을 해보겠습니다. 이를 위한 준비는 아래 2미디엄 글을 참조해주세요EOS Smart Contract 를 위한 준비EOS Smart Contract 배포먼저 저번 시간에 배포한 token 발행 abi 를 확인해 보겠습니다.$ cleos get abi hexlanthenryget abiabi를 확인하다보면 actions 라는 항목에 총 3개의 action이 있음을 확인할 수 있습니다. 이 3개의 name이 실행할 수 있는 action입니다. token발행은 create action을 통해 진행할 수 있습니다.Token 생성$ cleos push action hexlanthenry create '["hexlanthenry", "10000000000.0000 HEX"]' -p hexlanthenrycreate action 실행 결과create action 을 통해 ‘HEX’ 토큰을 100억개 생성했습니다. create 라는 action의 인자는 account_name(hexlanthenry), maximum_supply(10000000000.0000 HEX) 입니다. 즉 첫번째 인자는 토큰의 발행자를 나타내며, 두번째 인자는 토큰의 최대 수량을 나타냅니다.이 인자가 어떻게 들어가는지는 abi 의 struct 를 확인하면 알 수 있습니다.abi의 create structparameter 1 : account_name type— issuerparameter 2 : asset type — maximum_supply+ 저번 강의에서 공지한데로 다음 포스팅에서는 abi가 무엇을 뜻하는지, 이를 통해 어떻게 action을 실행할 수 있는지 알아보도록 하겠습니다.Token 발행생성과 발행 이 2개의 개념이 헷갈릴 수 있습니다. create action을 통한 생성은 최대 발행량을 결정 하는 것이며, issue action 은 토큰을 유통 시키는 것입니다.create : token 생성과 동시에 최대 발행량 결정issue : token 의 유통따라서 issue action을 통해 이전에 생성한 HEX token을 발행해보겠습니다.$ cleos push action hexlanthenry issue '["hexlanthenry", "10000.0000 HEX", "initial issue"]' -p hexlanthenryissue contract 실행 결과issue action 역시 data로 어떤 인자가 들어가는지는 abi를 통해 확인 가능합니다.abi의 issue structparameter 1 : account_name type — toparameter 2 : asset type — quantityparameter 3 : string type — memomemo 는 transfer 가 어떤 목적인지에 대해 설명해주는 인자 입니다. 생략해도 되는 값으로, 원하시면 parameter 개수를 유지하는 선에서 empty string을 넣으시면 됩니다. memo를 어떻게 쓰면 유용한지에 대해서도 다른 포스팅에 담도록 하겠습니다.issue가 잘 실행 되었는지 확인해 보겠습니다.$ cleos get currency balance hexlanthenry hexlanthenry저는 issue 를 4번 수행한 후 balance 를 체크 했기 때문에 총 40000개의 HEX token이 존재하는 것을 확인 할 수 있습니다.hexlanthenry 의 HEX token개수예외사항1create 하지 않은 token을 issue 할 경우해당 symbol 이 존재하지 않음예외사항2생성한 token 수보다 많은 양을 issue 할 경우maximum supply를 초과함Token transfer마지막으로 token을 다른 계정에 전송 해보도록 하겠습니다. 다른계정에 token을 보내야 하기 때문에 계정을 생성하거나 존재하고 있는 계정을 사용하시면 됩니다.아래 명령으로 hexlanthenry 계정이 babylion1234 계정으로 10000개의 HEX 토큰을 보냅니다.$ cleos push action hexlanthenry transfer '["hexlanthenry", "babylion1234", "10000.0000 HEX", "first"]' -p hexlanthenrytransfer 실행결과transfer 시 들어가는 data에 대해서도 abi를 확인해보겠습니다. 다른 action보다 많은 인자를 필요로 합니다. [“hexlanthenry”, “babylion1234”, “10000.0000 HEX”, “first”]abi의 transfer structparameter 1 : account_name type — fromparameter 2 : account_name type — toparameter 3 : asset type — quantityparameter 4 : string type — memo실제로 babylion1234 계정을 확인해 보면, 방금 배포한 HEX token을 보유하고있는 것을 확인할 수 있습니다.babylion1234의 HEX 보유이번 포스팅에서는 token을 생성과 발행 그리고 전송을 다뤄봤습니다. EOS는 Ethereum 과 달리 토큰 발행을 매우 쉽게 진행할 수 있습니다. 이 두 dapp의 차이에 대해서도 포스팅을 하고 싶으나 우선 다음 포스팅에서는 contract 개발의 기초를 다루도록 하겠습니다.감사합니다.#헥슬란트 #HEXLANT #블록체인 #개발자 #개발팀 #기술기업 #기술중심
조회수 1023

Good Bye, Parse

한 번도 안 써 본 개발자는 있어도 한 번만 써 본 개발자는 없을 듯한 Parse(parse.com)가 오늘 아침 충격적인 공지 메일을 보내왔는데, 1년후 서비스 종료한다는 것이었다. Parse는 모바일에 특화된 DB 플랫폼을 시작으로, 어드민툴, 푸시, 애널리틱스, 로그인, 크래쉬리포트 등으로 서비스를 확장하며 모바일 개발자들의 백엔드 구축을 편하게 만들어주었는데 2013년 페이스북에 인수되면서 안정성에 대한 신뢰가 커지고, 가격 정책이 변경되어 상당히 저렴해지면서 개발자들의 더욱 큰 호응을 얻었다. 1초에 30개의 요청까진 무료였으니 1개월로 환산하면 7700만 요청이 무료이고, 이는 10만 사용자 이상도 무난하게 대응할 수 있는 숫자이다. 물론 사용자와 요청 수가 늘어나면 월 100~200달러씩 비용을 추가하면 되고 무엇보다 서버 확장에 신경쓰지 않아도 됐다. 푸시 발송은 100만대의 기기까지 발송이 무제한 무료였고 크래쉬리포트와 유저 리텐션 분석도 심플하고 쓸만했는데 무료였다. 역시 무료인 2TB 트래픽은 상용 CDN을 사용하면 수십만원의 비용이 든다.복잡한 쿼리를 작성하기 어렵고 서버사이드 코드를 디버깅하기 쉽지 않아 서버 로직이 복잡한 서비스에는 적합하지 않았지만 계속 보완된다는 느낌이 있고 무료이니 불편해도 감수하고 쓸만 했어서, 이외에는 단점을 찾기가 어려울 정도였다. 무료티어가 워낙 후해서 돈을 내고 쓰는 개발자가 얼마나 될까 싶다는 점이 오히려 불안요소였다. Parse 그리고 페이스북 입장에서 수익성이 어떻게 확보될까 의구심이 들었던 것이다.  수익성 측면에서 무료로 사용하던 앱들의 트래픽이 늘어나 과금티어로 넘어가야 하는데 그러려면 100만 다운로드 이상의 중대형 서비스로 성장해야 하고, 그 정도 되면 그 스타트업도 자체 백엔드 엔지니어가 확보되고 백엔드 로직도 복잡해져 Parse와 궁합이 잘 안 맞게 되는 것이다. 수익성이 아니라면 잠재적인 가치로써 Parse를 사용하는 스타트업과 페이스북의 연결고리를 찾아 유저 베이스를 활용하던지 광고 매체로써 활용하던지 방안이 있어야 하는데 페이스북 자체 패밀리들(페이스북, 메신저, 인스타그램, 와츠앱)의 매체력과 광고수익이 워낙 크고 견고하게 성장하는 중인데다 페이스북 애널리틱스와 외부 광고 서비스가 자리잡으면 Parse는 더더욱 투자가치가 떨어진다. 당장 수익성이 없고, 잠재적인 가치도 잘 모르겠고, 똑똑한 내부 엔지니어들이 묶여 있고, 무료로 쓰는 개발자들은 매일 뭐 만들어달라 뭐 고쳐달라 요청을 하니 '우리가 이걸 왜 붙들고 있어야 하지' 내부 논의가 계속 있어왔을 것 같은데, 그래도 작년 가을까지는 페이스북 코리아에서 Parse 관련 세미나와 컨퍼런스도 열고 미국에서 F8이 열린 시점에는 IoT와 React로 확장하는 등 좀더 적극적으로 활용하려는 듯 했다. 작년 겨울부터 분위기가 이상해졌다. 우선 작년 말 크래쉬리포트 서비스 종료. Parse의 서비스의 일부이긴 했지만 다른 대안과 비교해서 확실한 우위가 있던 서비스여서 '수익성'의 이유 외에는 정리할 이유가 없어보였다. 그 동안 문제 삼지 않았던 '수익성'이 이제는 문제가 된건가? 그러면 사실 Parse 전체 서비스도 접을 수 있다는 생각이 들었다. 그리고 이어서 나온 '오픈소스화'와 'Heroku 연동'. 오픈소스는 좋은 의미 또는 서비스의 발전을 위해서라고 볼 수도 있는데 Heroku 연동은 굳이 왜? Parse 입장에서나 Parse를 쓰는 개발자 입장에서나 백엔드를 Parse 클라우드 코드 대신 Heroku로 이동할 이유가 없어 보였다. Parse를 접게 되어 마이그레이션 해야 한다면 모를까...??? 가 현실이 되었다.나도 작년까지는 서버비 한 푼 내지 않고 대부분의 서비스를(수십개) Parse에 올렸었고 주변에나 Parse 세미나에서도 Parse의 장점에 대해 이야기하곤 했는데... 수익성 없는 앱들을 정리하면서 Parse에 대한 의존도가 낮아지긴 했지만 지금 제작하고 있는 것들부터 마이그레이션 해야 하고, 추천했던 지인들에게는 마이그레이션 전략을 컨설팅해야 할 판이다. 서비스 종료라는 극단적인 선택을 하기 전에 무료 티어를 좁혀서 수익화를 한 상태로 좀더 오래 버텨줬으면 어땠을까 하는 아쉬움이 든다. 구글앱스도 수익화를 하면서 유지하듯이. 광고 외의 B2B 비즈니스에서 페이스북에 대한 신뢰가 많이 하락하지 않을까 싶다. 마이그레이션 비용은 상당하다. 우선 Parse의 슬로건이 백엔드 작업 없이 백엔드를 이용할 수 있는 것이었기 때문에 이제 백엔드를 직접 구성하던지 Parse가 제공하던 서비스들의 대체제들을 각각 찾아 옮겨야 하고, 초기부터 그런 대안으로 구축한 것보다 이전하는 비용이 훨씬 큰 것은 당연하다. 클라이언트 엔지니어가 Parse로 구축했다가 아직까지 백엔드 엔지니어가 없는 서비스들은 그냥 정리될 가능성도 크다. 사실 백엔드 서비스들의 이용료 자체는 많이 낮아진 상태이기 때문에 여기서 말하는 마이그레이션 비용은 대부분 외주/컨설팅이나 백엔드 개발자 채용 등의 엔지니어링 비용이다. 나도 대안들을 이제 막 찾기 시작했지만 이전할 수 있는 대안들을 정리하면서 마무리해본다. Parse DB: http://firebase.com/ (구글이 인수했다. 데자뷰의 느낌이 들 수도 있지만 그래도 믿어보자)Parse Push: http://valuepotion.com/ (푸시 & 분석& 마케팅툴 - 카카오 국내 자회사의 글로벌 서비스)https://www.pushwoosh.com/ (urbanairship보다 저렴하다고)Parse Crash Reporting: http://crashlytics.com (트위터 인수, 과거에 유료였으나 무료로 전환됨)Parse Cloud Code:http://heroku.com/ (Parse의 Heroku 연동과 함께 살펴보자)https://github.com/ParsePlatform/parse-server (Parse에서 제공한 서버 오픈소스. 이를 활용한 마이그레이션 서비스가 나올 듯 싶다)
조회수 2478

A/B Testing 도구인 Optimizely 사용법

웹 서비스를 운영하다 보면 준비하는 과정에서 정말 많은 고민이 오갑니다. 컨텐츠의 배치, 헤드 카피, 인터랙티브.. 하지만 어떤 요소가 조금 더 사용자의 반응을 이끌어내는지 정확히 알 수 없습니다. 이런 부분들을 ‘직감’이나 ‘경험’으로 막연하게 자기 자신과 타인에게 주장하고 있지는 않나요?그렇다면 두 가지 혹은 그 이상의 시안들을 직접 시험대에 올려 각각 더 좋은 것을 선택하는 것은 어떨까요?A/B 테스팅에 관련한 유명한 일화가 하나 있습니다. 1497년, Vasco da gama는 최초로 유럽에서 아프리카 남부를 거쳐 인도까지 항해한 인물입니다. 그가 인도를 발견하고 귀항했을 때 160명의 원정대원 중 100명이 괴혈병으로 사망하는 사건이 있었습니다. 그만큼 괴혈병은 항해하는 선원들의 공포 대상이었죠. 그로부터 약 300년 뒤, 영국의 의사인 James Lind는 괴혈병의 치료법을 알기 위해 실험군을 나누어 각각 다른 음식으로 실험을 진행했습니다.실험은 다음과 같습니다. 괴혈병에 걸린 12명의 선원을 선정하여 그 중 10명에게는 보통 음식을 주고, 두 사람에게는 매일 라임 과즙을 마시게 하였습니다. 6일 후 라임 과즙을 마신 선원 두 명만이 괴혈병에 완벽히 치료된 모습을 보였습니다. James Lind가 실험하기 전에는 단순히 ‘감귤류 과일이 괴혈병에 좋다.’, ‘괴혈병으로 죽어가는 찰나에 잡초를 먹고 다시 살아났다.’ 라는 이야기만이 난무했었고 직접적인 치료법을 제시한 사람은 James Lind가 최초였습니다. 비타민C가 발견된 것이 1928년임을 고려하면, 이 당시에는 비타민C 이라는 개념이 없었기 때문에 James Lind의 실험은 후에 많은 선원의 목숨을 괴혈병으로부터 지켜주는 사례가 됩니다.괴혈병이 해적보다 더 무서웠던 대항해시대에 보통 음식(A)과 라임(B)을 이용해 선원들을 모두 구했던 영국 해군의 현명한 대처법에서 우리의 웹 서비스를 더욱 더 활성화 시키는 지혜를 얻어야 합니다.Optimizely?Optimizely는 웹서비스를 운영하면서 A/B Testing 수행을 원하시는 분들에게 적합한 서비스입니다. Optimizely를 사용하기 전에 A/B 테스팅에 대한 정보가 필요하다면 A/B 테스팅에 관련한 JC Kim님의 글( A/B Testing에 대한 기초적인 정보들 )을 먼저 읽어보시는 것을 추천합니다.Optimizely는 단순히 A/B 테스트의 진행과 그 통계 결과만 제공하는 것이 아니라, 테스트를 진행하는 동안의 모든 준비 과정에서 사용자들에게 도움을 주고 있습니다. 오늘은 그 Optimizely의 핵심 기능 및 활용법에 대하여 알아보겠습니다. Optimizely는 유료 서비스이지만 30일 동안의 Free Trial을 제공해주므로 그 기간 동안 충분히 이 서비스의 모든 것을 체험할 수 있습니다.Optimizely는 세계적인 대형 기업들이 이용하는 서비스로, 이들은 이미 Optimizely를 통해 각각 컨텐츠들에 대한 사이트 접속자들의 반응을 체크하고 있습니다. 대표적인 회사로 Starbucks, Salesforce, MTV, The Walt Disney Company, ABC 등이 있습니다.그렇다면 왜 많은 기업들이 A/B Testing에 집중하고 있고, Optimizely를 이용하는 걸까요?더 정확한 데이터를 추출하려는 노력.메일링 리스트를 수집하는 등의 폼 입력/전송을 하는 비율을 구하는 경우, 혹은 메인 페이지에서 다른 세부페이지로 이동하는 이용자 비율을 나타내기 위해 목표(Goal)을 나타냅니다. 목표한 골에 A 버전(기존안/Original) 이용자가 더 많이 들어갔는지, B 버전(새로 작성한 안/Variation)이 효과적이었는지를 테스트 할 수 있습니다.이처럼 Goal에 도달하는 행위를 ‘Conversion’이라 표현합니다. 방문자 수 대비 Conversions 수치를 비교한 Conversion rate를 비교하면 A/B 시안 중에 더 효과적인 결과를 수치와 그래프, 특히 “기준을 이길 수 있는 확률”(Chance to beat baseline)을 철저하게 계산해 결과를 명확하게 진단할 수 있습니다. 말 그대로 Goal과 Conversion Rate 수치로 사용자가 승자를 판단하는 것이 아니라, 수치공식을 통해 B 버전이 기존안(A버전)을 확실하게 이겼는지 아닌지를 파악해줍니다.더 자세히 알고싶은 부분은 해당 값을 구하는 통계공식이 있는 링크를 참고해주세요.정말 쉬운 실험요소 변경.Optimizely를 이용하면 여러분이 복잡한 CSS나 Javascript 기술이 없어도 쉽게 A/B 테스팅을 진행할 수 있습니다. Optimizely에서는 실험군의 요소를 마우스 클릭 몇 번으로 손쉽게 바꿀 수 있습니다. 가령 B 버전에 A 버전과 다른 문서 배치를 하거나 배경화면, 이미지, 폰트, 버튼 속의 문구 등도 별도의 코딩 절차 없이 Optimizely 실험페이지 내에서 변경할 수 있다는 말이죠. 또한 실시간으로 CSS를 변경하여 적용하거나 Javascript도 적용할 수 있습니다. 마치 ‘나모 웹 에디터’ 나 ‘드림위버’ 같은 인터페이스로 파워포인트 내의 요소를 다루듯 쉽게 바꿀 수 있습니다.위치와 크기를 Drag & Drop 으로 쉽게 움직이게 할 수 있습니다.웹사이트에 적용된 이미지 또한 로컬에 있는 파일 혹은 웹에 있는 이미지로 대체할 수 있습니다.텍스트도 곧바로 변경할 수 있고 HTML을 직접 대체해서 끼워 넣을 수 있습니다.참 쉽죠?간단한 설치위처럼 변경했던 시험요소들을 저장하려면 복잡하고 긴 코드를 다시 원래 파일에 붙여 넣어야 할까요? 그렇지 않습니다. Optimizely는 변경한 컨텐츠 정보를 간단한 자바스크립트 코드로 ‘Optimize’ 해 주기 때문에 단 몇줄만 추가해주면 원하는 결과가 나옵니다.확장성유명한 아티스트 두 명이 콜라보레이션 하는 상상을 해보죠. 각자의 개성을 살려 새로운 결과물들을 창조해내지요. 물론 그들의 궁합이 잘 맞아야 한다는 전제가 있습니다. 하지만 다행히도 Optimizely와 연동되는 서비스들은 궁합이 잘 맞는 편입니다. Optimizely는 A/B 테스팅에 관한 자료에 집중하고 있기 때문에, 조금 더 디테일한 자료(Analytics, Heatmap)는 욕심내지 않고 기타 많은 서비스와 연동합니다.Optimizely와 연동되는 서비스는 다음과 같습니다.AnalyticsGoogle AnalyticsKISSmetricsMixpanelOmniture SiteCatalystHeatmapClickTaleCrazyegg위 서비스 중 하나라도 이용 중이시라면, Optimizely와 어떤 부분이 연동이 되는 지 살펴보세요.마치며페이지 두 개를 접속자들에게 무작위로 나누어 배포해서 반응을 트래킹하는 기술은 흔할지도 모릅니다. 하지만 Optimizely를, 그리고 연동되는 다양한 서비스들을 이용하면 조금 더 세밀하고 확실한 데이터를 얻을 수 있습니다. 정말로 나의 웹 서비스에 필요한 것이 ‘잡초’인지 ‘레몬’인지 알고 싶다면 지금 당장 시작해보세요.#스포카 #기획 #A/B테스트 #A/BTest #꿀팁 #인사이트 #조언
조회수 1358

'구루급' 개발자란...

'구루'라는 단어는 이제 '수준급'을 넘어선 분들에게 부여되는 의미 있는 호칭이다. 특히, 개발자 사회에서는 비공식적으로 '구루급'이라고 불리는 개발자들이 있다. 이 정의에 대해서 누가 명확하게 옳다고 이야기할 수 있는 것은 아니다.다만, 30년 동안 소프트웨어 개발자로 살아오면서 만난 수많은 개발자들과 해외 유수의 개발자들과 만나고 소통하면서 느낀 개인적인 경험을 바탕으로 '구루급'에 대해서 정의를 해보겠다.매우 당연하게 이 정의는 전적으로 객관화된 것이 아닌, 매우 주관적인 기준이다.보통, '구루'급 개발자라고 불리는 분들을 보면, 오픈소스로 한 획을 그었거나, 그의 뜻을 따르는 후배들이 많거나, 특정 분야의 경험이 매우 풍부한 분들을 대상으로 이야기한다.다만, 이 기준에 '돈'을 많이 벌었거나, 특정 제품이나 게임, 서비스를 잘 만들었다는 식의 기준은 들어가는 것은 일부 논외로 하겠다. 이것은 전적으로 개인적인 기준이다. 이런 분들은 '구루급'개발자가 되기보다는, 산업적이거나 경제적으로 크게 성공한 기준이 더 높기 때문이며, 금전적으로 성공한 분들이 '후배'들에게 개발자로서의 영향력을 주는 것이 사실상 어렵기도 하거니와, 이미 비즈니스의 단계로 넘어간 분들이기 때문에 '구루급'개발자라고 이야기하기에는 모호하다고 개인적으로 이야기한다.그렇다면, 내가 생각하는 구루급 개발자의 최소한의 필요조건을 나열해 보자. 전적으로 개인적인 기준이니 너무 주관적이라고 비판하지 마시기를... 그 이유는 정말 주관적이기 때문이다.하나. 하나의 소프트웨어나 도메인을 10년 이상 장기간 개발 및 연구하고 있는가?둘. 자신만의 개발 문화에 대한 철학과 그 기준을 가지고 실행하고 있는가?셋. 자신이 소유하거나 만들어낸 개발 도구나 방법, 기술에 대해서 후배 개발자들에게 전파하고 있는가?넷. 후배 개발자들에게 존경받는 개발자로서의 기본적인 성품을 가지고 있는가?다섯. 후배 개발자들에게 자신의 롤을 양보하거나, 팀과 조직을 위해서 자신의 자리를 포기할 줄 아는가?여섯. 자신의 먹을거리를 위해서 비용을 싸게 부르지 않고, 후배들도 대우를 받을 수 있도록 너무 싸게 일하지 않아야 한다는 것을 실천하는가?제가 생각하는 '구루급'개발자의 조건입니다.분명, 이렇게 활동하는 '구루급'개발자들이 주변에 존재하고 있으며, 이를 위해서 개발자의 처우에 대해서 노력하기도 하고, 불합리한 경영자들과 논쟁을 벌이기도 합니다. 자신의 개인적인 이익만을 위해서 움직이지도 않는 그들이야말로 '구루급'개발자 아닐까요?그리고.대부분의 구루급개발자들은 충분한 대우와 보수를 받고 일하고 있습니다.그것이, 후배 개발자들의 처우와 미래를 위해서 매우 필요하다고 생각하고 있기 때문이죠.저는 '구루급'개발자를 그렇게 생각합니다.ps.최고의 개발자, 슈퍼개발자 등에 대한 호칭도 있을 수 있습니다. 제가 생각하는 '구루'급 개발자는 후배들에게 존경을 받고, 후배들의 처우나 개발자들의 미래에 대해서도 고민하고 실천하는 분들에 대해서 정의해 본것입니다.

기업문화 엿볼 때, 더팀스

로그인

/