Google의 20% Time 제도는 Google의 직원이라면 누구나 업무 시간의 20%, 즉 매주 하루 정도의 시간을 자신이 원하는 일에 투입할 수 있다는 제도. 이 제도는 Gmail 과 같은 성공적인 프로젝트의 요람이 된 것으로 매우 잘 알려져 있고, Google이라는 회사에서 ‘혁신’이라는 가치를 소중하게 여긴다는 사실을 대변하고 있다.

그렇다면 어떤 소프트웨어 회사든 Google의 20% Time 제도를 도입한다면 ‘혁신’에 성공할 수 있을까? 현실을 냉철하게 바라보는 사람이라면 Google에서 조차도 20% Time 제도가 ‘혁신’에 있어서 성공적인가라는 질문에 의문을 품는 것이 당연하다고 본다.

예를 들어, 당신은 어떤 소프트웨어 회사의 상위 관리자이고, ‘혁신’의 추진력을 높이기 위해 (그다지 현명한 이유는 아닐지라도) 유명한 Google의 20% Time의 도입을 검토하고 있다고 생각해보자.

이러한 관점에서 20% Time에 대한 Quora의 답변 내용을 간략하게 정리해본다. 여러 사람들이 기술한 사항들이기 때문에 주관적이기도 하고 시간이 흐르면서 변화한 사항들도 있을 테니, 이 글에 있는 모든 사항들이 정확하다고 보기에는 힘들다는 점을 유념해서 읽어주었으면 한다. Google의 employee가 아닌 입장에서 이 글을 쓰는 한 대체로 부정확하고 상상력에 기초한 우스운 글이 되기 쉽다는 것을 잘 알고 있지만, 동기 부여라는 주제에 관한 스스로의 고민의 과정을 정리해놓는 의미로 생각한다. 이 글에서 언급된 현실을 반영하지 않는 잘못된 사실이나 미묘한 의미가 있다면 지적해준다면 그러한 과정에 매우 도움이 될 것이다.

평가: 20% Time은 어떻게 평가되어야 하는가?

20% Time을 도입한다고 할 때, 가장 먼저 부하 직원들이 묻는 것이 바로 이 부분일 것이다. 20% Time은 강제로 사용하는 것인가? 선택적으로 사용하는 것인가? 어느 쪽이든 평가에 불이익이 있는 것이 아닌가?

In Google

20% Time을 모든 사람이 반드시 활용해야 하는 것은 아니다. 한편, 20% Time을 활용하고자 하는 사람이 20% Time을 사용하는 것을 직접적으로 가로막는 것은 없다. 하지만, 관리자나, 함께 main project의 일정을 고려해야 하는 동료들의 동의를 얻는 것이 바람직하다. 관리자의 승인 하에 20% Time을 모아서 한 주 동안 Full Time으로 일할 수도 있다.

또한 기본적으로 20% Time은 평가 (performance review)에서 제외되며, 포함된다고 하더라도 평가 (performance review)에 인지되기 힘들다. 동료 평가(peer review)에서 인지되는 것이 바람직하겠지만, 현실적으로 100%의 시간을 주요 프로젝트에 사용한 동료가 더욱 좋은 평가를 얻을 확률이 높고 승진도 빠를 수 있다. 정당한 평가를 위해서는 실제로 자신이 기여한 프로젝트의 PM에 대해 정당한 동료 평가를 요구하여야 한다.

이러한 현실적인 어려움 때문에, 대부분의 Google 직원들은 이를 활용하고 있지 않다.

Opinion

보통, 관리자의 입장에서 20% Time을 위한 리소스를 할당하는 것은 절대 쉬운 일은 아니라고 본다. 하지만, 이는 리소스에 대해 단기적인 시각에서 바라보았을 때의 결과라고 생각한다. 만약 20% Time이, 혁신을 유도하거나 생산성을 높이거나 적어도 Turn-over 비율을 감소시킴으로써, 투입한 비용 이상의 성과를 산출할 수 있다면, 처음에 이를 선택하는 것은 조금 과감할 필요가 있겠지만, 곧 익숙해진다면 별로 문제가 되지 않을 거라고 생각한다.

20% Time을 평가에 포함시킬 것인가, 포함시키지 않을 것인가는 매우 어려운 문제다. 평가에 포함시킨다면, 평가를 어떻게 할 것인가라는 문제를 차치하더라도, 평가 자체가 20% Time에 참여하는 사람들의 의도를 왜곡하여 20% Time의 본래 의미를 잃어버리기가 쉽다. 평가에 포함시키지 않는다면, Google의 사례와 같이 20% Time을 사용하기 위한 커다란 incentive가 사라지게 된다. 양쪽 모두가 각각의 문제를 지니고 있기 때문에, 결국은 제도 자체의 겉모습에 치중할 것이 아니라, 제도를 통해서 획득하려는 가치를 기준으로 판단해야 한다고 생각한다.

20% Time이 조직에 혁신을 위한 문화를 조성하고 실제로 혁신을 이끌어내기 위한 것이라면, Google과 같이 평가에 포함시키지 않는 쪽이 더 바람직해 보인다. 그 이유는 다음과 같다.

  • 모든 사람이 혁신을 위한 아이디어를 가지고 있고, 이 아이디어를 실제로 실행할 의지를 가지고 있으며, 또 그를 성공시키기 위한 역량을 가지고 있으며, 상황적인 조건이 부합하는 것은 아니다. 아마도 이는 소수에 불과할 것이다.
  • 정말로 가치 있는 일이라면 적어도 20% 정도의 보상 기회를 희생할 정도의 가치가 있어야 할지도 모른다.
  • 불확실한 미래의 보상을 기대한다고 하더라도, 현재의 확실한 희생을 수용한 사람이라면, 그만큼 보람 있고 열정적으로 일 할 것이다.

물론, 실제 실행 시에는 보다 많은 미묘한 문제들이 발생할 거라고 추측되지만, 이러한 허들을 뛰어넘을 수 있는가의 여부는 실제로 실행해보지 않고서는 미리 예측하기 힘들다.

