스토리 홈

인터뷰

피드

뉴스

조회수 1604

레진 기술 블로그 - SVG를 이용해 간단한 웹 게임 만들어보기

근래 소규모로 게임 프로그래밍 스터디를 시작했습니다. 서비스 UI를 개발하는 프론트엔드개발자에게 있어 게임 프로그래밍은 언제나 커튼 뒤에 비친 풍경처럼 흐릿하고 형체를 쉽게 알 수 없는 신비한 존재입니다. 이번에 미약하게나마 커튼을 걷어 창문 너머 펼쳐진 풍경을 감상해 보자는 게 이번 스터디의 개인적인 목표입니다.왜 SVG를 선택했나게임을 만드는 데 어떤 기술을 사용할지 고민했습니다. 일반적인 DOM은 쉽게 객체를 조작할 수 있지만, 문서의 엘리먼트를 추상화한 것에 불과하므로 다양한 도형을 만들거나 좌표계에 사상(寫像, Mapping)1하기 쉽지 않습니다.캔버스는 그래픽 처리에 환상적인 성능을 보여주고 원, 다각형 등 다양한 도형을 그리기 쉽지만 일일이 객체화해야 하고 이를 관리하기 쉽지 않습니다. 여기에 필자가 캔버스를 좀 처럼 써 본 경험이 없어서 무턱대고 사용하기에도 부담을 느꼈습니다.하지만 SVG는 이 두 장점을 모두 갖고 있습니다. 확장 가능한 벡터 그래픽(Scalable Vector Graphics)이라는 이름을 통해서 알 수 있듯이 그래픽 요소를 그리는데 적합한 포멧이며 DOM처럼 추상화된 객체도 지원합니다.어떤 게임을 만들었나필자가 만든 게임은 크롬에 내장된 Running T-Rex와 비슷한 것으로 JUMPING CAR라고 이름을 붙였습니다. 플레이해보고 싶은 분은 uyeong.github.io/jumping-car를 방문하시기 바랍니다.규칙은 단순합니다. 게임을 시작하면 자동차가 달려나가고 이윽고 장애물을 만나게 됩니다. 장애물을 뛰어넘으면 점수가 1씩 증가하지만 부딪히면 게임이 종료됩니다.이 글에서는 게임을 만드는 과정을 소개하기보다 SVG를 이용하면서 알게 된 몇 가지 주요한 내용을 다룹니다.Pattern을 사용한 요소는 느리다이미지를 반복해서 출력할 때 HTML에서는 CSS의 background-url 속성으로 간단히 해결할 수 있습니다. 하지만 SVG에서는 Pattern 요소를 이용해야 합니다.아래 그림처럼 pattern#pat-land 요소를 만들고 이를 rect.parallax에서 사용하여 그림을 반복 출력되도록 합니다. 그리고 rect.parallax를 조금씩 Transform 하여 앞으로 이동하도록 구현합니다.코드는 다음과 같습니다(예제: svg-parallax-test/parallax1).<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="..."> <defs> <pattern id="pat-land" x="0" y="0" width="..." height="100%" patternUnits="userSpaceOnUse"> <image x="0" y="0" xlink:href="../images/land.png" width="..." height="100%"></image> </pattern> </defs> <g> <rect class="parallax" x="0" y="0" width="..." height="100%" fill="url(#pat-land)" transform="translate(0,0)"></rect> </g> </svg> 표면상으론 전혀 문제가 없는 코드지만 크롬 브라우저에서 이 코드를 실행하면 프레임이 50 이하로 떨어지는 경우도 발생합니다. 이 정도면 육안으로도 화면의 움직임이 매끄럽지 않게 느껴지는 수치입니다.따라서 성능에 영향을 주는 pattern을 제거하고 image 요소로 대체합니다. image 요소는 자동으로 반복할 수 없으므로 두 개의 요소를 이어 붙여 사용합니다(예제: svg-parallax-test/parallax2).<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="..."> <g> <image x="0" y="0" xlink:href="../images/land.png" width="..." height="100%"></image> <image x="..." y="0" xlink:href="../images/land.png" width="..." height="100%"></image> </g> </svg> 실행 결과 프레임이 안정적이고 육안으로도 이질감을 느낄 수 없습니다. 이처럼 Pattern을 이용한 SVG 요소를 애니메이션 처리할 때에는 주의가 필요합니다.일부 안드로이드 기종에서의 성능 문제pattern을 제거하고 image로 대체하면서 Parallax 처리 시 발생한 문제를 해결할 수 있습니다. 하지만 image로 대체하더라도 일부 안드로이드 기종에서는 여전히 성능 문제가 발생합니다.아래 영상처럼 image 요소를 Transform 할 경우 프레임이 급격하게 떨어집니다. 이는 크롬 개발자 도구에서도 쉽게 발견하기 힘든데 CPU 성능을 10배 줄여 테스트해도 수치상으로는 크게 차이 나지 않기 때문입니다.<style>.video-container { position: relative; padding-bottom: 56.25%; padding-top: 30px; height: 0; overflow: hidden; } .video-container iframe, .video-container object, .video-container embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }</style><iframe width="560" height="315" src="https://www.youtube.com/embed/F_-zXf1jb8I?rel=0" frameborder="0" allowfullscreen="">이 처리를 DOM으로 바꿔보면 어떻게 될까. 놀랍게도 큰 차이를 보여줍니다(예제: svg-parallax-test/parallax3).<iframe width="560" height="315" src="https://www.youtube.com/embed/VXQ1aT79D2s?rel=0" frameborder="0" allowfullscreen="">SVG에 대한 최적화 상황은 브라우저마다 조금씩 다릅니다. DOM은 과거부터 최적화 노력이 많이 이뤄졌지만, SVG는 pattern 요소나 다음 절에서 이야기할 리페인팅 문제 등 성능 문제를 일으키는 부분이 아직 남아있습니다.따라서 충돌 계산처럼 특별히 좌표계 연산이 필요 없는 배경은 DOM으로 옮기고 자동차, 장애물만 SVG로 구현했습니다(예제: svg-parallax-test/parallax4).SVG는 항상 페인트를 발생시킨다SVG는 이상하게도 svg 요소의 크기를 고정하더라도 자식 요소를 변경하면 페인팅이 발생합니다. 아래는 svg 요소의 자식 요소인 rect의 좌표를 수정하는 예제 코드입니다.<svg"http://www.w3.org/2000/svg" width="500px" height="500px" viewBox="0 0 500 500"> width="500" height="500" x="0" y="0"> </svg> [removed] setTimeout(() => { rect.setAttribute('x', '100'); }, 3000); [removed] svg는 viewBox로 설정한 사이즈 만큼 내부에 그림을 그립니다. 즉, 내부의 어떠한 그래픽적 변화가 문서에 변화를 일으킬 가능성이 없습니다. 그래서 개인적으로 쉽게 이해가 되지 않는 렌더링 흐름입니다.그러면 SVG 요소의 크기나 좌표를 바꾸지 않고 색상 또는 투명도를 변경하면 어떨까요. 이번에는 rect 요소의 좌표가 아니라 색상을 바꿔봅니다.<svg"http://www.w3.org/2000/svg" width="500px" height="500px" viewBox="0 0 500 500"> width="500" height="500" x="0" y="0"> </svg> setTimeout(() => { rect.setAttribute('fill', '#ebebeb'); }, 3000); 그래도 페인트가 발생합니다. 하지만 앞서 진행한 테스트의 페인팅 시간은 수십 마이크로세컨드로 크게 의미가 없어 보입니다. 그래서 현재 서비스 중인 레진코믹스의 메인페이지에 SVG를 넣고 테스트했습니다.페인팅에 0.51ms가 소요됐습니다. 작다고 느낄 수 있지만 페이지 전반적으로 영향을 줄 수 있으며, 애니메이션 처리 중인 SVG라면 성능적 문제를 발생시킬 수 있는 부분입니다.그래서 svg 요소에 null transforms 핵을 선언해 문서 상위 레벨까지 페인팅이 전파되지 않도록 합니다.<svg"http://www.w3.org/2000/svg" width="500px" height="500px" viewBox="0 0 500 500" style="transform:translate3d(0,0,0)"> width="500" height="500" x="0" y="0"> </svg> 또는 아예 svg 내부의 요소를 개별로 분리하는 방법도 있습니다(참고: Doubling SVG FPS Rates at Khan Academy).<svg> fill="red" transform="translate(2px, 3px)"> fill="blue" transform="scale(2)"> </svg> style="transform:translate(2px, 3px)"> <svg> fill="red"> </svg> style="transform:scale(2)"> <svg> fill="blue"> </svg> 끝으로여기까지 SVG를 이용해 게임을 개발하면서 만나게 된 이슈와 해결 방법을 간단히 정리했습니다.필자는 간단한 게임은 SVG로 만들 수 있고 괜찮은 성능을 보장할 것이라고 기대했습니다. 하지만 현실은 달랐습니다. 이 글에서 다룬 문제 외에도 사파리와 크롬 브라우저의 성능 차이, 자동차를 움직일 때 버벅이는 현상 등 다양한 문제를 해결해야 했습니다. 객체의 개수도 적고 애니메이션도 복잡하지 않은 단순한 게임이었는데 말이죠.다음 게임은 캔버스로 시작하고자 합니다.공간(空間)의 한 점에 대(對)하여, 다른 공간(空間) 또는 동일(同一)한 공간(空間)의 한 점(點)을 어떤 일정(一定)한 법칙(法則)에 의(依)하여 대응(對應)시키는 일 ↩
조회수 1786

[Tech Blog] Compare Software Architectures: Monoliths, SOA and Microservices

요즘 Software architecture 라는 단어를 들으면 아마도 Client engineer 분들은 MVC, MVP, MVVM 이 먼저 떠오를 것이고, Server engineer 분들은 Microservice architecture 를 먼저 떠오를 것 같네요. Clean architecture 나 Event-driven architecture 등을 떠올리는 분들도 계실 것 같구요. Software architecture 를 어떻게 정의할 수 있을지에 대해서는 Software architecture: The important stuff 에 적어 봤으니 여기에선 넘어가도록 하죠. https://mherman.org/blog/developing-microservices-node-react-docker/ Microservice architecture 는 대세라고 말할 수 있습니다. Netflix, Amazon 등 굴지의 기업들이 성공적으로 적용해서 운영하고 있고, 국내 기술적으로 뛰어난 많은 기업들 역시 이미 적용했거나 시도하고 있습니다. “남들 다 하는데 이러다 도태 되는거 아냐?” 라는 생각이 들 정도로 말이죠. 그러나 이전 글에서 얘기했듯이 정답은 없으며, Microservice architecture 역시 예외는 아닙니다. 모든 선택에는 Tradeoff 가 있고, Microservices 는 다른 architecture 에 비해 어떤 장점이 있는지 살펴봐야 합니다. 이와 관련하여 정말 많은 좋은 글들이 이미 있으니, 이 글에서는 몇 가지 Software architecture 들을 가볍게 정리 및 비교해 보도록 하겠습니다. Monolithic Architecture Monolithic architecture 는 Microservice architecture 의 장점을 얘기할 때 반드시 언급될 정도로 대척점에 있는 architecture 입니다. Monolithic architecture 는 하나의 큰 덩어리로 구성되어 있고, 모든 기능이 하나의 프로젝트에 집중되어 있습니다. 쉽게 구성이 가능하고 초기에 기능을 빠르게 추가하기에 용이하나, 복잡도가 늘어날수록 기능 추가 속도가 느려지고 문제가 발생할 가능성이 높습니다. PoC(Proof of Concept)를 위한 가벼운 프로젝트나 아주 초기 프로젝트에 적용 가능합니다. Semi-Monolithic Architecture Monolithic architecture 보다는 작지만, 여전히 기능들이 몇 개의 프로젝트에 집중되어 있는 architecture 입니다. 예를 들어 frontend 와 backend 프로젝트를 나누었지만 각 프로젝트가 monoliths 인 경우 semi-monolithic architecture 라고 볼 수 있습니다. 다만 Semi-monoliths 의 경우 몇 군데에서 언급한 것을 볼 수 있지만, 일반적으로 사용되는 architecture 용어는 아닌 듯하고, Semi-monoliths 로 구분될 수 있는 경우 Monolithic architecture 라고 분류할 수 있을 듯합니다. 단순 frontend / backend 보다 좀 더 많은 수의 service 로 분할된 architecture 를 구성하더라도 각 service 가 monoliths 로 구분될 수 있다면 여전히 monolithic architecture 를 구성하고 있다고 할 수 있습니다. Service-Oriented Architecture 여러 조직이 다수의 application 사이에서 로직과 데이터를 공유하기 위해 제안된 architecture 입니다. Monolithic architecture 와 달리 기능을 나눠서 여러 개의 서비스로 구성하고, 서비스 사이는 API 를 통해서 통신합니다. Microservice architecture 와 Service-oriented architecture (SOA) 를 비교하기 위해 Enterprise Service Bus (ESB)가 많이 언급됩니다. ESB는 Enterprise Application Interface (EAI) 와 대조적으로 가볍고 흔한 통신을 위해 제안되었으나, 통제와 관리를 위해 점점 무거운 방향으로 진행되면서 최초의 의도와 달라졌습니다. SOA 가 무거워짐에 따라 최초의 의도였던 빠른 적용, 민첩한 개발 및 적은 통합 비용과 멀어지게 되면서 자연스럽게 도태되었습니다. 서비스 사이에 데이터베이스를 공유할 수 있느냐 아니냐로 Microservice 와 구분을 짓는 의견도 있습니다만, SOA의 정의가 넓어서 이 부분에 대해서는 이견들이 있습니다.   https://dzone.com/articles/microservices-vs-soa-2 SOA가 넓은 범위에서 정의됐기 때문에 ESB 나 DB 공유 여부로 SOA 를 규정 짓기는 어렵습니다. 정의 상으로 보면 Microservice architecture 역시 SOA 의 일종이라고도 볼 수 있습니다. Microservice 의 예시로 자주 등장하는 Netflix 와 Amazon 역시 Microservice 라는 단어가 사용되기 전에는 스스로의 시스템을 SOA 라고 지칭했습니다. Microservice Architecture: The O’Reilly Book 의 공동 저자 Matt McLarty 는 Learn from SOA: 5 lessons for the microservices era 라는 글에서 SOA 와 Microservice architecture 가 같은가 다른가는 그다지 중요한 것이 아니며, 우리가 SOA 로부터 어떤 것들을 배웠는가가 중요하다고 강조합니다. Microservice Architecture Microservice architecture는 규모가 빠르게 커져도 제품 생산 속도를 빠르게 유지하고 안정성을 가질 수 있는 architecture 입니다. 충분히 작은 서비스들이 서로 통신하면서 기능을 수행합니다. Microservice architecture 를 SOA의 잘 구현된 형태라고 보는 시각도 있지만, micro 라는 단어가 SOA 에서 정의하는 서비스보다 작은 크기의 서비스임을 명시적으로 표현하기 때문에 매우 다르다는 의견 역시 있습니다. Microservice architecture 는 각 서비스의 크기를 작고 가볍게 유지함으로써 더 깔끔하고 명확하게 서비스를 유지할 수 있습니다. 잘 구성될 경우 특정 서비스에 장애가 생겨도 다른 서비스에 영향을 적게 미치거나 유연하게 대응할 수 있기 때문에 전체 시스템 오류(e.g Single Point of Failure)를 방지할 수 있습니다. 각 서비스는 독립적으로 배포 및 확장 가능하기 때문에 기능 배포가 빠르고 많은 트래픽에 유연하게 대처할 수 있습니다. 한편 Microsoft architecture 는 구조적인 면에서 복잡도가 증가하며, 많아진 서비스 및 서비스 간 통신에 대한 유지 보수 비용이 추가됩니다. 이를 대응하기 위해서 충분히 자동화되고 잘 구성된 시스템이 필수적으로 필요합니다. Conclusion 판단과 결정은 근거를 필요로 합니다. 가끔 감을 믿고 밀어붙여야 할 때(e.g 오늘 점심은 해장국을 먹어야 한다던가)도 있다는 점은 인정합니다. 하지만 그 역시 설득력을 가지지 못하면 하나의 목표를 향해 모두가 미친듯이 달려가기는 어렵겠죠. Software architecture 를 결정하기 위해서는 추구하는 비전과 비지니스를 이해하고 그에 맞는 근거 하에 모든 팀원을 판단하고 설득해야 합니다. 버즈빌 에서는 더 빠르고 큰 성장을 위해 Architecture Task Force 팀을 구성하였습니다. ATF 팀은 버즈빌에 최적인 Software architecture 를 판단하고, 구성하고, 실행하기 위해 바쁘게 움직이고 있습니다. Buzzvil Services Characteristic:  제품이 다양하고 제품별로 제공해야 할 기능이 많다. 각 제품이 공통적으로 필요로 하는 기능이 많다. 서비스 혹은 기능별로 대응해야 하는 트래픽이 다르다. 전체 서비스 장애 발생 시 많은 후속 문제가 발생한다. 트래픽 변동이 특정 이벤트에 의해 크게 일어날 수 있다.  Buzzvil 의 제품과 비지니스는 위와 같은 성격을 가지고 있습니다. 이를 바탕으로 우리는 Microservice architecture 가 가장 적절하다고 판단하였고, 현재 microservices 의 장점을 살리면서 안정적이고 빠르게 우리가 원하는 목표에 도달할 수 있도록 다양한 방면에서 변화를 가져가고 있습니다. References  Learn from SOA: 5 lessons for the microservices era Microservices vs. SOA On monoliths, service-oriented architectures and microservices Microservices.io Microservices Resource Guide Design Microservice Architectures the Right Way Developing Microservices – Node, React, and Docker    *버즈빌에서 개발자를 채용 중입니다. (전문연구요원 포함)작가소개 Whale, Chief Architect “Keep calm and dream on.”
조회수 1369

