스토리 홈

인터뷰

피드

뉴스

조회수 1408

창업의 시대, 교육의 미래

1."내가 누구냐고 묻지 마세요.나는 늘 변하니까요"- 보들레르'퇴사학교'에서 만나는 사람들에게 가장 먼저 물어보는 질문이 있다."나는 누구일까요?""내가 좋아하는 것이 무엇일까요?"어떤 분은,"요즘 그게 젤 고민이에요 정말!"이라고 하시는 반면,어떤 분은,"그걸 알면 여기 오지 않았겠죠~"라며 반문하시기도 한다.<너 자신을 알라, 나는 누구인가, 자아 탐색 프로그램, Knowing myself, 나, 나, 나...>나 역시 나 자신을 아직도 잘 모르면서 이런 질문들을 던지는 게 조금 우습기도 하지만,확실한 것은 퇴사를 하고 나서 바깥?으로 나가면서 나 자신에 대해 몰랐던 부분을 조금 알게 되었다는 점이다.나는 누구인가?나는 생각보다 잘 하는 게 별로 없었다. 대기업의 브랜드와 전략기획이라는 화려한 타이틀이 마치 내 것인 마냥 착각하던 시절에는 어깨를 으쓱하며 마치 뭐든지 맘만 먹으면 다 잘할 수 있으리라 생각했던 시절. (지금 돌아보면 그저 보고서를 조금 잘 쓰는 정도 말고는 딱히 없지만...)그때는 창업도 스타트업도 그냥 쉬워 보였다. 나조차 어느새 '주입식 서열화'에 익숙해져, 그만큼 공부하고 스펙 쌓았으니, 이제 나머지 내게 남겨진 '일'들도 이 트랙 안에서 쭉- 올라가면 되리라는 에스컬레이터처럼 생각했나 보다.그러나, 인생은 저절로 올라가는 에스컬레이터가 아니었다. (학교에서는 그렇게 배우지만) 지금 나의 인생은 차근차근 내 발과 땀으로 밟아가는 경치 좋은 둘레길과 앞뒤 좌우 모래폭풍이 휘몰아치는 사막길을 동시에 오르내리고 있는 것만 같다.2.나를 좀 더 알기 위해, '스타트업 위크엔드'라고 하는 해커톤 프로그램에 참여한 적이 있다. 2박 3일 동안 기획자, 개발자, 디자이너들이 수백 명 모여 밤을 새우며 프로토타입 제품을 만들며 짧고 굵게 스타트업 프로젝트를 경험해 보는 것이다. 금요일 저녁 퇴근길부터 싱숭생숭 거리는 마음으로 역삼동 마루 180으로 향했다. 난 내 아이디어에 대한 자신감으로 가득 차 있었다.'소셜스냅' - 전국의 (아마추어) 사진사들을 연결하여 이벤트/생일/데이트 등 다양한 고객의 니즈에 맞는 스냅사진을 찍을 수 있게 연결하는 플랫폼이었다. 혼자 잘 씹히지도 않는 제육볶음을 꾸역꾸역 삼키며, 잠시 후 있을 100초 스피치 연습에 매진하고 있었다.마루 180그렇게 짜잔 하고 발표를 해보려 했지만, 현실은 어버버버 난 준비한 말도 제대로 못하고 떨면서 내려왔다. 나 혼자 거창한 비전과 전략을 더듬거려 보지만, 눈치를 보아하니 내가 무슨 말을 하는지 아무 관심도 없는 사람들.  내 비장의 무기, 나의 오랜 독서와 고심으로 트렌드를 읽고 사회적 가치를 해결하고자 하는 '소셜 공유경제 스냅사진 플랫폼'은 그렇게 최종 득표에서 단 4표를 얻고 조용히 사라져 버렸다.'정말 이게 끝?'난 믿을 수 없는 표정으로 한동안 멍하니 앉아 있었다.쓰디쓴 패배감을 느끼며. 갑자기 이 자리에 앉아 있는 게 견디기 힘들어졌다. 내가 너무 많은 기대를 했나 보다.이윽고 네트워킹 시간 30분 동안 난 그저 축 늘어져 멘탈과 함께 사라진 내 아이디어와 함께 서서히 침몰해 가고 있었다.난 지금 당장 도망치고 싶어 졌다.그때 어쩌면 처음 생각했을지도 모른다.난 어쩌면 창업가 유형이 아닐 수도 있겠다. 기획자라고 앉아 있지만, 다른 사람들과 달리 할 줄 아는 게 아무것도 없구나.화려한 대기업의 전략기획 타이틀은, 이들 개발자와 디자이너가 당장 여기서 만들고 그리는 것들과 진짜 기획자들이 구현해내는 실행력에 비해, 아무런 쓸 데가 없었다.어쨌든 여차저차 2박 3일 동안 버티며 프로그램을 마치긴 했지만, 이후 나는 한 가지 생각에 사로잡혔다.'나는 정말 누구일까?''나는 왜 여기서 이렇게 힘들어하고, 내가 잘하는 것은 무엇일까?''과연 창업이 나에게 맞는 걸까?'모두가 창업을 외치는 신자유주의적 '창업 복음주의'의 시대에서,나 역시 그저 대박의 꿈을 갖고 사회적 가치라는 거창한 꿈을 표방하며, 그저 헛물만 켜고 있는 건 아닐까.그저 지금 현실이 무언가 잘못되었다는 답답함과 탈출에의 강박증에 의해, 도피처이자 환상으로써의 창업을 생각하는 건 아닐까.그리고 나는 정말 궁금해졌다.그저 주입식 공부만 하다 대기업에 취직한 내성적인 문과생이, 오늘날 스타트업 창업의 세계에서 살아남을 수 있을까?3.  아쇼카 코리아(Ashoka Korea)와 카카오 (Kakao), C-Program에서 주관하는 '미래를 듣는(여는) 시간'이라는 교육 포럼에 초청받았다.금요일 아침 9시. 각계각층의 인사들과 교육 사회혁신가들이 한 자리에 모이는 뜻깊은 시간.각자 짧게 자기소개를 하던 중 '퇴사학교' 대표입니다. 라는 말에 청중에서 웃음이 터져나왔다.'퇴사'라는 말이 아무래도 강력하다 보니, 확 꽂혀서 너무 좋다는 분들도 있고, 퇴사까지 배워야 하냐며 걱정하시는 분도 있다. 여러모로 '퇴사'란 화두가 오늘날 우리에게 결코 가볍지 않다는 반증.이 시대의 교육의 미래에 대해 카카오의 김범수 의장, 아쇼카 글로벌 헨리 드시오 (Henry DeSio) 의장, 모교 김용학 총장, 고려대 염재호 총장, 그리고 건명원 최진석 원장 등과 함께 대담의 자리가 이어졌다.그중 20년간 미래학에 대해 연구하셨다는, 고려대 염재호 총장의 말이 특히 인상적이었다.<취업>은 20세기 구시대의 모델입니다. 21세기 이후에는 새로운 생산 양식이 필요합니다.QWERTY 자판을 한 번 세팅해 놓으면 다시 바꾸기가 너무 힘든 것처럼, 이 시대의 패러다임은 여전히 과거 구시대의 것으로 견고하게 유지되고 있지만, 사실 환경은 너무나 빨리 변하고 있다는 것이었다.30년 안에 모든 제조 생산업의 공급은10%의 인구만으로 가능할 것- 제러미 리프킨과거 우리는 기존 경제 방식에서는 모든 것이 정해지고 안정적인 구조 속에서 그 길을 잘 따라가기만 하면 되었다.겉으로 드러나는 '형식지'가 중요하기에 기존의 매뉴얼과 시스템에 순응하면 매우 편리한 세상, 미래가 보장되는 세계였던 것이다.그러나 이제는 (어찌 된 일인지 그 시작과 끝을 다 알 순 없지만 확실한 것은) 분명 세상이 빠르게, 아주 빠르게 (너무나 뭐가 뭔지 파악하기에도 급급한 속도로) 변화하고 있다는 것이다.이런 시대에서는 훨씬 다양한 개인들의 보이지 않는 '암묵지'가 더 중요해진다. 딱히 매뉴얼화할 순 없지만 분명 개개인 고유의 가치와 특성으로 내재되어 있는 그 무언가.그것들을 함께 나누고 공유하고 교류하며 배우는 개인들의 오픈된 네트워킹 연결이 핵심인 것이다.아쇼카 이혜영 대표님, 연세대 김용학 총장님, 고려대 염재호 총장님, 건명원 최진석 원장님퇴사학교를 통해 만나는 사람들에게, 회사에서 가장 힘든 점이 무엇이냐고 물었을 때, 하나같이 대답한 공통점이 있었다.회사에서의 5년, 10년 뒤의 롤모델이 보이지 않는다.모두가 똑같은 정해진 길만 걷는 이 시대에서, 우리는 롤모델이 부재한 시대를 겪고 있는 건 아닐까.스티브 잡스나 저커버그 같은 너무나 뛰어난 아웃라이어들인 엘리트들만 조명되고 그들을 본받으라고 외치는 이 시대에서,사실은 우리 같은 보통 사람들에게 필요한, 보다 현실적인 내 주위의 이웃 같은, 나도 한 번쯤은 저렇게 해 보고 싶겠다 싶은 그런 롤모델의 부재 말이다.  4.그렇게 국내 최고의 지성 분들과의 중요한 화두들이 던져지던 와중, 건명원의 최진석 원장의 어떤 문장이 내 가슴에 꽂혔다.혁신은 '듣는 것'이 아닌, '하는 것'입니다."모두가 혁신과 변화를 외치고 그것에 대해 엄청나게 많은 논의와 토론, 연구가 이루어지는 와중에, 결국은 실행이 답이라는 의미였는데,무엇보다 '형용사'의 삶 중심으로만 살던 나에게 뼈아프게 다가왔다.'동사' 인생으로 노력하려 하지만, 여전히 어느새 '형용사'만 갖고 또 고민하는 내 모습.바보란 다른 결과를 기대하면서, 계속 똑같은 방법은 쓰는 사람- 아인슈타인우리는 늘 새로운 혁신과 변화를 기대한다고 '말'하면서, 정작 '행동'으로 넘어가면 아무런 일도 발생하지 않는 건 아닐까?이러한 현상을 연세대 김용학 총장은 'Weakness of Will'의 시대라고 진단했다. '크로키'라는 알람시계는 알람이 울리면서 바퀴가 달려 도망간다고 한다.아침에 잠에서 눈을 뜨는 것조차 혼자 제대로 하지 못하는 인간의 본성은, 이처럼 나약한 것일지도 모른다.'변화', '행동'이라는 쉬운 단어가 실은 가장 어렵다는 것을. 우리는 매번 다이어트에 실패하며 깨닫는다. 오늘도, '지금 맛있으면 0칼로리'를 외치면서.크로키 알람시계아쇼카의 헨리 의장은 이러한 새로운 변화를 위해서는 (Change Maker) 다음 3가지가 필요하다고 말한다.첫째, 어린 시절부터 쌓아야 할 다양한 공감과 가치관 정립 (Empathy)둘째, 경험을 통해 쌓아야 할 리더십 (New Leadership)셋째, 함께하는 사람들 (Team Work)이라는 것이다.결국 이러한 것들을 위해 가장 먼저 시작해야 할 것이 - 지금 우리가 여기 모인 이유인 - <교육>이라는 메시지를 던지며, 행사는 마무리되었다.5.특히 퇴사 후 혼자서 준비하며 겪은 어려움과 외로움을 잘 아는 나이기에,Empathy와 Leadership도 좋지만, 무엇보다 Team Work라는 단어가 더욱 의미심장하게 다가왔다.'혼자서는 아무것도 할 수 없다'이 말은 정말인 것 같다. 혼자서 할 수도 없고, 할 필요도 없다. (지금도 퇴사학교와 언더독스의 동료들이 함께 같은 뜻을 품고 재밌게? 일하고 있다)앞으로 다가올, 아니 이미 다가온 이 시대는 'Team of Teams'의 시대이다.더욱 다채롭고 자유로운 소규모 팀들이 모여 새로운 프로젝트를 만들고, 그들이 또 다른 팀들과 협업하며 더 큰 생태계를 함께 꾸려가는 것.이젠 더 이상 거대한 수천수만의 조직에서 일사불란하게 처리할 수 있는 일들이, 점점 '알파고'에게 대체될 것이다.자유롭고 독립된 개개인들이 자신만의 좋아하는 일을 하며 수익을 만들어 내고, 그들이 또 연결되고 모여 새롭고 재밌는 가치를 만들어 내는 세상.그런 점에서, 카카오 김범수 의장은, 더 많은 개개인들이 자신의 일을 하며 수익을 낼 수 있도록, 작가/택시기사/대리운전기사 등 다양한 분야로 연결 플랫폼을 확장하고 있다고 말했다. 몇몇 골목상권 침해라는 논란에도 불구하고, 실제 현업 종사자들 개개인의 가치에 더 집중하고자 한다는 방향성.그러면서 교육이란 것에 대해 수년간 스터디를 했지만, 여전히 고차원 방정식처럼 어렵고 복잡하다고 말하면서도, 그러기에 더더욱 함께 고민하고 풀어나가야 하지 않겠냐는 말은, 지금 내가 꾸려가는 퇴사학교의 방향성에 대해서도 더 고민할 수 있는 계기가 되었다.카카오 김범수 의장님좋은 대학과 회사를 가도 고민, 안 가도 고민인 이 시대에서, 이도 저도 할 수 없는 이 시대에서, 현실과 미래의 다리가 하나둘씩 끊기고 있는 이 시대에서, 더 늦기 전에 무언가를 해야 한다는 시기가 왔다고 김범수 의장은 덧붙였다.미래는 이미 와 있다.다만 널리 퍼지지 않았을 뿐.6.많은 사람들이 새로운 혁신과 가치를 위해 창업과 스타트업과 또 다른 새로운 활동들에 도전한다.나 역시 퇴사하고 (대기업을 박차고 나와 새로운 가치 어쩌구 저쩌구 전형적인 미사여구들로 포장되는 시대에서....) 지금 창업을 하고 있다.아직 나는 내가 누구인지 잘 모르고, 어디로 어떻게 가야 할지 역시 모른다.창업가 유형이 맞는지도, 이 길 이후에 무엇이 있을지도, 교육의 미래가 어떻게 되어야 할지도 물론 모른다.다만 확실한 것은, 과거 모든 것이 안정적이던 시절(좋은 학교와 좋은 대기업을 의지하던 시절)에는 나는 매우 비판적이고 시니컬한 사람이었다.그게 되겠어?너무 과도한 긍정주의 아니야?자기계발서는 딱 질색이야.그건 네 환경이 특이해서 그렇지.또 잘난 척하네.그래 봤자 허세일뿐.내가 다 아는데 그건 그렇지 않을걸...그러나,회사 안에 있을 때는 '거창한 사회적 가치를 위해 살겠노라'고 다짐했던 나였는데,회사 밖을 나오니, '그저 당장 내일 뭐 먹고살지'만을 고민하는 나를 발견했다.사회적 가치나 비전, 거창한 이상과 도전 같은 것들은, 당장 내가 무엇을 먹고살 것인가 하는 '먹고사니즘'보다 결코 앞서지 않았다.지금도 여전히 먹고사니즘이 내 최대의 관심사이자 화두이다.그러면서 한 편 좀 더 작은 가치를 만들어가려는 노력을 아주 조금씩 옵션?으로 덧붙이려는 정도.그래서 90%의 현실적 고민들 속에서도,여전히 10%의 이상적인 대안들을 놓지는 못하는 상황이라,그래도 이런 질문들을 계속 던지고, 또 조금씩 실행을 하는 사람들을 많이 만나 함께 만들어 가고 싶은 것이다.분명 이제는 창업(創業)의 시대이다.무분별한 극소수의 성공한 엘리트 중심 창업이 아니라,모두가 각자가 개인이 좋아하는 일을 찾고 그것을 새로운 '업(業)'으로 '만들어(創)' 갈 수 있는,회사 안이든 밖이든 상관없이 자신만의 '업(業)'을 찾을 줄 아는,원래 '창업(創業)'이란 단어가 품고 있는 진짜 '직업의 변화'를 말하는 것이다.과연 이러한 시대에서,우리의 창업의 방식과 교육의 미래는 어떤 그림이 되어야 할까.포럼이 끝나갈 무렵,'취업은 20세기 구시대 모델'이라고 말씀하신, 미래학을 20년간 연구하신 고려대 총장님께 질문을 드렸다.그렇다면 새로운 시대의 (일에 대한) 모델은 무엇일까요?카카오톡 게시판으로 올린 것이라,아직 구체적인 답변을 받지는 못했지만,나는 확신한다.언젠가 당신과 내가 함께 그 답을 찾아갈 수 있게 되기를.#퇴사학교 #자아찾기 #인사이트 #조언 #취업 #운영
조회수 5146