시간: 20% Time은 너무 길거나 반대로 너무 짧은 것은 아닌가?

In Google

Google에서 실제로 하나의 서비스를 launch하기 위해서는 개발 비용을 넘어서는 커다란 오버헤드를 필요로 한다. 예를 들어, 조그마한 서비스라고 하더라도 launch를 위한 기술 및 제품 승인을 얻기 위해서는 많은 노력을 필요로 한다. 자신의 프로젝트에 참여하기 위한 사람들을 찾는 것도 매우 어려운 과정 중의 하나라고 한다. 막상 서비스를 launch하더라도 수시로 발생하는 outage나 운영 상의 변화에 대응하기 위한 유지보수에 다시 20% Time을 들여야 한다. 따라서, 제대로 뭔가를 하려면 20% Time 만으로는 부족하고 야근과 주말근무를 불사해야 한다. 의견이 엇갈리기는 하지만, 20% Time은 workholic을 위한 제도라고 얘기할 정도. 20% Time은 서비스를 launch하는 수단으로서는 그다지 좋지 않다는 의견도 존재한다.

활용: 20% Time을 어떻게 활용하는가?

In Google

다음과 같은 다양한 활용이 가능하다.

  • 기존 및 현재의 프로젝트에서 다른 사람들을 설득하지 못하지는 못했지만, 스스로는 가치가 있다고 생각하는 문제를 개선할 수 있다. 현재의 개발팀이 우선순위 때문에 관심을 기울이지 못하는 어떤 기능을 개선할 수 있다.
  • 새로운 서비스나 새로운 소프트웨어를 개발한다.
  • 이미 존재하는 전사 프로세스나 도구를 개선한다.
  • 외부의 오픈 소스 프로젝트에 기여할 수도 있고, Journal에 기고하거나, 새로운 프로그래밍 언어나 UI 디자인에 대해 공부하는 등, Job Skill을 확장하기 위한 뭐든지 할 수 있다.

가치: 20% Time이 Google에게 가져다 주는 것은 무엇인가?

이에 대해서는 일단 Dion Almaer의 글을 인용해보자.

The key was the following effect:

  • In order for 20% time to work, anyone must be able to see what is out there
  • In fact, if you want to get some people working “for free” you need to both advertise your project, and write it in such a way that it is easy to get ramped up and productive (end result: better code)

The end result is the culture HAS to be kept very open. The ability to see the projects that are worked on, check out the code, see presentations and design docs, is a key reason why Google does so well at engineering in my opinion.

난 위의 Quora의 답변 내용에서 나왔던 사실들로부터 20% Time의 효과에 대해 원래 가지고 있었던 의심을 약간은 확인했다고 생각했는데, 이 글을 읽고 내가 지인들로부터 들었던 이야기들이 떠오르면서 그러한 생각이 완전히 바뀌게 되었다.

20% Time은 어떻게 동작하는가?

다음 사항들은 지인들로부터 들었던 이야기들이라 더욱 부정확할 수 있겠지만, 일단 정리해보자.

  1. Google에서는 20% Time 프로젝트에 참여할 다른 엔지니어를 모집하기 위해 전사 메일을 보낼 수 있다. 그리고, 20% Time 프로젝트에 리소스를 승인 받거나 공개 서비스로 내놓기 위해 승인 받는 과정이 정의되어 있다.
    • 자신의 좋은 아이디어를 전사 메일로 보낼 수 있고, 참여를 호소할 수 있으며, 이것이 제도적으로 뒷받침되는 소프트웨어 회사는 과연 얼마나 될까?
    • 관리자들은 자신에게 이야기를 하면 되는데 이야기를 하지 않아서 그렇다고 생각할 지 모르겠지만, 공식적인 제도가 있는 것과 이야기를 하면 된다라는 것은 조직원 입장에서는 천지차이다.
  2. Google에서는 자신이 만들어 낸 코드, 문서, 발표 자료 등을 누구든지 볼 수 있다.
    • 자신의 프로젝트에 참여하고자 하는 사람 또는 관심이 가는 프로젝트를 주도하는 사람이 얼마나 뛰어난가를 확인하는 가장 정확한 방법은 그 사람이 실제로 해놓은 것을 보면 된다. 다시 말해, 엔지니어가 다른 엔지니어의 산출물에 대해 가장 잘 평가할 수 있다.
    • 대부분의 회사에서도 어떤 방식으로 산출물이 관리되고 있긴 하겠지만, 실제로 어떤 사람의 산출물을 공개적으로 접근하는 것은 매우 어렵다.그래서, 직급이라든가, 함께 일했던 시절의 주고 받은 대화나 메일, 과거 동료들의 단평 정도를 간접적으로 이용하는 것에 불과하다.
  3. Google에서는 코드 리뷰가 필수적으로 행해지고 있으며, 코드에 대한 평가를 수치화한 Readability Score라는 척도가 공개적으로 조회 가능하고, 이러한 수치가 다른 프로젝트에 대한 Commit의 허용 여부에 영향을 미친다.
    • 단순히 모든 산출물이 공개되어 있을 뿐만 아니라, 이를 정량화하고 실제로 이러한 척도가 어느 정도의 신뢰성을 가지고 동작한다는 것이 매우 놀랍다.
    • Readability Score는 평가(Performance Review)와는 무관하다.
    • Google의 코드 리뷰 제도에 관해서는 역시 Quora의 답변들을 읽어보면 참고가 될 것이다.

제도, 시스템과 문화를 통한 혁신

혁신에 관한 이야기를 꺼낸다면 아마도 대부분의 상위 관리자들은 다음과 같은 이야기를 할 것이다.

혁신에서는 시간이 있는가, 없는가가 중요한 것이 아니라, 얼마나 열정적으로 문제를 해결하려고 하는 가가 중요하다. 또한, 혁신은 아이디어가 아니라 실행이다.