“디자인과 기술을 이어주는 존재, 마크업 개발자를 함께 알아볼까요?” - 유저플로우셀 오혜진

'마크업 개발자', 아직은 우리들에게 다소 생소한 직군이죠. '마크업 개발자'는 디자이너와 개발자 사이에서 '오작교' 같은 역할을 하는 아주 중요한 포지션이에요. 오늘은 코인원의 마크업 개발자로 활약 중인 혜진님과 이야기를 나눠보려 해요. 자신의 위치에서 묵묵히 유저 친화적인 웹 환경을 만들어나가고 있는 혜진님을 만나러 가보시죠!사실 이미 혜진님은 지난 4월 13일(토), 테크 업계 여성들의 목소리에 집중하는 소중한 행사 ‘Women Techmakers Seoul 2019’에서 ‘스타트업에서 마크업 개발자로 살아남기’를 주제로 자신의 이야기를 널리 알리고 왔답니다. 스타트업 그리고 코인원에서 마크업 개발자로 살아남는 혜진님만의 방법은 무엇일까요? :-)Q. 혜진님 안녕하세요, 자기소개 부탁드립니다.안녕하세요, 코인원 유저플로우셀에서 마크업 개발자로 일하고 있는 오혜진입니다. 유저플로우셀은 암호화폐 거래와 프로차트와 같은 트레이딩 영역을 제외한 전반적인 서비스 영역을 담당하고 있어요. 특히 ‘셀'이라는 목적조직으로 개편된 이후 PM, 디자이너, 개발자가 한곳에 모여 누구나 코인원에서 거래를 하고 싶은 마음이 들도록 매력적인 곳으로 탄생시키고 있답니다. 저는 셀안에서 마크업 개발자로 일하며 디자이너와 프론트엔드 개발자를 이어주는 다리 역할을 하고 있습니다.Q. 지난 ‘Women Techmakers Seoul 2019’에서 마크업 개발자를 널리 알리는 발표를 했다고 들었어요. 어떤 내용인지 소개해주세요!감사하게도 ‘스타트업에서 마크업 개발자로 살아남기' 라는 주제로 300명이 넘는 관중들 앞에서 발표를 하고 왔습니다. (사실, 많은 분들이 와주셔서 땀이 좀 나기도 했고요;) 마크업 개발자는 스타트업에서 발견하기 힘든 직군이기도 해요. 보통은 웹 에이전시에 많이 속해 있거든요. 제가 마크업 개발자로 일한지 6년이라는 시간 동안 스타트업에서 어떤 방식으로 일해왔는지 알리고 싶었어요. 그래서 지금까지 이런 일들을 해왔고, 앞으로도 더 활발하게 할 것이라고 속시원하게 말하고 왔습니다.Q. 마크업 개발자는 구체적으로 어떤일들을 하나요?마크업 개발자는 한마디로 디자인(Design)과 기술(Tech)의 오작교 같은 존재입니다. 디자인의 의도가 개발과 충돌하는 부분은 없는지 파악하고, 개발에 잘 녹아들 수 있도록 프론트엔드의 앞단을 맡고 있어요. 코인원 웹 서비스에서 제공하는 신규 기능의 마크업 개발을 담당하고, 운영하면서 생긴 이슈들을 처리합니다. 또한 마크업 레거시에 대한 유지보수 작업도 병행하죠.예를 들어, 코인원의 회원가입 페이지를 제작할 때 디자인 작업을 먼저 들어갑니다. 그럼 디자인 작업을 바탕으로 개발자들이 기능을 만들어 넣게 돼요. 이 때, 기능적인 개발을 제외하고 UI(User Interface)적인 부분을 제가 담당합니다. 회원가입 페이지에는 이메일 인증, 휴대폰 인증 등 여러가지 개발요소들이 많아요. 그래서 개발하기 전에 기능이 들어가는 기본적인 레이아웃을 만들어 개발자에게 전달합니다. 마크업 작업이 바탕이 되어 그 위에 기능 개발이 이뤄진다고 보시면 돼요.디자이너가 레시피를 만드는 사람이라면, 마크업 개발자는 레시피 재료를 세팅해 주는 사람이에요. 개발자들은 세팅된 레시피를 끓이고 버무려 요리를 완성시키고요. 저는 좋은 요리가 탄생할 수 있도록 중간과정을 도와주는 역할인거죠. ▲ 'Women Tachmakers 2019'에서 발표에 열중한 혜진님!Q. 디자인과 기술의 중간 역할을 담당하고 계시군요, 사실 중간자의 역할이라고 하면 이어주는 과정에서 고충(?)이 생길 것 같아요.아무래도 디자이너와 개발자, 양쪽과 다 소통해야하는 부분입니다. 디자이너 입장에서는 ‘왜 프론트엔드에서 이 디자인이 안되는걸까?’ 라는 불만이 생길때도 있고, 프론트엔드에서는 ‘왜 디자인이 이렇게 들어가야 하는걸까?’ 라고 이해를 못할 때도 있어요. 서로의 이해관계를 잘 전달해야 한다는 점이 나름의 고충이죠. 코인원에서는 ‘디자이너 - 마크업 개발자 - 프론트 개발자’의 협업 프로세스를 정립해서 각자가 맡은 분야에 집중 할 수 있는 초석을 다졌어요. 무엇보다도 배경이 다른 세 개의 직군이 원활하게 소통할 수 있는 체계가 잡혀 고충이 해결되고 있습니다 :) Q. 그렇다면 마크업 개발자는 어떤 부분을 기여한다고 볼 수 있나요?코인원 메인 화면에 기능 개발을 추가하지 않고도 마크업단에서의 처리만으로도 쉽게 변화를 줄 수 있습니다. 메인화면의 배너 이미지는 유저들이 코인원에 접속해 제일 먼저 마주하는 부분이죠. 그래서 유저들이 코인원의 시각화된 정보를 빠르게 접할 수 있도록 이미지를 교체합니다. 웹 페이지의 운영 측면에서 비주얼 개편을 빠르게 할 수 있는 환경을 만들어 놓고 대응하는거에요.곧 코인원 마이페이지 화면이 개편될겁니다. 웹 페이지를 새로 만든다는 것은 무에서 유를 창조하는 과정과 같아요. 제가 마크업 개발을 잘 해놓으면 다른 직군에게도 도움이 됩니다. 개발 속도도 더 잘 붙고, 디자인에서도 빈공간이 없는 페이지가 탄생하는거죠. 최대한 밑바탕을 꼼꼼하게 만들어 모두가 일에 더 집중할 수 있는 환경을 만든다고 보시면 돼요.Q. 코인원 마이페이지에서 새롭게 바뀌는 부분은?기존의 마이페이지는 유저들이 보기에 정리가 잘 안되어있다는 느낌이 있었어요. 어떤 인증과정을 끝마쳐야 하는지 한눈에 들어오지 않는 부분이 있었거든요. 이번에 개편될 마이페이지는 좀 더 명확해졌습니다. 이전의 인증페이지가 도돌이표의 느낌이었다면, 이번에는 UX(User experience)를 생각해서 flow 개선도 많이 이뤄졌습니다. 편리한 암호화폐 거래 경험을 코인원에서 느낄 수 있어요. (새롭게 바뀔 마이페이지 많은 기대 부탁드립니다! 물론 편리한 암호화폐 거래도 언제나 코인원!)Q. 유저들에게 편리한 거래경험을 선사하기 위해 어떤 가치를 가장 중요시 여기나요? 저는 중간자이므로 유저들 뿐만 아니라 개발까지 두 가지 측면을 모두 고려합니다. 유저의 입장에서 사용성과 접근성이 용이한 마크업을 짜려고 하고, 개발측면에서는 유지보수가 편리한 마크업을 최대한 짜려고 해요. 개발하기 편한것과 사용하기 편한 것은 다른 맥락이거든요. 요새는 코인원 디자인시스템을 적용하고 있어요. 디자이너 분들이 정리해주신 디자인 시스템을 잘 적용시켜서 코드적으로도 재사용성이 용이하게 관리가 되도록 하고, UI도 정돈이 되어가는 과정을 진행 중입니다. 이런 과정을 계속 거치면 유저들에게 편리한 거래 경험을 선사하는 부분은 놓치지 않을 것 같아요.▲ 마크업에 열중하고 있는 혜진님 (약간의 설정샷 +_+)Q. 코인원 크루로 일하면서 장점을 뽑자면?유저플로우셀은 코인원이 셀이라는 목적조직으로 개편되고나서 만족도가 높은 셀이라고 알고 있어요. 업무도 많은 편인데, 톱니바퀴처럼 잘 맞물린다는 느낌이거든요. 특히 일에 대해서 선긋지 않고, 이슈가 발생했을 때 해결할 수 있는 부분들을 빠르게 파악해주는 부분들이 정말 좋아요. 속도랑 효율성 측면에서 이만큼 해낼 수 있는 팀은 앞으로 만나지 못할 것 같아요. 항상 원활한 업무 소통을 위해 힘써주시는 셀원들에게 감사 드립니다!Q. 앞으로 이루고 싶은 목표가 무엇인가요?회사 안 뿐만 아니라, 바깥에서의 활동도 꿈꾸고 있어요. 마크업 개발자들이 모두 모여 이야기할 수 있는 CSS 컨퍼런스를 열어 좀 더 커뮤니티를 활성화 시키고 영향력을 높이고 싶습니다. 아직 마크업 개발자들만이 모여서 이야기 할 수 있는 곳이 부족하거든요. 저의 이야기도 차곡차곡 쌓아서 여러 창구를 통해 들려드리고 싶고요.코인원에서는 지금 하는 것 이상으로 마크업 개발도 열심히 할거에요. 우선 단기적인 목표로, 프론트엔드에서 사용하고 있는 angular에 대한 이해력을 높일 겁니다. 마크업 컴포넌트 단위에 최적화 된 CSS로 개편해서 사용하지 않는 스타일 리소스가 최소화가 되도록 만들거에요.▲ 마크업 개발자에 많은 관심 부탁드려요 :)디자이너가 디자인에 집중할 수 있게, 개발자가 개발에 집중할 수 있게 ‘일잘러’로 통한다는 혜진님. 혜진님의 인터뷰를 통해 ‘마크업 개발자’에 좀 더 친해지는 시간이길 바라봅니다. 그리고 이렇게 멋진 코인원 크루와 함께 성장하고 싶지 않으세요?  현재 코인원은 멋진 크루들과 함께 크립토갤럭시를 헤쳐나갈 분들을 기다리고 있습니다 :-)
조회수 254

컴공생의 AI 스쿨 필기 노트 ③ K-평균 군집화