피부처럼 사용하는 업무용 Tool

1위. Meistertask (https://www.meistertask.com/)올 타임 1위였던 슬랙을 제치고 Meistertask가 당당하게 내가 가장 많이 쓰는 툴로 자리 잡았다. Task management Tool로 Asana, Jira, Trello.... 등을 썼었는데 뭔가 한 끗 차이로 마음에 안 듦. 그래도 전체 flow를 볼 수 있고 Kanban 방식을 적용할 수 있었던 Trello로 한동안 만족했었다. 전체 흐름을 보기 편하고 이쁘다!그러다가.. 우연한 계기로 '예쁜' Trello를 발견하게 되었다. Slack integration app에서 소개된 Meistertask. 아무런 의도 없이 그냥 한번 써볼까 하고 가입했는데 괜찮았다. 뭔가 손에 착착 달라붙는 느낌 ㅎㅎ 거의 모든 기능은 Trello와 비슷하지만 앱도 훌륭하고, 디자인이 Trello와 넘사벽. 슬랙과 integration도 훌륭.. 한데 돈 내야 한다. 근데 뭐 적절하게 IFTTT으로 연동해서 부족한 만큼 쓸 수 있다. 한번 써보시라. 개인적으로 Trello의 지루한 UI 보다 훨씬 신선하고 좋다. 팀원이 말하는 불만은 한 가지. 업무 assign이 한 명밖에 안된다는 것! 근데 나는 사실 한 명한테만 assign이 되는 게 더 좋은 거 같다. Task owner는 언제나 1명일 때가 좋다. 2위. IFTTT (https://ifttt.com/)IF That Then That 풀어쓴 서비스 명이 모든 걸 설명한다. 이거 실행되면 저거 자동으로 실행하기.슬랙을 2위로 할까 하다가 슬랙을 기반으로 얽기 설기 굉장히 복잡하게 얽혀있는 IFTTT을 2위로 선정했다.처음엔 재미 삼아서 이런저런 기능 연결해서 쓰다가, 이제는 내가 쓰는 거의 모든 앱, 서비스들이 IFTTT로 복잡하게 연동되어 있다. 설명이 어렵다. 이걸 실행하면 저걸 실행해준다 정도?내가 IFTTT를 쓰는 수십 가지 중에서 많이 쓰는 것들....- 아이폰에 연락처 저장하면 구글 스프레드시트에 저장해주기- 아이폰에서 스크린숏은 다른 앨범에 저장하기- facebook에 특정 해쉬태그 달면 슬랙 채널에 쏴주기- facebook에 포스팅하면 evernote에 저장해주기- 인스타그램에 포스팅하면 evernote에 아카이브 해주기- pocket으로 저장할 때 특정 tag 달면 slack 채널에 쏴주기- 내일 비 올 때 아이폰으로 푸시 주기- Fitbit에서 일어나면 slack 채널에 쏴주기- 내가 선정릉역에 도착하면 alert 채널에 사장님 도착하심 메시지 쏴주기 등등등이외에도 수십 가지 더 된다. 뭘 해놨는지 까먹을 정도.. IFTTT은 언젠가 IOT의 종합 플랫폼이 될 거다. alexa가 있다면 할 수 있는 게 10배는 늘어날 듯. 3위.  슬랙 (https://slack.com/)어쩌다 보니 3위까지 밀렸는데, 아직도 하루 중 가장 많은 시간을 슬랙 안에서 보낸다. 항상 내 옆에 있는 거 같아서 가끔 질리기도 하지만 오후 8시부터는 Push를 죽이는 snooze 기능을 만들어내는 것을 보면, 미워할 수 없다. 팀 커뮤니케이션은 많이도 방황했는데 결국 결론은 슬랙이다. (울지 마 잔디야...)업무와 일상을 완벽하게 분리하고 싶어서 절대 업무용으로 카톡을 쓰지 않기로 했고, 업무별로 채널을 나누고, 해당 업무는 그 채널에서만 이야기를 나눌 수 있어서 좋다. 처음에는 조금 불편해하는 팀원도 있었지만 결국 슬랙으로 대동단결슬랙의 묘미는 바로 다양한 서비스들과 integration이다. 예를 들면, 관심 있는 아티클을 페북에서 보다가 Pocket을 통해서 저장하고 특정 Tag를 달아놓는다면 자동으로 지정된 슬랙 채널로 쏴줄 수 있다. 팀원들과 마케팅 계획에서 얘기를 하다가 할 일이 생겼다. task mangement를 하는 trello를 켜고 입력할 필요가 없다. 슬랙에서 /trello add를 통해서 간단하게 업무를 더할 수 있다. 뭐 이런 integration은 수두룩 하다. 슬랙 봇은 몇 가지 재미난 게 있지만 결국 그냥 재미용으로 결론을 내림. 4위. 에버노트 (https://evernote.com/)언제부터 썼는지 기억도 안 나지만 5년도 넘게 모든 문서는 에버노트에 빼곡히 기록했다. 얼마 전에 'First Dead Unicorn'으로 잠시 유명세를 탔다. 코끼리야 죽지 마....  얼마 전에 동기화 기기를 2개로 제한하면서 많은 사람들이 떠나갔지만 나는 코끼리에게 프리미엄 결제로 보답했다. 엔간하면 결제를 안 하는 내가 결제를 했으니 내 손을 떠날 수 없는 운명인가 보다. 맥북 에어에서 버벅대는 모습을 보면 화가 나기보다는 애처로운 생각이 든다. 5년 넘게 내 일상을 기록하다 보니 뭔가 감정적으로도 연결된 듯.죽지마 코끼리야..쉽고 빠르게 기록할 수 있는 본질에서 살짝 비켜나면서 굴곡이 있었지만 잘 버텨주길 바란다. 좀 잘하란 말이다. 이렇게 계속 버벅대면 언제 갈아탈지도 모르겠다. 요즘은 에버노트를 팀 위키로 어떻게 활용할 수 있을지 고민 중이다. 지금 위키로 쓰고 있는 구글 사이트 관리자는 너무 느리고, 모바일에서도 굉장히 불편함. 에버노트는 이상한 기능 추가하지 말고 에버노트 위키 기능이나 만들어 주지...5위. Mindmeister (https://www.mindmeister.com/)사실 이건 Meistertask가 너무 마음에 들어서 이 회사에서 만든 다른 서비스는 없나? 하고 둘러보다가 알게 된 서비스이다. 역시 하나를 보면 둘을 안다니깐... 이 서비스도 훌륭하다. 한마디로 마인드맵을 쉽게 만들 수 있는 서비스이다.  요즘 모든  기획을 빡세게 하려고 하면 mindmeister를 켠다. 매우 직관적으로 생각을 잘게 쪼개고 발전시킬 수 있는 툴이다. 꼼꼼한 기획자들에게 강추...안타깝게 순위권에서 떨어진 서비스들..- Pocket : 아티클 간편 저장- Wunderlist : To-do list 작성- beat : 노동요 청취 (푹 쉬렴)- Pomodoro : 25분 일 + 5분 쉬는 것을 도와주는 타이머. 멀티태스킹을 방지해줌결론 : 일 잘하는 사람은 A4 이면지,  모나미 펜만 있어도 충분하다. 그런데 적절한 업무 Tool의 활용은 효율성을 극대화 해준다.#삼분의일 #업무환경 #업무프로세스 #협업 #협업툴 #꿀팁 #스킬스택 #스택소개
조회수 934

방법론이 아닌 마음의 중요성

 기획, 또는 PM이라는 직군에서 일을 하다 보니, 개발자, 디자이너, 그리고 기획자 분들과 업무의 중심에서 커뮤니케이션을 많이 하게 되고, 커뮤니케이션을 하며 느낀 점들에 대해서 공유드리고 싶네요. 현업에서 계신 분들은 "당연히 그런 거지, "라고 생각할 수 있으나, 꼭 한 번쯤은 생각해 주셨으면 하는 일들이니, 읽어봐 주세요~1. 업무 끝의 기준은 "다음 작업자가 일할 때 문제가 없는가"입니다. 언제나 하는 이야기지만, 업무의 끝은 "내가 생각하기에 끝났다." 보다는, 다음 작업자가 "지금 내 작업물을 가지고 다른사람이 작업을 시작하면 고민이 생길까?"를 한 번만 더 생각해주세요.- 기획자 같은 경우, 자신이 설계한 플로우를 따라가면서, 될 경우 보단 안될 경우, 성공할 경우보단 실패할 경우에 대해 더 고려해 주시고 작업해 주세요.- 장표에 내가 기획한 정책, 규칙 등을 구현할 때 개발단에서는 어떤 식으로 동작을 해야 하는지, 또 디자인을 하면서 필요한 작업들에 대해서 한 번만 더 고려한다면(그럼에도 언제나 이슈가 생기기 마련이지요!), 서로의 업무에 더 큰 도움이 될 겁니다!2. 모를 수는 있어도 몰라도 되는 일은 없어요. 일을 하다 보면, 자리에서 순간순간 결정되는 것들이 있고, 회의를 통해 많은 분들이 모여 결정을 할 때도 있고 또, 스스로 내린 결정을 공유해 결정하는 다양한 상황들이 생깁니다. 그리고 기획자들에게는 어떤 이유에서건 결정된 사항에 대해서 기록하는 건 언제나 중요합니다. 그리고 더 중요한 건 "어떤 이유에서 어떤 것을 결정하기로 했다."라는 의사결정에 대해 업무파악을 놓칠 순 있어도, 놓아도 되는 일은 없습니다. "아 저는 잘 모르고 들어와서 이제야 파악했어요." "저는 회의 주제를 잘 모르고 들어와서..." 등과 같이 팀이 모여 일을 하고 있는 업무상황에서 항상 책임감을 가지고 업무를 진행해야 합니다.3. 내 업무가 밀리면, 다른 사람들의 업무도 밀립니다. 에자일 프로세스라고 하더라도, 1. 기획 없이 디자인과 기능 스펙을 짤 수 없고, 2. 디자인 없이 클라이언트가 개발을 할 수 없습니다. 정확한 기한이 있다면, 그전에 일을 마치는 것이 같이 일하는 업무자들에게 도움을 주는 것이 아닌, 당연한 일입니다. 그리고 기한이 없는 일은 늘어질 수 있으므로, 모호하게라도 기한을 잡아두고 시작하는 것이 중요합니다. 마지막 순간에 "준비가 안돼서..."가 나오는 건 정말 잘못된 표현입니다. 기한안에 완료를 못할 것 같다면 빨리 이야기해주는 것이 중요하고, 어떻게 대응할 건지에 대해 생각하고 행동하는 게 중요해요.항상 중요한 건 마음의 문제예요, 기술의 문제가 아니라. 우리는 항상 새로운 것들을 만들어 내는 것에 집중하면서 "기술집약적"인 사고를 기반으로 일을 하지만, 하나의 프로젝트를 기반으로 여러 인원들이 업무를 한다면, "타인의 이해를 기반으로 한" 사고를 가지고 일을 해야 한다고 생각해요. 그리고 궁극적으로도 내가 하는 업무에 대한 자부심을 느끼기 위해선, 서로가 서로 간의 업무에 대해서 자부심을 느낄 수 있는 환경을 만드는 것이 가장 선결돼야 합니다. 당장 내일부터라도, 조금씩만 더 서로를 생각하며 일하면 좋을 것 같습니다!#코인원 #블록체인 #기술기업 #암호화폐 #스타트업인사이트
조회수 1991

스타트업의 브랜딩 (2)

브랜드란 무엇일까?라고 생각을 해보면, 제품과 서비스에 담고 싶은 가치이고, 그 가치를 통해 고객들이 우리를 인식해주는 것이라고 파펨은 해석하고 있습니다. 스타트업의 브랜딩이라는 조금은 거창한 제목이지만, 브랜딩을 고민하면서 남겨보는 글입니다.한 줄로 요약하자면.. 내 브랜드의 본질에 맞는 Keyword를 찾고 다양한 영역에서 실행해보자!!입니다. 스타트업의 브랜딩 (1)의 링크는 여기 : 이 글은 멋진 브랜딩을 하고 있는 다른 회사들에 대한 기록입니다. 자동차 회사 볼보(volvo)는 Safety라는 키워드를 브랜드의 핵심으로 가지고 있고, BMW는 Sheer driving pleasure라는 단어로 운전이 즐거운 자동차를 강조하고 있습니다.  파펨에도 이런 phrase는 있습니다. 바로 Find your Signature"당신만의 향기를 찾으세요"라고 표현할 수 있겠는데, 파펨은 64가지의 제품 중 고객에게 가장 잘 어울리는 향수를 찾아줌과 더불어 Trial kit를 통해 시향까지 해볼 수 있도록 하고 있습니다. 즉 위의 문장을 현재의 비즈니스 모델이 나름 잘 실행하고 있다고 볼 수 있는데, 여기서 몇 가지 고민이 들었습니다. 브랜드가 고객에게 전달하는 가치와, 브랜드가 추구하는 본질은 조금 다르지 않을까? 이렇게 생각하게 된 계기는.. 파펨이라는 브랜드는 앞으로도 계속해서 진화를 해 나갈 것입니다. 그중에 고객에게 전달하고픈 메시지는 달라질 수 있겠지만, 추구하는 본질은 달라지지 않을 것이라는 생각입니다. 그러한 차원에서 파펨이 생각하고 있는 본질의 키워드를 공유하자면...Reasonable / 합리적인파펨은 Reasonable을 표현하는 브랜드를 추구하고 있습니다. 고객들에게 직접적으로 이 키워드를 표현하고 있지는 않지만, 다양한 영역에서 그 핵심을 표현해 나가고자 노력하고 있습니다. 그렇다면 왜 "합리적인" 인가? 사실 합리적이라는 단어는 어디에 붙여도 어색하지 않은 단어입니다. 어디에 붙여도 좋을 "Good"과 같은 단어이기 때문에 조금 조심스러웠습니다. 하지만 지금까지 나름 다양한 브랜드(명품에서 다이소 까지 등등) 들을 사용해본 결과, 요즘에 제가 소비하는 브랜드들은 다음과 같은 특징에 수렴되고 있는데... 1) 그 목적에 충실하고,  2) 제품으로서의 완성도가 있으며, 3) Value for Money가 있는 제품들인 듯합니다. 이러한 특징들이 "합리적"이라는 단어와 잘 어울리는 제품이고 또한 많은 사람들에게 꾸준하게 사랑받는 브랜드들이 가진 특징일 듯합니다. 제가 주변에서 느끼는 것들로는 Converse, LAMY, MUJI와 같은 브랜드들이 그러한 특징을 가지고 있습니다.파펨도 오랫동안 소비자들에게 사랑받는 브랜드가 되고 싶다는 생각에서.. 그 본질의 keyword를 "좋은 향기를 강조" 하거나, 혹은 "어디서도 맡아볼 수 없는 향기"와 같이 향기와 관련된 키워드를 내세우는 것보다는 "합리적인"을 강조하고 싶었습니다. (좋은 향기는 기본이겠지요 ^^;) 두 번째로, 그렇다면 합리적인 향수란 무엇인가? (왜 향수 브랜드에 합리적인 키워드를?)향수와 같이 luxury goods 제품 카테고리에 "합리적인"이라는 key word가 잘 어울릴 수 있을까?라는 고민을 해보았습니다. 지금까지의 향수는 글과 사진 등으로 설명하기가 꽤 까다로운 제품 카테고리이기 때문에, 대부분의 브랜드들이 유명 배우와 브랜드 이미지, 그리고 화려한 bottle design 등으로 소비자들을 push 하고 있다는 생각이었습니다. 게다가 꽤나 어려운 용어들이 많이 등장합니다.하지만 이제는 향수라는 제품 카테고리도 Life sytle 브랜드로써 신뢰할 수 있고 매력적인 브랜드가 필요한 시점이라는 생각을 하였습니다. 즉, 파펨은 Luxury Brand로써 고객에게 다가가는 것이 아닙니다.세 번째로, 파펨은 합리적인 이라는 keyword를 어떻게 표현하고 있는가? 브랜딩이 멋진 문장이나 로고를 보여주는 것도 중요하지만, 비즈니스 모델에 그 것들을 녹여낼 수 있는 것이 중요하다고 생각하였습니다. 그래서 후각 제품의 선택의 편리함을 위해..1) 다양한 향수 종류 중에서 고객의 취향을 알고리즘으로 파악하여 추천해주는 퍼퓸 텔러(PerfumeTeller)라는 서비스와 2) Trial kit라는 구매전 사전 시향이 가능한 서비스를 운영 중입니다. 3) 사용자에게 편리한 소용량의 5ml 제품을 출시하고 있습니다. 추가적으로 이번 브랜딩 작업에서는 logo, package, site에서 그 합리적을 시각적으로 표현해보았습니다. 01. new logo "더 기본으로" (the basic)고퀄리티의 향, 정직한 용량과 가격.합리적인 향수 브랜드 PAFFEM의 핵심 가치를 담았습니다.02. new package "더 단순하게" (the simple)블랙 앤 화이트, 01과 64, 5ML와 30M.합리적인 브랜드 이미지를 전달하기 위해 견고하고 절제된 스타일로 제작했습니다.03. new site "더 실용적으로" (the practical)TRIAL KIT, SUBSCRIPTION, 향수 서베이.합리적인 향수 경험을 위해 사용성은 높이고, 다양한 콘텐츠를 준비했습니다.파펨의 새로운 로고파펨의 새로운 패키지 파펨의 새로운 site 방문 : www.paffem.me이번에는 위의 세 가지 영역에서 표현을 하였지만, 파펨을 표현하는 더욱 다양한 영역에서 그 본질을 표현하기 위한 노력은 계속될 것입니다. 위에 설명해본, 제품/패키지/가격/Site 뿐만이 아니라... business partner와의 일하는 방식, 회사의 문화, 업무 방식 등등 소프트한 영역에서도 그러한 본질적 가치를 이어나가기 위한 노력을 지속하고자 합니다. 물론 '합리적인' 사람을 뽑아야 하는 것도 매우 중요하겠구요~아직은 많이 부족합니다. 지금 이 글을 쓰는 동안에도 부끄러운 생각들이 많이 들지만, 계속해서 노력하고자 합니다! 아래는 파펨 내부에서 파펨의 브랜딩을 논의하기 위해 만들어본 자료들의 사진입니다. ^^; #파펨 #스타트업 #창업가 #창업자 #마인드셋 #인사이트 #브랜드 #브랜딩
조회수 908