나는 이런 이야기들에 거의 찬성한다. 나조차도 이런 얘기를 한 적이 분명 여러 번 있을 것이다. 조직의 구성원들의 열정은 혁신에 있어서 필수불가결한 요소이고, 시간의 부족만을 그 원인으로 진단하는 것에 대해서는 반성이 필요한 경우가 많은 것이 사실이라고 본다.

그럼에도 불구하고 혁신과 열정의 원동력이 오직 조직 구성원 내부에만 있다고 보는 관점도 온전히 옳다고만 할 수는 없다고 본다. 단지 조직원 사이에서 혁신과 열정이 저절로 꽃피어나기를 기다리는 것보다는 구성원이 혁신적인 아이디어에 대해 열정적으로 일할 수 있도록 동기를 부여하거나 지원하는, 좀 더 적극적이고 체계적인 행동이 조직에는 필요하다고 생각한다. 이 때, 적극적이고 체계적인 행동이라는 것의 의미는 관리자 개인의 능력이나 성향, 선의에 의한 동기 부여 행동과 대비되는 것을 의미한다.

제도나 시스템이 아닌 관리자 개인에 의존할 경우 다음과 같은 문제들이 존재할 수 있다.

  • 관리자 개인에 따라 개인의 능력이나 성향, 선의에 따라서 동기 부여의 수준은 극단적으로 낮을 수 있다. 이러한 경우에 대한 대책이 없거나 있더라도 제대로 동작하지 않을 가능성이 있다.
    • 일반적인 hierarchical 조직에서, 관리자 개인이 조직원의 동기 부여를 크게 해친다고 하더라도 관리자 자신은 이러한 상황을 인지하지 못하거나, 인지하더라도 변화하기가 힘들며, 조직원은 변화를 위한 적절한 권한이나 역량이 없으며, 상위 조직장은 이를 인지하지 못하는 경우가 많다.
    • 조직이 보통 요구하는 것은 조직의 단기 성과를 높일 수 있는 충분한 역량을 가진 조직장이며, 물론, 동기 부여의 능력 또한 조직이 요구하고 바람직한 능력이나, 성과와 동기 부여가 충돌할 경우, 조직은 전자를 선택하는 경향이 있는 것 같다. 팀의 morale을 와해한 조직장이 승승장구하는 (적어도 살아남는) 스토리는 이러한 이유에 기인한다고 생각한다.
  • 조직의 상황에 따라 동기 부여의 수단이 쉽게 희생될 수 있다.
    • 일반적인 상황에서 조직 및 이를 대변하는 관리자는 생산성의 저하 요소를 제거하기 위해서 동기 부여에 노력을 기울일 수 있다. 하지만, 조직원의 동기 부여와 우선순위와 R&R 같은 좀 더 전통적인 조직 가치가 충돌할 경우 후자를 우선시하는 경향이 있는 것으로 보인다. 이러한 선택은 조직의 구조나 목적 상 물론 불가피한 측면이 있는 것이 사실이다.
    • 문제는 이러한 조정이 개인에 의한 것일 경우, 극단적인 희생이 이루어질 가능성이 높다는 것이다. 예를 들어, 일반적인 상황에서 동기 부여를 위한 노력이 50%의 비중이었다면, 문제의 상황에서는 0%가 되어버릴 수 있다는 것이다.

단편적인 예를 들어, ‘내가 원하기만 한다면 내가 원하는 일을 언제든지 할 수 있어’와 ‘내가 원하더라도 조직장에게 얘기를 해야할까? 얘기를 한다면 불이익을 받지 않을까? 소속 조직을 옮겨야 할까? 소속 조직을 옮기기 위해 회사의 제도를 활용할 수 있을까? 또는 누구와 얘기해야할까? 그냥 이직을 해야할까?’는 조직원 입장에서 엄청난 차이일 수 밖에 없다.

Google의 20% Time에서 가장 중요한 측면 중 하나는 Google은 조직원의 동기 부여에 대한 강조가, 관리자 개인에만 의존하지 않고, 전사적인 제도와 이를 뒷받침하는 시스템, 그리고 문화를 통해 항상 일정 수준으로 이루어진다는 것이다.

수평적인 평가와 비물질적인 보상을 통한 혁신의 동기 부여

평가와 보상이란 조직에 있어서 가장 중요한 요소 중의 하나이다. 평가의 본질적인 목적은 보상을 어떻게 공평하게 분배할 것이냐가 아니라, 조직원의 potential을 최대한 발휘하게 하여 조직 전체의 성과를 증가시키는 것에 있다.

하지만, 일반적으로 평가는 어려울 뿐만 아니라, 예측과 정량화의 어려움으로 인한 Software 개발의 본질 상 Software 개발 조직에서의 평가는 매우 어려운 것이 보편적으로 받아들여지고 있다.

<To Be Written>

Closing

Google이 20% Time을 통해서 단지 제도와 시스템 뿐만 아니라 혁신의 문화를 배양하는 것은 실제로 동작하는 사례로서 매우 높은 성취라고 생각한다. 하지만, 혁신을 위한 조직 문화를 만들기 위한 수단이 비단 Google의 20% Time만이 있는 것은 아닐 거라고 추측해본다. 보다 많은 조직에서 이에 대해 고민하고 또 실험하면서 그들만의 혁신 문화를 창조해나갔으면 좋겠다.

좀 더 읽어볼 글들:

 

Excellence Award는 Continuous Delivery, Productivity Award는 Seven Languages in Seven Weeks와 Mining the Social Web이 수상했다. 이들 Top 3 이외에 당장 관심이 가는 책은 Martin Fowler의 DSL 책, Scalability Rules 정도.

The Best Books

http://drdobbs.com/joltawards/231500080

  • Domain-Specific Languages, by Martin Fowler
  • The Art of Computer Programming, Volume 4A: Combinatorial Algorithms, Part 1, by Donald E. Knuth
  • The Joy of Clojure: Thinking the Clojure Way, by Michael Fogus and Chris Houser
  • Seven Languages in Seven Weeks: A Pragmatic Guide to Learning Programming Languages, by Bruce A. Tate
  • Mining the Social Web: Analyzing Data from Facebook, Twitter, LinkedIn, and Other Social Media Sites, by Matthew A. Russell
  • Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation, by Jez Humble and David Farley