AI 스쿨 3주차에서는 K-means clustering(K 평균 군집화)에 대해 배웠어요. 이에 대해서 간략하게 정리해볼게요.K-means clustering클러스터링이란 군집화를 의미하는데요, K-means clustering은 비슷한 데이터끼리 묶어주는 머신 러닝 기법이에요. K-means clustering은 비지도학습(Unsupervised learning)의 일종이에요. 비지도 학습이란 데이터와 각각의 데이터가 무엇인지를 설명해주는 라벨이 없는 학습을 말해요. 따라서 우리는 주어진 데이터들을 가장 잘 설명하는 클러스터를 찾아 데이터를 분류할 수 있어요. 아래는 데이터를 2개의 클래스로 군집화한 것을 잘 나타내주는 그래프에요.K-means는 클러스터 내부에 속한 데이터들이 서로 가깝다고 정의해요. 그렇다면 같은 클러스터에 속한 데이터들은 서로 가까이 근접해 있겠죠? K-means는 클러스터의 중심으로부터 가까운 데이터들을 찾아서 묶어주는 알고리즘이에요. 데이터들은 가장 가까운 내부 거리를 가지는 클러스터를 고르게 되는데, 이를 위해서 각각의 클러스터는 중심(프로토타입)이 존재하고 각각의 데이터가 그 중심과 얼마나 가까운지를 Cost로 정의해요.위의 식은 같은 클러스터에 속하는 각각의 점들로부터 그 클러스터의 평균(프로토타입)과의 거리의 합을 제곱한 함수에요. - N : 데이터의 개수- K : 클러스터의 개수- uk : k 번째 클러스터의 중심(프로토타입)- rnk : n 번째 데이터가 k 번째 클러스터에 속하면 1, 속하지 않는다면 0을 가지는 이진 변수우리는 위 식에서 rnk, uk를 구해야 해요. 이때 반드시 잊지 말아야 하는 조건은 각 데이터가 한 개의 클러스터에 할당이 되어야 한다는 것이에요.K-means 알고리즘K-means algorithm을 구하는 방법은 아래와 같이 크게 2단계로 나누어져요. 먼저 uk에 랜덤 값을 사용하여 임의의 초깃값을 설정해요.1. Expectationuk를 고정시키면서 J를 최소화하는  rnk값을 지정해야 하는데,  rnk은 모든 데이터 n에 대해 각각 모든 클러스터 중에서 xn- uk가 가장 작은 클러스터에 할당해요.2. Maximization새롭게 얻어진 rnk를 고정하고 uk는 k 번째 클러스터의 mean을 계산해요. 두 값이 적당한 범위 내로 수렴할 때까지 계산을 반복해요, 위의 두 단계를 각각 E(expectation) 단계와 M(maximization) 단계라 하고, 이 두 단계를 합쳐서 EM 알고리즘이라고 해요.알고리즘 코드로 나타내기그럼 K-means algorithm을 코드로 어떻게 나타내는지 살펴볼게요!Step1. 데이터 만들기np.random.seed(42)digits = load_digits()  data = scale(digits.data)n_samples, n_features = data.shapen_digits = len(np.unique(digits.target))labels = digits.targetx_train, x_test, y_train, y_test = train_test_split(data, labels, test_size=0.25, random_state=42) - digits = load_digits(): load_digits 함수를 사용하면 data와 target이 반환되는데 이 데이터를 scale 함수를 사용하여 전처리해요.- data.shape을 사용하면 n_samples에는 1797, n_feature에는 64가 할당돼요.- n_digits에는 digits의 target의 중복된 값을 제외한 개수를 할당해요.- train_test_split() 함수를 이용하여 train_set과 test_set을 랜덤 시드를 42를 가지는 75:25의 비율로 나눠요.Step2. KMeans model 만들기sklearn 라이브러리를 사용하면 KMeans model을 아주 쉽게 구현할 수 있어요.kmeans = KMeans(init='k-means++', n_clusters=10, random_state=42)clusters = kmeans.fit_predict(x_train)- KMeans 함수를 이용하여 모형은 k-means++를 가지고, cluster는 10개를 가지며 랜덤 시드는 42를 가지는 K-means clustering을 만들어요.- x_train 데이터 셋을 중심으로 클러스터의 중심을 계산하고 각 샘플에 대한 클러스터의 인덱스를 예측할 수 있도록 fit_predict()를 사용해요.Step3. K-means clustering 결과 출력print('Clusters: ', clusters)위와 같이 출력하면 아래와 같은 결과가 나와요.Clusters: [1 3 2 ... 6 6 0]]그래프를 출력하면 아래와 같은 결과를 볼 수 있어요!이번 수업에 배운 K-means clustering의 개념은 1주차와 2주차 수업의 개념에 비해 어렵지 않았던 것 같아요. 이해하기에 큰 문제는 없었지만 코드로 직접 짜려고 하니 막히는 부분이 있어서 고생을 좀 했어요. 저는 과제를 하다가 에러가 나면 구글링을 통해서 에러를 해결하거나 도저히 못하겠다 싶으면 도움 요청을 해요. 목요일에는 조교분들께서 Multiple Regression에 대해 숙명여대에서 수업을 진행해주셨는데요. 1, 2주차에 배운 내용을 복습하고 3주차 수업에서 짧게 살펴본 Multiclassification을 더 자세히 알려주셔서 본 수업 때 이해가 되지 않았던 부분이 해결이 되었습니다! 목요일 수업은 정식 수업이 아닌 보충수업이었기 때문에 소수의 사람들이 강의에 참여했는데요. 시간이 된다면 참석을 꼭 해주시면 굉장히 큰 도움이 될 것 같아요. * 이 글은 AI스쿨 - 인공지능 R&D 실무자 양성과정 3주차 수업에 대해 수강생 최유진님이 작성하신 수업 후기입니다.
조회수 2544

영화 ‘앤트맨’을 통해 알아 본 안드로이드 나인패치(Android 9 Patch)

시작영화 ‘캡틴 아메리카: 시빌워’를 본 사람이라면 작은 ‘앤트맨’의 존재감이 누구보다 컸다고 말할 수 있습니다. 앤트맨은 가장 중요한 전투 신에서 자유자재로 신체 크기를 바꾸며 맹활약을 한 히어로인데요.안드로이드에도 이런 앤트맨처럼 크기를 자유자재로 바꾸되, 해상도를 그대로 보존하여 앱을 구현하는데 큰 도움을 주는 이미지 저장방식이 있습니다. 바로 나인패치입니다. 포스팅을 통해 나인패치를 이해해보고자 합니다.나인패치 이해하기#사이즈는 바뀌지만 내용은 그대로영화 속 앤트맨은 핌입자를 통해 분자보다 더 작은 양자 사이즈만큼 작아졌다가, 비행기보다 더 큰 사이즈로 변하는 히어로인데요. 핌 입자를 사용시 질량에는 변화가 없어 작아진 크기에서도 정상 어른의 펀치와 같은 위력을 줍니다.나인패치 역시 앤트맨과 같은 특징을 가지고 있는데요. 우리가 사용하고 있는 핸드폰의 해상도는 제각각 입니다. 하지만 이미지를 그 해상도에 전부 맞춰서 제작하기에는 무리가 있죠. 그렇기 때문에 디바이스에 표현되는 아이콘이나 버튼 등에 확대 되는 영역을 지정해줍니다. 그러면 큰 해상도에 이미지를 적용 하여도 픽셀이 깨지지 않고 확대된 이미지를 사용 할 수 있습니다.좀 더 정확하게 설명하자면, 이미지를 9분할 하여 확대되는 영역과 아닌 영역을 구분하여 저장하는 방식이며 이미지 확장자는. 9.png가 됩니다. 아래의 그림에서 살펴보면 빨간색 화살표 영역은 늘어나고 흰색 영역은 늘어나지 않게 됩니다.나인패치 이미지가 어떤 구조를 가지고 있는 어떻게 동작하는지에 대해 추가적으로 설명해보겠습니다.우선, 나인패치는Stretchable area와 Padding box 두가지의 영역으로 나뉩니다.Stretchable area는 늘어나는 영역은 이미지를 늘려주는 구간을 설정해주는 나인패치 영역입니다. 그래서 가로, 세로 어떤 크기로 늘어나도 형태가 깨져 보이지 않습니다.Padding box는 이미지 위에 어떠한 내용물을 어느 위치에 표시할지 정의 하는 영역입니다.버튼 크기가 변경되어도 정보 표시 영역을 나인패치로 잡아 좌우,상하 여백은 그대로 두고 이미지 확대/축소에 따른 텍스트가 정리되어 보여집니다.나인패치는 1px 검정색 선의 길이와 여백을 이용해서 늘려주고 싶은 이미지 영역과 표현하고 싶은 텍스트의 영역을 지정할 수 있는 것입니다.조금은 복잡해 보이지만, 나인패치로 지정하는 과정이 필요한 이유는 모바일은 한정된 용량을 가지고 있기 때문에 용량을 줄여서 하나의 이미지로 다양하게 사용할 수 있도록 하기 위해서 입니다.나인패치 만들어보기#만드는 방법나인패치를 만드는 방법에는 여러가지가 있습니다.   1. 포토샵으로 만들고, 확장자를 name.9.png으로 저장   2. 안드로이드 sdk 도구를 다운로드하여 만든다.       https://developer.android.com/studio/?hl=ko   3. Android Asset Studio 활용       http://romannurik.github.io/AndroidAssetStudio/nine-patches.html그중에서 툴 설치도 필요 없고 쉽게 만들 수 있는 3번의 방법을 활용하여 간략하게 나마 만들어보겠습니다.#우리는 그저 감사하게 사용할 뿐세상은 넓고 금손이 많은 것 같아요. 빠르게 만들수 있는 방법을 선택하겠습니다. 위 3번의 주소를 타고 사이트에 접속하면 아래와 같은 화면이 보여집니다.나인패치를 만들 수 있는 웹 툴인데, 저 사이트에는 나인패치 뿐만 아니라 안드로이드 디자인을 위한 다양한 툴을 제공하니 한번 참고해보시면 좋을 것 같습니다. 언제 이런걸 만들 생각을 하셨는지 한번 더 자괴감과 감사함을 느끼며 샘플 버튼 이미지를 불러옵니다.왼쪽 패널을 보면 이미지의 리소스 해상도를 지정하는 부분과 Drawable 이름을 편집할 수 있는 기능이 있습니다. 이름을 변경하게 되면 zip파일로 다운 받았을 때 변경된 이름으로 다운로드 됩니다.자 그럼 불러온 이미지가 가운데 화면에 보여집니다. Stretch Regions는 늘어나게 되는 부분을 설정하는 것입니다. 화면에 보이는 얇은 검은 선으로 Stretch Regions을 지정하면 됩니다.위와 같이 설정하게 되면 해상도에 따라 붉은색 부분이 늘어나게 됩니다.Contetns Padding은 안에 들어가는 텍스트가 들어가는 여백을 설정해줍니다.오른쪽 패널에서 Preview로 텍스트가 들어가는 것을 확인하면서 설정 할 수 있습니다.With content를 체크해주셔야 텍스트가 보여집니다.완성되면 Assets 탭에서 zip파일을 다운로드 받아주세요.다운로드가 완료되면 drawable name.9.zip으로 다운로드 되고 zip파일을 압축해제 하면 해상도 별로 나인패치 파일이 생성됩니다.부족하지만 나인패치에 대해 알아가는 시간이 되었기를 바라며, 이번 글은 여기서 마무리 하겠습니다.#에이치나인 #디자이너 #개발자 #협업툴 #크래커나인 #솔루션기업
조회수 1713

냉정과 열정 사이