할아버지/할머니도 코딩을 해야 하는 이유

대부분의 교육은 초, 중, 고등학생이나 대학생 등 주로 젊은 층을 위주로 진행되고 있습니다. 프로그래밍 교육도 마찬가지로, 현재 10대에서 30대인 주로 젊은 층의 학생과 직장인들을 대상으로 교육이 서서히 일어나고 있습니다. 하지만 높아진 평균 수명으로 노인층이 급격히 늘어나고, 빠르게 변화하는 산업 아래 노인층의 재교육을 통한 지속적인 사회 활동이 요구 되는 시대가 되었습니다.2016년 한국의 인구분포도. 42–57세의 중장년층이 15–24의 청년층보다, 청년층이 0–9세의 유아층보다 월등히 많습니다. Wikipedia위 그래프에서 보이는 것처럼 이렇게 사회의 전체적인 평균 연령의 급격한 상승이 예고되어있음에도 불구하고, 고등학교나 대학까지의 일회성 교육이 아닌 전 연령층을 대상으로 한 지속적인 교육 제공은 아직 보편화 되어 있지 않습니다. 노인층 대상으로 진행되는 교육은 미미하며, 특히나 젊은층도 배우기 어려운 코딩 교육은 노인층에게는 교육이 불가능하거나 전혀 필요하지 않다고 여겨지고 있습니다.UC San Diego 대학의 Phillip Guo 교수Phillip Guo 교수는 HCI (사람-컴퓨터 인터랙션) 및 온라인/컴퓨터 교육 분야에서 명성이 높은 연구자입니다. Guo 교수는 처음으로 노인층에 대한 코딩 교육 연구를 진행하여 온라인에서 프로그래밍을 배운 52개국 60~80대 504명으로부터 다양한 설문조사와 심층조사를 진행한 결과를 CHI 국제 학술회에 출간했습니다. 본 연구 설명과 함께 엘리스에서 생각하는 로드맵을 소개합니다.연구본 연구는 http://www.pythontutor.com 웹사이트에서 실시된 온라인 코딩 교육 설문조사에 응한 504명의 60~85세 학생에 대한 심층 분석과 인터뷰로 이루어져있습니다. 이들이 코딩을 배우는 목적은 세가지 주요 요점으로 종합됩니다.첫째는 코딩을 배움으로서 노화되는 뇌를 자극하기 위함이고, 둘째로 젊은 시절 놓쳤던 새로운 기회를 잡기 위함, 그리고 마지막으로 어린 가족 구성원들과 소통하기 위함이었습니다.혼자 공부하는 방식의 교육은 온라인에서 특히 더 높은 이탈율을 보입니다.이들이 프로그래밍을 배우는 원동력은 교육을 통한 취업과 같은 정확히 정해진 목표보다는, 스스로의 동기부여 및 젊은층과의 소통을 위한 이유가 더 컸습니다. 코딩을 배우는 과정 중에 가장 힘든 세가지는 감퇴하는 인지력, 질문에 대답해 줄 수 있는 강사나 조교 혹은 학생이 없었고, 매번 변화하는 SW를 따라가기 어려움이 있었습니다. 첫번째를 제외한 나머지 어려움은 다른 연령층에서도 겪은 어려움이었습니다.마치며Philip Guo 교수의 논문에서 알 수 있는 것은 노인층이 노화하면서 겪을 수밖에 없는 배움의 어려움과 더불어, 현재 교육 시스템이 노인층을 전혀 고려하지 않고 있다는 것입니다. 이것은 노인층 대상의 교육을 더욱 어렵게 합니다.논문에서는 노인층에게 적합한 교육 시스템이 만들어지거나 제공된다면, 이들이 산업에 바로 투여될 수 있는 능력을 갖추기는 어려울 수도 있으나 프로그래밍 교육을 할 수 있는 선생님으로 활동할 수 있다고 서술하고 있습니다. 이를 활용하면 현재 현저히 부족한 SW 교육자 수로 어려움을 겪고 있는 공교육에 도움이 될 수 있습니다.엘리스에서는 라이브 교육 방송 진행, 헬프 센터 조교 도우미 등 학생들에게 좋은 교육을 제공하기 위해 부단히 노력하는 다양한 연령층의 온라인 조교님들이 계십니다. 언젠가는 60~80대 조교님이 활동하실 수 있다고 믿고 있습니다. 이러한 믿음을 주신 중2 아들을 둔 한 어머니의 피드백을 참조합니다. (엘리스 기초 자바 과정에서 최상위 점수를 받으셨습니다.)저는 전공도 인문학쪽이고 수학 싫어서 문과갔던 문과생인지라, 코딩처럼 논리력 요구하는 수업 따라가기나 할까 큰 기대없이 시작했었습니다.수업 초반에는 마냥 어리둥절했고, 시키는대로 따라하면 다 되었기 때문에 ‘어라 쉽잖아?’ 라고 느꼈습니다. 하지만 중반부 넘어가면서…클래스, 메소드라는 개념이 낯설기도 했고, 각종 연산자의 적용이나 변수들을 식에 적용시키는 다양한 패턴들이 적응이 잘 안되었어요. 반복문의 순서나 마침표,세미콜론, 콜론을 기억하지 못해서 다시 되돌아와서 확인한 것만도 수 십번이었습니다.다른 분들은 마치 초급 과정을 어디서 마스터 하고 온 것처럼 잘 따라가시는데, 저는 매 시간마다 헤매고 오류나고…하지만 똑똑한 것 보다 꾸준한 것이 더 낫다고… ‘머리가 안따라가면 더 오래 공부하면 되겠지’ 하고 다시 보고, 다시 풀고, 계속 질문하고그러나보니 어느 순간 이해가 가는 개념들, 저절로 외워지는 패턴들이 조금씩 늘어났어요.특히 실시간 강의라서 피드백을 받을 수 있고, 조교님이나 강사님들께 질문을 편하게 할 수 있는 시스템이 정말 좋았습니다. 비주얼 좋은 두 분이 수업을 진행해 주신 것도 좋았구요. 반응 좋은 우리 반 수강생들도 참 좋았습니다.저녁 설거지 해 두고 (때로는 저녁상을 치우기 바쁘게) 컴퓨터 앞에 앉아서 8주간 공부한 시간들이 저한테는 정말 소중한 시간이었습니다. 이렇게 집안 일 하고, 애들 챙기면서도 공부할 수 있고, 배울 수 있다는 것이 너무 좋습니다. 좋은 강의 열어주셔서 고맙습니다. ^^*p.s.수업 중에 어떤 분이 자바 알고리즘 강의 열어달라고 하시던데, 알고리즘이 뭔지 물어보고 싶었는데 못 물어봤네요 ㅋ#엘리스 #코딩교육 #교육기업 #기업문화 #조직문화 #서비스소개
조회수 4238