The Rest of the Best

http://drdobbs.com/joltawards/231600815

  • Arduino Cookbook
  • CLR via C#, 3rd Edition
  • Data Analysis with Open Source Tools
  • Eloquent Ruby
  • High Performance JavaScript
  • Scalability Rules: 50 Principles for Scaling Web Sites
  • The Software IP Detective’s Handbook: Measurement, Comparison, and Infringement Detection
  • The Rails 3 Way
  • The RSpec Book: Behavior Driven Development with Rspec, Cucumber, and Friends
 

http://www.infoq.com/presentations/NoSQL-Netflix

지난 7월 QCon 발표. 이 발표자는 굉장히 여러 군데서 동일한 내용으로 발표한 모양인데도 불구하고, 실은 썩 마음에 드는 발표는 아니었지만, 실제 엔지니어링 경험이 뼈저리게 느껴져서 인상 깊게 보았던 발표다.

Netflix’s Cloud Transition

2008년 말, Netflix는 하나의 데이터센터를 가지고 있었고, SPOF와 cooling, power, space, traffic capacity 문제에 봉착하고 있었다. (문맥상 그야말로 데이터센터를 ‘보유’하고 있었던 것으로 보이는데, 미국의 경우 이러한 방식이 일반적인 방식인 것인지, 그리고, SPOF가 중요한 문제가 될 만큼 데이터센터의 신뢰성이 문제가 되는 수준인지 궁금하다.) 그리고, 놀랍게도 outsourcing을 통해,  당시 IaaS 플랫폼으로서는 leader 격이었던 AWS를 통해 해결하기로 결정한다.

Netflix의 cloud migration에서 중요한 점 중 하나는 가장 중요한 사용자 개인 정보 (PII), 결제 정보 (PCI DSS)는 그들의 데이터센터에 남겨놓고, 나머지 – 비디오의 메타데이터, 리뷰, 사용자의 비디오 큐, 시청 기록, 평점, 로그 등 만을 cloud로 이동했다는 점이다.

AWS로 가면서 자연스럽게 선택하게 된 storage는 바로 Simple DB와 S3인데, Simple DB는 RDBMS의 대체, S3는 Simple DB의 item 크기 제약을 넘어서고, single key로만 액세스하는 데이터를 저장하는데 사용한다. 그러다 Simple DB의 데이터 모델 제약이라든지, Scalability concern등의 문제들을 넘어서기 위해서 Cassandra도 사용하게 되었다고 한다. 이 발표에는 등장하지 않았지만 M-R과의 조합이 필요한 곳에는 Bigtable도 사용하는 것으로 보인다.

이 발표에서는 Simple DB와 Cassandra를 간략하게 소개하고, Simple DB를 실제로 적용할 때 겪었던 문제들을 정리하고, Cassandra 에서 이러한 문제들이 많이 해결되었다고 얘기하고 있다.

Problems in transition from RDBMS to Key-Value Data Store

당연하지만, RDMS에 있을 때 편하게 썼던 기능들이 필요해지면 application layer에서 알아서 구현해야 한다.

  • partial or no sql support
    • joins이나 group by가 없기 때문에 application layer에서 구현
  • no relations between domains
    • application layer에서 구현.
  • no transaction
    • simple db에서는 conditional put/delete op이 존재하기 때문에 이를 이용해 optimistic locking
    • cassandra에서는 batch mutate op 이용
  • no schema
    • attribute 이름 등에서 misspelling이 발생할 경우 silent하게 실패.
    • 공통 data access layer에서 validation
  • no sequences
    • primary key를 위해서는 자연스럽게 발생하는 unique key나 그러한 경우가 아닐 때는 UUID 사용
    • ordering을 위해서는 distributed sequence generator (using zookeeper)나 client timestamps 사용
  • no constraints (uniqueness, foreign key, referential , integrity)
    • application layer에서 구현

Workaround Issues in SimpleDB

SimpleDB의 설계나 구현이 아직 충분히 성숙되지 않았음을 엿볼 수 있기도 하고, 어떤 측면에서는 다른 DBMS에서도 충분히 겪을 수 있는 문제이나, 충분한 사용 경험이 없기 때문에 해결에 많은 시간을 들여야 할 가능성이 높다고 생각한다. 발표를 들으면서 발표자인 Siddharth Anand가 얼마나 고생했을지 감정이입이 될 정도.

  • no backup and recovery
  • no native support for types
    • 모든 데이터는 UTF-8 character string이고 sorting은 lexicographical만 지원하기 때문에, 숫자 sorting을 하기위해서 데이터에 zero-padding을 해야 한다는 어처구니 없는 일이 발생한다.
  • null attributes are not indexed
    • null 은 indexing이 안되어있기 때문에 where clause에 is null을 쓰면 full domain scan.
      • null인지 여부를 나타내는 필드를 추가해야 하기 때문에, 결국 sparse table의 장점을 잃어버림.
    • 역시 비슷한 문제로 null일 수 있는 attribute에 대해 order by 하면 null attribute의 record는 아예 나오지 않음.
  • data set partitioning

    • domain에 10GB limit와 1B attributes limit가 존재하기 때문에 domain을 application level에서 sharding 해야 함.
    • write throughput을 늘리기 위해서는 sharding 해야 함.

  • attribute name이 case-sensitive하므로 miscased나 misspelled attribute names을 체크해야 함.
  • limit N clause가 없으면 100개의 row만 return 되므로 실수하지 않았는지 체크해야 함.
  • 하나의 statement 내에서 하나의 attribute를 업데이트하고 다른 attribute는 null out할 수 없음.

Thoughts

흔히 NoSQL로 분류되는 storage들은 RDBMS가 아니라는 것 외에는 별로 공통적이라고 할만한 것이 없다. 그래서 NoSQL이라는 말을 쓰는 것을 매우 싫어하는 편이다. 이 발표를 들으면서 이러한 생각에 좀 더 확신이 들었다고 할 수 있을 것 같다.