냉정과 열정 사이라는 소설이 있다. 대학교 때 읽었던 소설인데 두 사람의 여정을 각자의 시선에서 다룬 소설이다. 에잇퍼센트에 인턴으로 입사해 9개월간 일하고 훨훨 날아간 병훈님과 나도 이 소설처럼 각자의 시선에서 지난 9개월을 되돌아보려 한다. (경고한다. 로맨틱하지 않다.)병훈님이 떠나는 날. 아마 여러분이 보는것과 내가 이 사진을 보는 느낌이 많이 다를거다.1. 만나기까지- 소병훈 이야기2015년 대학교 3학년이 시작될 때부터 졸업 이후에 대한 고민이 생겨났다. 대학원 진학과 취직은 수많은 대학생들의 공통된 고민이기에 수많은 조언이 넘쳐나지만 결론은 '나에게 맞는 길'을 선택하는 것이다. 내 인생 내가 선택해야지 언제까지 남들 좋다는 길로만 가겠는가. 둘 다 겪어보고 내가 선택하겠다고 다짐했다.졸업을 위해서는 대학원에서 과제연구를 1년 해야 했기에 대학원은 겪어 볼 수 있었다. 그러면 취직도 경험해보고 싶은데 어떻게 하지? 대기업에서 1~2개월 인턴을 했던 친구들에게 물어보니 한결같이 '놀고먹다 보니 월급이 나온다'는 경험담을 늘어놓았다. 하지만 정말로 취직해서 놀고먹으면 잘리겠지. 대기업 인턴은 패스. 스타트업 관련 세미나에서 한 VC의 '스타트업은 망해도 스타트업 인턴은 망하지 않는다'는 말을 들었다. 창업에 생각이 있으면 스타트업에서 인턴을 해보라는 말이었다. 그래서 '스타트업에서 일해보자'라고 결정했다.수많은 스타트업 중에서 왜 에잇퍼센트를 선택했다고 물으신다면, 빠른 속도로 성장하면서 변하고 있는 스타트업 속에서 일해보기를 원했기 때문이다. 그리고 당시의 나는 CTO의 멋진 말 한마디에 눈을 반짝이며 '이 회사에서 이 사람과 일하고 싶다'라고 생각하면 앞뒤 안 가리고 지원하는 이상주의자였다. 그래서 페이스북에서 호성님의 글을 읽고 '이 회사가 내가 생각하던 회사구나'라는 생각이 들어서 먼저 지원했던 회사를 포기하고, 에잇퍼센트 입사를 간절히(?) 원하게 되었다.- 이호성 이야기2016년 1월의 첫 번째 근무 날. 대표님이 모두를 불러 모았다. 그리고는 회사의 투자 유치 소식을 알려 주었다. (무슨 투자 유치 소식을 "오늘 저녁에는 치킨을 시켜 먹기로 했어요." 수준으로 재미없게 이야기하는지 모르겠다.) 투자를 받는 것이 확정되었으니 대표님이 내게 전달해 주신 미션은 개발자를 채용해서 제품 개발의 속도를 높이라는 것이었다. 사실 에잇퍼센트에 오기 전에 한 회사에만 오래 있기도 했고 개발자들과의 네트워킹도 게을리했던 터라 당장 좋은 개발자를 뽑을 수 있는 방법이 없었다.그래서 블로그에 회사를 알리는 글을 쓰기 시작하면서 주위 분들께 추천을 부탁드렸다. 그중 JDLab의 양주동 대표님이 괜찮은 학교 후배를 추천해 주신다고 해서 속으로 쾌재를 불렀다. 하지만 추천해 주신 친구가 애매하게 9개월만 일할 수 있는 상황이라고 하니 고민이 되었다. 주니어가 실제로 일을 잘 하게 되려면 꽤 긴 시간이 필요한데, 실제로 일을 잘할 수 있게 되었을 때쯤 회사를 떠나는 게 아닐까 하는 생각이 들었기 때문이다. 하지만 인력(당시 4명)에 비해 해야할 일이 너무나도 많았기에 누군가의 손이라도 빌려야 할 판이었다. 그래서 일단 병훈님을 만나 보기로 했다.2. 면접- 소병훈 이야기에잇퍼센트에 들어가는 과정은 상당히 길다.처음에 간단한 티타임을 시작으로 실제 코딩 문제를 풀어보게 하고, 그 뒤에서 다시 1대 n으로 토론하는 과정, 그리고 대표님과의 이야기로 면접이 이어진다. 요즘은 논술 문제도 있다고 들었다. (역시 취직은 어려워)내 경우는 '면접 보려는 것은 아니니 그냥 커피 한잔 하자'는 부님의 간단한 속임수에 넘어가 티타임을 가졌다. 카페에서 커피 한잔 하면서 부님과 에잇퍼센트는 어떠냐고 물어보려고 왔는데, 어느새 내 앞에는 호성님이 앉아 있었고, 메일로 코딩 문제를 받는 것으로 커피 한잔이 끝났다. 이 티타임은 면접보다는 나에게 회사를 소개하고 회사가 나에게 적합한지 보는 과정이었다.코딩 문제는 성호님의 글로 유명해진 pingpong을 포함한 take-home 과제였다. 문제를 받은 다음날 다른 회사 면접을 보고 온 뒤 밤샘으로 문제를 풀었던 것과 제출할 때 pingpong 문제만큼은 자신 있어했던 기억이 난다. 그때의 기억을 떠올리며 당시에 제출했던 코드를 보니 'Assignment를 쓰지 말 것'이라는 조건이 깨져있었다. 자신감 넘치던 과거의 내가 부끄러워지는 순간이다.마지막 면접 과정도 조금은 숨 막히는 경험이었다. 가볍게 대화하는 분위기 속에서 대학에서 들었던 전공과목 별로 하나하나 물어가며 내 지식의 바닥을 확인했다. 대학에서 3년간 들었던 전공과목은 많지만, 질문 들어오는 족족 '모르겠습니다' 밖에 할 수 없었다. 내가 답할 수 있는 수준을 찾으시려는지 점점 질문의 난이도가 낮아졌고, 마지막으로 스택과 큐를 물어보는 질문에 답하면서 '이 회사는 못 들어가겠구나'라는 생각이 들었다.동시에 진행했던 다른 회사에서 합격 메일이 왔기에 에잇퍼센트에 '0월 0일까지 합격/불합격 결과를 알려주세요'라는 당당한 요구를 한 뒤 떨어졌다는 메일을 기다리고 있었다. 하지만 예상치 못한 합격 메일을 받았고, 그 메일에는실력에 대해서는 회사에 오셔서 보여주세요라는 잊지 못할 문구가 있었다.그리고 첫 출근, 4월 4일 9시 20분에 출근해서 잠긴 문을 보며 에잇퍼센트의 첫 날을 맞이했다.- 이호성 이야기병훈님이 왔다고 하셔서 학교 선배인 부님과 함께 회사 옆 '피어나' 카페로 갔다. (당시만 해도 사무실에 회의실이 없어서 모든 미팅을 회사 옆 카페에서 해야만 했다.) 병훈님의 첫인상은 “꺼벙이"였다.공대에서 흔히 볼 수 있는 스타일. 하지만 말하고 이야기하는 것은 번뜩이는 느낌은 크게 들지 않았다. 아마 나정도로 평범한 느낌이었던 것 같다. 이야기를 하다 보니 다른 곳에 면접을 이미 본 상태였다. 일단 우리 회사와 나에 대해서 좋은 감정을 갖게 하는 것이 좋겠다 싶어서 이래저래 약을 팔았다. 그리고 면접 문제를 메일로 전달하겠다고 하고 첫 번째 만남을 마쳤다.며칠 뒤 제출한 과제를 가지고 다시 한번 병훈님을 만났다. 전공에 관련된 기본적인 질문들을 던졌다.(정확히는 졸업한 지 10년이 지나서 그냥 내가 기억나는 것들을 물어보았다.) 그런데 10개의 질문을 던지면 8개의 질문 은 원하는 답을 듣지 못했다. 실망했다. 겸손하고 배움의 자세가 갖춰져 있는 친구라는 생각은 들었다. 하지만 이렇게 모르는 친구를 뽑아도 될까 하는 생각이 들었다.하지만 뽑았다. 솔직히 그냥 학벌을 보고 뽑았다. 좋은 학교에 다니고 있는 친구이니 지금까지 최소한 한 번쯤은 최선을 다해 본 적이 있겠지 라는 생각을 했다. 무엇보다 당시 나는 꽤 급했다.합격 메일에는 ‘실력에 대해서는 회사에 오셔서 보여주세요'라는 내용을 적어서 보냈다. 부족한 만큼 회사에 와서 최선을 다해주었으면 하는 마음이었다. 그리고 입사할 주에 있을 워크숍 준비에 대한 요청도 함께 드렸다.지금 와서 이야기하는 것이지만 최근에 병훈님을 면접 봤다면 떨어뜨렸을 거다. 생각해 보면 이게 면접, 특히 주니어 면접의 어려움이다. 그 사람이 입사해서의 2주 정도는 예상해 볼 수 있지만 그 뒤는 예상하는 것은 너무나 어려운 일이다.3. 들어와서 처음 했던 일- 소병훈 이야기들어와서 처음으로 했던 일은 나를 대학생에서 직장인으로 바꾸는 일이었다.회사에 들어온 지 1~2개월이 지났을 때 외부 업체와 전문 통신을 개발하는 작업을 맡았다. 대학교에서 두 PC 사이의 전문 통신 프로젝트를 만들었던 기억이 있어 충분히 혼자서(그리고 짧은 기간에) 만들 수 있으리라 생각하고 작업을 시작했다. 기존의 코드를 조금씩 수정하고 추가하던 이전의 작업들과는 다르게 처음부터 만들어내는 일이었다.이 일을 하면서 지금까지 '하나의 동작을 하는 무언가'를 100% 혼자서 만든 적이 없다는 것을 깨달았다. 항상 기본 틀을 받아서 코딩하고, 어려울 때는 모범 답안을 보면서 힌트를 얻었으며, 그러고도 힘이 부치면 7~80%만 완성하고 (시간이 없었다는 핑계를 대면서) 넘어갔었다. 회사에서는 이 일이 '소켓 통신의 이해를 확인하기 위한 프로그래밍'이라고 설명되어 있지 않았고, 어디서 버그가 발생했는지 힌트를 얻을 수 없었다.대학 강의로 들었던 내용들과 전혀 다른 지식들이 필요했지만, 필요한 기초적인 요소들은 구글에서 찾을 수 있었다. 하지만 어떤 키워드를 검색해야 하는지부터가 문제였다. 검색해야 하는 단어를 알아내려고 시니어 개발자님들께 돌아가면서 물어봤다. (너무 자주 물어야 해서 한 분에게만 묻기 죄송했다.) 처음에는 학교에서 배운 내용은 쓸모없다고 생각했었는데, 지금 생각해보니 그마저도 없었으면 구글과 위키의 내용도 이해 못했을 것 같다.웹 개발에 대한 기초도 없고, 어디가 끝인지 확신도 없어서 개발 시간이 길어졌다. 야근을 반복했다. 노력한다고 해서 없던 능력이 생기지는 않았고, 결과로 커다란 똥덩어리 같은 코드가 만들어졌다. 다행히도 (달리는 중간에 몇 개의 부품을 갈아 끼운 이후에) 최소한의 기능은 정상적으로 돌아갔다.그렇지만 이 코드가 12월까지 구린 냄새를 피우고 있었다. 에러를 만들지는 않지만 가독성이 떨어지고 창의적인 구조 때문에, 유지/보수를 할 때마다 과거의 내 실력을 확인하는 좋은 지표가 되었다.- 이호성 이야기시간이 많다면 병훈님을 옆에 앉혀 두고 차근차근 알려주고도 싶고, 같이 스터디도 하고 싶었지만 내게는 당장 해야 하는 일이 쌓여 있었다. 다행히 팀에 계신 시니어 개발자 분들이 병훈님일 이래 저래 잘 돌봐 주었다. (20살이 넘는 청년에게 "돌봐 주었다"라는 표현이 적당한 가에 대해서 곰곰 생각해 보았는데, 흠. 역시 적절하다.) 병훈님께 처음 한 달 동안은 조각을 고치는 일, 작지만 급한 일 들을 맡겼다. 덕분에 시니어 개발자들이 다른 일들에 집중을 할 수 있었다. 그리고는 한 달이 지나자 하나의 일을 떼어서 맡겨볼 수 있겠다는 생각이 들었다. 단순히 개발하는 일뿐만 아니라 다른 회사 개발자들과 커뮤니케이션을 직접 하면서 일을 할 수 있도록 했다. 병훈 님은 잊어버렸을지는 모르겠지만 외부 업체로 처음 전화를 걸었을 때 우리 팀의 시니어 개발자들은 모두들 키보드에서 손을 놓고 병훈님의 대화를 노심초사하면서 듣고 있었다.이 프로젝트는 곧 병훈님이 예상한 일정을 넘어섰고, 얼마 이후에는 내가 예상한 일정도 넘어섰다. 병훈님이 끙끙 앓고 있는 게 보였다. 그 일을 다른 사람에게 넘겨야 하는가의 고민도 여러 번 했다. 병훈님이 만들어 낸 창의적(이라고 말하고 싶겠지만 상식을 벗어난)인 코드들을 뜯어고치고 싶다는 생각도 했다. 하지만 시간은 지났고 테스트를 통과한 코드는 에잇퍼센트 프로덕트의 한 자리를 차지했다.4. 무엇을 배웠을까?- 소병훈 이야기첫 번째로 회사가 어떻게 돌아가는 지를 배웠다. 작은(?) 스타트업이었기에 개발팀 외 다른 팀원들과도 친하게 지낼 수 있었고, 회사 내에서 생기는 사건들을 전부 들을 수 있었다. 그렇게 아이디어가 나오는 순간부터 제품으로 완성되는 과정을 볼 수 있었다. 또한 회사의 크고 작은 의사 결정 과정을 지켜볼 수 있었는데, 모든 의사 결정들에 원인과 논리적인 과정이 따른다는 점이 재밌었다.내가 알지 못하는 원인들과 다른 사람들이 결정하게 된 이유가 궁금해서 여기저기 물어보았고, 모두들 숨기지 않고 말해 주었다. 대표님과의 티타임에 찾아가서 묻기도 하고(모두에게 열려있었는데 단 2명이 왔었다), 퍼포먼스 마케팅이 궁금하다며 점심시간에 옆에 앉아 이야기하고, 전화 응대를 어깨너머로 들어보기 했다. 글로 적어보니 처음 초등학교에 들어간 8살 아이 같기도 하지만, 에잇퍼센트에 있으면서 물어보는 만큼 알 수 있었고, 그만큼 이전과는 다른 세상을 알 수 있었다. (그리고 그만큼 야근을 했다.)두 번째는 개발자가 되는 과정을 배웠다. 당연히 개발 실력도 늘었지만, 조금 더 보태서 개발자가 되는 과정을 배웠다고 말하고 싶다. 누구라고 말할 것 없이 남는 시간을 조금씩 쪼개 공부하고 있는 사람들, 새벽 4시가 넘었음에도 꼼꼼히 기록을 남기며 마무리하는 야간작업, 그리고 혼자서는 만들 수 없는 거대한 코드를 점진적으로 만들어가는 개발팀을 보면서 개발자라는 직업을 만날 수 있었다. 내가 본 개발자는 (에잇퍼센트의 개발자만의 특징일 수도 있지만,) 모든 결과를 '우연'으로 넘기지 않고 원인을 찾았고, 원하는 분야를 찾아서 스스로 공부하고, 삶의 즐거움을 하나씩 가지고 있는 사람들이었다.마지막으로 나 되돌아보기. 나는 내 실력을 과대평가하고 있었다. 회사에 들어오면서 '열심히 하겠다'라고 말했지만 몇 개월 '열심히' 뛰어서 갈 수 있는 거리에는 한계가 있었다. 다른 사람들이 불가능하다고 말해도 혼자서 '노력하면 할 수 있다'라고 생각하면서 오기로 붙잡고 있다가 결국 기한을 넘긴 적이 많았다. 시간이 지나면서 '할 수 있을 것 같다'는 자신감이 아니라 완성된 결과물을 보면서 실력을 확인했다. 항상 자신감이 넘치다 보니 매번 내 생각보다 실력이 뒤에 있었고, 그런 생각이 들 때마다 기숙사에서 공부를 했다.그렇지만 나를 과대평가했던 것처럼 나의 목표도 과대평가 했었다. 내가 도달하려고 했던 목표도 꾸준히 달리면 도달할 수 있는 거리에 있었고, 생각보다 멀리 있지 않았다. 다만 '꾸준히'의 기준이 몇 주, 몇 개월이 아니라는 것을 배웠을 뿐이다.- 이호성 이야기내가 입사하기 전에 에잇퍼센트에 여러 명의 개발 인턴이 있었다고 했다. (commit log에서만 만날 수 있는 그대들이여. 왜 버그를 내게 주고 갔는가.) 그리고 한 명을 제외하고는 회사를 모두 떠났다. 처음에 대표님이 인턴 채용 제안을 몇 번 하셨을 때 개발팀에는 인턴을 채용하지 않겠노라고 말했었다. 사람이 전부인 개발팀에서 떠나는 것이 예정된 사람을 뽑고 싶지 않은 마음이었다. 하지만 병훈님은 이런 내 생각을 바꿔 놓았다.연말 평가에서 성장에 대한 상을 받을 만큼 병훈님의 성장은 눈부셨다. 이제 좋은 주니어는 무엇인가에 대해서 병훈님을 기준으로 생각을 할 수 있게 되었다. 주니어 채용에 대한 성공체험을 했다고도 할 수 있겠다.상은 병훈님이 받는데 주는 사람이 더 좋아하네?좋은 주니어는 당연하게도 일정 시간이 지났을 때 높은 곳에 올라갈 수 있는 사람이다. 높은 곳에 올라가기 위한 조건은 다음과 같은 것들이 있다.1) 상대적으로 이미 높은 곳에 있을 것 전설 속에만 존재하는 시니어 같은 주니어 되시겠다. 고등학교, 대학교 때 많은 지식과 경험을 쌓아서 이미 현업에서 잘할 수 있는 친구들이다.2) 인지능력, 학습능력문제를 이해하고 정의하는 능력이 뛰어나고 논리적인 사고를 한다. 속칭 똑똑한 친구들이다. 문제를 자세하게 설명해 주지 않아도 문제의 본질을 이해할 수 있고, 답으로 가는 길을 빠르게 찾아낼 수 있다. 새로운 것을 빠르게 익히고 배움에 대한 두려움이 없다.3) 지적겸손배움에 대해 열린 자세를 가지고 있어야 한다. 나는 개인적으로 주니어의 경우 이 능력을 "내갈굼력"이라고도 부른다. 다른 사람들에게 지적과 갈굼을 받으면서도 그것이 배움으로 이어진다면 감사한 마음으로 받아들인다. 감사한 마음은 다시 지식을 전해주는 사람에게 긍정적인 피드백이 되어 더 많은 것을 알려주게 되는 선순환 구조를 만들어 간다.4) 태도긍정적이고 도전적인 태도를 갖추어야 한다. 자신의 인생을 발전적으로 개척해 나갈 태도. 그리고 자신을 둘러싼 환경에 감사하는 태도. 이 태도는 팀에도 많은 영향을 미친다.병훈님을 면접 볼 때의 나는 1) 만을 중요하게 생각했기에 병훈님을 떨어뜨려야 하나 하고 생각했다. 하지만 이제 와서 뒤돌아 보니 병훈님은 2), 3), 4)을 모두 갖추고 있는 인재였다. 아마 몇 년 뒤에는 1)도 충분히 갖추게 되리라.5. 어떻게 일했나?- 소병훈 이야기 9개월 동안 에잇퍼센트를 다니면서 항상 내 능력으로 조금 힘들지만 불가능하지 않을 만큼 업무가 들어왔다. 스프린트(2주) 단위로 업무를 나눠가지는데, 일방적으로 업무를 할당받지 않고 팀 회의로 업무를 나눠갖는다. 호성님이 업무를 강요하지도 않고 업무 일정도 각자가 정하지만, 모두가 보고 있다는 느낌과 '스스로를 과대평가하는 나' 때문에 매번 촉박한 일정에 시달리게 되었다. 그렇게 나는 손을 들고 해당 업무의 책임자가 된다. 초반에는(전문 개발할 때까지)는 아예 질문하지 않아서 혼자 끙끙 댔는데, 너무 안쓰러워 보였는지 옆에 앉은 연태님이 먼저 도와주셨다. 시간이 지나면서 길이 명확하게 보이지 않을 때는 시니어 개발자(대부분 연태님)에게 물어보면서 일을 진행했다. 어느 날 호성님이 에잇퍼센트처럼 '실패하면서 성장할 수 있는 환경'이 다른 회사에서는 없다고 말했었다. 생각해보니 내가 자유롭게 개발해도 테스트와 코드 리뷰를 거치면서 문제를 잡아낸다. 그러고도 버그가 생기면 실서버에서 디버깅해서 문제를 해결한다. 심적으로 매우 죄송한 마음이 들지만 추가적으로 다른 벌은 받지 않았다. 일을 시작하기 전부터 지레 겁먹을 필요는 없었다. 그 뒤로 길이 희미하더라도 우선 걸어가 봤다. 그러다가 도저히 길이 보이지 않을 때, 조언을 받는 방식으로 일을 진행했다. 시간이 더 오래 걸리면서 최종 결과물의 수준이 떨어지는 상황이 발생했지만, 코드 리뷰를 받으며 최소한의 수준은 맞춰졌다. (그러면서 시간은 더 오래 걸린다.) 최대한으로 생각해서 만들어도 항상 놓치는 부분이나 더 간단한 해결 방법이 있었고, 그때 느끼는 아쉬움과 안타까움이 다음 개발할 때 잊지 않고 기억나서 내가 성장한다는 느낌이 들었다. 막바지에는 개발을 시작하기 전에 항상 의자를 들고 해당 업무를 요청한 사람 옆으로 갔다. 말로 이야기면 Slack이나 Trello로 이야기하는 것보다 빠르고, 해당 문제를 직접 보면서 자세한 설명도 들을 수 있었다. 요청사항을 받아 개발하는 느낌이 아니고 함께 문제를 해결한다는 느낌으로 이야기하면서 실시간으로 여러 해결방안을 제시하면서 생각을 주고받았다. 문제를 해결하면서 회사에 장기적으로 도움이 되는 방향을 고민하다 보니 '주인의식을 가지고 일한다'는 느낌이 들었다. (정확히는 이왕 만드는 거 아름답게 만든다는 생각이었다.)- 이호성 이야기회사에서 병훈님의 별명은 '아기새'였다. 업무를 하면서도 사람들의 보살핌을 필요로 했지만 그것 외에도 이런저런 허술한 면을 많이 보여줘서 누가 붙였는지 기억이 나진 않지만 모두의 입에 착 붙어 있는 별명이었다. (개발팀 내에서는 간혹 '아. 이런. 손이 많이 가는 친구'로 불리기도 했다.)에잇퍼센트에는 퇴사하면 털린다. 다들 떠나지 마라.병훈님을 연태님 옆자리에 앉게 했다. 회사 내에서 스위퍼(스프린트 내의 개발 잡일들을 처리하는 담당) 팀도 연태님과 같이할 수 있도록 했다. 경험과 인내심이 많고 상냥한 언니 같은 연태님(남자)은 병훈님의 좋은 파트너가 되어 주었다. 그리고 세바님은 어려운 문제를 함께 해결해 주고 코드의 퀄리티에 대한 감시자(갈굼자)가 되어 주었다. 언젠가 병훈님이 개발자의 길을 가게 되어 첫 월급을 받게 되면 이 두 분에게는 빨간 내복을 사드려야 할 거다.처음에는 아기새의 Pull Request(반영하고자 하는 코드 뭉치)에는 코멘트가 수십 개가 달렸다. 그것들을 꾸역꾸역 고치고 나면 다시 그 절반 정도의 코멘트가 달리곤 했다. 하지만 병훈님이 떠날 때쯤에는 내 코드에 "이렇게 저렇게 고치는 게 더 좋은 것 같은데요?"라고 코멘트를 달곤 했으니 발전하지 못한 나는 부끄러울 따름이다.그리고 병훈님은 다른 팀일에도 참 관심이 많았다. 그러고 보면 나도 처음에 스타트업에서 일하기 시작했을 때 다른팀 일들도 왜 그렇게 재미있었는지 모르겠다. 하지만 분명한 것은 작은 조직에서는 다른 팀에 대한 관심이 개발을 잘하는 데 많은 도움이 된다.6. 떠나기 이주일 전- 소병훈 이야기정해졌던 퇴사일이 가까워지면서 새로운 업무는 들어오지 않았다. To-do list는 사라지고, 대신 '인수인계'라는 일이 생겨났다. 지금까지 했던 일들을 문서로 남기면서 새로운 책임자에게 넘겨주는 일이었다. 큰 그림을 그렸던 것들이 있는데 완성을 하지 못한다는 아쉬움이 컸다.호성님께 1,2월 프리랜서 제안서를 받게 된 건 우연이였다. 다 같이 점심을 먹을 때 우연히 호성님과 같은 테이블에 있었고, 1,2월에 남은 일정을 이야기하다 농담처럼 나온 제안이었다.제안서를 받은 날, 기숙사에서 많은 계산을 했다. 개발하는데 어느 정도 시간이 걸릴지, 제안서의 업무 기한을 변경한다면 일정이 어떻게 될지, 그렇게 받은 돈으로 어느 정도 도움이 될지. 충분히 가능한 일정이었다. 못해서 아쉬워하던 일이기도 했다. 그렇기에 더 고민했다.긍정적으로 고민하던 제안을 거절한 이유는 '여행 도중에도 계속 개발을 생각할까 걱정되어서'였다. 이번 여행에서 아쉬움이 남으면 다음은 언제가 될지 모른다는 생각이 들자, 내 시간이 더 귀하다는 생각이 들었다.그러면서 내가 조금이라도 더 필요하다고 말해주는 점이 고마웠다. 내가 생각해보지 못한 선택지를 받아서, 나의 가치관을 되짚어 본 느낌이었다.- 이호성 이야기병훈님과 같이 식사를 했다. 병훈님은 복학하기 전 유럽으로 여행을 다녀온다고 했다. 밤에 돌아다니면 위험하니까 숙소에서 코딩이나 하라고 살살 꼬셨다. 밤에 코딩하고 그 아르바이트비로 낮에 럭셔리하게 맛있는 것 먹고 다니면 얼마나 즐거운 여행이 되겠냐고. 제안서를 하나 작성해서 해야 할 일과 보수를 적어서 병훈님께 주었다. 왠지 넘어올 것만 같은 느낌이었다.병훈님이 하루 정도 생각해 보더니 "어정쩡한 상태가 될 것 같아요. 생각해보니 이런 제안을 주신 것만으로도 정말 감사합니다."라고 했다. 실패했다.회사 입장에서 업무를 잘 알고 있는 병훈님이 조금이라도 일을 더 해주면 하는 마음이었다. 하지만 다시 생각해보니 인생의 후배에게는 좋지 않은 권유였던 것 같다. 돈이 중요할 때가 아니라 세상에 대한 경험과 자신을 뒤돌아 볼 시간이 필요했던 거니깐.7. 떠나는 날케익이나 먹고 떠나랏!- 소병훈 이야기떠나는 날도 크게 다르지 않았다. 코드도 살펴보고 pull request도 적으면서 이전과 같은 하루를 보냈다. 그리고 마지막 날, 혹시 작별 인사를 하면서 내가 울지 않을까 걱정했지만 괜한 걱정이었다. 2달 전부터 작별 인사(라 쓰고 갈굼이라 읽는다)를 받아서 그런지 마지막 인사가 특별한 느낌이 들지 않았다.그렇지만 그 뒤로 며칠간 회사를 나왔다는 묘한 홀가분함과 그동안 했던 일들이 내 손을 떠난 공허함이 있었다. 내가 없으면 회사가 바뀌지 않을까 하는 조그만 기대도 있었지만, 다들 나 없이 잘 지내나 보다. 나는 조금 아쉬웠는데.- 이호성 이야기9개월이라는 시간이 참 금방 지났다. 남은 기간 동안 여행을 떠나는 병훈님에게 사람들이 "에이 그거 여행 가면 뭐해. 그냥 회사에서 일해"와 같은 장난을 수도 없이 했던 것 같다. 하지만 떠날 시간은 정해져 있었고 병훈님은 사람들의 박수를 받으며 떠났다. 마치 80분을 열심히 뛴 축구선수가 교체를 위해 떠날 때 받는 박수처럼.8. 떠나고 난 후- 이호성 이야기며칠 간은 아침 데일리 미팅이 왠지 허전하고, 슬랙으로 말을 걸면 대답을 할 것만 같았다. 하지만 또 새로운 사람이 회사에 들어오고 바쁘게 회사가 돌아가면서 금방 잊혀지긴 하더라. 아 그러고 보니 병훈님이 만든 코드에서 버그가 나올 때마다 우리는 회사에 남은 아기새 인형을 괴롭히긴 했다.병훈님이 떠나고 나서 같은 학교의 후배인 선희님이 회사에 마케팅 인턴으로 들어왔다. 선희님이 자기소개 시간에병훈 선배와 같은 동아리에..라고 말하자마자 전 직원이 다 뒤집어졌다. 그렇다. 우리에게 "병훈"과 "선배"는 함께할 수 없는 단어였다.여행을 갔다가 돌아온 아기새 병훈님이 와인을 하나 물어왔다. 그리고는 파닥파닥.군대 문제가 있기에 당분간 병훈님과 함께 오래 일할 수 있는 기회는 찾아오지 않을 것 같다. 아쉬운 마음이 든다. 에잇퍼센트에서의 병훈님을 "막 알에서 깨어나 호기심을 가지고 세상을 바라보는 아기새"로 기억해야겠다. 그리고 그 모습을 기억하며 나 또한 초심을 되새겨야지.우리가 다시 만날 그날까지 병훈님이 더 큰 날갯짓으로 더 넓은 세상을 여행하길 바란다. 9개월간 함께 해준 병훈님께 감사한다. 안녕!덧, 그나저나 난 또 어디에서 찾아야 하나. 이 다음 아기새를.#8퍼센트 #에잇퍼센트 #인턴 #조직문화 #후기 #팀워크 #팀플레이
조회수 4348

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