서버 비용을 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]로 이메일을 주시기 바랍니다!
조회수 1253

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]브랜디, 오직 예쁜 옷만#브랜디 #개발문화 #개발팀 #업무환경 #인사이트 #경험공유
조회수 2451

[Buzzvil People] Kay Kim, Chief Finance Officer

 Buzzvil People에서는 다양한 배경과 성격 그리고 생각을 지닌 버즈빌리언들을 한 분 한 분 소개하는 시간을 갖습니다. 어떻게 버즈빌에 최고의 동료들이 모여 최고의 팀을 만들어가고 있는 지 궁금하시다면, 색색깔 다양한 버즈빌리언들 한분 한분의 이야기가 궁금하시다면, Buzzvil People을 주목해주세요.1. 간단한 자기 소개 부탁드립니다. 안녕하세요. 김규홍입니다. 버즈빌에서는 Kay(케이)로 불리고 있습니다. 저는 한국 공인회계사이고 딜로이트안진회계법인에서 사회생활을 시작했습니다. 회계법인에서는 감사와 M&A부서에서 일했으며 이후 쿠팡 회계팀장, 옐로오투오 재경 실장을 거쳐 작년 4월부터는 버즈빌의 CFO를 맡고 있습니다. 퇴근하면 육아에 집중해야 하는 두 아이의 아빠이기도 합니다. 회사와 가정 모두 가장 바쁜 시기에 있어 정신이 없지만, 하루하루 즐겁게 지내고 있습니다. 2. 어떻게 버즈빌에 오시게 되셨나요? 회계법인을 퇴사하고 스타트업 업계로 들어오면서 좋은 스타트업에서 CFO가 되는 목표를 가지게 되었습니다. 저는 몇 번의 이직을 통해 경력을 개발해 왔으며, 스스로 CFO 업무가 가능하다고 판단한 시점에서 헤드헌터를 통해 버즈빌을 소개 받았습니다. 처음에는 관심이 있던 업종이 아니어서 큰 관심이 없다고 거절했었는데, 마침 버즈빌에 대해 알고 있던 지인이 좋은 피드백을 주셔서 면접을 보게 되었습니다. 면접을 보면서 제 선입견이 좋은 방향으로 변하게 되었고, 면접 과정에서 회사의 대표님들(John & Young)과 많은 이야기를 나누면서 이런 사람들이 이끌어가는 회사라면 같이 한번 일해보고 싶다는 생각이 들어서 합류를 결정하였습니다.  3. 버즈빌에서 어떤 업무를 담당하고 계신가요? CFO를 맡고 있으며, 회계/세무/IR 등 재무 관련 업무를 총괄하고 있습니다. 현재는 회사의 재무 정보가 신뢰성을 담보한 상태에서 적시성을 가질 수 있도록 시스템을 만드는 것에 집중하고 있습니다. 이를 위해 back office의 개선, 수익 인식기준의 변화, ERP 도입 등을 진행하였으며, IFRS 전환  및 내부회계 관리제도의 도입 등의 프로젝트도 진행할 예정입니다. 기존의 투자자와의 커뮤니케이션, 신규 투자자의 발굴 등의 IR 업무도 주요 업무입니다. 추가로 버즈빌은 글로벌 비즈니스를 추구하는 회사임에 따라 해외 자회사와의 거래와 관련하여 이전가격세제(TP) 이슈를 사전에 준비하고 해외 자회사 관련 연결재무제표 작성 및 공시도 준비하고 있습니다. 4. 스타트업에서 혹은 광고업계에서 일하는 느낌이 어떠세요? 제가 스타트업에서 일하게 될 것이라고 처음 회계사가 되었을 때는 상상도 하지 못했습니다. 그 당시에는 스타트업이라는 용어조차 생소했던 것으로 기억합니다. 회계법인에서 쿠팡으로 이직하는 시점에서 스타트업이라는 존재를 알게 되었고, 당시에는 큰 기대 없이 스타트업에서 일하게 되었는데 그 이후 운이 좋아 잘 풀렸다고 생각합니다. 회계업계는 굉장히 보수적이고 안정적인 면을 추구하는 경향이 강해서 도전적이고 계속 변하는 스타트업은 서로 간에 잘 연결이 되지 않습니다. 저는 회계일을 하는 사람 중에서는 굉장히 특이하게 호기심이 많고 새로운 것을 하는 것을 좋아해서 스타트업과 잘 fit 되는 것 같습니다. 5. 이것만큼은 버즈빌이 참 좋다! 어떤 게 있으실까요? 처음에 영어 이름을 쓰라고 했을 때 굳이 이렇게까지 해야 할까 하는 생각이 있었는데, 영어 이름을 쓰고 자연스럽게 부르게 되니 수평적인 소통이 되어서 좋습니다. 그리고 본인의 업무역량도 뛰어나지만, 다른 직무의 인원과 다양한 주제를 가지고 커뮤니케이션을 하고자 하는 의지를 가진 직원들이 너무 많아 신기하다는 생각이 들고 저도 자연스러운 자극을 받고 있습니다. 경력이 많아지면서, 내가 생각하는 틀에 맞춰 세상을 해석하게 되는 경향이 강해지는데 버즈빌에서 일하면서 저 자신에 대해서 많이 돌아보게 되는 계기가 되었습니다. 6. 개인적인 목표나 꿈이 있으신가요? 있다면, 버즈빌에서의 경험이 어떻게 도움이 된다고 생각하시나요? 저는 스타트업이 결국 나라의 미래라고 생각합니다. 스타트업을 통해 자수성가한 세대들이 국내 부호 순위에 들어가고 있으며, 이러한 분들이 스타트업 생태계에서 액셀러레이터, 엔젤투자자 등의 역할을 수행하며 생태계를 키우고 있습니다. 지금은 꿈과 열정, 실력을 갖춘 인재들이 본인의 자본 없이 사업을 시작하고 키워갈 수 있는 환경이 서서히 갖추어 지고 있는 단계에 들어섰다고 판단합니다. 저는 제가 지금까지 스타트업 업계에서 일하면서 쌓은 많은 경험을 바탕으로 스타트업 생태계를 조금 더 좋은 방향으로 발전시키고, 이를 통해 조금 더 좋은 사회를 만들 수 있도록 기여하는 것이 꿈입니다. 