NoSQL이라고 하는 storage들을 실제로 자세히 들여다보면 각각마다 데이터모델, 오퍼레이션 특성, 성능 특성, 성숙도는 천차만별이다.  결국 하나의 storage를 채용하기 위해서 서로 다른 특성들을 이해하고, 유효한 방법으로 평가는 일만 하더라도 결코 쉬운 일이 아닐뿐더러, 채용하기로 결정한 storage의 데이터모델에 적합하게 데이터를 구성한다든가, 위의 사례에서 보았듯이 각 storage별 세부 특성이나 결함 등을 처리하는 일까지 더한다면 하나의 storage solution을 도입하는 일은 보통 일이 아니다. 그래서, “NoSQL이란 거 좋다면서?”라고 말을 꺼내는 사람이 있으면 “그냥 RDBMS 쓰세요”라고 얘기해주는 것이 정답이라고 본다. NoSQL이라는 bandwagon에 타려고 발걸음을 서두르기 전에, 남들이 하는 이야기들을 반복하기 전에, 왜 RDBMS를 쓰면 안되는 지부터 자신의 도메인에서 고민해보았으면 한다.

주변 사람들에게는 몇 번 얘기했었지만, 이 발표를 들으면서 한가지 매우 인상 깊었던 얘기는 consistency가 깨질 수 있는 것을 인정하고 배치의 형태로 항상 백그라운드에서 동작하고 있는 data fixer를 개발하고 있다는 내용이었다. 별 것 아니라고 생각할 수도 있지만, 이러한 패러다임은 RDBMS를 사용하던 시절에는 inconsistency를 유발하는 원인이 있다면 이를 제거해야 하는 것으로 보는 것 (아니면 아예 무시하거나)과는 완전히 다른 패러다임이다. 현재로서는 weak consistency의 NoSQL storage를 사용하면서도 아직 기존의 패러다임에 젖어 있는 것이 사실인 듯 하다. 지금은 transaction 없이 application layer에서 index를 만들고 나중에 consistency가 깨어지지 않기를 기도하겠지만, 앞으로는 application layer에서도 anomaly를 탐지하고 자연스럽게 해결할 수 있도록 해야할 뿐만 아니라, 지속적인 validation & flx 작업이 필요할 것이다. RDBMS도 경쟁하고 있는 환경에서 weak consistency 모델이 얼마나 유행할지는 잘 모르겠지만, weak consistency 모델의 이러한 데이터 운영 패러다임을 간략한 개념과 구현으로 정리할 수 있다면 바람직할 것 같다.

 

어제 송년회가 피곤했던지 일찍 잠들었다 새벽에 깨는 바람에, QCon SF 2010에서 Google의 Engineering Manager인 Ashish Kumar가 발표한 Development at the Speed and Scale of Google이라는 Presentation을 보게 되었다.

이 발표의 내용은 Google의 Infrastructure 중 하나인 빌드 시스템에 관한 내용으로 아주 재미있는 발표는 아니었지만, 몇 가지 흥미로운 점이 있었다.

Monolithic Code Tree

Google은 어느 정도 알려진 바와 같이, 하나의 코드 저장소에 모든 코드를 관리하고 있으며, 누구든지 필요한 소스코드를 체크아웃해서 사용할 수 있다.

Reducing Checkout Costs

모든 것을 소스로부터 빌드하기 때문에, 의존성을 가진 코드들을 체크아웃하는 비용을 무시할 수가 없는데, 사실 변경하려는 코드가 아닌 코드에 대한 로컬 복사본은 필요 없으므로, FUSE 기반 파일 시스템을 이용한 전체 code tree의 읽기 전용 복사본을 이용한다고 한다.

Reducing Code Review Costs

Google의 개발 프로세스를 보면 commit 이전의 코드 리뷰가 필수적으로 들어가있는 것으로 보이며, 코드 리뷰의 비용을 줄이기 위한 시도로서, 웹 상에서 graphical diffs를 조회하고 이에 대한 comment를 남길 수 있는 code review 도구와 lint error, code coverage, code analysis, test results 등이 제공된다.

IDE 기반의 도구에 대비해, 웹 기반 도구를 사용하고 있는 것이 흥미로운 점인데, C/C++ 계열에는 적절한 IDE가 부족한 점도 있겠지만, 아무래도 웹 기반 도구는 그 기본적인 특성 덕분에 하나의 정보를 여러 사람들에게 공유하기가 매우 쉽다는 점이 커다란 장점으로 작용하는 듯 하다. 다시 말해, 웹 만큼 훌륭한 shared workspace는 흔치 않다.

Reducing Build Costs

개발 과정에서의 커다란 비용 중의 하나로 지적하고 있는 것이 바로 build를 하는 도중 기다리는 비용인데, 이를 줄이기 위해서 object 파일들의 캐슁, 빌드 결과물에 대한 lazy한 액세스, incremental link (old binary + modified object files) 등을 지원하는 분산 빌드 시스템을 채용하고 있는 것 같다.

Continuous Integration

지속적인 통합 (Continuous Integration)이 실패했을 때 발송되는 메일에는 빠르게 원인을 파악할 수 있도록, 실패한 테스트의 목록, 실패를 유발한 Difff를 포함하고 있으며, 테스트 결과, 변경사항, 빌드 결과에 해당하는 웹 도구들에 대한 직접적인 링크를 포함하고 있다.

흔히 이러한 종류의 메일 보고서의 내용은 소홀한 경우가 많은데, 문제에 대한 진단이라는 것이 최종적인 목표라는 점을 생각한다면, 이러한 메일 보고서의 내용을 잘 갈고 닦을 필요가 있다.

Infrastructure

