스토리 홈

인터뷰

피드

뉴스

조회수 950

AI 스쿨 필기 노트 ① 선형회귀분석(Linear Regression)

전세계가 AI first를 외치고 있습니다! 엘리스 인공지능 오프라인 교육과정인 AI 스쿨의 필기노트를 8주간 연재합니다. 인공지능 개론과 알고리즘에 대해 함께 공부해요.지난 5월 8일 구글의 연례 개발자 콘퍼런스 I/O에서 구글은 구글 듀플렉스라는 새로운 AI 기술을 선보였습니다. 구글 듀플렉스가 직접 미용실에 전화를 걸어서 예약에 성공하는 이 시연은 매우 인상적인 장면이었는데요. 국내의 여러 기업에서도 이미 인공지능 스피커를 출시하는 등 우리의 일상 생활 곳곳에도 인공지능 기술이 스며들고 있습니다.IDC, Tractica, Markets and Markets 등 글로벌 시장조사기관들은 2020년까지 세계 인공지능 시장이 연평균 50% 이상 가파르게 성장할 것이라고 예측하기도 합니다. 이미 세계 각국의 주요 IT 기업들은 AI 시장에서 영역을 넓히고 경쟁력을 확보하고자 전력을 투입하고 있는데요. 국내 기업들 역시 인수합병과 조직개편 등으로 인공지능 기술과 인재 확보를 위해 발 빠르게 움직이고 있습니다.엘리스에서는 IT 분야 및 연구 기관에 취업하고자 하는 분들을 위한 오프라인 교육과정을 운영하고 있습니다. 지난해에 이어 올해에는 양재 RNCD 혁신허브와 함께 인공지능 R&D 실무자 양성과정을 운영하게 되었는데요! 이론 수업(8주)과 팀 프로젝트(6주), 커리어 코칭 과정(2주)로 이루어진 이번 과정은 수료증 및 입사 추천서 발급, 테크니컬 인터뷰와 포트폴리오 준비, 국내 IT 기업과의 채용 연계 등으로 구성되어 있어 관련 분야에 취업을 희망하시는 분들의 많은 관심이 있었습니다.300명 가까운 분들이 지원해주셨고, 이 중 선발 과정을 거친 40여 명의 분들이 16주간 오프라인+온라인 교육을 받게 되었습니다. 이 중 기계학습과 알고리즘 개론에 대한 8주간의 교육 내용을 앞으로 8주간 여러분과 함께 공유하고자 합니다. 컴퓨터 공학과에 재학 중인 AI 스쿨 수강생이 직접 필기노트를 공유해 준다고 하니 함께 AI 개론에 대해서 공부해 봐요. :)안녕하세요! 저는 숭실대학교 컴퓨터학부 4학년에 재학 중인 대학생이에요. 저는 평소에 AI에 대해 관심이 많아서 제대로 된 교육을 받고 싶어서 이번 과정을 수강하게 되었어요. 앞으로 AI 스쿨에서 받는 수업이 제가 AI 엔지니어로 성장할 수 있는 밑거름이 될 것이라고 생각해요. 아직 배우는 단계이기 때문에 많이 부족하지만 앞으로 8주 동안 이 글을 통해서 함께 공부한다고 생각하며 그 주에 배운 내용을 요약해보려고 합니다!AI 스쿨 첫 수업에서는 ‘Linear Regression(선형 회귀)’에 대해 배웠어요. 대학교 2학년 때 전공 과목으로 ‘선형대수학’이 있었는데요, 배우면서 이런 학문은 도대체 어디에 쓰이는지 혹시 필요 없는 것을 배우느라 시간 낭비를 하는 것은 아닌지 힘들게 공부했던 기억이 나네요. 그런데 제가 읽은 한 기사에서 미국의 연구팀이 ‘장기적인 공기 정화 노력이 성장기 아이들의 폐기능을 개선시켰다’는 연구 결과를 증명한 후 캘리포니아 남부지역에서 ‘공기오염의 질 관리 정책’을 시행하여 오염 수준이 꾸준히 감소하고 있다는 내용이 있었는데요. 연구팀은 공기오염의 감소와 소아 호흡기 질환의 개선 사이에 개연성을 평가했고 이 연구에서 사용한 방법이 선형회귀분석(linear regression model)이라고 해요!첫 수업에서는 앤드류 응 교수님 강의 자료의 쉬운 예시를 바탕으로 Linear Regression(선형회귀)을 공부했어요.이 예시에서는 집 크기에 관한 정보 하나로 집의 가격을 예측하는 할 수 있는 데이터가 있다는 가정을 하고, 이 가정이 직선의 방정식 y = ax + b의 형태를 따른다고 가정했어요.인공지능은 예측을 기본으로 다루는데, 우리는 과거의 데이터를 학습함으로써 최적의 예측 모델을 만들게 돼요.이때 다루는 데이터를 Training set이라고 부르고, m은 학습 데이터의 숫자, x는 입력 변수 또는 feature, 그리고 y는 출력 변수 또는 타깃 변수라고 불러요.기존의 Training set으로 Learning 알고리즘을 학습시키면 그 학습된 부분이 h, 즉 가설이 돼요. h를 통해서 우리는 어떠한 집 크기에 대한 예측된 가격을 구할 수 있어요. 그런데 이때 보다 정확히 예측을 하려면 error를 최소로 하는 a, b의 최적의 값을 설정해야 해요.우리의 모델인 직선의 방정식을 통해 오차가 적은 예측값을 얻기 위해서는 a와 b에 어떠한 값을 넣어야 좋을까요? 위에서 언급했듯이 우리에게는 주어진 학습 데이터가 있죠. 이를 이용하여 최적의 값을 도출해야 해요. Cost function 이란 a, b가 주어진 학습 데이터인 Training set을 가장 적은 오차로 표현하고 있는지 알 수 있는 방법인데요. Loss function 또는 Objective function이라고도 해요. Linear Regression에서는 Cost function으로 Squared error function을 사용해요. Squared error function 이란 가설에 Training data의 입력값을 넣었을 때의 출력값과 해당 입력값에 대한 training data의 실제 출력값의 차를 제곱하여 이용하는 방법이에요.그렇다면 우리는 a, b를 어떻게 구할 수 있을까요? 이 방법을 산을 내려가는 예시를 통해서 쉽게 이해할 수 있었어요.만약 깜깜한 밤에 산꼭대기에서 길을 잃었다면 랜턴을 키고 주변을 살펴본 후 아래로 내려가는 길을 찾아 그 방향으로 내려가고, 도달한 지점에서 또다시 랜턴을 켜 주변을 살펴 아래로 향하는 길로 가야 산 아래까지 내려갈 수 있겠죠. 이것이 최적의 a, b를 구하는 Gradient descent의 기본 방식이에요.Gradient descent는 임의의 a, b를 지정한 후, 그 점으로부터 감소하는 기울기를 구간을 찾아 이동하는 것을 반복함으로써 해를 구하는 방법입니다!이번 주 수업의 과제로는 Loss Function과 Linear Regression을 구하는 과제가 주어졌어요. 첫 번째 과제인 만큼 난이도가 많이 높지는 않았지만 파이썬이 익숙하지 않다면 조금 헷갈릴 여지가 있는 문제였던 것 같아요. 강의를 해주신 주재걸 교수님께서는 첫 시간에 배운 개념들이 Linear regression에서 뿐만 아니라 인공지능, 머신 러닝, 딥러닝 분야에서 많이 쓰이기 때문에 첫 시간에 배운 것만 제대로 이해하고 가도 많은 것을 얻어 가는 것이라고 하셨어요. 위의 개념에 대해서 다른 자료들도 찾아보면서 공부하고, 다음 필기 노트로 만나요!#엘리스 #코딩교육 #교육기업 #기업문화 #조직문화 #서비스소개
조회수 855

Android 와 iOS에서 모바일 앱 삭제수 분석하기

앱 삭제수 분석이 중요한 이유모든 비즈니스에서 사용자 획득만큼 중요한 있다면, 기존의 고객들이 지속적으로 서비스/상품을 찾고 사용하도록 만드는 것입니다.특히, 모바일 앱 서비스의 경우 사용자가 손가락을 한번 움직이는 것만으로 스마트폰에서 앱을 삭제할 수 있기 때문에, 사용자 유지에 더욱 신경 써야 할 수 밖에 없습니다. 실제로 다수의 조사에서, 앱 설치 후 30일 내 90%가 넘는 사용자가 앱을 삭제하거나 사용하지 않는 것으로 나타났습니다. 만약 수백, 수천만원의 광고비를 들여 앱 설치수를 증가시켰는데, 대다수의 사용자가 한 달 뒤에 앱을 삭제한다면 앱 비즈니스 입장에서 큰 시간과 비용 낭비일 것입니다. (관련 포스팅: 앱재사용율(Retention)이 앱 설치수보다 중요한 이유)이 때문에 사용자가 지속적으로 앱을 사용하고 있는지 체크하고, 더 나아가 사용자가 우리 앱을 삭제하는 비율이 얼마나 되는지 파악해 해결방법을 찾는 것이 중요합니다.앱 삭제수를 분석하는 방법그렇다면 앱 삭제수는 어떻게 분석할 수 있을까요? 앱 삭제수 분석은 크게 Daily Ping Service 혹은 Silent Push Notification 방법으로 이루어집니다.와이즈트래커 분석 서비스의 경우, Android 는 Daily Ping Service 를 통해, iOS는 Silent Push Notification 방법으로 앱 삭제수 분석 데이터를 제공하고 있습니다. 아래 내용을 통해 와이즈트래커가 앱 삭제수를 분석하는 방법에 대해 자세하게 알아보도록 하겠습니다.ANDROID 앱 삭제수 분석 – DAILY PING SERVICEDaily Ping Service는 하루에 한번 앱에서 서버로 신호를 보내, 앱이 설치 되어있는지 삭제되었는지 분석하는 방법입니다. 각각의 사용자 앱은 고유의 식별코드를 가지고 있기 때문에, 특정 앱에서 신호가 오지 않는다면 해당 사용자는 앱을 삭제한 것으로 판단합니다.이러한 방법으로 앱 내 설치된 와이즈트래커 SDK는 하루에 한번 특정 시간에 서버로 알림을 보내고 서버에서는 알림이 오지 않은 사용자 앱들을 파악해, 앱 삭제수 데이터를 웹 대시보드로 보여줍니다. IOS 앱 삭제수 분석 – SILENT PUSH NOTIFICATIONSilent Push Notification이란 각 플랫폼의 푸시 메시지 전송 서버에 앱 사용자들에게 내용이 없는 (Silent) 푸시 메시지 전송을 요청해, 해당 서버로부터 앱을 삭제한 사용자에 대한 피드백을 받는 방식입니다.구체적으로, 와이즈트래커는 하루에 한번 Apple의 푸시메시지 전송 서버인 APNs (Apple Push Notification Service) 에게 앱 사용자들에게 Silent 푸시메시지를 전송하도록 요청합니다. 이 메시지는 내용이 없기 때문에 실제 사용자들에게는 팝업으로 나타나거나 보여지지 않습니다. Apple은 해당 메시지 전송 시, 앱을 삭제해 푸시 메시지를 받지 못한 디바이스들의 식별코드를 모아 와이즈트래커에 전달해줍니다. 이러한 정보를 바탕으로 와이즈트래커는 앱 삭제수 데이터를 파악해 보여줍니다. 앱 삭제수 분석의 정확성앱 삭제수 분석의 경우, 분석 방식의 특수성으로 인해 사용자가 앱을 삭제하지 않아도, 앱을 삭제한 것으로 처리되는 경우가 있습니다. 예를 들어, 와이즈트래커 SDK가 서버로 신호를 보내거나 APNs에 푸시메시지 전송을 요청한 시간에 해당 앱 사용자의 디바이스가 꺼져있거나, 네트워크 연결이 안되어 있다면 해당 사용자는 앱 삭제수에 포함됩니다.와이즈트래커는 앱 삭제수 분석의 정확성을 높이기 위해, 앱을 삭제한 것으로 간주된 사용자가 추후 지속적으로 사용하고 있는 것으로 파악될 경우, 기존 삭제수 데이터에 소급 적용해 업데이트 하고 있습니다.와이즈트래커 대시보드에서 앱 삭제수 파악하기실제 와이즈트래커 서비스에서 앱 삭제수는 다음과 같이 Retention 리포트에서 확인 가능합니다.각 날짜별로 앱을 설치한 사용자 그룹을 대상으로, 1일, 7일, 15일, 30일 뒤 앱 재사용수와 앱 삭제수를 Retention 리포트를 통해 한 눈에 파악할 수 있습니다. 위 서비스의 경우 앱 설치 하루 뒤에는 평균 47%, 30일 후에는 평균 67%의 앱 삭제율을 기록하고 있습니다.더 나아가 세그먼트 기능을 이용해 플랫폼, 성별, 연령대, 광고 채널 별로 나누어 앱 삭제수를 볼 수 있기 때문에, 어떤 특성의 그룹이 앱 삭제율이 높은지 파악할 수 있습니다.(페이스북 채널을 통해 앱을 설치한 사용자들의 앱 재사용/삭제수 리포트)또한 와이즈트래커는 앱 삭제 데이터를 더욱 가치 있게 활용할 수 있도록, 앱을 삭제한 사용자들을 타겟팅해 Re-acquisition 을 가능하게 하는 기능을 출시할 예정입니다.와이즈트래커의 앱 삭제수 분석 방법이나 앱 삭제수 리포트에 대해 더 궁금하신 분들은 [email protected]로 언제든 연락주세요! 앞으로도 와이즈트래커는 단순한 분석 데이터 제공을 넘어, 고객사가 데이터를 통해 인사이트를 얻고 지속적으로 성장하는데 도움이 되도록 노력하겠습니다. * WISETRACKER는 모바일 광고 성과 측정부터 In-app 이용자/컨텐츠 분석, 푸시메시지 최적화까지 지원하는 모바일 통합 분석/타겟팅 솔루션입니다. 와이즈트래커 솔루션의 무료체험을 원하실 경우 여기를 클릭해주세요.* WISETRACKER가 제공하는 무료 데이터 분석 컨설팅를 원하신다면 여기를 클릭해주세요.#와이즈트래커 #앱마케팅 #마케터 #인사이트 #성과분석 
조회수 786

제대로 물 마시는 법