조회수 1842

데일리호텔의 Exit Poll 플로우

데일리호텔에서는 지난 11월말에 Exit Poll 기능을 서비스에 도입했습니다. 출구 조사는 숙박 예약을 했던 고객 등을 대상으로 간단한 설문을 진행하여 서비스의 품질을 끌어올리는 수단입니다. Product 팀은 이를 구현하기 위해 몇 가지 방안을 검토한 후 아래와 같은 플로우로 작동하는 구현체를 만들기로 했습니다.앱보이에서 캠페인을 진행한다. 앱보이에는 HTML을 푸시로 앱에 날리는 기능이 있으므로 간단한 설문 조사 웹페이지를 앱에 보낼 수 있다.사용자가 설문에 응하면 설문 내용을 서버로 보낸다.서버가 설문을 구글 스프레드시트에 저장한다.업무 관련자는 설문 내용을 담은 구글 스프레드 시트를 공유 받는다.이와 같이 결정하기까지 주로 고려한 점은 다음과 같습니다.앱보이는 고객 세그멘테이션을 나눠서 푸시를 발송하는 기능이 있으므로 캠페인의 효율이 높다.설문 내용은 캠페인마다 바뀌므로 비정형 데이터에 가깝다. 그러므로 관계형 데이터베이스에 넣기에 불편하다. 뿐만 아니라 데이터를 분석하려는 사람은 데이터베이스에서 설문 조사 결과를 자신의 분석도구로 가져가는 일을 따로 해야 한다. 그러므로 바로 분석을 시작할 수 있도록 구글 문서로 결과를 쌓는다.이렇게 구현한 결과물은 다음과 같습니다.설문조사 화면구글 스프레드시트에 쌓인 설문조사 결과이렇게 스프레드시트로 데이터를 바로 쌓기 때문에 시트가 제공하는 기능이나 구글의 또다른 서비스인 데이터스튜디오 등으로 분석을 바로 진행할 수 있습니다. 데이터베이스에서 데이터를 추출해 분석도구에 넣는 작업을 하지 않아도 됩니다.물론 이런 작업 플로우가 모든 데이터에 적합한 것은 아닙니다. 특히 구글이 제공하는 API에 몇 가지 제약이 있기 때문에 주의할 필요가 있습니다. 예를 들어초당 API 호출 회수 등에 제약이 있고스프레드시트 하나는 40만개가 넘는 셀은 담지 못합니다.이러한 제약이 큰 문제가 되지 않는다면 매우 효율적인 작업 플로우로써 기능합니다. 자세한 구현 이슈는 기회가 닿는다면 다른 글로 설명하겠습니다. 그럼 다들 즐거운 하루를~#데일리 #데일리호텔 #개발 #개발자 #기획 #기획자 #마케팅 #마케터 #데이터분석 #인사이트 #도입후기 #일지
조회수 1370