Google의 빌드 시스템은 외부에서도 사용할 수 있는 형태로 공개되어 있지는 않지만, 원래는 존재하지 않던 도구들을 Google이 사용하고 있는 것은 아니다. 가장 중요한 것은 아무래도 모든 도구들과 시스템이 통합된 형태로, 아무런 비용을 지불하지 않아도 전사적으로 제공되며, 실제 개발 과정에서 가능한 한 보이지 않는 형태로 제공되는 것으로 보인다.

여러 가지 종류의 도구들 (예를 들어, 여러 회사의 도구)을 혼합해서 사용하는 경우, 절대로 기능적인 면은 통합된 도구에 비해서 부족하지 않겠지만, 실제로는 접근성 등에 있어서 균질적이지 않아서, 어떤 도구는 사용하지만, 어떤 도구는 상대적으로 소외되어서 결과적으로 효율 차이가 발생하는 것으로 보인다.

Measurement

빌드 시스템 자체와는 별개로 흥미로웠던 것은 빌드 시스템의 각 요소에 대한 필요성을 실제 데이터로 증명하고, 빌드나 빌드 시스템의 개선을 위해서도 측정의 중요성을 지속적으로 강조하고 있다는 점이다. 즉,  ‘Cannot improve what we don’t measure’라는 모토인데, 엔지니어로서는 더 이상 공감하기 어려운 이야기라고 생각한다. 단기간의 개선은 직관이나 추측이 잘 먹힐지는 몰라도, 장기간에 걸친 개선에 있어서 측정은 필수적이다.

현실에서는 time-to-market 요구사항이나 엔지니어 개인의 취향, 심리적 상태와 같은 요소 때문에 측정이 희생되는 모습을 자주 보게 된다. 다소 공격적으로 얘기해서, 합리적인 trade-off를 통해 희생하거나, 다른 요소에 의해 제약 받지 않은 상태임에도 불구하고, 측정을 소홀히 하는 엔지니어는 엔지니어로서의 기본적인 소양이 부족한 것이 아닌가 생각을 해본다.

 

Whatever failing prompted Cutler to mistreat people, his capacity for blocking out the ordinary distractions of life was his road to excellence. People rarely achieved greatness because they were too blinded by daily routine even to try anything extraordinary. For Cutler mediocrity was a failure of will, not talent.

커틀러가 사람들을 학대하게 만드는 것이 무엇이었든 간에, 그를 뛰어나게 만드는 것은, 바로 일상 생활에서 집중을 방해하는 것들을 차단해내는 능력이었다. 사람들이 훌륭한 무언가를 이루어내기 어려운 이유는, 반복되는 일상에 잠식되어, 더 이상 평범하지 않은 무언가를 시도하지 못하기 때문이다. 커틀러가 생각하기에, 뛰어남에 미치지 못하는 평범함이란, 그저 의지의 부족이지, 재능의 부족이 아니었다.

— quoted from Showstopper!, Pascal G. Zachary

 

The best teams I have worked in and with are those that defy the traditional roles and responsibilities.  Putting up artificial walls between extremely closely related disciplines can only be detrimental to getting great team work.  Any given set of devs, testers and PMs working on a feature have a different set of skills and experience they bring to the team.    Putting in place a structured set of expectations denies this fact.  If the developer is more senior and experienced in an area, then  you may want them leading more of the design of the feature, not just the implementation.   Likewise if the PM is very senior and an experienced software architect, you may want them to have more of an input in the actual implementation decisions.

내가 함께 일했던 최고의 팀들은 전통적인 역할과 책임에 반하는 팀들이었다. 서로 밀접한 관련을 갖는 분야들 사이에 장벽을 세우는 것은 팀워크에 방해가 될 뿐이다. 하나의 기능을 위해 모인 개발자, 테스터, PM들로 구성된 팀은 서로 다른 기술과 경험의 집합을 보유하고 있다. 정해진 역할과 책임을 강제하는 것은 이러한 사실을 부인하는 것이다. 개발자가 해당 분야에 있어서 경험이 깊다면, 구현 뿐만 아니라 좀 더 많은 기능 설계를 이끌어가기를 바랄 것이다. 마찬가지로, PM이 매우 숙련된 소프트웨어 아키텍트라면, 실제 구현 결정에 있어서 좀 더 관여하기를 원할 것이다.

– quoted from ‘Great teams have members that defy roles‘ by Brad Adams

 

"None of us knew anything about the PC industry," said Rob Short. "We thought we were the hotshots–and knew what was going on–because we understood the technology. But we didn’t see what was happening in the PC business."

“우리들 모두는 퍼스컴 업계에 대해 아무 것도 몰랐습니다. 기술을 이해하고 있으니까 그것이 전부인 듯 자신만만하게 상황을 잘 알고 있다고 우리 스스로 생각하고 있었을 뿐입니다. 그러나 퍼스컴 업계에서 무엇이 일어나고 있는지 우리는 사실 아무것도 모르고 있었습니다.”

— quoted from Showstopper!, Pascal G. Zachary

 

이번에 Ubuntu Karmic으로 업그레이드 하고 나서, Eclipse 3.5에서 다음과 같은 증상들이 관찰되었다.

  • 몇몇 대화 창에서 마우스 클릭으로는 버튼이 동작하지 않는 문제
  • Synchronize View에서 Synchronize 버튼들이 보이지 않는 문제

 

이 문제는 GTK 2.18의 버그로 인한 것으로 알려져 있다.

 

workaround는 eclipse 실행 시, GDK_NATIVE_WINDOWS 환경 변수를 true로 설정해주는 것이다.

e.g. cd $HOME/local/eclipse/bin; GDK_NATIVE_WINDOWS=true ./eclipse > $HOME/eclipse.log 2> $HOME/eclipse.err

 

GFS: Evolution on Fast-forward by Marshall Kirk McKusick, Sean Quinlan

FreeBSD의 McKusick이 GFS tech leader 였던 Sean Quinlan을 인터뷰한 acmqueue 기사.(McKusick은 ‘The Design and Implementation of the 4.4 BSD Operating System’의 저자로 FreeBSD 계의 인물이고, Sean Quinlan은 Sawzall 페이퍼에 이름이 올라가있다.)