나에겐 일년에 한번 꼭 치러야 하는 거사가 있다.바로 환절기 감기로 병원을 찾는 일이다.올해도 가을로 넘어가는 문턱에 걸려 병원을 찾아 진찰을 받았다."몸이 많이 무리를 했네요. 당분간은 쉬시면서 무리하지 마시고, 스트레스 많이 받지 마세요. 따뜻한 물 많이 드시구요"매 해 다른 병원에 가서 새로운 의사선생님을 만나지만 처방내용은 거의 비슷하다. 무리하지 말것 그리고 물 많이 마실 것. 물 많이 마시라는 처방은 나도하겠선생님 앞에서는 시키는 것은 뭐든 다하겠노라 약속하지만, 집에 돌아와서는 약먹는 것 마저도 거를 때가 많다. 하물며 물을 많이 마시라니. 하지만 올해는 병원을 나오며 나도 이참에 물을 한번 마셔볼까 하는 생각을 했는데, 그 계기는 올 여름 결혼한 동생 덕분이다.올 초, 결혼을 3개월 앞둔 동생이 다이어트를 하겠다고 호들갑을 떨며 물을 마시기 시작했다.평소 한방울의 물로 하루를 버텨내던 선인장같은 동생이 어느 순간부터 물을 찾았다. 아마도 다이어트 클리닉을 다녀온 다음이었던 것 같은데, 운동을 하지 않고도 살을 빼는 방법이라며 물을 마시기 시작한 것이다. 내심 얼마나 가겠냐고 생각했지만, 동생은 물통을 끼고 살았다. 도대체 물을 마시면 뭐가 좋은걸까. 동생은 두말 않고 나에게 링크 하나를 던져줬다."우리 몸은 진짜 배고픔과 가짜 배고픔을 구별하지 못한다"사람은 밥을 먹은 직후에도 갑자기 허기가 지는 느낌을 받는다. 단맛이나 자극적인 음식을 먹고 싶은 것이 가짜 배고픔의 예다. 가짜 배고픔은 영양분이 부족해 나타나는 진짜 배고픔과 달리 스트레스를 받을 때 세로토닌 수치가 떨어지기 때문에 나타난다. 이 세로토닌 분비를 다시 늘리기 위해 뇌가 몸에게 당을 더 섭취 하도록 만드는 것이다. 결국 '스트레스를 받았어' 라는 신호를 '난 배고파' 라는 신호로 해석하는 것이 가짜 배고픔의 골자다.이런 실수에서 벗어나는 좋은 판별법이 물마시기라고 한다. 물을 마시고 20분이 지나도 식사를 하고 싶다면 음식을 적정량 섭취해주면 되고, 그렇지 않다면 가짜 배고픔이었으니 물로 넘기면 된다는 것이다. 과연 그 이론적인 내용만큼 효과도 있을까? 나는 이후 여동생을 유심히 살펴봤다. 동생에게 나타난 첫번째 변화는 간식먹는 양의 감소였다. 주말이면 집에 있는 과자나 빵을 누가 다 먹었느냐며 서로를 의심했는데, 올 초에는 집안에 늘 간식이 풍족한 상태가 유지되었다. 이것도 일종의 가짜 배고픔이었는지, 간식이 풍족해지니 나도 평소보다 오히려 과자를 찾는 양이 줄었다. (물마시기의 간적적 수혜를 입은 셈이다) 대신 집 냉장고에 몇통씩 자리를 차지하던 물들이 점점 줄어갔는데, 심할 때는 어머니께서 하루에 한번 보리차를 끓이기도 하셨다. 물 마시기를 하고 2-3주가 지난 시점부터는 동생의 체형도 조금씩 변하는 것 같았다. 매주 몇킬로씩 빠졌다며 자랑처럼 이야기를 하던데, 숫자도 숫자지만 한 눈에도 팔이나 다리 살이 많이 빠진 것이 눈에 들어왔다. 누가 알겠냐마는 3개월 동안 6kg 을 빼서 지금은 50kg 초반이라고 한다.하지만 동생이 진짜 입이 마르게 자랑하는 물마시기의 장점이 있었으니, 그것은 바로 화장이 잘 먹는다는 것이었다. 자기는 여름에도 수분크림을 한통씩 써야하는 건성피부인데, 물마시기 하고 나서는 피부가 촉촉하고, 당기는 느낌도 예전보다 덜하다고 했다. 동생은 피부과 열심히 다닐 때보다도 피부 상태가 훨씬 좋아졌다며 이것만큼은 물마시기 효과가 분명하다고 만나는 사람마다 이야기를 하고 다녔다. 결혼 준비를 하면서 다이어트 클리닉은 빠지지 않고 가던데, 피부과 가겠다는 이야기는 안했던 것을 보면 확실히 효과가 있긴 있었지 싶다. 동생이 물마시기로 톡톡한 효과를 보는 것을 바로 옆에서 봤기에, 매년 흘려들었던 의사선생님의 '물마시라'는 조언이 이번에는 마음에 걸렸다. 그래서 병원을 다녀온 날 (9/21 금) 부터 하루 2L 물마시기를 시작했다. 의식적으로 물을 마시기 시작했다물마시기를 하니 확실히 간식을 줄일 수 있었다. 입이 심심할 때면 으레 쵸콜렛이나 과자를 찾았는데, 지금은 배가 불러서 음식이 땡기지 않는다. 그래서인가 확실히 컨디션도 좋아지는 것 같고 덜 피곤한 것 같은 느낌을 받았다. 그런데 문제는 물마시기를 자꾸 까먹는다는 것이었다. 처음 3일은 250ml 컵으로 하루 6잔을 즐거운 마음으로 마셨는데, 그 다음주는 하루 평균 2-3잔을 마시게 되었다. 어떻게 하면 물을 꾸준히 마실 수 있을까?동생이 나름의 노하우 두가지를 알려줬는데, 첫째는 밥먹고 잠자는 행동과 연결해서 규칙적으로 물을 마시는 방법이다. 먹는 약도 사실 '식후 30분이내' 에 먹어야 할 이유가 별로 없다고 한다. 다만 사람들의 약 복용률이 너무 낮아서 이를 개선할 의도로 '밥먹는 행동' 과 연결을 시킨 것이다. 밥먹는 것만큼 하루에 규칙적으로 까먹지 않고 하는 행동이 없으니 그야말로 창의력 넘치는 해결방법인 것이다. 어쨋든 동생의 이야기는 '밥먹기', '잠자기' 와 연결을 시켜서 물을 마시면 하루 5잔은 꼭 마실 수 있다고 했다. 잠에서 깨서 한잔, 자기 전에 한잔. 그리고 매 끼 식사전 30분-1시간 전에 한잔씩. 그리고 추가적으로 생각날 때 한두잔을 더 마시면 2L 를 빼놓지 않고 먹을 수 있다.물마시기 알람을 설정해두는 것도 방법이다또 한가지 방법은 아침 출근했을 때 책상에 2L 물을 준비해놓고 퇴근하기 전까지 물을 다 마시는 것이다. 나는 물 마시러 캔틴으로 가며 움직이기 위해 이 방법대신 알람을 선택했다. 하지만 같은 사무실에 근무하는 동료들 중에 아침 출근할 때 물을 떠오고 하루 종일 떠온 물을 나눠 마시는 것이 이제는 눈에 들어오기 시작했다. 어쨋든 해야 하는 일이 눈에 보이면 목표를 까먹을 일이 없다. 끝으로 물마시기와 관련해서 한가지 팁이 있다.우리가 보통 2L 의 물을 하루에 마셔야 하는 이유는 하루동안 몸에서 배출되는 2.5L 의 수분중 0.5L 를 음식 등을 통해서 얻고 있기 때문이다. 즉, 빠져 나가는 만큼 채우는 공식인데, 흔히 맥주와 차 그리고 커피를 마시면서 수분 보충을 했다고 생각들을 많이 한다. 하지만, 술이나 커피는 마시는 양보다 더 많은 양을 체내에서 빼내는 효과가 있다고 하니 사실상 마실수록 손해인 것이다. 그러니 잊지 말자. 물은 그냥 물이다. 바라건대 올 해 물마시기 습관을 꾸준히 이어가서, 내년 환절기에는 굳이 병원을 찾지 않아도 되면 좋겠다. by 건강에 관심많은 20대 직장인챌린저스, 확실한 목표달성 꾸준한 습관형성 앱www.chlngers.com
조회수 1090

스타트업, 그거 왜 하세요? (2)

지난 글에서는 개인적인 이유에서 스타트업을 만들고 운영하는 이유에 대해서 기록해 보았다. 그럼 나 좋자고 이런 일을  벌이는가?라는 질문이 생길  수밖에 없는데... 물론 이유가 그것 뿐만은 아니다.  회사 차원에서는 아래 정도의 이유가 있지 않을까 싶다.첫 번째로, Be A Game Chnager! 즉, Fragrance industry의 Game Changer가 되고 싶다.향수를 만드는 업체들은 대부분이 유명 luxury goods brand들이다. 본인들의 브랜드 이미지를 활용하여 향수를 판매하는 경우가 많고, 대단히 높은 마진을  가져간다. 그리고 그러한 상황들이 크게 변화한 경우는 없었다. 평화로운 industry이다.간간이 Niche perfumer 들 (e.g. 영국의 조 말론, 미국의 Le Labo 등등) 이 시장에 참전하기는 하였지만, 그들도 뭐 그다지 다를 것은 없었다. 이미 기존의 player들이 만들어 놓은 좋은 play ground를 굳이 깰 필요가 없었을 것으로 생각된다.물론 그러한 명품 브랜드들이 지금의 위치를 차지하기 위해서 엄청난 제품 개발을 위한 노력과, 마케팅 그리고 자금이 들어갔기 때문에 누릴 수 있는 고 마진 구조이다. 그것을 부정하는 것은 아니다. 하지만 그렇다고 해서 그렇게 쌓아 올린 것들이 평생 가게 된다면 인더스트리의 발전이라는 것은 그다지 없을 것으로 보인다.파펨은 Trendy, Speed, Reasonable Price라는 무기를 가지고 이러한 조금은 굳어버린 industry를 깨고 싶다는 욕심이 있다. ZARA, UNIQLO 등이 SPA라는 새로운 영역을 창출해 낸 것과 같이.... 자극이 필요하다. 그래야 더 발전할 것이라는 믿음이다.두 번째, 새로운 시도에 대한 가능성을 타진.유명하지 않은 향수를 온라인부터 판매하는 경우는 흔치 않다. 파펨이 온라인을 주요 채널로 생각하게 된 것은, 물론 내가 on-line channel에 어느 정도 노출이 된 것도 있었지만, 일단 기존의 off-line  channel들이 너무 비싸기 때문이었다. 40%의 수수료 라니...게다가 최근 몇몇 제품을 보면, 애초부터 가격 책정을 할 때, 판매할 가격이 아닌 어느 정도 할인을 했을 때 본인들의 수지 타산이 맞는지를 계산해보고, 아예 처음부터 그 할인율을 표시한 채, 제품을 출시하는  듯하다. 물론 이것도 하나의 마케팅 전략이겠지만, 새로운  시도라기보다는 기득권을 잘 활용하는 것으로만 보인다. 왜 본인들이 새로운 무기를 만들 생각을 하지 않을까? (아.. 물론 나도 이제 시작이다.)깨고 싶었다. 온라인 채널에서 판매하기 어렵다고 생각되는 상품을 온라인의 강점을 이용해 보란 듯이 잘 만들어 보고 싶었다. 물론 아직은 뭔가 그럴 듯한 결실을 보여주고 있지는 못하지만, 그러한 시도들이 향후에도 계속해서 나올 수 있도록 깰 수 있다는 것을 보여주고 싶다.세 번째, 진정한 평가에 대한 욕심..사실 지금까지 직장을 다니면서, 여러 가지 성과 평가를 경험해왔다. 하지만, 그것은 그 프로젝트에서 혹은 내 boss가 만족한 것이지 세상에서 나온 진짜  평가일까?라는 생각을 해본 적이 있었다.그럼 진짜 평가는 뭐라고 정의해 볼 수 있을까? 다른 사람이 소중하게 생각하는 무언가를 대가로 줄 수 있다면 그것이 칭찬이 아닐까? 스타트업을 하면서 돈을 번다는 것, 즉 고객이 돈을 지불한 다는 것은.. 어찌 보면 세상에서 가장 냉정한 평가라는 생각이다. 고객 입장에서 어렵게 벌어들인 돈을 의미 없는 곳에 쓰지는 않을 것이기 때문이다. (아닌 경우도 있긴 하다..)네 번째, 같은 목적을 향해 가는 사람들의 성장, 가깝게는 주변 인물 (나와 함께 이 회사를 운영하는..)의 여러 가지 측면에서의 성장을 이루었으면 좋겠다. 본인의 분야에 대한 성장, 문제를 해결하는 능력의 성장, 그리고 금전적인 자산의 성장 또한 물론 중요하다.조금 더 확장하면.. paffem이  나오기까지 함께 일하는 협력사들 (fragrance company, bottle manufacturer, 인쇄 업체 등등)이 조금 더 좋은 상황이 될 수 있게 도움을 줄 수 있으며,궁극적으로는 이 paffem이라는 서비스를 사용하는 고객들까지 확대할 수 있겠는데,  그분들은 이 서비스에 대한 반대급부(물론 돈이겠지)를 지불하고도 너무나도 만족스러운 경험을 하는... 가치가 있는  서비스이다!!라는 경험을 할 수 있게 하면 좋겠다.이러한 과정에서 부산물로써 "better world"가 될 수 있다면 좋겠으나, 인위적으로 마케팅을 위해서 혹은  마음속에서 진정으로 우러나오지 않는 무언가를 하면서, 파펨은 그런 것들을 달성하기 위한 회사 입니다 라는 위선을 떨고 싶은 마음은 없다.다섯 번째, 좀 더 다양한 세상을 만든다는 욕심?멋진 스타트업들은 많다. 내가 좋아하고 자주 이용하는 것들만 봐도.. 페이스 북, airb&b, Uber 등등 세상을 더욱 좋은 & 멋진 곳으로 만들어가는 스타트업들이 많다. 한정된 자원을 보다 효과적으로 사용하고, 세상이 만들어낸 혜택들을 보다 많은 사람들이 이용하며 즐길 수 있도록 도움을 주는 멋진 회사들!그런데 나는 조금 더 재미있는 세상을 만드는데 중점을 두고 싶다.파펨의 중/장기 비전은.. "향의  객관화"이다. 코딩을 할 때, color에 대해서는 이미 전 세계적으로 통용되는 color code들이 있다. 하나의 코드를 말하면, 전 세계 모두가 동일한 색을 떠올린다. 이러한 표준을 만든 곳이 PANTONE 이라는 기업니다.하지만, 향은 아직 그런 과정을 거치지 못했는데, 너무나도 다양하기도 하고 개인에 따라 동일한 것도 다르게 느끼기도 쉽고, 인간이 주요 감각인 시각(~60%), 청각  (~20%)에 인간의 관심들이 많이 가 있었기 때문이다.파펨이 향의 객관화/표준화를 하는 회사가 되었으면 한다. 예를 들면,Pantone Fragrance 를 paffem이 만들어 가는 것이다.PANTONE이 색상을 측정하는 tool인 CAPSULA즉 객관적인 측정이 가능 하고 그런 후에, 그렇게 객관화된 향을 직접 만들어내는 machine(?)을 만들어 보고 싶다.  적용의 예를 들면, VR을 통해 시각과 청각적인 가상 체험을 하는 사람에게 후각적인 지원까지 하게 되는 것이다. 필요한 시점에 이 향을 뿌려주고, 저 향을 뿌려주는 것이 아니라, 스크린에 나타난 이미지를 인식하면 그 것의 향기를 자동으로 만들어 내고 뿜어주는 것이다. 엄청난 몰입감이 만들어 질 것으로 생각된다.물론 아직은 나조차 과연 이게 실행될 수 있는  일인가?라는 것 조차 모르지만... 가고 싶고 가야 할 길이라는 생각을 하고 있다.마지막 덧. 내가 주커버그나 래리 페이지 같이 이 세상을 크게 변화시킬 만한 회사를 만들고 운영할 능력이 없기도 하거니와.. 그런 회사를 만들어서 (본인들은 행복하겠지만) 죽어라 일하기도 싫다. 조금 웃기게 어처구니 없게 들리겠지만.. 그게 사실이다. ㅡㅡ;;;Image Source : www.pantone.com#파펨 #스타트업 #창업가 #창업자 #마인드셋 #인사이트
조회수 1214