개발자 직군 파헤치기 4 | 빅 데이터 엔지니어

빅 데이터 엔지니어는 무엇을 하나요?빅 데이터가 부상하면서 그와 관련된 직업군도 함께 주목받기 시작했습니다. 빅 데이터 엔지니어, 빅 데이터 애널리스트, 빅 데이터 사이언티스트 등 다양한 직업군이 생겼습니다. 오늘은 개발자 직군 중 데이터와 관련된 빅 데이터 엔지니어에 관해 이야기해 볼 것입니다. 빅 데이터 엔지니어는 무엇을 할까요? 빅 데이터 엔지니어가 무엇을 하는지 알기 위해서는 먼저 빅 데이터가 뭔지 알필요가 있겠습니다.빅 데이터는 기존 데이터베이스 관리도구의 능력을 넘어서는 대량의 정형 또는 심지어 데이터베이스 형태가 아닌 비정형의 데이터 집합조차 포함한 데이터로부터 가치를 추출하고 결과를 분석하는 기술입니다(위키 참조).빅 데이터의 특징은 방대한 데이터와 더불어 비정형 데이터까지 포함한다는 것입니다. 많은 양의 데이터와 정형화 되지 않은 데이터를 수집하는 일은 보통 일이 아닙니다. 빅 데이터를 통한 새로운 알고리즘를 만들거나 인사이트를 발견하기 위해서는 빅 데이터가 존재해야 합니다. 빅 데이터 엔지니어는 이러한 빅 데이터를 수집하고 관리하는 프로그래머입니다. 일반적인 데이터 수집과 달리 수십테라 정도의 정보를 수집 하게 됩니다. 또 그런 데이터를 어떻게 효율적으로 관리할지 고민해야합니다.데이터는 미래의 석유라고 합니다. 빅 데이터 엔지니어는 빅 데이터 분석가나 과학자들에게 이러한 석유를 가져다 주는 송유관을 설치하고 관리하는 역할을 한다고 볼 수 있습니다. 빅 데이터 활용을 위해서라면 빅 데이터 엔지니어의 역량이 반드시 필요합니다.데이터 과학자와 데이터 엔지니어는 다르다.위에서 빅 데이터 엔지니어는 데이터를 수집하고 관리하는 업무를 한다고 했습니다. 하지만 구체적으로 빅 데이터 과학자(Big Data Scientist)와 빅 데이터 엔지니어(Big Data Engineer)는 무엇이 다를까요?어떤 직업의 업무라는 것이 무 자르듯 쉽게 나눌 수 있는 것은 아니지만 확실히 그 직업만의 특징은 존재합니다. 각 직업 별로의 특징을 통해 빅 데이터 엔지니어가 빅 데이터 과학자와 어떻게 다른지 알아보도록 하겠습니다.1. 빅 데이터 엔지니어(Big Data Engineer)빅 데이터 엔지니어는 위에서도 언급 했지만, 데이터를 수집하고 관리하는 일을 합니다. 빅 데이터 엔지니어를 통해 '빅 데이터'가 만들어진다고 해도 무방하죠. 숫자나 규칙이 있는 정형 데이터는 물론이고 글자나 불규칙적인 비정형 데이터까지 수집하고 관리합니다. "그냥 데이터를 수집하고 관리하는 일인데 별거 있나?"라고 생각하실 수도 있습니다. 빅 데이터라는 개념 이전에도 데이터는 수집되었고 분석을 통해 비즈니스 문제를 해결해 왔으니까요. 그렇지만, 빅 데이터라는 개념이 부상하고 실현 가능할 수 있었던 이유는 방대한 데이터를 수집할 수 있는 퍼널(funnel) 설계과 그 데이터를 관리하고 알맞게 사용할 수 있는 시스템을 구축할 수 있었기 때문입니다.그렇기 때문에 빅 데이터 엔지니어는 프로그래밍에 아주 능숙해야합니다. 빅 데이터를 수집하고 관리할 수 있는 방법을 짜야하니까요. 또한, 개별적인 정보가 아닌 큰 틀에서의 정보를 다루고 통합하고 나누어 볼 수 있는 설계 능력이 따라주어야 합니다.정교하게 짜여진 빅 데이터가 아니라면 빅 데이터 과학자가 그것을 분석하고 사용하는데 상당한 자원이 들거나 최악의 경우 아예 이용하지 못하게 될 것입니다.2. 빅 데이터 과학자(Big Data Scientist)빅 데이터 엔지니어가 빅 데이터를 수집하고 관리한다면 빅 데이터 과학자는 그것을 요리하는 역할을 합니다. 데이터보고 직면한 비즈니스 문제를 해결할 새로운 인사이트를 도출해 내는 것입니다. 혹은 현재 가지고 있는 프로세스를 개선할 알고리즘을 만들어 낼 수도 있습니다.빅 데이터 과학자는 데이터를 분석할 수 있는 통계학적 지식뿐만 아니라 그 데이터를 다룰 수 있는 프로그래밍적 지식도 요구됩니다. 일반적인 데이터가 아닌 '빅' 데이터다 보니 그것을 쉽게 운용하고 자유자재로 이용하게 해줄 툴을 익혀야합니다. 또한, 빅 데이터 과학자에게 요구되는 핵심 역량 중 하나는 바로 머신러닝에 대한 지식입니다. 이 또한 프로그래밍 지식과 알고리즘 지식이 필요합니다. 빅 데이터 엔지니어가 되기 위한 Key Skills그렇다면 빅 데이터 엔지니어가 되기 위해서는 어떤 기술 스택들을 익혀야할까요? 빅 데이터 엔지니어는 데이터와 관련된 직군인만큼 데이터베이스와 관련된 기술스택들이 중요합니다.1. SQL데이터 관리를 하시는 분들이면 다들 알고 계시는 SQL입니다.  SQL은 관계형 데이터베이스 관리 시스템의 데이터를 관리하기 위해 설계된 특수 목적의 프로그래밍 언어입니다(위키참조).2. MapReduce(맵리듀스)맵리듀스는 구글에서 대용량 데이터 처리를 분산 병렬 컴퓨팅에서 처리하기 위한 목적으로 제작하여 2004년에 발표한 프레임워크입니다.(위키참조).3. Apache Hadoop(아파치 하둡)Apache Hadoop은 대규모 데이터 세트를 효율적으로 처리하는 데 사용할 수 있는 오픈 소스 소프트웨어 프로젝트입니다. 하나의 대형 컴퓨터를 사용하여 데이터를 처리 및 저장하는 대신, 하둡을 사용하면 상용 하드웨어를 함께 클러스터링하여 대량의 데이터 세트를 병렬로 분석할 수 있습니다.4. Apache Cassandra(아파치 카산드라)Apache Cassandra 자유-오픈 소스 분산형 NoSQL 데이터베이스 관리 시스템의 하나로, 단일 장애점 없이 고성능을 제공하면서 수많은 서버 간의 대용량의 데이터를 관리하기 위해 설계되었습니다. 카산드라는 여러 데이터센터에 걸쳐 클러스터를 지원하며 마스터리스(masterless) 비동기 레플리케이션을 통해 모든 클라이언트에 대한 낮은 레이턴시 운영을 허용합니다(위키참조).5. Java(자바)빅 데이터 엔지니어는 기본적으로 프로그래머이기 때문에 프로그래밍 지식있어야 합니다. 빅 데이터 엔지니어를 목표로 처음 프로그래밍을 시작한다면 자바를 추천합니다. 물론, 다른 언어를 통해 프로그래밍 실력을 쌓아도 됩니다. 그렇지만, 아파치 하둡과 아파치 카산드라가 자바를 베이스로 만들어졌기 때문에 자바를 배운다면 이 기술스택들을 습득하는데 훨씬 효율적일 것입니다.다른 포스팅에서도 항상 말씀드려왔지만 기술스택만 익힌다고 해서 그 직업을 가질 수 있는 것은 아닙니다. 기술스택은 기본이고 개발자로써의 역량이 뒷받침 되어야 시장에서 환영받는 빅 데이터 엔지니어가 될 수 있습니다.Photo by Ehud Neuhaus on Unsplash빅 데이터 엔지니어가 되기 위한 학습 콘텐츠시중에서는 완성된 단계로써 빅 데이터 엔지니어를 양성하는 프로그램은 많지 않습니다. 따라서 개인이 빅 데이터 엔지니어에게 필요한 기술 스택들을 하나씩 익혀 나가야 합니다.무료 온라인 콘텐츠도 많겠지만, 비싸지 않으면서도 잘 정제된 콘텐츠를 소개하려고 합니다. 유튜브 강좌보다는 보기 편하고 학습 환경이 잘 갖춰져 있어서 공부하기에 좋은 콘텐츠를 추천합니다.1. SQL - SQL 프로그래밍 : SQL을 무료로 학습할 수 있는 사이트(한글)2. Hadoop - 유데미 The Ultimate Hands-On Hadoop - Tame your Big Data! (영어)3. Cassandra - 유데미 From 0 to 1: The Cassandra Distributed Database (영어)데이터 엔지니어는 예전부터 있었다.오늘은 빅 데이터 엔지니어에 대해 알아보았습니다. 사실, 빅 데이터 엔지니어는 어느 날 갑자기 생겨난 직업이 아닙니다. 데이터베이스를 관리하는 프로그래머가 더 나은 기술 스택을 익히고 더 좋은 방법으로 데이터를 수집하고 관리하면서 생겨난 것입니다.세상은 빠르게 변한다고 하지만 그 안을 들여보면 서서히 발전한 것들이 다르게 네이밍(Naming) 되면서 새롭게 다가오는 것이라 생각합니다. 그렇다고 해서 그것이 변하지 않는 것이 아닙니다. 새롭게 변하는 기술들을 익히고 자신의 역량을 갈고 닦아야만 새롭게 다가오는 변화에 휩쓸리지 않고 주도할 수 있는 것 같습니다.
조회수 1216