GFS 페이퍼가 발표된 지 이미 6년이 다 되었는데, 그 동안 GFS에 어떤 변화가 있었는지, 구글의 엔지니어링 방식은 어떠한 지를 부분적으로나마 엿볼 수 있는 글이다.

이 인터뷰에서 GFS가 진화해나가고 있는 모습을 보는 것도 의미가 있겠지만, 일반적인 엔지니어링의 양상을 보여주는 것도 시사하는 바가 있다고 생각한다.

  • 초기 시스템 설계에서는 설계의 단순함이나 짧은 개발기간을 위해 설계의 완결성을 일부 희생할 수 있다.
  • 설계의 결함으로 인한 시스템 문제는 시스템이 실제로 적용되면서, 스케일이 커지면서, 여러 가지 용도가 생겨나면서 드러난다.
  • 시스템 문제를 해결하는 방법은 여러 가지가 있다. 단기간의 튜닝을 해서 시스템의 수명을 연장할 수도 있고, 시스템의 배치 등을 조정함으로써 해결할 수도 있고, 시간과 비용을 들여 설계의 결함을 해소하는 새로운 시스템을 설계할 수도 있다.
  • 시스템이 더욱 넓은 범위에서 사용되면서, 설계의 초점은 처음의 것과 전혀 다른 것 (심지어는 완전히 반대의 것)으로 변화할 수 있다.
  • 초기 시스템 설계에서 유용하다고 생각했던 기능들이 오히려 부작용을 낳거나 쓸모가 없는 경우가 있다.

어떤 시스템의 엔지니어링에 있어서, 변화하는 요구사항에 얼마나 적극적이고 효율적으로 대응해나가느냐가 성공의 관건이 아닌가 싶다.

간단히 이 인터뷰 내용을 한번 정리해본다. (정리하다 보니, GFS 페이퍼를 읽은 지 너무 오래되어 GFS에 관한 세부사항이 잘못될 수 있으리라고 생각된다.)

single-master 디자인

이 인터뷰에서는 주로 single-master 디자인의 문제를 중점으로 다루고 있다. GFS 페이퍼를 읽었든지, GFS 클론을 프로덕션 환경에서 사용해봤다면, single-master 디자인이 어떠한 문제들을 가지게 될 지 쉽게 상상할 수 있을 것이다.

일단 초기 GFS에서 single-master 디자인을 선택한 것에 대해서는, 분산 파일시스템이라는 커다란 시스템을 설계하는 입장에서 초기에 디자인 문제들을 단순화하는 것, 그리고 개발기간을 단축하여 단시간 안에 많은 사용자들이 사용할 수 있었던 것으로부터 이득을 볼 수 있었다고 이야기하고 있다.

bottleneck on single-master

single-master 디자인은 초기에 예측한 사용 시나리오나 규모에서 크게 문제가 되지 않을 것으로 생각했으나, 곧 master에서 유지해야 하는 메타데이터가 증가하면서, 메타데이터 operation이 bottleneck이 되기 시작했다고 한다.

구글에서는 하나의 바이너리가 충분히 잘 동작하기만 한다면, scale 하도록 만드는 일에 좀 더 치중을 하지만, GFS의 메타데이터 문제의 경우, 예외적으로 master의 튜닝에 많은 노력을 들였다고 한다. 물론, 약간의 노력으로 이를 상회하는 효과를 얻을 것이란 느낌으로 튜닝을 진행하였으며, 일정 범위 내의 로드에서, single master가 bottleneck이 되는 현상을 줄여 single-master GFS의 수명을 연장할 수 있었다고 한다.

file-count problem (a.k.a. small-file problem)

GFS는 원래 크롤과 인덱싱과 같은 대용량 파일의 저장을 위해 만들어진 시스템이다 보니, 원래의 페이퍼에서도 chunk의 크기는 64MB다. GFS가 성공한 시스템이 되고, 여러 사용자들이 여러 용도로 사용하게 되면서, 많은 수의 작은 파일들을 저장하는 경우들도 생겨나기 시작했다고 한다. 자연스레 master가 메타데이터를 유지해야 하는 파일의 수가 증가하다 보니, master의 메모리가 차버리는 문제가 발생했다.

이 문제를 해결하기 위해 메타데이터를 여러 master에 분산할 수 있는, distributed master 시스템이 기존의 single-master와 완전히 별도의 시스템으로 개발되었고, distributed master는 여러 종류의 용도에 대응하기 위해, 평균 1MB의 파일들에 맞추어 디자인되었다고 한다.

BigTable

BigTable은 현재 크롤과 인덱싱 용도에 점점 많이 사용되고 있으며, 프론트엔드 애플리케이션에도 많이 사용되고 있다고 한다. 특히, 많은 수의 작은 데이터를 가지고 있는 애플리케이션은 BigTable을 사용하는 경향이 있다고 한다. BigTable이 file-count 문제를 해결하는 용도로도 사용될 수 있는 듯 하다.

latency-sensitive applications

batch efficiency에 초점을 맞추어 디자인 된 GFS는 latency의 면에서 여러 가지 약점을 가지고 있다. Quinlan은 대표적인 사례로 pullchunk (chunk의 replication)에 따른 latency나 master의 failover 시간에 따른 downtime, 수천 개의 operation을 queue에 한꺼번에 넣고 나서 처리를 시작하는 (아마도 MapReduce) 메커니즘 등을 들고 있다.

이러한 문제들을 해결한 사례로는 BigTable을 들고 있다. BigTable의 transaction log의 write가 지연 또는 실패할 경우 latency가 발생하는데, 항상 2개의 로그에 쓸 수 있도록 준비하고, 나중에 replay가 필요할 경우 이를 merge한다는 것이다. BigTable과 같은 GFS 애플리케이션들을 설계할 때, 이와 같이 기본적으로 latency를 숨기는 방식으로 동작하도록 설계하는 경향이 있다고 한다.

consistency