스타트업에 다니는 아빠

스타트업에 다니는 두 아이의 아빠인 나의 하루 일과를 소개해 본다. (광화문으로 이사 오기 전 사당 버전이다)7시첫째가 깨워 준다. 최근 첫째는 아빠가 아침을 준비하는 동안 TV를 조금이라도 보기 위해 빨리 일어난다. 아내와 함께 두 아이의 아침을 먹이고 어린이집 등원 준비를 시킨다. 9시집에서 출발해서 회사로 향한다. 조금 여유 있게 집에서 나오면 일부러 5분 정도 더 걸리지만 환승이 없는 2호선을 탄다. 자리에 앉게 되면 노트북을 꺼내 오늘 해야 할 일을 정리한다.10시 매일 10시부터 팀의 데일리 미팅이 있다. 항상 오늘의 나의 목표를 이야기 하지만 말한 만큼을 완료하는 날은 흔치 않다. 늘 욕심은 앞서고 할 일은 넘친다.12시입사 후 한 달은 회사에 계신 분들과 친해지기 위해 나가서 점심을 먹었다. 그 이후 한참 동안은 시간이 부족해서 점심을 근처 편의점에서 사 먹었었다. 식사를 마치면 바로 일을 한다. 20시 아내에게 8시 30분까지 간다고 이야기해놓고, 일을 하다 보면 항상 시간이 빠듯해진다. 같이 논의를 하다가 혹은 같이 디버깅을 하다가도 12시를 넘긴 신데렐라처럼 빠져나오게 된다. 10번 중에 8번은 뛰어서 퇴근을 한다.  물론 회사에서 집까지 뛰어다닌 것은 아니고 지하철역과 회사 사이를 그리고 지하철역에서 집 사이를 뛰어다닌다. 퇴근하는 지하철에서는 테더링을 해두고 회사에서 하던 일을 보통 이어서 한다. 많은 사람들이 회사에 남아 일을 하고 있기 때문에 슬랙으로 대화를 이어가고, 마무리 못한 코드를 정리하기도 한다.20시 30분 간단하게 저녁을 먹고 아이들 목욕을 시킨다. 첫째를 목욕시키면서 나도 같이 목욕을 한다. 그러면 30분 뒤에 아내는 둘째를 재우러 들어간다. 평일에는 아내와 거의 대화할 시간이 없다. 둘째는 목욕하는 시간과 출퇴근할 때 한 번씩 안아주는 것을 제외하면 평일에는 거의 놀아주지 못한다. 미안한 마음이다. 21시 첫째와 놀아준다. 자동차 놀이를 할 때도 있고 책을 읽어 줄 때도 있다. 이제 말도 꽤 늘어서 대화하는 재미가 있다. 하지만 놀아주는 동안에도 슬랙을 확인하지 않으면 불안하다. 중간중간 확인을 하고 답을 한다. 22시 첫째와 같이 잠자리에 든다. 보통 20분 정도면 잠이 든다. 아들이 잠든 것 같으면 빛이 새어나가지 않도록 이불을 덮어쓰고 웹툰을 보거나 페북을 하며 10분 정도를 논다. 푹 잠든 것 같으면 슬그머니 잠자리에서 빠져나온다. 간혹 빨리 나오려다가 아들에게 “아빠. 어디가?” 라며 걸리는 경우도 있다. 그 전날 늦게 까지 일을 하거나 공부를 한 경우에는 첫째보다 먼저 잠드는 경우도 있다. 22시 30분간단한 집안일을 한다. 거실 정리를 간단하게 해두고 국을 끓이거나 한 그릇 요리들을 준비한다. 23시 드디어 나만의 시간이다. 회사에 급한일이 있거나 테스트해봐야 할 아이디어가 있는 경우 회사일을 한다. 보통은 그렇다. 그렇지 않으면 공부를 하거나 글을 쓴다. 대부분 컴퓨터를 쓰게 되기 때문에 슬랙을 통해서 회사 업무에 대한 의견을 내거나 회사 사람들과 시답잖은 채팅을 하기도 한다.1시 보통 1시에서 2시 사이에 잠자리에 든다. 이런 식의 생활을 8퍼센트에 입사한 후 6개월째 이어오고 있다. 이 일과에서 벗어난 것은 회사 회식을 포함하고도 손꼽을 정도다. 개인적인 약속은 단 한 번도 잡지 않았다. 모임에 초청해 주는 친구들에게 미안한 마음이다. 회사 동료들과도 따로 술자리를 만들어 많은 이야기들을 나누고 싶은데, 그런 기회 또한 거의 없었다.큰 빈틈없이 팍팍하게 살아간다.  CTO와 가장 양쪽 모두에 내가 만족하지 못하니 삶에 여유가 부족할 수밖에 없다. 특히 입사 초반에는 회사 내에서 나를 증명해 내야 한다는 압박감에 시달려서 잠을 줄였었다.(회사에서 준비해준 아빠와 아들의 커플 티셔츠)내 마음의 많은 부분이 회사에 가있다 보니 가족들에게 항상 미안한 마음이다. 상대적으로 안정적이고 대우도 좋았고 가족과 함께 하는 시간도 많았던 전 직장을 떠나서 내게 많은 곳을 요구하는 곳으로 옮겨 왔다. 이 결정이 나를 위한 것인가? 우리 가족을 위한 것인가?라고 묻는다면 나를 위한 선택이었다. 나의 행복을 위해 가족의 행복을 양보받았다. 아이들과 많은 시간을 함께 보내지 못하고 아이들과 함께 하는 시간에도 일이 머리에서 쉬이 떠나지 않는다. 그럼에도 불구하고 8퍼센트에 지금보다 더 많은 시간을 쓰고 싶다. 미혼이거나 자녀가 없는 경쟁자들은 더 많은 시간을 회사에 쏟고 있을 거다. 바쁜 일이 있으면 회사에서 자면서 일을 할 수도 있을 테고, 특별한 일이 없다면 주말에도 나와 일을 할 수도 있을 거다. 내가 결혼 전에 그랬던 것처럼. 그리고 내가 퇴근 한 이후에도 전우들은 회사에 남아서 열심히 일을 하고 있다. 나는 그들의 희생에 기대어 성공을 바라고 있는 것이 아닌가 하는 생각이 종종 든다. 스타트업이라는 선택을 한 만큼 그 선택을 옳게 만들기 위해서는 노력만이 남아 있다. 조금 더 불태워서 회사일을 하고 싶지만 시간의 분배 면에서 보면 지금 이 정도가 장기적으로 지속할 수 있는 최선이라고 생각한다. 앞으로 내가 할 수 있는 것은 질적인 개선이다. 순간순간에 최선을 다하자. 단 하나의 답이다.#8퍼센트 #에잇퍼센트 #스타트업 #가장 #CTO #워라밸 #워라벨 #워크라이프밸런스
조회수 2288

Dropwizard와 Asynchronous HBase 적용기