★워라벨★ 살아 숨시는 프리윌린을 소개합니다 :)

안녕하세요. 매쓰플랫이에요.그동안 매쓰플랫을 만드는 회사는 어떤 회사일까궁금해 하시는 분들이 계실거 같아요~!쾌적한 근무 환경에서,좋은 서비스가 나오는 거 다들 아시죠?지금부터 '프리윌린'을 소개해드릴게요 :)1. 프리윌린 소개저희는 수학 교육에 필수적인 모바일 솔루션,매쓰플랫(mathFLAT)을 만들어 나가고 있습니다.2016년 8월 정식으로 서비스를 런칭하였고,2017년 3월에는 국내 최고의 엑셀러레이터 '프라이머'로부터가능성을 인정받아 시드 투자를 유치하였습니다!열려있는 사고의 젊은 직원들로 구성되어 있으며,각자의 역량을 충분히 발휘 할 수 있는 환경을 조성해줍니다.우리 IT 기술을 이용한 따뜻한 혁신, 같이 만들어요.- 근무 형태 : AM 10 - PM 07 (주5일제, 주말근무 절대 no no!!!!)- 보험,의료 : 4대 보험 - 개인 장비 : 듀얼 모니터, 사무용품 등등- 회식 참여는 자유~! 강요하지 않아요 :)아침 출근 길 2호선....정말 출근대란이거 아시죠?프리윌린에 다니면 출근 시간이 10시!지하철 앉아서도 올 수 있어요 ♥모든 직원은 '00쌤'으로 통일! (대표님도 열외 없습니다!)그외 필요한 사항에 관하여 최대한 지원해 드립니다.사무실  모습 중 일부!!!  ▼ 자세한 내용은 '사무실 투어'에서 보여드릴게요 :) ▼소회의실 & 휴게실사무실 전경- 식사 : 중식제공, 석식제공- 간식 : 고급 캡슐 커피 제공, 간식 무한 제공, 먹을 거 빼면 시체 프리윌린!식대 제한 없는 점심식사...시간 ♥회사 근처가 샤로수길, 핫한 맛집 천국!요즘 유명한 샤로수길 맛집은 모두 가봤어요~!▼ 실제 먹었던 점심 식사 메뉴중 극히 일부!!!!! ▼- 연차/월차 : 월차 제공현재 프리윌린에서는 반차/월차를 사용 할 수가 있어요.또한 휴가 희망 시에는,최대 평일 5일까지 사용이 가능하답니다 :)주말 포함을 한다면....무려 9일동안 휴가가 가능~! 실화냐???본인 할 일만 열심히 한다면, 적절한 휴식도 ok!방탈출카페, 코인노래방, 영화감상, 헬스, 보드게임 등등좋아하는 취미가 있다면, 칼퇴하고 함께해요 ^__^매쓰플랫 만드는 회사 '프리윌린'에 대한 궁금증이 좀 풀리셨나요?최적의 근무 환경에서, 최고의 서비스를 만들기 위해서모든 팀이 항상 노력하고 있습니다.프리윌린은 항상 열려있는 마음으로함께 성장 할 분을 언제나 환영합니다 :)
조회수 1213