GFS의 모델에서는 client가 write가 성공할 때까지 push하는 방식이므로, operation 중 client의 crash가 일어나면 indeterminate state가 될 수 있다고 한다. 처음에는 이런 현상은 크게 문제가 아닌 것으로 봤으나, 파일 길이 등이 서로 다르게 보이는 문제 등 혼란의 여지가 많았기 때문에, 점차로 inconsistent한 상태를 허용하는 time window를 줄여갔다고 한다.

여러 client가 동시에 로그를 append할 수 있도록 하는 RecordAppend 기능과 같은 경우, loose한 consistency 모델 하에서는 서로 다른 순서의 데이터나 중복 write된 데이터 등이 발생해, 혼란을 줄 수 있는 여지가 많아지면서, RecordAppend 기능이 처음에 의도된 이득보다는 오히려 손실이 많았다고 한다.

snapshot

GFS의 recovery 메커니즘은 client가 write를 할 수 없도록 chunk를 lock하고 snapshot을 복제하는 방식으로 동작한다. 이러한 방식은 latency의 원인이 될 수 있다.

GFS의 일반적인 snapshot 기능은 초기의 다른 설계와는 달리 제대로 구현되어 있는 영역인 것으로 보이고, 구현에 있어서 많은 비용이 들어간 듯하나, 그리 자주 사용되지는 않는 듯하다.

 

object님이 적으시며 좌절하신 코드 문제.

int a = strlen("123");int b = strlen("123\0");int c = strlen("123\012");int d = strlen("123\0123");int e = strlen("123\0123\0ABC");int f = strlen("123\0ABC");

C/C++ 프로그래밍 언어 표준을 뒤지며 나름대로 language lawyer로서의 자부심을 가지고 있었는데, 한 순간에 그러한 생각을 깨뜨린 문제네요. 물론 농담이고요. 이런 것을 프로그래밍 실력과 직접적으로 연결해서 생각하지는 않지만, 프로그래머 만이 가질 수 있는 일종의 취미 정도로 생각해주시면 좋을 것 같습니다.

NoSyu님이 컴파일 결과에 따른 답과 나름대로의 해석을 하셨기에 정답은 나온 셈이지만, 이런 문제는 역시 컴파일러의 구현 뿐만 아니라, 표준 문서를 뒤져보아야 하는 문제겠죠.

제가 가지고 있는 C 표준 문서는 ISO/IEC 9899:1999, 소위 C99라고 불리는 문서입니다.

Character constants에 관한 항목은 6.4.4.4인데요. backslash를 이용한 escape sequence는 크게 4가지로 나뉘고, 그 중의 하나가 octal escape sequence입니다. 논의의 간소함을 위해 여기서는 octal escape sequence와 hexadecimal escape sequence만 보도록 하죠.

octal-digit:
0 1 2 3 4 5 6 7
octal-escape-sequence:
\ octal-digit
\ octal-digit octal-digit
\ octal-digit octal-digit octal-digit
hexadecimal-digit:
0 1 2 3 4 5 6 7 8 9
a b c d e f
A B C D E F
hexadecimal-escape-sequence:
\x hexadecimal-digit
hexadecimal-escape-sequence hexadecimal-digit

이러한 문법에 따르면 다음과 같은 사실들을 알 수 있습니다.

1. octal escape sequence에는 각각 8진수를 표현하는데 사용할 수 없는 문자는 파싱 단계에서부터 octal escape sequence의 고려에서 제외됩니다. 즉, 위의 문제에서, "\0ABC"의 경우, ‘A’, ‘B’, ‘C’는 octal-digit가 아니므로, "\0"만이 octal-escape-sequence로 파싱되고 결과적으로 { ‘\0’, ‘A’, ‘B’, ‘C’, ‘\0’ }로 해석되는 것입니다.

이러한 행동은 C89에서 변화된 것으로 보이는데요. 마찬가지 이유로 “\078”의 해석은 { ‘\07’, ‘8’ }로 되지만, 예전에는 0 prefix에 따르는 2개의 digit를 해석하는 구현의 책임 (implementation-defined)이었고, “\078”은 “\100”(078 = 0100)으로 해석되기도 한 모양입니다. C89 이전의 머나먼 옛날의 이야기이니, 현 시대의 컴파일러에서 이러한 동작은 신경 쓰지 않아도 될 것 같습니다.

2. octal-escape-sequence에서는 3개까지의 octal-digit를 허용합니다.

예를 들어, “\0123”는 어떨까요? octal-digit 3개 까지만 허용하므로 일단 ‘3’은 배제하고 “\012” “3”으로 해석되겠네요. 그러면 “\012”는?

다시 C99 문서로 돌아가보면,

Each octal or hexadecimal escape sequence is the longest sequence of characters that can constitute the escape sequence.

라는 얘기가 있습니다.

즉, “\012”는 { ‘\0’, ‘1’, ‘2’, ‘\0’ }나, { ‘\01’, ‘2’, ‘\0’ }로 해석되는 것이 아니라, 가장 긴 매치에 해당하는 { ‘\012’, ‘\0’ }로 해석된다는 것입니다. 사실 octal escape sequence에 대해서 알고 나면, 상식적인 이야기라고 볼 수 있겠습니다.

한편, { ‘\01’, ‘2’, ‘\0’ }을 표현하고 싶다면 어떻게 해야할까요? 이것은 C/C++의 편리한 String Concatenation 문법을 사용하면 됩니다. 즉, “\01” “2”라고 하면 되겠죠.

3. octal-escape-sequence에서 ‘\0’ prefix가 요구되지 않습니다. 이것은 그 동안 제가 몰랐던 중요한 사항 중 하나네요. 즉, ‘\012’나 ‘\12’나 동등한 의미를 가진다는 것입니다. 아마 그 동안 코드를 보면서 그러한 경우를 봐왔을 텐데 조금 더 세심하게 보지 않았던 것 같네요.

재미있는 문제를 제공해주신 object님, 그리고 assembly까지 확인해주신 NoSyu님께 감사드립니다. :)

© 2012 The Last Mind Suffusion theme by Sayontan Sinha