레진 기술 블로그 - AWS Auto Scalinging Group 을 이용한 배포

레진코믹스의 서버 시스템은 잘 알려진대로 Google AppEngine에서 서비스되고 있지만, 이런저런 이유로 인해 최근에는 일부 컴포넌트가 Amazon Web Service에서 서비스되고 있습니다. AWS 에 새로운 시스템을 셋업하면서, 기존에 사용하던 PaaS인 GAE에서는 전혀 고민할 필요 없었던, 배포시스템에 대한 고민이 필요했습니다. 좋은 배포전략과 시스템은 안정적으로 서비스를 개발하고 운영하는데 있어서 필수적이죠.초기에는 Beanstalk을 이용한 운영에서, Fabric 을 이용한 배포 등의 시행착오 과정을 거쳤으나, 현재는 (스케일링을 위해 어차피 사용할 수밖에 없는) Auto Scaling Group을 이용해서 Blue-green deployment로 운영 중입니다. ASG는 여러 특징 덕분에 배포에도 유용하게 사용할 수 있습니다.ASG를 이용한 가장 간단한 배포는, Instance termination policy 를 응용할 수 있습니다. 기본적으로 ASG가 어떤 인스턴스를 종료할지는 AWS Documentation 에 정리되어 있으며, 추가적으로 다음과 같은 방식을 선택할 수 있습니다.OldestInstanceNewestInstanceOldestLaunchConfigurationClosestToNextInstanceHour여기서 주목할 건 OldestInstance 입니다. ASG가 항상 최신 버전의 어플리케이션으로 스케일아웃되게 구성되어 있다면, 단순히 인스턴스의 수를 두배로 늘린 뒤 Termination policy 를 OldestInstance 로 바꾸고 원래대로 돌리면 구버전 인스턴스들부터 종료되면서 배포가 끝납니다. 그러나 이 경우, 배포 직후 모니터링 과정에서 문제가 발생할 경우 기존의 인스턴스들이 이미 종료된 상태이기 때문에 롤백을 위해서는 (인스턴스를 다시 생성하면서) 배포를 다시 한번 해야 하는 반큼 빠른 롤백이 어렵습니다.Auto scaling lifecycle 을 이용하면, 이를 해결하기 위한 다른 방법도 있습니다. Lifecycle 은 다음과 같은 상태 변화를 가집니다.기본적으로,ASG의 인스턴스는 InService 상태로 진입하면서 (설정이 되어 있다면) ELB에 추가됩니다.ASG의 인스턴스는 InService 상태에서 빠져나오면서 (설정이 되어 있다면) ELB에서 제거됩니다.이를 이용하면, 다음과 같은 시나리오로 배포를 할 수 있습니다.똑같은 ASG 두 개를 구성(Group B / Group G)하고, 그 중 하나의 그룹으로만 서비스를 운영합니다.Group B가 라이브 중이면 Group G의 인스턴스는 0개입니다.새로운 버전을 배포한다면, Group G의 인스턴스 숫자를 Group B와 동일하게 맞춰줍니다.Group G가 InService로 들어가고 ELB healthy 상태가 되면, Group B의 인스턴스를 전부 Standby로 전환합니다.롤백이 필요하면 Standby 상태인 Group B를 InService 로 전환하고 Group G의 인스턴스를 종료하거나 Standby로 전환합니다.문제가 없다면 Standby 상태인 Group B의 인스턴스를 종료합니다.이제 훨씬 빠르고 안전하게 배포 및 롤백이 가능합니다. 물론 실제로는 생각보다 손이 많이 가는 관계로(특히 PaaS인 GAE에 비하면), 이를 한번에 해주는 스크립트를 작성해서 사용중입니다. 대략 간략하게는 다음과 같습니다. 실제 사용중인 스크립트에는 dry run 등의 잡다한 기능이 많이 들어가 있어서 걷어낸 pseudo code 입니다. 스크립트는 사내 PyPI 저장소를 통해 공유해서 사용 중입니다.def deploy(prefix, image_name, image_version): '''Deploy specified Docker image name and version into Auto Scaling Group''' asg_names = get_asg_names_from_tag(prefix, 'docker:image:name', image_name) groups = get_auto_scaling_groups(asg_names) # Find deployment target set future_set = set(map(lambda g: g['AutoScalingGroupName'].split('-')[-1], filter(lambda g: not g['DesiredCapacity'], groups))) if len(future_set) != 1: raise ValueError('Cannot specify target auto scaling group') future_set = next(iter(future_set)) if future_set == 'green': current_set = 'blue' elif future_set == 'blue': current_set = 'green' else: raise ValueError('Set name shoud be green or blue') # Deploy to future group future_groups = filter(lambda g: g['AutoScalingGroupName'].endswith(future_set), groups) for group in future_groups: asg_client.create_or_update_tags(Tags=[ { 'ResourceId': group['AutoScalingGroupName'], 'ResourceType': 'auto-scaling-group', 'PropagateAtLaunch': True, 'Key': 'docker:image:version', 'Value': image_version, } ]) # Set capacity, scaling policy, scheduled actions same as current group set_desired_capacity_from(current_set, group) move_scheduled_actions_from(current_set, group) move_scaling_policies(current_set, group) # Await ELB healthy of instances in group await_elb_healthy(future_groups) # Entering standby for current group for group in filter(lambda g: g['AutoScalingGroupName'].endswith(current_set), groups): asg_client.enter_standby( AutoScalingGroupName=group['AutoScalingGroupName'], InstanceIds=list(map(lambda i: i['InstanceId'], group['Instances'])), ShouldDecrementDesiredCapacity=True ) def rollback(prefix, image_name, image_version): '''Rollback standby Auto Scaling Group to service''' asg_names = get_asg_names_from_tag(prefix, 'docker:image:name', image_name) groups = get_auto_scaling_groups(asg_names) def filter_group_by_instance_state(groups, state): return filter( lambda g: len(filter(lambda i: i['LifecycleState'] == state, g['Instances'])) == g['DesiredCapacity'] and g['DesiredCapacity'], groups ) standby_groups = filter_group_by_instance_state(groups, 'Standby') inservice_groups = filter_group_by_instance_state(groups, 'InService') # Entering in-service for standby group for group in standby_groups: asg_client.exit_standby( AutoScalingGroupName=group['AutoScalingGroupName'], InstanceIds=list(map(lambda i: i['InstanceId'], group['Instances'])) ) # Await ELB healthy of instances in standby group await_elb_healthy(standby_groups) # Terminate instances to rollback for group in inservice_groups: asg_client.set_desired_capacity(AutoScalingGroupName=group['AutoScalingGroupName'], DesiredCapacity=0) current_set = group['AutoScalingGroupName'].split('-')[-1] move_scheduled_actions_from(current_set, group) move_scaling_policies(current_set, group) 몇 가지 더…Standby 로 돌리는 것 이외에 Detached 상태로 바꾸는 것도 방법입니다만, 인스턴스가 ASG에서 제거될 경우, 자신이 소속된 ASG를 알려주는 값인 aws:autoscaling:groupName 태그가 제거되므로 인스턴스나 ASG가 많아질 경우 번거롭습니다.cloud-init 를 어느 정도 최적화해두고 ELB healthcheck 를 좀 더 민감하게 설정하면, ELB 에 투입될 때까지 걸리는 시간을 상당히 줄일 수 있긴 하므로, 단일 ASG로 배포를 하더라도 롤백에 걸리는 시간을 줄일 수 있습니다. 저희는 scaleout 시작부터 ELB에서 healthy 로 찍힐 때까지 70초 가량 걸리는데, 그럼에도 불구하고 아래의 이유 때문에 현재의 방식으로 운영중입니다.같은 방식으로 단일 ASG로 배포를 할 수도 있지만, 배포중에 혹은 롤백 중에 scaleout이 돌면서 구버전 혹은 롤백 버전의 인스턴스가 투입되어버리면 매우 귀찮아집니다. 이를 방지하기 위해서라도 (Blue-green 방식의) ASG 두 개를 운영하는게 안전합니다.같은 이유로, 배포 대상의 버전을 S3나 github 등에 기록하는 대신 ASG의 태그에 버전을 써 두고 cloud-init 의 user-data에서 그 버전으로 어플리케이션을 띄우게 구성해 두었습니다. 이 경우 인스턴스의 태그만 확인해도 현재 어떤 버전이 서비스되고 있는지 확인할 수 있다는 장점도 있습니다.다만 ASG의 태그에 Tag on instance 를 체크해 두더라도, cloud-init 안에서 이를 조회하는 경우는 주의해야 합니다. ASG의 태그가 인스턴스로 복사되는 시점은 명확하지 않습니다. 스크립트 실행 중에 인스턴스에는 ASG의 태그가 있을 수도, 없을 수도 있습니다.굳이 인스턴스의 Lifecycle 을 Standby / InService 로 전환하지 않고도 ELB 를 두 개 운영하고 route 53 에서의 CNAME/ALIAS swap 도 방법이지만, DNS TTL은 아무리 짧아도 60초는 걸리고, JVM처럼 골치아픈 동작 사례도 있는만큼 선택하지 않았습니다.물론 이 방법이 최선은 절대 아니며(심지어 배포할때마다 돈이 들어갑니다!), 현재는 자원의 활용 등 다른 측면에서의 고민 때문에 새로운 구성을 고민하고 있습니다. 이건 언젠가 나중에 다시 공유하겠습니다. :)
조회수 1129

국내 IT 산업을 주무르는 첫눈 마피아