정책 콘텐츠 디자인하기 - Spoqa Policy 작업기

안녕하세요. 스포카 Product designer 박지선입니다.Spoqa Policy가 최근에 런칭되었습니다. Spoqa Policy는 spoqa의 정책과 약관을 볼 수 있는 사이트입니다. 기존의 스포카 약관 및 정책 페이지는 효율적인 업데이트가 어려운 상황이었고 이런 상황을 개선하기 위해 독립적인 사이트가 필요했습니다. 디자인을 진행하면서 했던 생각들을 공유합니다.정책이란 무엇인가서비스 사용자로서 정책 콘텐츠는 무관심의 대상 혹은 귀찮은 존재입니다. 솔직히 저는 서비스 가입 시 읽지도 않고 동의한다고 체크박스를 클릭한 적도 많습니다. 하지만 약관 및 정책은, 서비스 제공자와 사용자 사이에 일어나는 정보를 주고받는 일련의 과정에 대한 약속을 서술한 것입니다. 또한, 법적 효력을 지니기 때문에 굉장히 중요한 문서입니다. 그 중요성에 비해 한국에서는 별도의 정책 사이트를 가진 곳 혹은 다른 메인 페이지들과 비교하여 공을 들인 곳은 드물었습니다. 읽을 수 있는 콘텐츠로 존재하기보다는 서비스가 필수적으로 갖춰야 하는 성격의 아이템으로만 보였습니다.정책 콘텐츠 디자인의 역할은?(법적으로) 중요하지만 (시각적으로) 중요함을 놓치고 있는 정책 콘텐츠를 어떻게 하면 더 취지에 맞게 잘 드러낼 수 있을까 고민이 생겼습니다. 우선 약관과 정책이 무엇으로 정의되고 있고 어떤 역할을 해야 하는지 알아야 한다고 생각했습니다. 리서치 중 이 고민의 나름의 답을 얻을 수 있었습니다.정책 콘텐츠 디자인은 단순히 정책 내용을 표기해주는 것으로 끝나면 안 됩니다. 정책들이 바탕이 되어 개인정보를 투명하게 관리할 수 있고, 모은 정보가 서비스를 개선하는 데 사용되며, 사용자에게 해가 되는 것이 아니라는 점 또한 내포하여 전달해야 합니다. 즉, 이해하기 쉽고 신뢰할 수 있는 콘텐츠로 보이도록 디자인해야 한다는 말로 줄일 수 있겠습니다. 지면 관계상 양이 굉장히 많아서 혹은 전략적으로 이해하기 어렵게 하는 경우도 있는지도 모르겠습니다만(^^;), 스포카 정책에서는, 웹에서는 그럴 필요가 없다고 생각했습니다.정책 콘텐츠는 조항의 나열이기 때문에 일일이 읽으면 굉장히 지루할 수밖에 없습니다. 그렇다고 이해하기 쉽게 콘텐츠 가공을 많이 가하면 유지보수가 굉장히 어려워집니다. 그러므로 요약하여 제공해주어야 합니다.500px와 Pinterest에서는 이를 충실하게 따랐습니다. 확실히 요약문만 읽어도 약관/정책이 어떤 의도로 만들어졌는지, 사용자에게 어떤 혜택이 있는지 쉽게 이해할 수 있습니다.개선점 파악하고 CSS로 해결하기이번에는 콘텐츠에 대한 이해를 마치고 나서 작업하는 과정에서 느꼈던 주요 개선점과 해결방향을 함께 소개하겠습니다.1. 처음부터 끝까지 타이포그라피콘텐츠 특성상 9할 이상이 텍스트이기 때문에 타이포그라피가 전부라 해도 과언이 아니었습니다. 정책 콘텐츠라고 특별한 타이포그라피가 필요한 것은 아닙니다. 우리가 알고 있는 올바른 타이포그라피의 조건들을 충족시켜주면 됩니다.글자 크기 (font-size)기존에는 글자가 작아 제대로 읽기 어려웠고, 모바일앱 등 다양한 스포카 제품의 스크린 크기에 대응하기 어렵게 되어 있었습니다. 글자는 장식으로 의도한게 아닌 이상 가독성이 좋아야 한다고 생각합니다. 그래서 읽기 쉬운 크기이되 방대한 텍스트량을 고려하여 글자 크기를 정하였습니다.글자 두께 (font-weight)당연한 이야기지만 같은 글자 두께로만 이루어져 있으면 단어 식별이 어렵습니다. 정책 이름, 조항 이름, 조항 세부 내용 등 텍스트 성격에 맞게 글자 두께를 스타일링했고, 내용 파악에 용이하도록 했습니다.글줄 길이 (line-length)웹에서 글줄 길이라고 하면, 글줄 길이 = 콘텐츠 너비 = container 박스의 너비입니다. 기존에는 글줄 길이가 길어서 읽기에 부적합했습니다. 게다가 정책에는 여러가지 어려운 용어들이 등장하여 읽을때 눈의 피로도가 가중됩니다. 그래서 읽기 쉽도록 콤팩트한 길이로 너비를 줄였습니다.리스트 스타일 타입 (list-style-type)앞서 말했듯이 정책 콘텐츠는 조항의 나열입니다. 그렇기 때문에 ul(unorderd list), ol(ordered list), li(list)를 빼놓을 수 없습니다. 기존에는 리스트 스타일 순서가 국가별, 정책 별로 중구난방으로 되어 있었습니다. 이를테면, 어떤 정책에서는 두번째 위계의 리스트가 upper-latin(대문자)으로 나오는데 다른 정책에서는 decimal(십진법 숫자)로 나오는 식이었습니다. 그래서 어떤 정책이든 일관된 순서로 리스트 스타일이 적용되도 어색하지 않는 방향으로 정리했습니다. 그 중 첫번째 리스트 다음에 나오는 두번째 ol의 li는 첫번째 리스트보다 위계가 높아보이지 않고 웹페이지가 아닌 종이 위에 옮겼을 때에도 어색해 보이지 않도록 lower-latin(소문자)으로 선택했습니다.줄바꿈 (word-break)다행히(?)도 아직 스포카에서 운영하는 제품은 한국, 일본 두 나라에서 운영중입니다. 그렇기 때문에 두 나라의 언어 체계도 신경써야 했습니다. 두 언어의 띄어쓰기 규칙이 다르다는 점이 좁은 너비의 화면에서 문제가 되었기 때문입니다. 한국어에서는 각 단어간 띄어쓰기를 원칙으로 하지만 일본어는 띄어쓰기를 사용하지 않습니다.CSS에서 word-break 단어 중간에 줄바꿈을 어떻게 하는지 설정하는 프로퍼티입니다. 여기에 break-all을 지정하면 단어 중간에 줄바꿈이 됩니다. 반면 keep-all은 단어 중간이 잘리면서 줄이 바뀌는 현상이 없습니다. 이를 이용하여 한국어는 keep-all 속성을 적용해서 오른쪽 흘림의 장점이 드러나도록 했고, 일본어는 break-all로 지정하여 일부 문장의 길이가 container 너비를 넘어가지 않도록 했습니다.              좌. {word-break: break-all;} 한 일본어 | 우. {word-break: keep-all;} 한 한국어2. 정책 콘텐츠 디자인 후처리의 한계기존에는 웹페이지 임에도 불구하고 링크가 링크로 작동하지 않았습니다. 텍스트로서 단순 줄글 나열에 그치고 웹이라는 도구의 특성을 살리지 못하고 있었던 것입니다. 그래서 필요한 부분들에 별도로 anchor 처리를 했습니다. 더불어 정보가 잘 읽히기 위한 약간의 시각화가 필요하다고 생각했고, 마냥 딱딱하게 보이지만은 않도록 스타일링을 시도했습니다. 하지만 문서가 수정되고 웹페이지로 변환되는 과정에서 별도의 스타일을 지정하는 것은 꽤나 수고스러운 지점이었습니다. 별도의 스타일을 부분적으로 일일히 지정하여 정책에 대한 이해도는 높아질 수 있겠지만 유지보수 비용이 높아지고, 전면적으로 드러나는 콘텐츠가 아니다보니 효용성에서는 다소 떨어질 수 밖에 없다고 판단했습니다. 그래서 결국 최소한의 후처리만 진행하게 되었습니다.마치며프로젝트를 진행하면서 배운 것들 중에 막상 사정상 프로젝트 내에 실행하지 못했던 점도 있었습니다. 그런 점은 아쉬웠지만 평소에 생각해볼 일이 없던 콘텐츠를 처음부터 하나하나 고민해보는 그 과정이 재밌었습니다. 남들은 깊이 고민해볼 수 없는 좋은 기회를 가지게 된 것 같았기 때문이었던 것 같습니다. 어떻게 보면 사소한 것들인데 국내에도 이런 작업기가 실무자 사이에서 많이 작성되었으면 좋겠다는 생각을 했습니다.감사합니다.#스포카 #디자인 #디자이너 #디자인팀 #인사이트 #업무환경 #프로젝트 #협업 #CSS

기업문화 엿볼 때, 더팀스

로그인

/