Background워크인사이트 서비스는 루비 온 레일즈 기반으로 작성된 웹 애플리케이션입니다. 주로 사용하는 데이터의 대부분은 HBase에 저장되어 있습니다. HBase는 자바로 작성된 API를 기본으로 제공하므로, 레일즈가 직접 HBase의 데이터에 접근할 수 없습니다. 따라서 데이터를 효과적으로 읽어들이기 위해서는 두 가지 방법 중 하나를 선택해야 합니다. 첫 번째는 HBase Java API를 이용하기 위해 웹 애플리케이션 역시 자바 기반의 프레임워크로 재작성하는 것이고, 두 번째는 HBase 스토리지 측 데이터 형식과 레일즈 웹서비스 측 데이터 형식을 서로 연결해주는 RPC 중개자를 도입하는 것입니다. 첫 번째 방법은 프로그래밍 언어를 통일함으로써 데이터 통신의 일관성은 물론 시스템 안정성이나 성능 측면에서 좀 더 낫다는 장점이 있는 반면에, 현재까지 작성한 레일즈 애플리케이션을 전부 자바 기반의 프레임워크로 재작성해야한다는 단점이 있습니다. 두 번째 방법은 보다 범용성을 지향하는 방식으로 향후 시스템의 확장에 좀 더 유용하지만, 첫 번째 방법보다 시스템 전체 성능은 뒤떨어진다는 단점을 갖고 있습니다.당시에는 이미 워크인사이트의 개발이 상당히 진척된 상태였기 때문에, 레일즈 프레임워크를 그대로 유지하면서 자바와 소통할 수 있는 JRuby를 사용하는 것이 최선인 것 같았습니다. 하지만 실험 결과 JRuby는 실 사용할 수 없을 정도의 성능을 냈습니다. 무엇보다도 레일즈 지원이 아직 미성숙한 상태였고, 사용중인 루비 젬 중에도 네이티브 C 구현 루비만 지원하는 젬이 상당 수 있었으며, 이러한 이유들로 인해 결국 JRuby는 대안에서 제외되었습니다. 루비 온 레일즈를 버리고 다른 자바 기반 프레임워크로 전면 재작성하기에는 너무 큰 소모비용과 위험요소가 있었기에 다른 방식을 고려하게 됩니다.그래서 조이는, 앞서 말한 크게 두 가지의 대안 중 두 번째, 범용 데이터 중개자를 도입하기로 결정하고, Thrift를 선택하기로 결정하였습니다. Thrift는 페이스북에서 처음 개발하였고, 현재는 아파치 재단에서 관리하고 있는 범용 RPC 프레임워크입니다. 비슷한 기능을 가진 다른 프레임워크로는 구글의 Protocol Buffer나 아파치 Avro등이 있습니다만, Thrift를 선택한 이유는 지원하는 프로그래밍 언어의 종류가 가장 다양하다는 것이었고, 워낙 많은 사용 사례가 있어 신뢰성이 검증되었다는 판단을 했기 때문입니다. Thrift는 그 규모에 걸맞게 다양한 플랫폼별 배포판을 지원하고 있으며, 조이는 현재 사용중인 하둡 시스템 관리용 Cloudera manager를 지원하는 배포판을 이용하여 디플로이하였습니다. 레일즈와의 연동도 thrift젬을 이용하여 손쉽게 할 수 있었습니다. 테스팅 결과도 문제 없었고, 이것으로 모든 것이 잘 돌아가는 줄 알았습니다.그림1. Thrift를 적용한 ZOYI Back-end SystemProblem워크인사이트는 런칭 이후 지금까지 가파른 성장세를 이어오고 있습니다. 서비스 초기에 느긋한 속도로 성장하던 적용 매장 증가 추세는, 2015년 현재 기하급수적으로 증가하는 상승곡선을 그리고 있으며, 그에 따른 시스템의 스케일 업 & 아웃 이슈도 매 달 새롭게 발생하고 있습니다.그림2. 오픈 이후 워크인사이트가 구동 중인 실제 매장 수문제없이 잘 굴러갈 것만 같았던 Thrift서비스 역시 조이의 성장세에 따라 점차 부하가 걸리기 시작했는데, 당초에 기대했던 범용 RPC 프레임워크가 보장하는 확장성과 동시성과는 조금 다른 성격의 문제가 발생하게 되었습니다. 시스템에 대규모 질의가 집중되는 시점에 병목 현상이 발생하고, 이것이 CPU와 메모리의 한도를 초과하면 그대로 다운되는 현상이었습니다. 특히 메모리 사용량이 복구되지 못하고 계속 쌓여만 가는 누수 현상이 치명적이었습니다. 게다가 이렇게 다운된 Thrift가 재시작된 경우, 레일즈와의 연결을 복구하지 못하는 현상도 비주기적으로 발생하였습니다.조이의 하둡 클러스터는 본래부터 확장성을 고려하여 설계되었기 때문에, Thrift에서 발생한 이러한 문제는 생소한 것이었습니다. 다각도에서 테스트를 해 봤지만, 처음에는 원인을 파악하기가 쉽지 않았습니다. 리부트된 클러스터도 자가 복구가 되지 않아, 개발팀이 직접 클라우데라 매니저를 주시하고 있다가 Thrift 서버의 다운 시점에 수동으로 재시작을 해 줘야 하기도 했습니다. 데이터 변환 프로토콜의 문제인지 검토해 보았으나, Thrift 프로토콜이 갖는 본질적 결함은 더더욱 아니었습니다. 자바 언어가 갖고 있는 내재적 결함도 아니었습니다. HBase가 제공하는 자바 API의 문제도 아니었습니다.하지만 심도 있는 검증 과정을 통해, Thrift의 가비지 컬렉션이 제대로 작동하지 않는 문제를 발견하였고, 이는 단순히 Thrift의 최적화의 문제가 아니라는 결론에 이르렀습니다.Dropwizard그렇게 고심하던 개발팀은, 2014년의 워크인사이트 첫 런칭 시점으로 되돌아가서 생각해보기로 합니다. 당시의 조이가 먼저 생각했던 방식은 JVM 기반의 프레임워크였는데, 자바를 이용하여 서비스 레벨도 구현하면 Thrift에서의 데이터 변환 과정에서 야기되는 문제를 원천적으로 방지할 수 있음에 다시금 주목하게 되었습니다. 많은 프로그래밍 언어간의 데이터 통신을 위해 설계된 Thrift는 사실 레일즈와 자바로 균일하게 구축된 조이 시스템에는 필요 이상으로 무겁고 큰 프레임워크였습니다. 조이가 겪은 이런 Thrift의 문제를, 해외의 여러 기업들도 경험하였고 각기 다른 방법으로 최적화를 진행한 것도 알게 되었습니다. 이렇게 된 이상 바꿀 수 밖에 없었던 것입니다.그래서 다음 대안을 찾기 위해 많은 리서치와 스터디를 진행했습니다. 넘쳐나는 프레임워크들의 홍수 속에서 가볍고 안정적이며 구현이 편리한 프레임워크를 찾기란 쉽지 않았습니다만, 결국 Dropwizard라는 자바 프레임워크를 도입하기로 결정하게 됩니다. Dropwizard는 이미 잘 알려져 있는 Spring이나 Play 등과 같은 풀 스택 자바 프레임워크와는 다른, 경량 REST API 프레임워크입니다. Dropwizard는 모듈화가 잘 되어 있고, 숙성된 자바 생태계의 안정적인 라이브러리(Jetty, Jersey, Jackson)들을 사용하였으며, 모던 자바에 걸맞는 방식(리플렉션, 동시성 등)을 사용하기 쉽게 패키징되어있습니다. 국내에는 잘 알려지지 않았지만, 해외에서는 이미 Airbnb 등 유수의 스타트업들이 실제 서비스에 사용함으로써 그 유용성을 입증하고 있는 프레임워크입니다.그림3. Dropwizard로 새로 구성된 ZOYI Back-end System다만, 처음 사용하는 프레임워크에 조이의 모든 서비스를 포팅하는 것은 불가능에 가까웠고, 설령 하더라도 엄청난 리스크를 감당할 가치가 있는 지 의문이었습니다. 레일즈가 보장해주는 빠른 기능 구현과 쉬운 배포 및 강력한 ORM 등은 루비 온 레일즈가 주는 최대의 강점이기에, 이를 포기하기는 쉽지 않았습니다. 생산성과 성능, 어느 한 쪽도 놓치고 싶지 않았습니다.그래서 조이는 두 마리 토끼를 다 잡아 보기로 결정합니다. 레일즈의 장점을 유지하면서, Dropwizard의 최대 장점인 HBase 데이터 접근의 유연성도 살릴 수 있는 방법을 찾기로 하였고, 결론적으로 Dropwizard는 기존의 Thrift가 담당하던 데이터 중개자의 역할만을 수행하게 되었습니다. Dropwizard의 잘 나뉘어진 모듈화는 이를 가능하게 해 주었습니다. 모든 모듈을 사용하면 풀 스택 프레임워크에 버금가는 규모의 시스템도 구축할 수 있지만, 필요한 것만 선택하여 사용하면 가볍고 빠르게 작동하는 미들웨어 역할도 가능한 것입니다.Asynchronous HBase, and Java 8Dropwizard가 HBase 연결에 사용한 클라이언트 모듈은 AsyncHBase입니다. Asynchronous HBase는, 타임스탬프 기반 데이터베이스인 OpenTSDB를 만든 팀이 자신들의 제품에 HBase를 연동하기 위해 기존의 HBase 클라이언트인 HTable을 대체하는 모듈을 재작성한 것으로, 완전한 비동기 방식과 넌블록킹 및 스레드 안전성 보장이 강점이라 할 수 있습니다. AsyncHBase와 Dropwizard를 연동하는 것은 매우 수월했습니다. 테스트 결과, 간결한 코드로도 초당 수 만 단위의 동시성을 안정적으로 처리할 수 있음을 검증했습니다. 조이는 OpenTSDB를 실시간 데이터 분석에 사용하고 있어, 해당 팀이 제공하는 제품의 품질과 전망에 대해 신뢰를 갖고 있었습니다. 테스트 결과는 이 신뢰를 더욱 뒷받침해주었고, 본 모듈을 Dropwizard의 HBase 연결 모듈로 선정하게 되었습니다.또한, Dropwizard와 AsyncHBase의 도입과 함께 처음으로 자바 버전 8로의 이식도 진행하게 되었습니다. 자바 8은 람다와 스트림 등 함수형 프로그래밍의 여러 기법을 대거 도입하였고, 자바 특유의 장황한 문법을 조금 더 간결하게 축약할 수 있는 장점이 있습니다. Dropwizard와 AsyncHBase 모두 자바 8과 순조롭게 연동되었으며, 이 결과에 만족한 조이는 기존의 하둡 맵 리듀스 프로젝트 역시 자바 8로 버전업하기로 결정하였습니다.PerformanceDropwizard의 성능 테스트 결과는 만족스러웠습니다. AsyncBase도 기대를 저버리지 않는 결과를 보여 주었습니다. HBase Java API와의 매끄러운 연동은, 성능 측면에서 기존과는 비교할 수 없을 정도의 향상을 보여주었고, 이 덕분에 기존 맵 리듀스 워크플로우 중 일부를 실시간 처리로 옮겨, 좀 더 유연하고 동적인 분석이 가능하게 되었습니다.다음의 비교는 Thrift와 Dropwizard의 각각의 벤치마크 테스트를 100개 동시 작업, 단위당 10000개의 요청으로 수행한 경우의 결과를 나타낸 것입니다.그림4. Thrift 테스트 시의 메모리 사용량Concurrency Level: 100 Time taken for tests: 514.315 seconds Complete requests: 10000 Failed requests: 0 Total transferred: 32090000 bytes HTML transferred: 27600000 bytes Requests per second: 19.44 [#/sec] (mean) Time per request: 5143.151 [ms] (mean) Time per request: 51.432 [ms] (mean, across all concurrent requests) Transfer rate: 60.93 [Kbytes/sec] received Thrift 벤치마크 결과. 전체 수행에 514초가 걸렸습니다.그림5. Dropwizard 테스트 시의 메모리 사용량Concurrency Level: 100 Time taken for tests: 4.599 seconds Complete requests: 10000 Failed requests: 121 (Connect: 0, Receive: 0, Length: 121, Exceptions: 0) Non-2xx responses: 121 Total transferred: 23288000 bytes HTML transferred: 21559452 bytes Requests per second: 2174.25 [#/sec] (mean) Time per request: 45.993 [ms] (mean) Time per request: 0.460 [ms] (mean, across all concurrent requests) Transfer rate: 4944.72 [Kbytes/sec] received Dropwizard 벤치마크 결과. 전체 수행에 4초가 걸렸습니다!그림6. 초당 처리량 (높을수록 좋음)벤치마크 테스팅 시 스레드 분산이 최적화 된 경우에는 최대 100배 이상의 속도 향상이 있었습니다. Dropwizard는 기존 Thrift에 비하여 성능 향상은 물론, 안정성 면에서도 시스템이 다운된 이후에 자동 복구되지 않는 현상도 사라졌습니다. 무엇보다도 짧은 코드만으로 대규모의 질의에도 견고하고 신속하게 반응하는 서비스를 구현할 수 있다는 점이 Dropwizard의 가장 큰 장점입니다.Conclusion유용한 오픈소스 프로젝트는 시장에 너무나도 많이 널려 있습니다. 이 중에 어떤 것을 선택하는가는 소프트웨어 기업에게 중요한 안건이며, 잘못된 결정은 프로젝트 자체는 물론 회사의 생사를 결정하기까지 합니다. 조이는 적합성, 성능, 안정성, 생산성 등 모든 면에서 조이의 서비스와 알맞는 제품을 찾으려고 항상 노력하고 있으며, 가능한 한 넓고 깊은 검증, 분석 및 연구를 통해 최적의 대안을 찾아내고 있습니다. 그 결과, 이번 Dropwizard와 Asynchronous HBase를 도입하여 기존의 Thrift를 대체하는 프로젝트는 예상보다 훨씬 좋은 성과를 낼 수 있었습니다. 국내에는 Dropwizard의 실무 사용기 등을 찾아보기 힘들고, 한글화된 문서 자체도 찾기 쉽지 않은데, 이 글이 앞으로의 선택을 고민하는 분들, 드롭위자드에 관심이 있는 분들께 도움이 될 수 있으면 좋겠습니다.#조이코퍼레이션 #개발팀 #개발자 #개발환경 #업무환경 #인사이트 #경험공유
조회수 4106

서버 비용을 70%나 줄인 온디맨드 리사이징 이야기

비트윈의 서버에는 사용자들이 올리는 수많은 사진이 저장되어 있습니다. 2016년 3월 기준으로 커플들이 데이트에서 찍은 사진, 각자의 프로필 사진, 채팅을 나누며 올린 재미있는 짤방까지 약 11억 장의 사진이 저장되어 있습니다. 비트윈에서는 이러한 사용자들의 소중한 추억을 잘 보관하고, 사용자들의 요청을 빠르고 비용 효율적으로 처리하기 위해서 많은 노력을 기울이고 있습니다. 이번 포스팅에서는 비트윈 개발팀이 사용자들의 사진 처리를 보다 효율적으로 하기 위해서 어떠한 노력을 하였는지 공유하고자 합니다.기존의 아키텍쳐¶비트윈 사용자가 채팅창이나 모멘츠 탭에서 사진을 업로드 할 경우, 해당 사진은 업로더 서버라고 불리는 전 세계 각지에 퍼져 있는 사진 업로드 전용 서버 중 가장 가까운 서버를 자동으로 찾아서 업로드 됩니다. 업로더 서버는 사진을 해당 AWS Region의 S3 bucket에 적재하고, 미리 지정된 크기의 썸네일을 자동으로 생성하여 역시 S3에 저장합니다. 그리고 Tokyo Region에 있는 비트윈 메인 서버에 이 결과를 토큰 형태로 전송하여 DB에 그 정보를 저장하도록 합니다. 이러한 과정을 통해서 일반 HTTP request보다 훨씬 큰 용량을 가지고 있는 사용자의 사진이 최대한 적은 지연시간을 가지고 업로드되도록 합니다.사용자가 올린 사진은 원본이 S3에 저장됨과 동시에 미리 정해진 사이즈로 썸네일을 생성해서 저장된다.하나의 사진이 대략 5장에서 6장의 서로 다른 크기의 썸네일로 리사이징이 되는데, 이는 클라이언트의 디스플레이 크기에 따라서 최적화된 이미지를 내려주기 위함이었습니다. 예를 들어서 아주 작은 썸네일이면 충분한 채팅 프로필 표시 화면을 그리기 위해서 사용자가 올린 3백만 픽셀이나 되는 원본 사진을 받아서 클라이언트가 리사이징 하는 것은 지연 시간뿐 아니라 과도한 데이터 사용이라는 측면에서 효율적이지 않기 때문에 작게 리사이징 해놓은 사진을 내려주는 것이 더 바람직합니다.비트윈 사용자들의 넘치는 사랑(?)에 비트윈은 출시 후 5년 동안 약 11억 장, 썸네일을 모두 합치면 66억 장의 사진을 저장하게 되었습니다. 이 사진은 전부 AWS S3에 저장되어 있으며, 썸네일을 합친 총 용량은 2016년 3월 기준 무려 738TB였습니다. 이에 따라 사진을 저장하기 위한 S3 비용이 전체 인프라 운영 비용에서 상당 부분을 차지하게 되었습니다.기존 아키텍쳐의 비효율성¶비트윈 팀은 어느 날 위와 같은 기존의 사진 전송 아키텍쳐에 의문을 가지게 되었습니다. 비트윈 서비스가 다른 서비스와 가장 다른 특징 중의 하나는 커플 간의 데이터는 그 둘 사이에서만 공유된다는 점입니다. 일반적인 웹사이트 같은 경우, 하나의 게시물 혹은 이미지가 수천 수 만명의 유저에게 전달되지만 비트윈에서는 그렇지 않습니다. 즉, 개별 사진의 Fan-out이 작다는 점을 특징으로 가지고 있습니다.그리고 클라이언트에서 LRU를 기반으로 한 파일 캐쉬를 사용하고 있는데, 이를 통해서 위에서 말씀드린 채팅창 프로필 사진 같은 경우 클라이언트에서 캐쉬될 가능성이 매우 커지게 됩니다. 그리고 CDN으로 사용하고 있는 AWS의 CloudFront에서도 약 30~40%의 추가적인 Cache hit을 얻을 수 있었습니다. 즉, 이미 Fan-out이 낮은 리소스가 높은 Cache hit rate를 가지는 사용패턴을 가지고 있는 셈이 됩니다.더군다나 사용자의 디바이스 사이즈에 따라서 미리 리사이징 해놓은 썸네일 중 일부는 아예 사용하지 않는 사용패턴이 나타나기도 합니다. 아이패드와 같은 큰 디스플레이를 가진 클라이언트를 쓰는 사용자와 아이폰4를 사용하는 사용자가 필요로 하는 썸네일의 크기는 다를 수밖에 없기 때문입니다.아래의 그래프는 S3 접근 로그를 분석해서 파악한 특정 기간 내에 같은 해상도를 가지는 썸네일을 클라이언트가 한 번 이상 재요청 하는 비율을 나타내는 그래프입니다. 하루 내에 같은 해상도의 사진을 요청하는 경우는 10% 가 되지 않으며, 한 달 안에도 33% 정도에 불과한 것을 알 수 있습니다.특정 기간 내에 S3에 저장된 썸네일이 다시 요청되는 비율결국 비트윈 팀은 미리 여러 해상도의 썸네일을 준비해서 저장해 놓은 아키텍쳐보다는 사용자가 요청할 때 그 요청에 알맞게 리사이징된 썸네일을 새로 생성해서 내려주는 게 훨씬 비용 효율적이라는 결론에 도달하게 됩니다.새로운 아키텍쳐¶Skia¶하지만 이러한 온디맨드-리사이징 아키텍쳐로의 변환에 가장 큰 걸림돌이 있었습니다. 바로 사진의 리사이징에 오랜 시간이 걸린다는 점이었습니다. 비록 아키텍쳐 변화를 통해서 저희가 얻을 수 있는 비용 이득이 크더라도, 비트윈 사용자 경험에 느린 사진 리사이징이 방해가 되어서는 안 되었습니다.이때 저희가 찾은 것이 바로 Skia 라이브러리였습니다. Skia 라이브러리는 Google에 의해서 만들어진 2D 그래픽 라이브러리로써, 크롬이나 안드로이드, 모질라 파이어폭스 등에 사용되고 있었습니다. 그리고 이 라이브러리는 CPU 아키텍쳐에 따라서 인스트럭션 레벨로 매우 잘 최적화가 되어 있었습니다. 저희가 기존에 쓰고 있던 ImageMagicK에 비해서 거의 4배 속도로 이미지 리사이징을 처리할 수 있었으며, 총 CPU 사용량도 더 적었습니다. 저희는 이 라이브러리를 Python으로 wrapping한 PySkia라는 라이브러리를 내부적으로 만들어서 사진 리사이징에 사용하기로 하였습니다.WebP¶저희는 여기서 한발 더 나아가 보기로 했습니다. 단순히 리사이징만 Skia로 대체하는 것이 아니라, 원본 사진의 저장도 더 효율적으로 할 방법을 찾게 되었습니다. 그 결과 자연스럽게 떠오른 것이 비트윈 스티커 시스템에서 사용되었던 WebP 방식이었습니다. WebP 역시 구글이 만든 이미지 인코딩 방식으로써, 비슷한 화질을 가지는 JPEG에 비해서 약 26% 정도의 용량이 절약된다는 점에서 장점이 있습니다.온디멘드-리사이징¶위에서 언급한 대로 Skia 리사이징과 WebP 원본 저장을 합하여 아래와 같이 필요한 해상도의 사진을 그때그때 리사이징 하는 온디멘드-리사이징 아키텍쳐로 옮겨가게 되었습니다.사용자가 올린 사진은 원본이 WebP로 변환되어 S3에 저장된다. 클라이언트의 요청이 있을 때는 그때그때 요청한 사이즈로 리사이징한 썸네일을 생성해서 내려준다.리사이저 서버가 사용자의 요청을 받아서 원하는 해상도의 사진을 리사이징해서 내려주기까지 채 100ms가 걸리지 않는데, 이 정도면 사용자의 경험에 영향을 주지 않는다고 판단하였습니다. 리사이저 서버는 업로더 서버와 함께 세계 각지의 AWS Region에 배포되어 있으며, 이는 사용자가 요청한 사진을 최대한 빨리 받아가기 위함입니다.기존 사진 마이그레이션¶위와 같은 아키텍쳐 전환을 통해서 새롭게 업로드 되는 사진들은 원본만 WebP로 변환되어 저장한 후 요청이 들어올 때만 온디멘드 리사이징이 되지만, 그동안 비트윈 사용자들이 축적해 놓은 11억 장의 사진은 여전히 여러 사이즈의 썸네일로 미리 리사이징이 되어 있는 비효율적인 상태였습니다. 저희는 이 사진들도 마이그레이션하는 작업에 착수했습니다.11억 장이나 되는 원본 사진들을 전부 WebP로 변환하고, 나머지 50억 장의 미리 생성된 썸네일 사진을 지우는 작업은 결코 간단한 작업이 아니었습니다. 저희는 이 작업을 AWS의 Spot Instance와 SQS를 통해서 비용 효율적으로 진행할 수 있었습니다.Auto Scaling with Spot instance¶마이그레이션 작업은 크게 다섯 단계로 이루어져 있습니다.커플 단위로 작업을 쪼개서 SQS에 쌓아놓습니다.Worker가 SQS로부터 단위 작업을 받아와서, 해당 커플에 존재하는 모든 사진을 WebP로 변환하고 S3에 올립니다.S3로의 업로드가 확인되면, 그 변경 사항을 DB에 적습니다.기존 썸네일 사진들을 삭제합니다.기존 썸네일이 삭제되었다는 사실을 DB에 적습니다.작업을 하는 도중에 얼마든지 Worker가 중단되거나 같은 커플에 대한 작업이 두 번 중복되어서 이루어질 위험이 있습니다. 이를 위해서 마이그레이션 작업을 멱등적으로 구성하여서 사용자의 사진이 손실되는 등의 사고가 발생하지 않도록 하였습니다. 중간마다 DB에 접근해서 변경된 내용을 기록해야 하는 작업의 특성상, 작업의 병목 구간은 비트윈 DB였습니다. 그리고 사진 인코딩을 바꾸는 작업의 특징상 많은 CPU 자원이 소모될 것으로 생각하였습니다.DB에 부담이 가지 않는 범위내에서 많은 CPU 자원을 끌어와서 작업을 진행해야 할 필요성이 생긴 것입니다. 이 조건을 만족하게 하기 위해서 SQS를 바라보는 Worker들로 Auto-scaling group을 만들었습니다. 그리고 이 Auto-scaling group은 c3.2xlarge와 c3.4xlarge spot instance로 구성되어 있으며, DB의 CPU 사용량을 메트릭으로 하여 Scaling이 되도록 하였습니다. 작업은 주로 DB의 부하가 적은 새벽 시간에 집중적으로 이루어졌으며, 이 인코딩 작업은 대략 4일 정도가 소모되었습니다. 작업 과정에서 Tokyo Region에 있던 c4.2xlarge와 c3.4xlarge spot instance를 최대 140대를 사용했고, 총 사용 시간은 6,767시간이었습니다. 사용한 instance의 계산 능력을 ECU로 환산하면 총 303,933 ECU · hour를 작업에 사용하였습니다. 마이그레이션에 사용된 EC2 비용을 바탕으로 계산해 보면, 백만 장의 WebP 인코딩을 위해서 사용한 비용이 $1.8 밖에 되지 않았다는 것을 알 수 있습니다.작업 과정에서 AWS 서비스에 의외의 병목 구간이 있다는 것을 알게 되었는데, S3 단일 버킷에 1분당 1천만 개 이상의 object에 대한 삭제 요청이 들어오면 Throttling이 걸린다는 사실과 SQS의 in-flight message의 개수가 12만 개를 넘을 수 없다는 것입니다.결과¶위의 아키텍쳐 변화와 마이그레이션 작업 후 저희의 S3 비용은 70%가 넘게 감소했으며 전체 인프라 비용의 상당 부분이 감소하였습니다. 온디멘드 리사이징으로의 아키텍쳐 변화는 Storage 비용과 Computation 비용 사이의 교환이라고 볼 수 있는데, 아래 그래프에서 볼 수 있듯이 확연한 비용 절감을 달성할 수 있었습니다.총 마이그레이션 비용¶항목사용량비용 ($)EC2 spot instance6,767 hrs1,959.11SQS188,204,10489.59S3 Put/Get Requests2,492,466,8605,608.34총비용7,657.04마이그레이션 결과¶항목Before MigrationAfter Migration감소량 (%)S3 # of objects6.65 B1.17 B82.40S3 storage738 TB184 TB75.06비용 감소¶사진 저장과 리사이징에 관련된 비용이 68% 감소하였음못다 한 이야기¶이번 포스팅에서는 최근에 있었던 비트윈 사진 아키텍쳐의 변화에 대해서 알아보았습니다. 주로 사용자의 경험을 방해하지 않는 조건에서 비용을 아끼는 부분에 중점을 두고 저희 비트윈의 아키텍쳐 변화에 대해서 설명해 드렸습니다. 하지만 이 글에서 미처 언급하지 못한 변화나 개선 사항들에 대해서는 다루지 못했습니다. Tokyo Region에서 멀리 떨어져 있는 사용자를 위해서 전 세계 여러 Region에 사진 저장/전송 서버를 배포하는 일이나, 사진을 로딩할 때 낮은 해상도로부터 차례대로 로딩되도록 하는 Progressive JPEG의 적용, 사진을 아직 받아오지 못했을 때 Placeholder 역할을 할 수 있는 사진의 대표색을 찾아내는 방법 등이 그것입니다. 이에 관해서는 후에 자세히 다뤄보도록 하겠습니다.정리¶비트윈 개발팀에서는 많은 인프라 비용을 소모하는 기존 썸네일 저장 방식을 개선하여 70%에 가까운 비용 절감 효과를 보았습니다. 기존의 썸네일을 미리 생성해놓는 방식으로부터 클라이언트가 요청할 때 해당 크기의 썸네일을 리사이징해서 내려주는 방식으로 변경하였고, WebP와 Skia등의 새로운 기술을 적용하였습니다. 이를 통해서 사용자 경험에는 거의 영향을 주지 않은 상태로 비용 절감 효과를 볼 수 있었습니다.저희는 언제나 타다 및 비트윈 서비스를 함께 만들며 기술적인 문제를 함께 풀어나갈 능력있는 개발자를 모시고 있습니다. 언제든 부담없이 [email protected]로 이메일을 주시기 바랍니다!
조회수 1203

AWS Batch 사용하기

OverviewAWS Batch는 배치 컴퓨팅 작업을 효율적으로 실행할 수 있게 도와줍니다. 배치 작업량과 리소스 요청을 기반으로 최적의 리소스 수량 및 인스턴스 유형을 동적으로 프로비져닝합니다. AWS Batch에서는 별도의 관리가 필요 없기 때문에 문제 해결에 집중할 수 있습니다. 별도의 추가 비용은 없습니다. 배치 작업을 저장 또는 실행할 목적으로 생성된 AWS 리소스(인스턴스 등)에 대해서만 비용을 지불하면 됩니다. 이번 포스팅에서는 간단한 튜토리얼로 AWS Batch 사용 방법을 크게 11개의 Step으로 알아보겠습니다. 이렇게 진행하겠습니다.AWS에서 제공하는 Dockerfile, fetch&run 스크립트 및 myjob.sh 다운로드Dockerfile를 이용하여 fetch&run 스크립트를 포함한 Docker 이미지 생성생성된 Docker 이미지를 ECR(Amazon Elastic Container Registry)로 푸쉬간단한 샘플 스크립트(myjob.sh)를 S3에 업로드IAM에 S3를 접속 할 수 있는 ECS Task role 등록Compute environments 생성Job queues 생성ECR을 이용하여 Job definition 생성Submit job을 통해 S3에 저장된 작업 스크립트(myjob.sh)를 실행하기결과 확인 STEP1. AWS에서 제공하는 Dockerfile, fetch&run 스크립트 및 myjob.sh 다운로드AWS Batch helpers페이지에 접속합니다.    2. /fetch-and-run/에서 Dockerfile, fetchandrun.sh, myjob.sh 다운로드합니다.STEP2. Dockerfile을 이용하여 fetch&run 스크립트를 포함한 Docker 이미지 생성Dockerfile을 이용해서 Docker 이미지를 빌드합니다.잠시 Dockerfile의 내용을 살펴보겠습니다.FROM amazonlinux:latestDocker 공식 Repository에 있는 amazonlinux 의 lastest 버젼으로 빌드RUN yum -y install which unzip aws-cliRUN을 통해 이미지 빌드 시에 yum -y install which unzip aws-cli를 실행ADD fetch_and_run.sh /usr/local/bin/fetch_and_run.shADD를 통해 Dockerfile과 같은 디렉토리에 있는 fetch_and_run.sh를 /usr/local/bin/fetch_and_run.sh에 복사 WORKDIR /tmp컨테이너가 동작할 때 /tmp를 기본 디렉토리로 설정USER nobody컨테이너 실행 시 기본 유저 설정 ENTRYPOINT [“/usr/local/bin/fetch_and_run.sh”]컨테이너 실행 시 /usr/local/bin/fetch_and_run.sh를 call shell에 docker 명령을 통해 이미지 생성shell : docker build -t fetch_and_run . 실행하면 아래와 같은 결과가 출력됩니다.[ec2-user@AWS_BRANDI_STG fetch-and-run]$ docker build -t fetch_and_run . Sending build context to Docker daemon 8.192kB Step 1/6 : FROM amazonlinux:latest latest: Pulling from library/amazonlinux 4b92325dc37b: Pull complete Digest: sha256:9ee13e494b762db41b9db92a200f6784b78da5ac3b0f974fb1c38feb7f636474 Status: Downloaded newer image for amazonlinux:latest ---> 81bb3e78db3d Step 2/6 : RUN yum -y install which unzip aws-cli ---> Running in 1f5293a2294d Loaded plugins: ovl, priorities Resolving Dependencies --> Running transaction check ---> Package aws-cli.noarch 0:1.14.9-1.48.amzn1 will be installed --> Processing Dependency: python27-jmespath = 0.9.2 for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: python27-botocore = 1.8.13 for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: python27-rsa >= 3.1.2-4.7 for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: python27-futures >= 2.2.0 for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: python27-docutils >= 0.10 for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: python27-colorama >= 0.2.5 for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: python27-PyYAML >= 3.10 for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: groff for package: aws-cli-1.14.9-1.48.amzn1.noarch --> Processing Dependency: /etc/mime.types for package: aws-cli-1.14.9-1.48.amzn1.noarch ---> Package unzip.x86_64 0:6.0-4.10.amzn1 will be installed ---> Package which.x86_64 0:2.19-6.10.amzn1 will be installed --> Running transaction check ---> Package groff.x86_64 0:1.22.2-8.11.amzn1 will be installed --> Processing Dependency: groff-base = 1.22.2-8.11.amzn1 for package: groff-1.22.2-8.11.amzn1.x86_64 ---> Package mailcap.noarch 0:2.1.31-2.7.amzn1 will be installed ---> Package python27-PyYAML.x86_64 0:3.10-3.10.amzn1 will be installed --> Processing Dependency: libyaml-0.so.2()(64bit) for package: python27-PyYAML-3.10-3.10.amzn1.x86_64 ---> Package python27-botocore.noarch 0:1.8.13-1.66.amzn1 will be installed --> Processing Dependency: python27-dateutil >= 2.1 for package: python27-botocore-1.8.13-1.66.amzn1.noarch ---> Package python27-colorama.noarch 0:0.2.5-1.7.amzn1 will be installed ---> Package python27-docutils.noarch 0:0.11-1.15.amzn1 will be installed --> Processing Dependency: python27-imaging for package: python27-docutils-0.11-1.15.amzn1.noarch ---> Package python27-futures.noarch 0:3.0.3-1.3.amzn1 will be installed ---> Package python27-jmespath.noarch 0:0.9.2-1.12.amzn1 will be installed --> Processing Dependency: python27-ply >= 3.4 for package: python27-jmespath-0.9.2-1.12.amzn1.noarch ---> Package python27-rsa.noarch 0:3.4.1-1.8.amzn1 will be installed --> Processing Dependency: python27-pyasn1 >= 0.1.3 for package: python27-rsa-3.4.1-1.8.amzn1.noarch --> Processing Dependency: python27-setuptools for package: python27-rsa-3.4.1-1.8.amzn1.noarch --> Running transaction check ---> Package groff-base.x86_64 0:1.22.2-8.11.amzn1 will be installed ---> Package libyaml.x86_64 0:0.1.6-6.7.amzn1 will be installed ---> Package python27-dateutil.noarch 0:2.1-1.3.amzn1 will be installed --> Processing Dependency: python27-six for package: python27-dateutil-2.1-1.3.amzn1.noarch ---> Package python27-imaging.x86_64 0:1.1.6-19.9.amzn1 will be installed --> Processing Dependency: libjpeg.so.62(LIBJPEG_6.2)(64bit) for package: python27-imaging-1.1.6-19.9.amzn1.x86_64 --> Processing Dependency: libjpeg.so.62()(64bit) for package: python27-imaging-1.1.6-19.9.amzn1.x86_64 --> Processing Dependency: libfreetype.so.6()(64bit) for package: python27-imaging-1.1.6-19.9.amzn1.x86_64 ---> Package python27-ply.noarch 0:3.4-3.12.amzn1 will be installed ---> Package python27-pyasn1.noarch 0:0.1.7-2.9.amzn1 will be installed ---> Package python27-setuptools.noarch 0:36.2.7-1.33.amzn1 will be installed --> Processing Dependency: python27-backports-ssl_match_hostname for package: python27-setuptools-36.2.7-1.33.amzn1.noarch --> Running transaction check ---> Package freetype.x86_64 0:2.3.11-15.14.amzn1 will be installed ---> Package libjpeg-turbo.x86_64 0:1.2.90-5.14.amzn1 will be installed ---> Package python27-backports-ssl_match_hostname.noarch 0:3.4.0.2-1.12.amzn1 will be installed --> Processing Dependency: python27-backports for package: python27-backports-ssl_match_hostname-3.4.0.2-1.12.amzn1.noarch ---> Package python27-six.noarch 0:1.8.0-1.23.amzn1 will be installed --> Running transaction check ---> Package python27-backports.x86_64 0:1.0-3.14.amzn1 will be installed --> Finished Dependency Resolution Dependencies Resolved ================================================================================ Package                              Arch   Version            Repository                                                                           Size ================================================================================ Installing:  aws-cli                              noarch 1.14.9-1.48.amzn1  amzn-main 1.2 M  unzip                                x86_64 6.0-4.10.amzn1     amzn-main 201 k  which                                x86_64 2.19-6.10.amzn1    amzn-main  41 k  Installing for dependencies:  freetype                             x86_64 2.3.11-15.14.amzn1 amzn-main 398 k  groff                                x86_64 1.22.2-8.11.amzn1  amzn-main 1.3 M  groff-base                           x86_64 1.22.2-8.11.amzn1  amzn-main 1.1 M  libjpeg-turbo                        x86_64 1.2.90-5.14.amzn1  amzn-main 144 k  libyaml                              x86_64 0.1.6-6.7.amzn1    amzn-main  59 k  mailcap                              noarch 2.1.31-2.7.amzn1   amzn-main  27 k  python27-PyYAML                      x86_64 3.10-3.10.amzn1    amzn-main 186 k  python27-backports                   x86_64 1.0-3.14.amzn1     amzn-main 5.0 k  python27-backports-ssl_match_hostname                                       noarch 3.4.0.2-1.12.amzn1 amzn-main  12 k  python27-botocore                    noarch 1.8.13-1.66.amzn1  amzn-main 4.1 M  python27-colorama                    noarch 0.2.5-1.7.amzn1    amzn-main  23 k  python27-dateutil                    noarch 2.1-1.3.amzn1      amzn-main  92 k  python27-docutils                    noarch 0.11-1.15.amzn1    amzn-main 1.9 M  python27-futures                     noarch 3.0.3-1.3.amzn1    amzn-main  30 k  python27-imaging                     x86_64 1.1.6-19.9.amzn1   amzn-main 428 k  python27-jmespath                    noarch 0.9.2-1.12.amzn1   amzn-main  46 k  python27-ply                         noarch 3.4-3.12.amzn1     amzn-main 158 k  python27-pyasn1                      noarch 0.1.7-2.9.amzn1    amzn-main 112 k  python27-rsa                         noarch 3.4.1-1.8.amzn1    amzn-main  80 k  python27-setuptools                  noarch 36.2.7-1.33.amzn1  amzn-main 672 k  python27-six                         noarch 1.8.0-1.23.amzn1   amzn-main  31 k Transaction Summary ================================================================================ Install 3 Packages (+21 Dependent packages) Total download size: 12 M Installed size: 51 M Downloading packages: -------------------------------------------------------------------------------- Total 1.0 MB/s | 12 MB 00:12 Running transaction check Running transaction test Transaction test succeeded  Running transaction   Installing : python27-backports-1.0-3.14.amzn1.x86_64                    1/24   Installing : python27-backports-ssl_match_hostname-3.4.0.2-1.12.amzn1    2/24   Installing : python27-setuptools-36.2.7-1.33.amzn1.noarch                3/24   Installing : python27-colorama-0.2.5-1.7.amzn1.noarch                    4/24   Installing : freetype-2.3.11-15.14.amzn1.x86_64                          5/24   Installing : libyaml-0.1.6-6.7.amzn1.x86_64                              6/24   Installing : python27-PyYAML-3.10-3.10.amzn1.x86_64                      7/24   Installing : mailcap-2.1.31-2.7.amzn1.noarch                             8/24   Installing : python27-ply-3.4-3.12.amzn1.noarch                          9/24   Installing : python27-jmespath-0.9.2-1.12.amzn1.noarch                  10/24   Installing : python27-futures-3.0.3-1.3.amzn1.noarch                    11/24   Installing : python27-six-1.8.0-1.23.amzn1.noarch                       12/24   Installing : python27-dateutil-2.1-1.3.amzn1.noarch                     13/24   Installing : groff-base-1.22.2-8.11.amzn1.x86_64                        14/24   Installing : groff-1.22.2-8.11.amzn1.x86_64                             15/24   Installing : python27-pyasn1-0.1.7-2.9.amzn1.noarch                     16/24   Installing : python27-rsa-3.4.1-1.8.amzn1.noarch                        17/24   Installing : libjpeg-turbo-1.2.90-5.14.amzn1.x86_64                     18/24   Installing : python27-imaging-1.1.6-19.9.amzn1.x86_64                   19/24   Installing : python27-docutils-0.11-1.15.amzn1.noarch                   20/24   Installing : python27-botocore-1.8.13-1.66.amzn1.noarch                 21/24   Installing : aws-cli-1.14.9-1.48.amzn1.noarch                           22/24   Installing : which-2.19-6.10.amzn1.x86_64                               23/24   Installing : unzip-6.0-4.10.amzn1.x86_64                                24/24   Verifying  : libjpeg-turbo-1.2.90-5.14.amzn1.x86_64                      1/24   Verifying  : groff-1.22.2-8.11.amzn1.x86_64                              2/24   Verifying  : unzip-6.0-4.10.amzn1.x86_64                                 3/24   Verifying  : python27-pyasn1-0.1.7-2.9.amzn1.noarch                      4/24   Verifying  : groff-base-1.22.2-8.11.amzn1.x86_64                         5/24   Verifying  : aws-cli-1.14.9-1.48.amzn1.noarch                            6/24   Verifying  : python27-six-1.8.0-1.23.amzn1.noarch                        7/24   Verifying  : python27-dateutil-2.1-1.3.amzn1.noarch                      8/24   Verifying  : python27-docutils-0.11-1.15.amzn1.noarch                    9/24   Verifying  : python27-PyYAML-3.10-3.10.amzn1.x86_64                     10/24   Verifying  : python27-botocore-1.8.13-1.66.amzn1.noarch                 11/24   Verifying  : python27-futures-3.0.3-1.3.amzn1.noarch                    12/24   Verifying  : python27-ply-3.4-3.12.amzn1.noarch                         13/24   Verifying  : python27-jmespath-0.9.2-1.12.amzn1.noarch                  14/24   Verifying  : mailcap-2.1.31-2.7.amzn1.noarch                            15/24   Verifying  : python27-backports-ssl_match_hostname-3.4.0.2-1.12.amzn1   16/24   Verifying  : libyaml-0.1.6-6.7.amzn1.x86_64                             17/24   Verifying  : python27-rsa-3.4.1-1.8.amzn1.noarch                        18/24   Verifying  : freetype-2.3.11-15.14.amzn1.x86_64                         19/24   Verifying  : python27-colorama-0.2.5-1.7.amzn1.noarch                   20/24   Verifying  : python27-setuptools-36.2.7-1.33.amzn1.noarch               21/24   Verifying  : which-2.19-6.10.amzn1.x86_64                               22/24   Verifying  : python27-imaging-1.1.6-19.9.amzn1.x86_64                   23/24   Verifying  : python27-backports-1.0-3.14.amzn1.x86_64                   24/24 Installed:   aws-cli.noarch 0:1.14.9-1.48.amzn1        unzip.x86_64 0:6.0-4.10.amzn1   which.x86_64 0:2.19-6.10.amzn1   Dependency Installed:   freetype.x86_64 0:2.3.11-15.14.amzn1   groff.x86_64 0:1.22.2-8.11.amzn1   groff-base.x86_64 0:1.22.2-8.11.amzn1   libjpeg-turbo.x86_64 0:1.2.90-5.14.amzn1   libyaml.x86_64 0:0.1.6-6.7.amzn1   mailcap.noarch 0:2.1.31-2.7.amzn1   python27-PyYAML.x86_64 0:3.10-3.10.amzn1   python27-backports.x86_64 0:1.0-3.14.amzn1   python27-backports-ssl_match_hostname.noarch 0:3.4.0.2-1.12.amzn1   python27-botocore.noarch 0:1.8.13-1.66.amzn1   python27-colorama.noarch 0:0.2.5-1.7.amzn1   python27-dateutil.noarch 0:2.1-1.3.amzn1   python27-docutils.noarch 0:0.11-1.15.amzn1   python27-futures.noarch 0:3.0.3-1.3.amzn1   python27-imaging.x86_64 0:1.1.6-19.9.amzn1   python27-jmespath.noarch 0:0.9.2-1.12.amzn1   python27-ply.noarch 0:3.4-3.12.amzn1   python27-pyasn1.noarch 0:0.1.7-2.9.amzn1   python27-rsa.noarch 0:3.4.1-1.8.amzn1   python27-setuptools.noarch 0:36.2.7-1.33.amzn1   python27-six.noarch 0:1.8.0-1.23.amzn1   Complete! Removing intermediate container 1f5293a2294d  ---> 5502efa481ce Step 3/6 : ADD fetch_and_run.sh /usr/local/bin/fetch_and_run.sh  ---> 1b69173e586f Step 4/6 : WORKDIR /tmp Removing intermediate container a69678c65ee7  ---> 8a560dd25401 Step 5/6 : USER nobody  ---> Running in e063ac6e6fdb Removing intermediate container e063ac6e6fdb  ---> e5872fd44234 Step 6/6 : ENTRYPOINT ["/usr/local/bin/fetch_and_run.sh"]  ---> Running in e25af9aa5fdc Removing intermediate container e25af9aa5fdc  ---> dfca872de0be Successfully built dfca872de0be Successfully tagged awsbatch-fetch_and_run:latest docker images 명령으로 새로운 로컬 repository를 확인할 수 있습니다.shell : docker images [ec2-user@AWS_BRANDI_STG fetch-and-run]$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE fetch_and_run latest dfca872de0be 2 minutes ago 253MB amazonlinux              latest              81bb3e78db3d        2 weeks ago         165MB STEP3. ECR에서 repository 생성아래는 ECR 초기 화면입니다.fetch_and_run이란 이름으로 Repository 생성합니다. 3. Repository 생성이 완료되었습니다.STEP4. ECR로 빌드된 이미지를 pushECR에 docker login후 빌드된 Docker 이미지에 태그합니다. shell : aws ecr get-login --no-include-email --region ap-northeast-2 빌드된 docker 이미지에 태그하세요.shell : docker tag fetch_and_run:latest 000000000000.dkr.ecr.ap-northeast-2.amazonaws.com/fetch_and_run:latest 태그된 docker 이미지를 ECR에 push합니다.shell: docker push 000000000000.dkr.ecr.ap-northeast-2.amazonaws.com/fetch_and_rrun:latest 아래는 ECR fetch_and_run Repository에 푸쉬된 Docker 이미지입니다.STEP5. 간단한 샘플 스크립트(myjob.sh)를 S3에 업로드아래는 간단한 myjob.sh 스크립트입니다.#!/bin/bash date echo "Args: $@" env echo "This is my simple test job!." echo "jobId: $AWS_BATCH_JOB_ID" sleep $1 date echo "bye bye!!" 위의 myjob.sh를 S3에 업로드합니다.shell : aws s3 cp myjob.sh s3:///myjob.sh STEP6. IAM에 S3를 접속할 수 있는 ECS Task role 등록Role 등록 화면에서 Elastic Container Service 선택 후, Elastic Container Service Task를 선택합니다.AmazonS3ReadOnlyAccess Policy를 선택합니다.아래 이미지는 Role에 등록 하기 전 리뷰 화면입니다.Role에 AmazonS3ReadOnlyAccess가 등록된 것을 확인합니다.STEP7. Compute environments 생성AWS Batch 콘솔에서 Compute environments를 선택하고, Create environment 선택합니다.Compute environment type은 Managed와 Unmanaged 두 가지를 선택할 수 있습니다. Managed는 AWS에서 요구사항에 맞게 자원을 관리해주는 것이고, Unmanaged는 직접 자원을 관리해야 합니다. 여기서는 Managed를 선택하겠습니다.Compute environment name을 입력합니다.Service Role을 선택합니다. 기존 Role을 사용하거나 새로운 Role을 생성할 수 있습니다. 새 Role을 생성하면 필수 역할 (AWSBatchServiceRole)이 생성됩니다.Instnace Role을 선택합니다. 기존 Role을 사용하거나 새로운 Role을 생성할 수 있습니다. 새 Role을 생성하면 필수 역할(ecsInstanceRole)이 생성됩니다.EC2 key pair에서 기존 EC2 key pair를 선택합니다. 이 key pair를 사용하여 SSH로 인스턴스에 접속할 수 있지만 이번 글의 예제에서는 선택하지 않겠습니다.Configure your compute resources Provisioning Model은 On-Demand와 Spot이 있습니다. 차이점은 Amazon EC2 스팟 인스턴스를 참고해주세요. 여기서는 On-Demand를 선택합니다.Allowed instance types에서는 시작 인스턴스 유형을 선택합니다. optimal을 선택하면 Job queue의 요구에 맞는 인스턴스 유형을 (최신 C, M, R 인스턴스 패밀리 중) 자동으로 선택합니다. 여기서는 optimal을 선택하겠습니다.Minimum vCPUs는 Job queue 요구와 상관없이 Compute environments에 유지할 vCPU 최소 개수입니다. 0을 입력해주세요.Desired vCPUs는 Compute environment에서 시작할 EC2 vCPU 개수입니다. Job queue 요구가 증가하면 필요한 vCPU를 Maximum vCPUs까지 늘리고 요구가 감소하면 vCPU 수를 Minimum vCPUs까지 줄이고 인스턴스를 제거합니다. 0을 입력해주세요.Maximum vCPUs는 Job queue 요구와 상관없이 Compute environments에서 확장할 수 있는 EC2 vCPU 최대 개수입니다. 여기서는 256을 입력합니다.Enable user-specified Ami ID는 사용자 지정 AMI를 사용하는 옵션입니다. 여기서는 사용하지 않겠습니다.Networking VPC Id 인스턴스를 시작할 VPC를 선택합니다.Subnet을 선택합니다.Security groups를 선택합니다.그리고 EC2 tags를 지정하여 생성된 인스턴스가 이름을 가질 수 있게 합니다. Key : Name, Value : AWS Batch InstanceCreate을 클릭해 Compute environment를 생성합니다.아래 이미지는 생성된 Compute environment입니다.STEP8. Job queues 생성AWS Batch 콘솔에서 Job queues - Create queue를 선택합니다.Queue name을 입력합니다.Priority는 Job queue의 우선순위를 입력합니다. 우선순위가 1인 작업은 우선순위가 5인 작업보다 먼저 일정이 예약됩니다. 여기서는 5를 입력하겠습니다.Enable Job queue가 체크되어 있어야 job을 등록할 수 있습니다.Select a compute environment에서 Job queue와 연결될 Compute environment을 선택합니다. 최대 3개의 Compute environment를 선택할 수 있습니다.생성된 Job queue, Status가 VALID면 사용 가능합니다.STEP9. ECR을 이용하여 Job definition 생성AWS Batch 콘솔에서 Job definitions - Create를 선택합니다.Job definition name을 입력하고 이전 작업에서 만들 IAM Role을 선택하세요, 그리고 ECR Repository URI를 입력합니다. 000000000000.dkr.ecr.ap-northeast-2.amazonaws.com/fetch_and_runCommand 필드는 비워둡시다.vCPUs는 컨테이너를 위해 예약할 vCPU의 수, Memory(Mib)는 컨테이너에 제공할 메모리의 제한, Job attempts는 작업이 실패할 경우 다시 시도하는 최대 횟수, Execution timeout은 실행 제한 시간, Ulimits는 컨테이너에 사용할 사용자 제한 값입니다. 여기서는 vCPUs는 1, Memory(MiB)는 512, Job Attempts는 1로 설정, Execution timeout은 기본값인 100 그리고 Limits는 설정하지 않습니다.vCPUs: 컨테이너를 위해 예약할 vCPU의 개수Memory(Mib): 컨테이너에 제공할 메모리의 제한Jop attempts: 작업이 실패할 경우 다시 시도하는 최대 횟수Execution timeout: 실행 제한 시간Ulimits: 컨테이너에 사용할 사용자 제한 값User는 기본값인 nobody로 선택 후, Create job definition을 선택합니다.Job definitions에 Job definition이 생성된 것을 확인할 수 있습니다.STEP10. Submit job을 통해 S3에 저장된 작업 스크립트(myjob.sh)를 실행하기AWS Batch 콘솔에서 Jobs를 선택합니다. Job을 실행할 Queue를 선택하고 Submit job을 선택합니다.Job run-time1)Job name을 입력합니다.2)Job definition을 선택합니다.3)실행될 Job queue를 선택합니다.Environment Job Type을 선택하는 부분에서는 Single을 선택합니다. Array 작업에 대한 자세한 내용은 어레이 작업 페이지를 참고해주세요.Job depends on은 선택하지 않습니다.자세한 내용은 작업 종속성 페이지를 참고해주세요.Environment Command에서 컨테이너에 전달할 명령을 입력합니다. 여기서는 [“myjob.sh”, “30”] 를 입력해주세요. vCPUs, Memory, Job attempts와 Execution timeout은 job definition에 설정된 값을 가져옵니다. 이 Job에 대한 설정도 가능합니다.Parameters를 통해 job을 제출할 때 기본 작업 정의 파라미터를 재정의 할 수 있습니다. Parameters에 대한 자세한 내용은 작업 정의 파라미터 페이지를 참고해주세요.Environment variables는 job의 컨테이너에 환경 변수를 지정할 수 있습니다. 여기서 주의할 점은 Key를 AWS_BATCH로 시작하면 안 된다는 것입니다. AWS Batch에 예약된 변수입니다.Key=BATCH_FILE_TYPE, Value=script Key=BATCH_FILE_S3_URL, Value=s3:///myjob.shSubmit job을 선택합니다.Job이 Submitted 된 화면입니다.Dashboard를 보시면 Runnable 상태로 대기 중인 것을 확인할 수 있습니다.STEP11. 결과 확인CloudWatch > Log Groups > /aws/batch/job에서 실행 로그를 확인할 수 있습니다.Conclusion간단한 튜토리얼로 AWS Batch를 설정하고 실행하는 방법을 알아봤습니다.(참 쉽죠?) 다음 글에서는 AWS Batch의 Array 또는 Job depends on등의 확장된 기능들을 살펴보겠습니다. 참고1) AWS Batch – 쉽고 효율적인 배치 컴퓨팅 기능 – AWS2) AWS Batch 시작하기 - AWS Batch3) Amazon ECR의 도커 기본 사항 - Amazon ECR글윤석호 이사 | 브랜디 [email protected]브랜디, 오직 예쁜 옷만#브랜디 #개발문화 #개발팀 #업무환경 #인사이트 #경험공유
조회수 1219

LG와 함께라면 언제나 Life’s Good, 지원부문장 인터뷰

지난 6월 5일 세계 환경의 날 캠페인을 진행한 LG전자 CSR(Corporate Social Responsibility, 기업의 사회적 책임)팀이 LG전자 지원부문장 이충학 부사장을 만났습니다. LG전자의 사회공헌활동에 대한 이야기를 나누기 위해서인데요. 때로는 유쾌하게 때로는 진지하게 진행된 우리들의 따뜻했던 오후를 잠시 엿보도록 할까요?CSR 팀 : 올해 진행한 LG전자 세계 환경의 날 캠페인에 대해 소개 부탁합니다.지원부문장 : LG전자는 2010년부터 노동조합과 함께 매년 세계 환경의 날인 6월 5일을 글로벌 자원봉사자의 날로 정하고 임직원 봉사 활동을 실시하고 있습니다. 일 년에 한 번 임직원들이 봉사 활동을 같이 한다는 것도 의미가 있지만, 무엇보다 노동조합과 함께 한다는 데 큰 의의가 있는 것 같습니다. 노조와 회사가 함께 사회에 보다 긍정적인 영향력을 만들어내겠다는 의지가 잘 반영된 활동인 것 같아요. 게다가 7년째 지속하고 있으니 더욱 의미가 깊다고 하겠습니다.l LG전자 지원부문장 이충학 부사장CSR 팀 : 올해는 문화유산 보존과 환경 보호를 주제로 삼았는데요. LG전자와 어떤 관련이 있을까요?지원부문장 : 처음 듣기에는 문화유산 보존과 LG전자의 환경 보호 활동이 무슨 상관이냐고 할지도 모르겠지만, 저는 듣자마자 지역 사회 곳곳에 뿌리내리고 있는 우리가 관심을 가질만한 분야라는 생각이 들었어요. LG는 전 세계에서 사업을 전개하고 있는데, 결국 그 지역 생태계의 일원이거든요. 생태계 보존에 힘쓰고 동참하는 것은 너무나 당연한 일이지요. 게다가 작년에는 올레드 TV와 함께 경복궁, 고궁박물관에서 <대한민국 문화유산 전시회>, <다시 만난 우리 문화유산전>을 진행했을 때 단순 봉사 활동을 넘어 LG 제품으로 고객들에게 보다 더 큰 가치를 전할 수 있겠다는 생각이 들었어요. 올해는 특히 세계문화유산인 창덕궁에서 문화재청과 함께 문화유산 지킴이 활동을 함께 할 수 있어서 더욱 좋았던 것 같습니다.l 2016년 2월 케냐 의수족 지원 10주년 기념식 참석 모습CSR 팀 : 글로벌 기업인 LG의 많은 법인들이 함께 동참하는 것도 무척 의미가 있는 것 같은데요.지원부문장 : 전 법인들이 참여하는 사회공헌 활동이 1년에 두번 정도 진행 중인데요. 6월 ‘세계 환경의 날 캠페인’과 9월 ‘헌혈 캠페인’이 그것인데요. ‘헌혈 캠페인’의 경우 국가적 특성에 따라 헌혈이 익숙하지 않은 곳도 있는 것이 사실입니다. ‘환경 캠페인’은 국경을 넘나드는 글로벌 이슈이니 전 법인이 참여하기에 좋은 것 같습니다. LG가 지역사회에서 사랑받고 있는 기업이라는 점을 감안해 해당 국가와 지역 주민들이 도움을 필요로 하는 문제를 해결하는 데 동참하면 참 좋을 것 같다는 생각입니다. 또 올해에는 약 35개 사업장에서 수천 명이 임직원들이 참여했고 SNS로 고객 참여를 유도하는 이벤트도 반응이 좋았던 것 같습니다.l 2016년 2월 케냐 의수족 지원 수혜자와 만남CSR 팀 : LG전자 CSR 방향에 대해 한 말씀 부탁드려요.지원부문장 : 일단 올해는 우리가 사회공헌의 전반적인 비전과 전략을 수립한 데 의의가 있다고 생각이 들고요. 3가지 실행 전략으로 선정한 ‘따뜻한 기술’, ‘신뢰의 파트너십’, ‘함께하는 나눔’을 기반으로 어떻게 LG다운 가치를 만들어낼 것인가를 고민하는 게 좋겠어요.l ‘16년 선포한 LG전자 사회공헌 Guide우리가 정말 잘 하는 역량으로 사회에 기여해야 더 커다란 임팩트를 만들어 낼 수 있으니 내/외부 전문가들이 함께 늘 고민하면 좋을 것 같아요. 그렇게 하면 여러분들이 늘 말하는 ‘LG와 함께라면 언제나 Life’s Good’이 되었으면 좋겠다는 목표가 진정성 있고 자연스럽게 전달되지 않을까 싶어요.l 2016년 5월 에티오피아 LG-KOICA 희망직업훈련학교 방문올해로 5년째 LG전자 CSR 팀이 속한 지원부문의 수장으로서 이충학 부사장의 생각은 확고했습니다. LG다운 사회공헌 그리고 진정성 있게 지속적인 활동을 묵묵히 하는 것! 임직원들과 야구 관람을 즐기고, 임직원들과 국내외 봉사에도 적극적으로 참여하는 그의 모습은 평소 이충학 부사장의 가치관이 발현된 것은 아닐까.#LG #LG그룹 #LG전자 #CSR #문화유산 #세계환경의날 #이충학부사장 #헌혈캠페인 #CSR활동 #기업문화 #조직문화 #사내문화 #구성원인터뷰
조회수 12624

Jekyll을 이용하여 github에 블로그 만들기

티스토리에서 여러 불편함들을 느껴 깃헙 블로그로 갈아타려고 한다. 자유도가 높아보여 티스토리에 블로그를 개설했으나 오히려 글이 노출되는 디자인이나 (줄간격, 글씨 크기 등등) 기존 테마를 변경하기에 불편했다. 결정적으로 gist 스크립트를 삽입했을 때 미리보기가 안돼서 고민 끝에 깃헙 블로그를 선택했다. 워드프레스도 개설해봤지만 왠지 모르게 마음에 안들어서 깃헙 블로그로 갈아타기로 마음먹었다. 그 후에 이것저것 알아보니 내 마음에 쏙 드는 요소들이 많았다.마음에 드는 부분git을 이용해 커밋, 푸시로 글을 포스팅함. 그 덕분에 블로그에 대한 모든게 로컬에 있고 모든 글들을 로컬에서 관리 할 수 있음.마크다운을 이용하여 글 작성. 글과 html을 마음대로 오갈 수 있어서 좋음. 마크다운 에디터가 없었다면 불편했겠지만 세상은 넓고 좋은 에디터는 많다..! 다만 이미지 삽입에서는 좀 불편.다른 웹 프로젝트처럼 웹스톰에서 블로그 관리 가능. 인텔리 제이를 사랑하는 나로서는 이 부분 또한 큰 장점.아무튼 이런 이유로 깃헙 블로그로 갈아타기로 결정. 구글링을 통해서 깃헙 블로그를 개설하는 방법에 대해 잘 정리해놓은 블로그를 찾았다. 놀부 블로그를 참고하여 깃헙 블로그를 개설했다. 아래에는 내가 보기 편하도록 더 간략하게 정리해보았다.깃헙 블로그 만들기 (Mac OS X)1. Jekyll 설치터미널에서 아래 명령어 입력으로 설치. $ sudo gem install jekyll2. 설치한 Jekyll을 이용하여 블로그 생성블로그를 만들고자 하는 위치에서 아래 명령어로 생성.$ jekyll new [github사용자명].github.com블로그 생성후 생성된 위치로 이동하여 아래의 명령어 실행 후 브라우저에서 http://localhost:4000으로 접속하면 로컬에 생성된 블로그를 볼 수 있음.$ jekyll serve --watch3. github에 온라인 저장소 만들기위에서 생성한 블로그 이름과 동일한 이름([github사용자명].github.com)으로 github에 온라인 저장소를 생성. 그 후 로컬에 있는 블로그와 만들어준 저장소를 remote 해주면 끝.$ git init$ git remote add origin [저장소URL]$ git add .$ git commit -m "Initialize Blog"$ git push origin master생성된 블로그는 http://[github사용자명].github.com으로 접속하면 볼 수 있다. 처음 생성하는 경우 몇 분의 시간이 걸리는 경우도 있다고 함.포스팅하기글은 _post 파일 안에 YYYY-MM-DD-[글 제목].markdown 형식으로 파일명을 지정하여 생성한 후 커밋, 푸시하면 업로드됨.테마 적용하기테마를 직접 만들기에는 시간이 너무 많이 소요되니 인터넷에 공유되어있는 테마를 사용하면 좋다. 테마를 적용하는 부분에서 여러모로 애를 먹었는데 제일 쉬운 방법은 테마가 올라가있는 저장소를 포크하여 [github사용자명].github.com으로 이름을 바꾸는게 제일 쉽다. 내 블로그는 심플한 테마를 적용하였다.다른 테마들은 Jekyll Themes 사이트에서 찾아볼 수 있다. 훨씬 이쁘고 좋은 테마들도 많음.Jeykll 더 알아보기Jeykll 공식 번역 사이트에서 몇 개의 문서를 읽어보면 더 다양하게 활용해 볼 수 있다. _config.yml파일이나 _post, _include, _layout 파일 정도는 기본으로 살펴보아야 함.#트레바리 #개발자 #안드로이드 #앱개발 #Jeykll #백엔드 #인사이트 #경험공유
조회수 1114

[직무] 미미박스에 올라오는 제품은 누가 선택하는 걸까? 화장품 MD 직무 소개

안녕하세요. 미미박스의 소식을 여러분께 전달드리는 Ava입니다.미미박스(www.memebox.com)에 들어가면 수많은 제품들이 있습니다.근데 궁금하신 적 없으셨나요? 이 수많은 제품들이 누구 손을 거쳐서 미미박스에 들어오게 되었는지!바로 MD(Merchandiser) 분들이 미미박스에 들어오는 수많은뷰티 아이템들을 직접 고르는데요. 오늘은 미미박스의 MD 직무를 소개 드릴게요!그럼 다 같이 팔로 팔로 미 ~ Q. MD는 어떤 일을 하나요?A. MD는 미미박스 플랫폼에 올라오는 브랜드, 업체, 상품에 대해 처음부터 끝까지 총괄 책임을 맡고 있어요. 그만큼 유관 부서도 많죠. 예를 들면 어떤 상품이 미미박스의 타겟과 맞으면 업체 영업이 시작돼요. 영업이 성사되면 법무팀과 함께 계약을 진행합니다. 고객들이 직접 보고, 테스트할 수 없고 제품의 상세페이지로만 어필해야 하기 때문에 이 상세 페이지는 정말 중요해요. 에디터 팀, 디자인 팀과 함께 셀링 포인트를 정하고, 워딩과 디자인을 기획하죠. 이 과정에서 좋은 것 중 하나는 미미박스의 명확한 UI/UX 가이드에요. 덕분에 '왠지 모를 촌스러움'은 거의 없어요.판매가 시작되면 마케팅 팀과 함께 판매를 촉진해요.배송과 관련해서는 물류팀과 소통하고, 고객이 상품을 받고 난 후의 CS 팀으로 들어오는 고객의 소리 관리까지... MD는 상품을 처음부터 끝까지 관리합니다.또 MD는 시장조사를 통해 트렌디한 제품을 빠르게 파악해야 해요. 미미박스는 다른 플랫폼과 다르게 방향을 알 수 없이 인기 제품이 통통 튀기 때문에 고객과 시장에 대한 빠른 이해가 중요해요.Q. 미미박스의 MD 팀은 어떤 전략을 가지고 있나요?A. 미미박스는 명확한 고객타겟을 가지고 있어요. 뷰티에 대한 관여도가 높고, 가격에 대한 민감도가 낮고, 내 수입(용돈, 월급)의 일정 부분 이상을 주기적으로 뷰티에 투자하는 사람들이에요. 그렇기 때문에 다른 플랫폼과 달리 신상품을 빠르게 소싱(sourcing) 하는 전략을 가지고 있어요. 신상품이라 하면 일반적인 화장품 브랜드의 신상품뿐만 아니라 SNS/뷰티 커뮤니티에서 핫하게 화두 되는 상품들, 텍스처나 패키지가 신박한 상품이에요다른 플랫폼과의 차이점을 설명해드리면 이해가 더 쉬울 것 같아요. 타 플랫폼의 경우 대중적인 브랜드에서 출시한 제품이 매출 상위 TOP10을 차지하고 있어요. 미미박스의 경우에는 새로운 브랜드나 신박한 제품들이 매출 상위를 차지하고 있죠. 또한 리뷰 역시 타 플랫폼은 배송이나 상품문의가 많다면 미미박스의 고객들은 제품에 대한 퀄리티 있는 리뷰를 많이 써요.Q. MD의 구체적인 하루 일과가 궁금해요.A. 오전에는 공통적으로 MD는 매출과 재고관리로 하루를 시작해요. 전일 보고가 있는데, 이 보고를 통해 전일에 대한 매출 달성률을 보고, TOP5 매출 상품을 체크하고, 재고관리를 하죠. 오후에는 각 업체와 영업활동을 진행합니다. 입점한 업체와 함께 상품기획, 구성 기획, 론칭 일정, 프로모션, 특가 영업 등을 논의하죠. 이를 통해 미미박스 플랫폼 내 한정 특가, 배너, 페이스북 콘텐츠, '이건 꼭 사야 돼' 등의 각 구좌를 매일 기획합니다. 그 외 입점이 안된 상품에 대해서는 직접 입점 영업을 합니다.Q. 말씀하신 전략을 바탕으로 진행한 제품이나 사례를 설명해주실 수 있나요?A. 리즐리라는 브랜드는 저희 MD가 업체랑 직접 기획했어요. 미미박스 플랫폼에서 고객에게 좋은 반응을 보이는 섀도 컬러에 대한 데이터와 MD의 촉을 바탕으로 데일리 컬러를 선택했죠. 또 해외 브랜드 중 6구짜리 투명 케이스 섀도 팔레트가 있는데 많은 고객들이 직구를 하는 것을 보고 국내에서 처음으로 투명 패키지를 만들었어요. 미미박스 고객 특성이 유명하진 않더라도 여러 브랜드를 도전해보는 분이 많기 때문에 충분히 어필할 수 있을 거라고 생각했죠. 이 과정에서 가능성을 본 제조업체들이 직접 투자를 하기도 했고요. 결과적으로 제품이 출시 후 계속 매출 상위를 달렸죠. 덕분에 시즌 3까지 제품이 나오고 틴트도 출시하게 되었어요. 무엇보다 고객들이 원하는 제품을 딱 기획해낸 것이 가장 뿌듯했어요.또 다른 사례로는 눈썹 도장이 있어요. 저희가 이 제품을 처음 소싱한 건 아니에요. 이미 다른 큰 플랫폼에 입점해있었죠. 하지만 크게 주목받지 못했어요. 그다음에 미미박스에 입점했는데 저희가 제품의 특성을 살려 콘텐츠를 만들었죠. 그러자 제품이 온라인에서 팍 튀었어요.Q. MD가 되기 위해서 갖춰야 할 자질은 무엇인가요?A. 가장 중요한 것은 코덕마인드에요. 면접 시 트랜디한 제품에 대해 물어보면 보통 대중적인 제품을 많이 이야기해요. 하지만 MD는 트렌드를 더 앞서야 하죠. 뷰티 유튜브도 많이 보고, 작지만 마니아 층이 있는 브랜드도 알고 있고... 이런 뷰티에 대한 배경지식이 필요해요. 또 회사 분위기가 도전을 장려하다 보니 눈치 보지 않고 적극적으로 목소리를 내고 표현할 수 있어야 해요. 매출 관리, 딜 관리, 디자인 하나하나가 고객과의 접점이기 때문에 꼼꼼하게 관리하는 능력이 필요하고요.많은 사람들과 협업하는 직무이기 때문에 다른 팀, 업체, 타 몰 MD와 좋은 관계를 유지할 수 있는 능력도 필요합니다.Q. 고객이 앞으로 미미박스를 어떻게 바라보길 원하시나요?A. 고객이 '가장 빠르고, 가장 트렌디한 플랫폼이 어디지?'라고 생각했을 때 가장 빠르게 떠오르는 플랫폼이 미미박스가 되었으면 좋겠어요. 2014년 5월까지만 해도 '미미박스'라고 이야기하면 사람들이 잘 몰랐어요. 월 매출도 엄청 적었어요. 하지만 지금은 메이저 브랜드들이 거의 다 입점했고, 럭셔리 브랜드의 입점이 막 시작되었죠.앞으로는 뷰티에 관한 가장 많은 제품을 만날 수 있고, 굳이 블로그를 안 찾아도 미미박스 리뷰를 통해 뷰티 정보를 얻을 수 있고, 바로 쉽게 구매까지 할 수 있는 뷰티 플랫폼이 되게 만들고 싶어요. 고객이 미미박스를 뷰티에 관한 것이면 원스톱으로 모든 게 되는 플랫폼으로 인지했으면 좋겠어요.  Q. 미래의 뷰티 MD들에게 한마디 남겨주세요.A. 남들과 똑같은 취업 준비 보다 나만의 구체화된 뷰티 스토리를 만든다면 그게 큰 강점이 될 것 같아요. 예를 들면 자기만의 피부 고민 해결 방법을 다양하게 도전해보는 방법도 있을 것이고, 해외 직구 템을 많이 구매해서 뷰티에 대한 시야를 넓힐 수도 있을 것 같고요. 뷰티의 세계는 들어갈수록 끝이 없는 것 같아요. 뷰티에 대한 시야를 넓히고 자신만의 뷰티 스토리를 꼭 만들어보세요!MD 직무에 대한 궁금증이 조금 풀리셨나요?미미박스에서 궁금한 직무가 있다면, 댓글로 많이 물어봐 주세요! (힘닿는 데까지 여러분을 위해 조사해드리겠습니다!)
조회수 1155

옐로모바일의 첫 인상 담당자, ‘올리비아’

안녕하세요, Y의 옐로피플 인터뷰가 돌아왔습니다:D 오늘은 아주 특별한 옐로피플과 인터뷰를 진행했답니다. 바로 아름다운 미소로 옐로모바일의 얼굴! 옐로모바일의 첫 인상을 책임지고 있는 리셉셔니스트! 올리비아입니다 :)다양한 레저스포츠를 취미로 즐기며 필라테스 자격증까지 준비 중이라는 올리비아! 오다 가다 마주쳤던 그녀의 이야기가 궁금하다면 퐐로퐐로 미! Y: 안녕하세요! 옐블 독자들을 위해 간단히 자기소개 부탁 드립니다 :)올: 안녕하세요 여러분 :) 클럽옐로 프론트 지킴이 올리비아라고 합니다. 반갑습니다! Y: 많은 분들이 왔다 갔다 하면서 올리비아에 대해 궁금해 하신다고 해요! 옐로에서 근무한지 얼마나 되었나요? 올: 저는 올해 2월에 입사했습니다. 그 동안 옐로에서 정말 많은 분들을 만나고 좋은 인연도 많이 만든 것 같네요 :)Y: 오래 계셨던 것 같은데, 아직 1년이 안됐군요! 기억나는 에피소드가 있나요?올: 아, 사실 출근 첫날이 아직도 생생합니다. 출근 첫날, 옐로 카페 분들께서 그 주말에 스키장에 가는 일정이 있는데 같이 조인하면 어떻겠냐고 물어봐 주시더라고요! (설렘+당황) Y: ㅋㅋㅋㅋㅋㅋ 만나자마자 스키장 제안이라니! 엄청난 친화력이네요올: 네! 그러니까요. 막 들이대주신(?) 덕분에 금방 친해졌죠 :)Y: 그 동안 느꼈던 옐로모바일의 분위기는 어떤가요? 올: 클럽옐로를 둘러보면 정말 진취적이고 자유로운 분위기가 느껴져요. 직원들은 늘 열정이 넘쳐 보이고요. Y: 특별한 취미가 있다고 들었어요! 올: 레저스포츠를 정말 좋아해요. 봄, 가을에는 MTB 싸이클을 즐기고 등산도 자주 하는 편입니다. 여름에는 웨이크보드, 겨울에는 스노우보드를 타러 가고요. 압구정한강에서 여의도나 하남시까지 왕복코스로 다녀오곤 하는데, 보통 두 시간 반 정도 걸립니다. Y: 와… 두 시간 반이요? 제 허벅지가 다 아픈 느낌이네요ㅋㅋㅋ 등산도 자주 하세요?올: 네. 그렇지 않아도, 다 다음주에 옐로모바일 경영지원팀과 같이 등반 예정이라 엄청 기대 중이에요! 얼마 전에도 다 함께 청계산 매봉까지 찍고 왔고요 :)Y: 프론트에 있다 보면, 거의 모든 옐로인들을 만날 것 같아요! 가장 고마운 옐로인은 어떤 옐로인인가요? 올: 최근에 바뀐 클럽옐로 회의실 운영 시스템을 적극적으로 활용해 주시는 옐로인들이요. 그리고 반갑게 인사해주시는 분들도 참 고마워요. 반대로 눈이 마주쳐서 인사했는데도 무시하면 많이 민망해요 :(Y: 인사 하고 삽시다!ㅋㅋㅋ 클럽옐로에서 가장 좋아하는 메뉴가 있나요? 올: 너의 사랑, 나의 사랑, 우리 모두의 사랑 카페인, 아메리카노가 최고죠! 사회생활 시작하고 나서는 생존을 위한 음료인 것 같아요ㅋㅋY: ㅋㅋㅋ생존을 위한 음료…아 뭔가 웃프네요Y: 옐로모바일 서비스 중 가장 많이 이용하는 서비스는 무엇인가요? 올: 쿠차요! 입사 초, 블루투스 이어폰을 구입할 일이 있었어요. 옐로에서 친하게 지내는 분과 함께 좀 더 저렴한 가격으로 알아보고자 네이X 검색을 하고 있는데, 그 분이 “아 뭐해? 쿠차로 찾아! 최저가로 한번에 다 비교돼” 라고 귀뜸을.. 해주셨죠. 그 이후로 꾸준히 잘 활용하고 있답니다.Y: 뜬금없지만, 피부가 완전 꿀 피부세요+_+ 비결이나 본인만의 인생템이 있나요?올: 타고난 피부가 아니라… 나름대로 노력합니다!!! (흐규) 1일 1팩에 도전하고 있는데, 확실히 피부가 좋아지는 느낌입니다:D 인생템은 최근에 찾았는데요, 피부과에서 시술 후 실제로 사용되는 재생 비비크림이에요. 전 피부가 예민한 편인데, 이 비비크림은 순한데다가 피부재생과 보호까지 한번에 돼서 데일리로 꾸준히 활용하고 있어요.Y: 여기서는 홍보하면 안되니까.. 궁금하신 분들이 있다면 클럽옐로 올리비아에게 문의를!ㅋㅋㅋㅋㅋㅋY: 자, 사실 많은 (남자)사람들이 궁금해 할 것 같은데요. 올리비아의 이상형은?!올: 스포츠를 즐겨 하는 사람이 이상형입니다:) 운동을 하시는 분들은 대체적으로 매사에 밝고 긍정적인 걸 느껴요. 건강을 위해 음주를 즐겨 하는 편이 아니라, 내외적으로 건강한 사람이죠. 그리고 이건 모든 여자들의 심쿵 포인트인데, 요즘 들어 셔츠 소매를 걷었을 때 보이는 팔뚝 힘줄이 그렇게 매력적이더라고요ㅋㅋㅋY: ㅋㅋㅋㅋ나이 먹을수록 그런 데서 매력을 느낀다던데.. 아..아닙니다. Y: 아, 너무 솔직하셔서 좋네요. 올해가 가기 전에 꼭 이루고 싶은 일이 있나요?올: 자격증을 따는 게 목표인데요, 현재 필라테스 교육자격증을 따려고 준비 중입니다! 내년 여름시즌에는 스킨스쿠버 자격증도 따려고 하고 있어요. Y: 마지막으로 한마디 부탁 드립니다!올: 늘 밝은 옐로모바일 여러분을 보면서 저도 덩달아 기분 좋게 일하고 있습니다:D 앞으로도 오다가다 인사 나눠요! 옐로 화이팅!! 

기업문화 엿볼 때, 더팀스

로그인

/