업계에서 페이팔 마피아(PayPal mafia)에 대한 이야기를 듣는 건 어렵지 않다. 전세계 IT 산업의 핵심인 실리콘밸리를 장악하고 있는 페이팔 마피아를 탄생시킨 회사는 컨피니티(Confinity)라는 회사다. 이 회사의 이름은 낯설지 몰라도 이 회사가 개발한 페이팔(PayPal)이라는 전자 송금 서비스의 이름은 낯설지 않을 것이다. 1998년 시작된 컨피니티는 페이팔을 만들어 2002년 상장한 뒤 얼마 지나지 않아 이베이(eBay)에 매각된 닷컴 버블 폭풍의 몇 안되는 생존자 중 하나였다. 페이팔 마피아란 페이팔의 초기 임직원들을 일컫는 말로, 이들은 이후에 또 다른 혁신적인 회사들(Tesla Motors, LinkedIn, Palantir Technologies, SpaceX, YouTube, Yelp, Yammer 외 다수)을 계속 만들어 내고 있다. 이들의 모습이 마치 사회 모든 곳에 얽혀 있는 마피아 조직을 연상시킨다는 것에 비유해, 이들을 페이팔 마피아라고 부르기 시작했다. 심지어 포춘지(Fortune)에서는 2007년 이들을 한데 모아 마피아 같은 옷을 입히고 재미있는 사진을 남기기도 했다. 출처 : Fortune Magazine, 2007년 11월페이팔 마피아들의 성공은 절대 우연이 아니라고 생각한다. 이들이 닷컴 버블의 위기를 이겨낼 수 있었던 밑바닥에는 페이팔이라는 회사가 가진 확고한 고유의 문화(culture)가 존재했다. 자신들이 만들어 낸 본연의 문화가 몸에 배인 초기 구성원들이 새로운 회사를 시작하고, 또 다시 새로운 그들만의 확고한 문화를 만들어 가면서 또 다른 페이팔이 만들어 질 가능성이 높아졌다고 할 수 있다. 또한 각자가 가진 강력한 인적 네트워크를 통해 서로 도움을 주고 받으며 새로운 회사를 만들고 함께 성장할 수 있도록 하는 노력을 아끼지 않았다. 실리콘밸리에 또 다른 닷컴 버블이 터진다 하더라도 이들 페이팔 마피아의 생존 가능성은 의심할 여지가 없을 것이다. 정부 시스템이 무너져도 마피아 조직의 견고함은 무너지지 않는 영화 같은 이야기가 실리콘밸리에서 실제로 일어나고 있는 것이다.출처 : jamesaltucher.com한국에서는 이런 사례가 없는지 늘 궁금했다. 얼마 전 알토스벤처스의 한킴 대표님 페이스북에서 ‘네오위즈 마피아'에 대한 이야기를 본적이 있다. 그런데 나는 이 이야기를 읽으면서 네오위즈보다 주목해야 할 회사는 첫눈이 아닌가 하는 생각이 들었다. 네오위즈, 넥슨, NHN 같은 회사보다 훨씬 더 마피아의 밀집도가 높은, 미국의 페이팔을 연상시킬만한 작은 조직이었기 때문이다.첫눈은 2005년 6월 네오위즈에서 분사하며 설립되었던 검색 회사다. 가장 큰 특징은 자사의 내부 DB를 통해 검색 결과를 제공하는 경쟁사들과 차별화하여 인터넷 전체를 검색 대상으로 삼는다는 점이었다. 이후 설립 1년 만에 NHN에 350억원 규모로 매각되었고, NHN의 당시 보도자료에 따르면 임직원은 총 55명이었다. ‘첫눈 마피아’에 대해 정리하려고 마음 먹고 그간 나왔던 첫눈에 대한 기사들을 많이 읽어 봤다. 간간이 첫눈을 페이팔 마피아에 비유했던 기사들도 있었다. 또 마침 우리 회사 렌딧의 홍보 담당인 꼬날이 첫눈의 홍보 담당이었던 덕분에 생생한 이야기를 직접 들을 수 있었다. 정리해 본 첫눈 마피아들은 아래와 같다 (존칭 생략):장병규 : 지난 9월 25일 4차산업혁명위원장에 임명되어 국가적 화제의 인물로 떠오른 장병규 블루홀스튜디오 의장이 첫눈의 창업자. 2005년 6월 네오위즈에서 검색엔진 개발팀 인력들을 이끌고 분사해 첫눈을 창업했다. 2006년 6월 첫눈 설립 1년 만에 NHN 과 350억원 규모로 매각. 이렇게 NHN에 들어간 첫눈의 인재들이 주축이 되어 개발한 서비스가 라인(LINE)이다. 장병규 대표는 첫눈의 NHN 인수 후 초기 기업에 전문적으로 투자하는 벤처캐피털 본엔젤스벤처파트너스를 설립해 우수한 창업자와 스타트업을 발굴하고 지원하는 일에 힘써왔다. 2007년에는 게임개발사인 블루홀스튜디오를 창업해 현재까지 의장직을 맡고 있다.신중호 : 신중호 라인 CGO(Chief Global Officer)는 첫눈의 CTO였다. 2005년에 첫눈 창업 시 장병규 대표와 함께 네오위즈에서 나왔다. 2006년 NHN 인수합병 시 NHN에 합류, NHN 재팬의 검색서비스를 책임지고 일본에 건너가 있던 중 라인을 개발했다. 일본과 동남아시아 여러나라에서 현지화에 성공, 2016년 7월 라인의 나스닥 상장을 견인했다. 최근에는 WAVE, Clova 등 네이버의 AI 사업을 총괄하며 미래를 이끌어 가고 있다.이상호 : SK텔레콤 AI사업단장 역시 첫눈 출신이다. 자연언어처리와 음성합성, 음성검색 분야의 국내 최고 권위자로 알려졌다. 첫눈에 합류하기 전에는 LG전자 연구원을 거쳐 서울산업기술대학 교수를 지냈다. 당시 이상호 교수를 첫눈에 영입하기 위해 장병규 대표가 오랜 시간 공을 들인 것으로 알려졌다. 이상호 단장 역시 첫눈의 NHN 인수합병으로 NHN에 합류한 후 음성 검색 서비스 등 검색 개발에 집중하다, 2011년 다이알로이드라는 음성 인식 개발사를 창업했다. 국내 최고의 음성 검색 전문가 4인으로 구성되었던 다이알로이드는 2012년 9월 국내 최초로 음성으로 문자를 전송하는 앱 ‘다이알로이드'를 선보였다 (관련 내용 : http://limwonki.com/536). 이상호 대표는 2012년 말 다음이 다이알로이드를 인수하며 다음을 거쳐 카카오에서 음성 검색 연구를 지속했으며, 이후 SK플래닛에 입사, CTO 로 기술을 책임지다 2017년 4월부터 SKT AI 사업단장을 맡아 누구 (NUGU) 등 AI 부문 사업을 총괄하고 있다.노정석 : 잘 알려지지 않은 사실이지만 노정석 리얼리티 리플렉션 대표 역시 첫눈 출신이다. 첫눈 창업 초기 약 4개월 간 글로벌 사업 담당으로 일하다, 2005년 9월에 블로그 개발사인 태터앤컴퍼니를 창업했다. 노정석 대표는 1996년 카이스트-포항공대 해킹 전쟁의 주인공으로 유명하다. 이후 1997년 선배들과 창업한 보안회사 인젠이 2002년 코스닥 상장에 성공. 2005년에 설립한 태터앤컴퍼니는 2007년 9월 구글이 인수하며 국내 스타트업으로는 드물은 글로벌 M&A 성공 사례로 기록 되었다. 이후 구글에서 2년여 간 프로덕트 매니저로 일하다 2010년에 설립한 파이브락스(설립 시 사명은 아블라컴퍼니)가 2014년 8월 다시 미국의 모바일 광고 플랫폼 회사인 탭조이에 매각되며, 국내 스타트업에서 드물은 글로벌 M&A 성공 사례를 다시 남긴 주인공이 되었다. 2015년 5번째 회사인 리얼리티 리플렉션을 창업해 국내 대표적인 ‘연쇄 창업가'로 불리운다. 창업과 더불어 엔젤투자자로서 좋은 창업가들을 발굴하고 후배 창업가들과 함께 호흡하는 것을 좋아한다. 티몬, 비트파인더, 미미박스, 다이알로이드, 다노, 다이알로이드(다음이 인수), 파프리카랩(일본 그리 인수), 울트라캡숑(카카오 인수) 등에 투자했다. 나 역시 2011년 미국에서 창업했던 두번째 회사인 스타일세즈 창업 때 노정석 대표의 엔젤투자를 받았다.그 외 2011년 모바일 메신저 ‘틱톡'을 개발해 카카오톡의 강력한 경쟁자로 부상했던 매드스마트의 김창하 대표 역시 첫눈 개발자 출신이다. 김창하 대표는 2012년 매드스마트를 SK플래닛에 매각하며 SK플래닛에서 일하다, 현재는 라인에 합류해 신중호 CGO와 함께 일하고 있는 것으로 알려져 있다. 라인의 박의빈 CTO 역시 첫눈 출신으로 오랜 기간 신중호 CGO 와 함께 하고 있는 핵심 인물이다. 천재 개발자로 유명한 보이저엑스 남세동 대표 역시 장병규 대표와 오랫동안 함께 한 개발자다. 19살에 네오위즈 인턴으로 시작해서 세계 최초의 웹기반 채팅 서비스인 ‘세이클럽 채팅' 개발을 주도하였고, 이후 첫눈을 거쳐 라인에서 일했다. 카카오의 AI 사업을 총괄하고 있는 김병학 부사장 역시 첫눈 출신이다.    대기업과 스타트업을 오가며 활약 중인 첫눈의 인재들도 있다. 이은정 라인플러스 이사는 베인앤컴퍼니 등에서 컨설턴트로 일하던 중 장병규 대표에게 스카우트되어 첫눈에 입사. 첫눈이 NHN에 인수된 후 현대카드, GS홈쇼핑, 삼성카드 등 대기업에서 승승장구 하던 중 2014년 라인플러스에 입사해 글로벌 사업의 중추 역할을 하며 다시 신중호 CGO와 일하고 있다. 엘지생활건강에서 모바일 플랫폼 혁신을 주도하고 있는 권도혁 상무 역시 첫눈 출신이다. 첫눈 합류 전 베인앤컴퍼니와 NHN에서 경력을 쌓았던 권도혁 상무는, 첫눈이 NHN에 인수된 후 다시 전직장 NHN에 합류하지 않고 스타트업인 큐박스에 합류했다. 이후 2011년 ‘울트라캡숑' 이라는 재미있는 이름의 스타트업을 창업, 대학생들의 익명 커뮤니티인 ‘클래스메이트', 소셜미디어 서비스 ‘너 말고 니 친구', ‘마티니', 다이어트 앱 ‘다이어터' 등을 개발해 서비스 하던 중 2014년 카카오에 매각하고 엘지생활건강에 합류했다.   스타트업 홍보를 열심히 하고 있는 우리 회사 꼬날도 첫눈 출신이다. 첫눈 (NHN 매각) - 태터앤컴퍼니 (구글 매각) - 엔써즈 (KT 매각, 이후 닐슨에 재매각됨) - 파이브락스 (탭조이 매각) 등 성공적인 엑시트로 평가되는 스타트업에 연이어 렌딧에 합류. 스타트업 홍보의 미다스 손으로 불리는 국내 유일무이한 이력의 홍보전문가다.첫눈이 NHN에 인수되면서 첫눈의 새로운 검색 정책과 혁신적인 서비스에 기대를 많이 했던 초기 사용자들이 '첫눈이 녹아 버렸다'며 아쉬워했었다고 한다. 하지만 첫눈은 매각 당시 보도했던대로 NHN과 함께 글로벌 서비스 개발에 힘썼고, 메신저 서비스 라인을 만들어 글로벌 시장 진출에 성공했다. 또한 다양한 첫눈 마피아들이 여전히 창업 전선에서 맹활약 중이다. 내가 창업에 뛰어든지 이제 만 12년이 되었고 세번째 회사인 P2P금융 렌딧을 시작한지 2년 반이 지났다. 렌딧은 기술 혁신을 통한 금융 서비스의 효율화라는 미션을 갖고 시작되었다. 혁신적인 서비스를 통해 우리 삶에 긍정적인 영향을 주는 것만큼이나 내게 강한 동기가 되는 것은 함께 일하는 사람들과의 동반 성장이다. 렌딧의 성장 뿐만 아니라 우리 고유의 문화가 몸에 배인 렌딧맨들이 미래에 또 다른 곳에서 새로운 혁신을 만들어 낼 수 있는 강력한 렌딧 마피아가 형성되기를 기대해본다.지난 5월27일, 렌딧의 SeriesB 투자가 확정되던 날 모든 렌딧맨과 함께
조회수 2597

사운들리 백엔드 이야기

사운들리는 '귀에 들리지 않는 소리'를 이용해서 컨텐츠를 전달할 수 있는 SaaS 플랫폼을 서비스하고 있습니다.제품의 구성요소는,음파를 송신할 수 있는 송신단음파를 모바일에서 수신할 수 있는 Android, iOS SDK그리고 컨텐츠를 제공하고 데이터를 수집, 분석하는 백엔드로 구성되어 있습니다.오늘은 구성 요소중 백엔드에 대해서 이야기 해보도록 하겠습니다.<그림 1. 사운들리 솔루션 구성도>사운들리의 인프라는 모두가 잘 아시는 아마존 웹 서비스를 이용하고 있으며, 크게 컨텐츠를 제공하는 API서버 부분, 로그를 수집, 분석하는 부분, 그리고 컨텐츠를 관리하는 CMS 부분으로 이루어져 있습니다.소프트웨어 스택Java : 현재 사운들리의 일부 시스템을 제외하고는 전부 자바로 작성되어 있습니다. Node.js로 시작하여 PHP를 거쳐 지금의 자바 기반의 시스템으로 구성하게 되었습니다. 다양한 사람들이 개발을 해오면서 각자 가장 잘할 수 있고, 빠르게 구현할 수 있는 언어로 개발되어 가다 현재의 자바로 통일되어 구성되게 되었습니다.Spring : API서버는 HTTP 기반의 REST API를 이용해 컨텐츠를 전달하고 있으며 스프링 프레임워크를 이용해 개발되었습니다. 이외에도 일부 분석에 스프링 배치를 사용하고 스프링을 편리하게 사용할 수 있게해주는 스프링 부트도 이용하고 있습니다.gRPC : 분산되어있는 서버들끼리 이기종 언어간 통신을 하기 위해서 Protocol Buffers 기반의 gRPC를 이용하고 있으며 서버들의 모니터링하는 서버와 에이전트들 사이의 통신 목적으로 사용합니다.Flume : 분산된 서버들에서 로그를 수집하는 역할을 합니다. 수집된 로그는 파일로 저장하며 실시간으로 볼수 있도록 엘라스틱서치에 같이 저장하고 있습니다. SDK에서 전송되는 로그 또한 웹서버의 엑세스 로그를 플럼 에이전트가 수집하는 방식으로 비동기로 처리하고 있습니다.ElasticSearch : 수집된 로그들을 실시간으로 확인하기 위해서 사용되며 Kibana를 이용해 시각화하고 있습니다.Angular.js : CMS의 프론트엔드는 Angular.js + Bootstrap을 이용해 개발되었으며, Bower를 이용한 라이브러리 관리, Grunt를 이용한 빌드 관리를 하고 있습니다.소프트웨어 개발/운영GIT : 소스코드는 git로 관리하며 Git-Flow를 이용한 브랜치 정책을 수립하여 가져가고 있고 저장소로는 깃허브를 이용합니다.Quality Practice : QA단계에서 제품을 테스트하기 전 개발자들은 QA 프로세스에 맞게 다음 3가지 기준으로 소스 코드의 품질을 관리합니다.코딩 컨벤션 : 사운들리 내부 코딩 컨벤션에 맞게 개발되었는지 확인합니다. Checkstyle의 규칙을 정의 및 자동화합니다.테스트 코드 : 단위 테스트 코드를 작성하며 테스트 결과는 모두 통과되어야 합니다.테스트 커버리지 : 단위 테스트 코드가 작성된 커버리지를 계산하며 현재 60%를 목표로 진행하고 있습니다.젠킨스 : 소스코드 저장소에 변동이 일어나면 젠킨스가 소스코드를 빌드하고 위에서 언급한 세가지에 대한 리포트를 작성합니다.소나큐브 : 무료 오픈소스로 코드 정적 분석을 해주며 및 QA 리포트를 같이 볼 수 있습니다.슬랙 : 인력이 적은 저희 팀도 슬랙을 적극적으로 개발/운영에서 사용하고 있습니다.팀 커뮤니케이션 : 팀원들 간의 의사사통을 위한 주요 수단으로 모든 팀원이 함께 사용하고 있습니다.분석 리포트 : 젠킨스나 배치를 통해 분석된 데이터들은 분석이 끝난 지표들은 슬랙으로 결과를 전송하여 모든 팀원이 볼 수 있도록 공유하고 있습니다.서버 모니터링 : 서버들의 이상 징후 감지나 배치 오류등을 슬랙을 통해 담당자에게 전송하여 조치할 수 있도록 합니다.애플리케이션 및 서버 모니터링 : 애플리케이션의 모니터링은 Naver에서 오픈소스로 공개한 핀포인트를 사용하고 있고, 서버 상태 모니터링을 위해 자체 개발한 모니터링 시스템을 사용하고 있습니다. 모니터링 데이터 수집을 하는 에이전트와 전체 시스템의 데이터를 관장 하는 서버간에는 gRPC를 이용하여 상태 체크를 합니다. 서버의 상태에 문제가 있을 때에는 slack을 통해 담당자들에게 알람을 주도록 시스템 설계를 하였습니다.개발 문화개발자들은 각각 개발을 할때 정해진 정책에 맞춰 브랜치를 만들어 개발합니다.각각 개발된 소스들은 저장소인 깃허브에 푸시된 후 깃허브의 댓글 기능을 이용하거나 오프라인을 통해 코드 리뷰를 진행합니다.리뷰가 끝난 후 합쳐진 소스는 QP 활동을 통해 분석이 됩니다.빌드가 실패할 경우 커피를 사야합니다 ^^ (커피를 얻어 먹으려는 것이 아닌 소스코드를 푸시하기 전 잘 확인하자는 취지입니다) AWSEC2 : 사운들리의 대부분의 구성 요소인 API서버와 로그 수집, 분석 서버, 엘라스틱서치, 플럼, CMS등이 모두 EC2에 구축되어 있습니다.RDS : 컨텐츠의 주 저장소로 데이터베이스 관리의 용이성을 고려하여 RDS의 Multi-AZ에 배포하여 Active-Standby로 구성되어 있으며 이 데이터들은 레디스와 로컬 캐시를 이용하여 API서버에서 활용하고 있습니다.S3 : 컨텐츠에 포함된 각종 정적 데이터들이 저장되며 수집된 로그들도 저장하여 보관됩니다. EMR : 로그 수집서버를 통해 S3에 저장된 로그들은 EMR을 이용해서 분석됩니다.Beanstalk : 개발 서버의 배포에 사용됩니다. 최근 IntelliJ의 플러그인이 업데이트 되면서 IntelliJ 15버전을 지원하게 되므로써 로컬에서 개발하고 개발 서버에 배포까지 편리하게 하고 있습니다. VPC : 인터넷이 필요 없는 서버들은 VPC 내부 private-zone에 배포 및 ELB를 통해 외부에서 접근하도록 구성되어 있습니다.<그림 2. AWS 배포 구성도>이상으로 사운들리에서 사용하고 있는 백엔드 소프트웨어들을 소개해 보았습니다. 적은 인력으로 빠르게 사업을 진행하는 스타트업에서는 비즈니스에 집중할 수 있도록 도와주는 다양한 툴이나 오픈소스를 이용하여 많은 도움을 받을 수 있는 것 같습니다. 또한 코드를 잘 작성하여 에러를 줄이는 것도 필요하지만 여유가 많지 않으면 최소한 제품의 에러에 빠르게 대응할 수 있도록 하는 방법도 필요한 것 같습니다.#사운들리 #개발 #개발자 #문제해결 #프레임워크 #스킬스택 #스택 #인사이트
조회수 2640

[H2W@NL] 로봇과 디자인

디자인이란 단어가 이제는 어디서나 익숙합니다. 그만큼 디자인의 정의와 역할은 다양한 영역에서 분화되어 있기도 합니다. 네이버랩스에서는 로봇이라는 대상에 대해 여러 분야의 디자인이 진행되고, 종국에는 통합됩니다. 하나의 로봇으로 이어지는, 로봇시스템/UX/ID 각각의 디자인에 대해 물었습니다.Q. 어떤 ‘디자인’을 하나요?로봇의 메커니즘에서 인터페이스까지, 최적의 시스템을 디자인(김인혁|Robot) 제가 하는 디자인은, 시스템 디자인이라고 말할 수 있습니다. 아, 물론 제가 속한 Robot팀엔 더 많은 디자인 과정들이 있어요. 로봇의 기구, 전장, SW 등 각각의 영역에서도 디자인 과정이 존재합니다. 저는 그 중에서 주로 시스템 제어 엔지니어로서의 디자인을 이야기할 수 있겠네요.사실 시스템이란 말이 좀 모호하죠. 과학분야에선 이렇게 정의할 수 있습니다. 구성 요소들이 내외부와 경계를 가진 상태에서 각 요소 간에 긴밀한 상호작용을 하는 집합체. 쉽게 설명하고 싶었는데, 여전히 어렵긴 하네요.로봇은 단순한 기능을 구현할 때에도 복잡한 요소들이 동시에 작동합니다. 메커니즘, 동력원, 에너지원, 제어기와 인터페이스 등. 이들이 서로 잘 연결되어 작동할 수 있어야 합니다. 이를 위한 최적의 시스템을 구성하는 디자인이라 하겠습니다.로봇, 그리고 사람, 그 사이에서의 상호작용(김석태|UX) UX의 입장에서는 HRI (human-robot interaction) 디자인이라고 정의할 수 있습니다. 앱이나 웹 등의 화면 기반 인터페이스와는 조건이 다른데요. 물리 공간에서 로봇이 동작한다는 점이 그렇습니다. 주변 사물이나 사람을 로봇이 인식하는 순간처럼 다양한 상황에서 로봇이 어떻게 동작하거나 반응해야 하는지, 그리고 로봇을 활용한 서비스는 다른 디바이스나 앱과 달리 어떤 방식을 통해 제공되어야 더욱 직관적으로 사람과 상호작용이 가능한지 등을 디자인하고 있습니다.기술만큼, 인상과 매력도 중요하다(김승우|ID) 로봇의 외관도 중요합니다. 로봇은 여전히 일반인들에겐 생소합니다. 이들에게 로봇은 흥미로움을 일으키는 대상일 수도 있지만, 마주치는 순간 기피하고 싶은 이질적 존재일 수도 있어요. 그래서 외관을 통해 느끼는 인상과 그 효과에 대해 세심한 접근을 하고 있습니다. 로봇 서비스가 보편화되지 않은 시점에서는, 사람들이 기대하는 로봇다운 매력을 잘 체감할 수 있게 하는 것도 로봇 대중화를 위해 중요한 역할인 것 같습니다.“기술이 지닌 본래의 가치를 더욱 잘 느낄 수 있도록 전달하는 것, 그것도 디자인의 역할입니다.” Q. 어떤 프로세스로 작업하나요?단순한 목표를 위해 필요한 복잡한 과정들(김인혁|Robot) 기본 목표라고 한다면, 일단 요구 스펙을 잘 만족하는 시스템을 설계하는 것입니다. 현실은 아주 복잡하죠. 요소들이 워낙 다양하기 때문인데요. PoC, 성능 테스트 등 평가 과정을 거치면 조정해야 할 것들이 많아집니다. 아예 새로 개발을 할지를 고민하게 될 때도 있는데, 참고할만한 레퍼런스가 없을 때는 참 어려워집니다. 이럴 때는 원론적으로 풀 수밖에 없죠. 공학적인 문제부터 정의하고 문제 해결을 위한 방법론을 탐색합니다. 이런 일들이 수없이 많지만, 시스템 디자인의 일반적인 프로세스이기도 합니다. 목표는 단순하지만, 과정은 현란하죠.산업을 이해하면 목표가 보이고, 사람을 이해하면 디테일이 보인다(김석태|UX) 앞서 말씀드린 것처럼, 서비스 로봇은 다른 앱/웹 서비스와 상황이 많이 다르죠. 앱이라면 프로토타이핑과 검증 과정을 상당히 빠른 주기로 반복할 수 있는데, 로봇은 그런 면에서는 제약이 있습니다.일단 로봇 서비스 산업에 대한 이해부터 시작하였습니다. 그간 어떤 로봇들이 어떤 서비스를 했고, 학계에서는 어떤 연구들이 선행 되었는지를 꼼꼼히 연구했습니다. 그리고 나니 목표 수준이 좀 더 명확해지고, 시나리오를 구체화할 수 있었습니다.중요한 건 역시 사람에 대한 이해입니다. 실제로 유용하다고 느낄까? 어떤 니즈가 여전히 숨어있을까? 로봇이 대신 해 주었을 때 더 가치 있는 것은? 이런 질문에 대한 답을 찾은 후 다음 숙제가 이어집니다. 사람들의 삶 속으로 이질감없이 자연스럽게 녹아 들기 위한 인터랙션입니다. 인터랙션 상황들을 정의하는 일부터가 시작이고, 어떤 이슈나 문제가 있는지를 찾아냅니다. 가장 단순하면서도 자연스러운 해결 방법은 무엇일지 실험을 통해 검증합니다. 이 과정에서 굉장히 많은 디테일들이 새롭게 발견됩니다.기술에 대한 이해도 중요합니다. 예를 들어 최근 AROUND C에는 디자이너가 가장 이상적인 로봇의 속도 및 이동 경로를 선택하면, 이를 바탕으로 딥러닝 기술을 적용해 최적화된 자율주행을 할 수 있는 기술이 적용되어 있습니다. 지켜보는 사람이 언제 안정감을 느끼는지, 로봇과 사람이 교차할 때엔 상대 속도나 동선을 어떻게 할지, 공간상의 제약이 복합적으로 작용하면 어떤 기준을 세워야 할지 등등. 수많은 요소들 사이에서 최적의 인터랙션 디자인을 설계해야 합니다. 이런 사소해보이는 사용자 경험이 로봇 서비스 과정에서 뜻밖의 감동까지도 전달할 수 있다고 생각합니다.“우리가 추구하는 기본 방향은, 실용적이면서도 사람을 배려하는 로봇입니다. 문제 상황을 분석해 나온 다양한 해결책 중에, 사람이 직관적으로 파악할 수 있는 방법을 택합니다.” 최근에는 AROUND C에서는 gaze, sound, lighting을 통한 비언어적 커뮤니케이션을 테스트하고 있습니다. 왜 굳이 로봇이 직접 말하게 하지 않고 비언어적 커뮤니케이션을 연구할까요? 그게 서비스 시나리오 상에서 더 직관적이며, 심지어 더 똑똑해 보이기 때문입니다. 스타워즈의 R2D2와 C3PO를 떠올리시면 됩니다. 점과 선을 활용해 가장 로봇다운 눈을 디자인 했고, 이를 통해 다양한 상태 정보를 사람에게 직관적으로 전달하고자 했습니다.전체의 통일감과 개별 디자인의 완성도라는 두개의 과녁(김승우|ID) 제가 공을 들이는 건 전체 제품의 통일감과, 개별 디자인의 완성도입니다. 네이버랩스에서 그간 공개했던 제품들은 작은 디바이스부터 중형 로봇, 대형 차량 센서박스에 이르기까지 다양한 카테고리에 걸쳐 있습니다. 디자인의 토대가 되는 조형 요소인 제품의 크기와 형태, 구조가 상이하다 보니 각각의 형태와 구조적 특성을 고려하면서도 전체 제품에 통일감이 느껴지도록 하는데 많은 노력을 기울여 왔습니다. 기업에서 일관된 메시지를 전달하는 것은 그 기업을 신뢰할 수 있는가에 대한 중요한 가치라고 생각해요. 디자인도 마찬가지입니다. 네이버랩스라는 기술 기업에서 전달해야 할 가치는 ‘정밀함’과 ‘단단함’이라고 생각했고, 로봇을 포함한 전체 제품에서 이 키워드들을 담은 일관된 디자인 언어가 느껴질 수 있도록 조형의 기본이 되는 면, 면의 기본이 되는 선을 세밀하게 다듬으며 디자인했습니다.또한 개별 디자인의 완성도를 위해 밸런스와 디테일을 중요하게 생각합니다. 로봇은 움직이기 때문에 다양한 각도에서 바라보게 되고, 어느 방향에서 보아도 완성도 높은 밸런스가 특히 중요합니다. 잘 안보이는 곳의 디테일도 쉽게 드러나기 때문에 세밀한 디테일을 놓치지 않기 위해 노력하고요.로봇의 경우엔 일반인들의 디자인 완성도에 대한 기대 수준이 더 높은 편입니다. 이런 기대를 충족시키는 동시에 기술적인 요구도 충족해야 합니다. 예를 들어, AMBIDEX의 전체 디자인 균형을 잡는 과정에서 팔의 부피를 늘리는 선택이 필요했는데, 동시에 무게는 가볍게 유지해야만 로봇의 기능을 100% 발휘할 수 있었습니다. 경량성이 AMBIDEX라는 로봇 팔 기술의 핵심 특성이기 때문이죠. 외관 부피를 늘려 디자인 밸런스를 최적으로 잡으면서도 1g을 더 줄이기 위해 질량을 체크하며 표면과 두께를 조정하고, 강성을 높이는 내부 구조를 추가하며 문제를 해결했습니다. 이런 디자인 과정을 거쳤기에 외관에서도 내부의 단단함과 견고함이 배어 나온다고 생각합니다.Q. 서로 어떻게 협업을 하나요?어차피 목표는 하나(김인혁|Robot) 각기 다른 분야의 전문가들이 협업할 때의 견해차이는 프로세스를 통해 해결되어야 한다고 생각해요. 그게 아니라 의견의 일방향성이 생기면 그건 곤란하죠. 저는 각 분야의 선/후행을 두지 않고 초기부터 과정 전반에 걸쳐 계속 공유하고 의견을 나누며 서로의 수용성을 늘리는 것이 아주 중요하다고 생각해요.“한 영역의 전문가가 모든 결정을 하고 다른 분야의 전문가는 일방적으로 종속되어야 한다면, 그건 문제가 있습니다. 선행과 후행을 나누면 안됩니다. 초기부터 같이 고민하고 대화하고 함께 풀어야 합니다.” (김석태|UX) 저도 커뮤니케이션이 협업 과제를 빠르게 가속하는 가장 중요한 요소라고 봅니다. 다양한 관점에서 의견을 나누는 건 정말 필요해요. 그 과정 없이 한번에 이상적인 솔루션을 바라는 건 무리입니다. 지금 진행 중인 1784 프로젝트 역시 이러한 소통을 원활히 이어가고 있기 때문에 좋은 협업이 진행되고 있고요.(김승우|ID) 차이란 것은 자연스럽죠. 좋은 결과를 위해 필수적입니다. 궁극적인 목표를 달성하고자 한다는 동질감을 느끼기 때문에 서로의 진정성을 확인허는 과정이기도 합니다. 어떤 디자인이라도 많은 협의와 조율이 전제됩니다. 하나의 입장에 매몰되어 있는지 되돌아보기도 하고, 전체를 바라보는 기회로 삼기도 합니다.Q. 앞으로의 도전은?(김인혁|Robot) 우리의 목표는 사람에게 도움이 되는 로봇을 개발하는 것입니다. 단순하죠. 이를 기술 관점에서 고민하고, 가장 적합한 답을 찾고, 그 답을 세상과 공유하고 싶습니다. 그것이 제가 맡은 역할이라 생각하고요. 그 역할을 잘 할 수 있도록 연구개발자로서도, 프로젝트를 리드하고 완성하는 실무자로서도 역량에 깊이를 더하고 싶습니다.새로운 스탠다드라는 설레는 도전(김석태|UX) 이제는 실험실이나 전시장이 아니라, 우리가 실제 살아가는 공간으로 로봇이 들어옵니다. 그런 시대에 도달했습니다. UX디자이너로서는 완전히 새로운 기회이자 설레는 도전입니다. 한때 모바일이란 세상으로 패러다임이 이동했던 시기가 있었죠. 이제는 가상 세계에서 제공하던 다양한 서비스와 기술들이 일상의 물리 공간으로 다시 돌아올 것입니다. 서비스 로봇을 통해 이 분야의 새로운 스탠다드를 만들고 싶습니다.(김승우|ID) 네이버랩스에서는 늘 흥미로운 프로젝트들이 진행되어 왔습니다. 그 중에서도 로봇 디자인은, 다른 어느 로봇보다도 디자인 완성도가 높으며, 동시에 기능적 가치를 충실히 구현하는 것을 목표로 진행해 왔습니다. 게다가 로봇은 외관 그 자체가 하나의 강렬한 인상이자 브랜드 체험 요소가 되기 때문에 더욱 큰 책임감을 느끼고 있습니다. 네이버랩스는 기술이 강점인 회사입니다. 동시에 디자인 또한 우리의 탁월한 강점입니다. 이를 위해 앞으로도 노력하려고 합니다. 네이버랩스의 인재상은 passionate self-motivated team player입니다. 어쩌면 '자기주도적 팀플레이어'라는 말은 형용모순(形容矛盾)일 지도 모릅니다. 하지만 우린 계속 시도했고, 문화는 계속 쌓여갑니다. 다양한 분야의 전문가들이 경계없이 협력하고 스스로 결정하며 함께 도전하는 곳의 이야기를 전합니다. How to work at NAVER LABSH2W@NL 시리즈 전체보기

기업문화 엿볼 때, 더팀스

로그인

/