Facebook이 대규모 확장성 도전에서 배운 것
Upcoming SlideShare
Loading in...5
×
 

Facebook이 대규모 확장성 도전에서 배운 것

on

  • 5,062 views

 

Statistics

Views

Total Views
5,062
Views on SlideShare
4,902
Embed Views
160

Actions

Likes
25
Downloads
102
Comments
0

5 Embeds 160

http://jacking.tistory.com 143
http://www.hanrss.com 8
http://50.10.65.200 4
http://static.slidesharecdn.com 3
https://twitter.com 2

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Facebook이 대규모 확장성 도전에서 배운 것 Facebook이 대규모 확장성 도전에서 배운 것 Presentation Transcript

  • Facebook이 대규모 확장성 도전에서 배운 것
    마이에트 엔터테인먼트 건즈팀
    서버 프로그래머
    최흥배
    MS Visual C++ MVP
    Twitter : @jacking75
  • 이 글은
    http://www.publickey1.jp/blog/09/facebook8php.html와
    http://www.publickey1.jp/blog/09/facebook.html의 글을 번역 정리한 것으로
    원문은 2009년 10월 8일 미국의 캘리포니아 대학 센티에이고교에서 열렸던 세미나 「High Performance at Massive Scale-Lessons learned at Facebook」의 내용을 정리한 것입니다.
    강연자는 패이스북 기술담당 부사장 Jeff Rothschild 이다.
  • 3만대의 서버에 대해서 엔지니어는 230명
    이 세미나에서는 Facebook이 지금까지 직면한 과제를 어떻게 극복해 왔는지를 설명 한다. Facebook은 세계 최대급 Web 사이트의 하나로서
    1개월에 200빌리언(2000억) 페이지 뷰로,
    300밀리언(3억) 명의 액티브 유저가 1일에 1빌리언(10억)의 채팅,
    1일에 100 밀리언(1억)의 검색 등을 실행하고 있다.
    게다가 이용자가 믿을 수 없을 정도로 비약적으로 증가해 왔다. 또금년은 회사에 있어서 중요한 이정표를 경험했다. 4월에 회사가 단월 흑자가 되어현재에도 적극적인 캐쉬플로우(cash flow)를 유지하고 있다.
  • Zuckerberg(이)다.그리고 현재, 사내의 엔지니어 팀은230사람이 되었다.
    Facebook의 중심은 엔지니어링이지만 2005년에 회원이 약 200만명이었을 때는사내의 엔지니어는 불과 2명 밖에 없었다. 게다가 그 중 한 명은 창업자인 Mark Zuckerberg이다. 그리고 현재사내의 엔지니어 팀은 230명이 되었다.
    Facebook의 액티브 유저수로 사내의 엔지니어 수를 나누면, 대체로 110만 액티브 유저에 대해서 1명의 엔지니어라는 것이 된다. 이것은 다른 인터넷 기업과 비교하면 극단적으로 적은 엔지니어수라고 말할 수 있다. 우리는 이것을 향후도 한층 더 향상시켜 가려고 생각한다.
  • 디스크의 물리 I/O가 한계를 결정한다
    그런데 SNS의 소셜그래프는사람 뿐만이 아니라, 기업이나 제품이나 회사나 친구의 블로그 포스트나 비디오나 사진 등각각이 어떻게 관계하고 있는지를 나타내고 있다. 대량의 데이터와 함께 그 사이의 릴레이션쉽이소셜그래프로서 발생하고 있다. 이렇게 복잡하게 관계한 대량의 데이터를 어떻게 보존하고표현할지가Facebook에 있어서의 도전이다.
  • 넷 상에는 많은 사진이 있다. 사진을 구성하는 이미지 데이터는 크고, 게다가 Facebook에 보존된 사진은 소셜그래프로 결합되고 있다. 예를 들면누군가가 사진을 Facebook에 업 로드하고 태그를 붙이면그 사람의 소셜그래프로 결합되고 있는 사람에게는사진이 공개되었다고 하는 통지를 Facebook으로부터 받게 된다.
    Facebook에는 약 20빌리언(200억)장의 사진이 보존되고 있으며 각각 4 종류의 해상도로 보존되고 있기 때문에전체 800억장의 사진이 보존되고 있다고 말할 수 있다. 이것은 사진을 전부 이으면 지구를 10회 둘러 쌀 만한 면적이 있다.
  • 기술적인 챌린지는대량의 데이터를 보존할 뿐만 아니라그것을 유저에게 전달(표시) 해야 하는 점이다. Facebook에서는 1초간에 60만장의 사진을 표시하고 있으며여기가 가장 어려운 점이다.
    그러나 우리와 같은 소규모의 회사에서는 사내의 자원만으로 문제를 전부 해결할 수 없다.스킬이 있는 사내의 엔지니어를대량의 사진을 표시하기 위한 연구 최종 단계 부분의 문제 해결에 투입 해야할 것인가? 그렇지 않으면 독특한 신기능을 개발하는데 투입 해야할 것인지? 선택하지 않으면 안 된다.
    대답은 분명하다. 우수한 엔지니어는 독특한 기능의 개발에 투입하고
    타사와 기술적인 과제가 오버랩 하는 부분은 솔루션을 구입하면 된다. 거기서 우리는 간단한 방법을 선택하기로 했다. NFS 스토리지 제품을 구입했던 것이다.
    그런데그 파일 시스템은 대량의 파일을 지원하는데 용의하지 않아서데이터는 파일 캐쉬에 들어가지 않고, 스토리지 용량보다 I/O가 많음에 의해서 성능이 한계를 맞이해 버렸다.
  • 계를 맞이해 버렸다.
    의 개발 팀).
    대량의 사진 데이터를 취급할 때디스크의 물리 I/O가 성능의 한계를 결정한다. 조사해 보면 하나의 사진을 꺼내는데 10회의 물리 I/O를 하고 있었다. 데이터는 복잡한 디렉토리안에 저장되어 파일 캐시 기억 장치는 대량의 사진 데이터를 위해서 거의 도움이 되지 않았었다.
    거기서 우선파일 메타데이타의 취급이나 디렉토리의 구조, 블록 사이즈 등에 대해서 최적화를 실시하여물리 I/O를 24회 정도까지 줄였다.
    게다가 독자적인 Heystack로 불리는 오버레이 파일 시스템을 구축했다. 이것은 많은 사진 데이터를 모아 그것들을 OS에서는 하나의 파일과 같이 가장히여 메타 데이타는캐쉬하는 등의 구조를 가진다. 이것으로 대부분의 경우 1회의 물리 I/O로 사진 데이타를 뽑기 시작할 수 있게 되었다(아래 사진은 Haystack의 개발 팀).
    Haystack은 오픈 소스로 되어 있다. 우리는 오픈 소스를 강하게 믿고 있다.
  • 프레젠테이션 레이어는PHP로 프로그래밍
    Facebook의 아키텍처는 다른 사이트와 그다지 다르지 않다. 로드 밸런스가 Web 서버의 앞에 있으며 Web 서버의 뒤에 서비스군, 피드, 서치, 광고, 그리고 캐싱이나데이타베이스레이어가 있다.
    그런데. Web 서버 부분을 보자. Web 서버에서 동작하는 프로그램은 PHP를 사용하고 있다.
    PHP를 선택한 이유는심플한 언어로 배우기 쉽기 때문이다. 쓰는 것도 간단하고, 읽는 것도 디버그도 간단.
  • 한편, 어두운 점도 있다. 그것은런타임 코스트다. CPU와 메모리의 소비가 크고, 다른 언어와 통합하는 것도 어렵다. 또 대규모 프로젝트에서는모듈 구조를 잘 지원하고 있다고는 말할 수 없다.
  • 그 이외에도긴 경험으로부터 발견한 PHP의 과제가 있다. 새롭게 쓴 코드가 낡은 코드를 늦게 하는 것이다. 예를 들면 PHP로 썼던 ABC라고 하는 기능에 DEF라고 하는 신기능을 덧붙이면비록 ABC에서 DEF를 호출하지 않았다고 해도 ABC의 동작이 이전보다 늦어지다. 초기화 코스트 등이 증가하기 때문이다. PHP에는 이러한 확장성의 과제가 있다.
    거기서 우리는 PHP의 초기화를 완화하기 위한 확장인 Lazy loading이나, Cache priming, 최근에는 PHP를 C++로 컴파일 한다고 하는 어프로치를 채용하고 있다.
  • ている。
    backend 개발용으로 프레임워크를 준비
    Facebook은 backend에 많은 서비스가 동작하고 있다. backend 서비스의 구축에는 PHP는 사용하지 않고, C++를 사용하는 것이 많지만그 이외에도 복수의 언어를 이용해 개발하고 있다.
    서비스 구축을 쉽게 하기 위해서 backend 서비스용 서비스 프레임워크를 개발했다
  • 選んでライブラリを作り、それをRPCで呼んでいる。
    Thrift
    Thrift는 오픈 소스 프로젝트로서 개발하고 있는 크로스 언어 프레임워크로 RPC 환경을 제공한다. Facebook에서는서비스의 태스크 마다 적절한 언어를 선택하고 라이브러리를 만들고그것을 RPC로 부르고 있다. Thrift는 라이트웨이트한 프레임워크로 만들어져 직렬화, connection 핸들링 등을 신경 쓰지 않고 끝나는 기본적인 템플릿을 제공해 준다. 필요한 서버기능은 프레임워크가 제공해 준다.
  • 換してくれる。このScribeもThriftの上に構築されている。
    Scribe
    Scribe는 분산한 데이터를 중앙의 데이타베이스에 집약하는 프레임워크다. 그 예의 하나서 UNIX의 로그인 syslog를 모아 관리하는 구조도 만들었다.
    각 머신의 로그를 큐잉 하면서 통합하여거대한 하나의 시퀀셜한 로그로 변환해 준다. 이 Scribe도 Thrift 위에 구축되고 있다. Scribe로 트래픽을 처리하는데 소수의 서버로 끝나는 매우 효율적인 방법이다. 서비스를 configuration 하거나 모니터 하는 시스템도이러한 위에서 만들어져 있다.
  • 캐쉬가 확장성에 큰 역할을 이루고 있다
    Facebook의 주된 역할은유저가 간단하게(친구들의) 정보를 모으는 것이 가능할 뿐만 아니라, 정보를 만들어 내는 것도 용이한 점에 있다. 그 중심에 있는 것이 「뉴스 피드」라고 하는 서비스다.
    누군가가 Facebook에서(발언을 포스트하거나 사진을 업 로드하거나 하며) 자신의 스테이터스를 업데이트 하면그것이 리프노드에 전해진다. 그리고 다른 누군가가 페이지를 업데이트 하면그 리퀘스트가 뉴스 피드를 통해서 리퀘스트를 전체에 발신하여그가 흥미가 있는 모든 갱신 정보를(리프노드에 대해서) 체크, 그것이 어그리게이션 되고, PHP 레이어로 정리하여 Web 페이지가 만들어져 유저에게 표시된다.
    여러 가지 의미로이러한 시스템의 중심에 있는 것이 캐쉬다. 캐쉬는 시스템의 확장성에 큰 역할을 이루고 있다.
  • Facebook에서는각 유저의 데이터가 연계하고 있으므로 1%의 액티브 유저가 자신의 정보를 변경이나 추가라고 하는 조작을 하고 있어도그 결과는 거의 모든 데이타베이스에 걸쳐서 조작되게 된다. 여기에소셜애플리케이션의 확장성에 대한 과제가 있다.
    그러나 데이터의 분할을 할 수 있으면이 과제는 비교적 간단하게 해결한다.
    5년전Facebook이 대학생 전용의 사이트였던 때는버클리든가 하버드라는 대학별로 데이타베이스를 가지고 있고, 데이터를 분할하고 있었다. 주된 교류 관계는 대학 내에서 닫고 있어 대학 사이에 걸치는 관계는(그렇게 말했던 것이 발생한다) 이벤트 등의 부분에서 묶으면 충분했다.
    그러나 지금은 그렇지 않다. 유저 전체가 종횡으로 연결되어 있어 유저는 데이타베이스 전체에 걸쳐서 랜덤으로 분산하듯이배치하고 있다. 그런 만큼 확장성은 어려워지고 있다.
  • 이것은 즉 자신이 페이지를 리드로 할 때몇 백의 친구에 관한 대량의 데이타베이스 액세스가 발생한다라고 하는 것이다. 이것을 해결하기 위해서매우 고속의 캐쉬를 채용하고 있다.
    캐쉬에 이용하고 있는 것이Memcache이다. Memcache는 쿼리 성능을 향상해 준다. 한편Memcache의 데이터는 망가지기 쉽다고 하는 결점이 있다.(데이터가 망가지지 않게 하려면) 데이터가 데이타베이스를 갱신하면 캐쉬 데이터를 삭제한다라고 하는 룰에 프로그래머가 모두 따를지에 걸려 있다.
  • Facebook은 대규모 운용에 견딜 수 있도록Memcache도 개량해 왔다. 64비트 대응, 보다 효율적인 직렬화, multi-thread 대응, 프로토콜의 개량, 네트워크 스택의개량 등등. 현재 Facebook에서는 Memcache가 1초 마다 120밀리언(12억)의 리퀘스트를 처리하고 있다.
  • Memcache에서일어나는 과제
    Memche를 운용해 나가는데 있어서의 과제의하나는 Network Incast라고 부르는 현상이다.
    PHP 클라이언트가 리퀘스트를 내면, 복수의 캐쉬로부터각각 40 마이크로 세컨드 정도로 거의 동시에 정리하여결과가 되돌아 온다. 그러면스위치가 버퍼 오버 런이 되고 패킷이 없어져 버린다.
    이것을 없애기 위해서Memcache에 TCP 윈드윙을닮은 오프 sliding window 프로토콜을 구현하여응답 시간을 늦추는 것으로 해결했다.
    그 밖에도 과제가 있다. 어떻게 캐쉬를구성할 것인가 이다.
  • 캐쉬안에서 작은 오브젝트를 많이 취급하는 서버는많은 리퀘스트를처리하고대답을 하기 위해 CPU를 많이 사용하는한편 큰 오브젝트를 취급하는 서버는 데이터 송수신을 위해서 네트워크의 대역폭을 대량으로 사용한다.
    여기서캐쉬에 대해서 오브젝트의 종류를 믹스 하면 CPU와 대역폭의 자원을 어느쪽이나 풀로 사용할 수 있을 것 같다.
  • 그러나실제로는 이렇게 간단한 룰은 들어맞지 않는다.
    2개의(캐쉬) 풀에 2종류의 오브젝트TypeA와TypeB를 균형있게 믹스 해 배치했다고 한다. 클라이언트로부터TypeA에 대한 리퀘스트, TypeB에 대한 리퀘스트를 각각의 풀에 보낸다고 하자. 그러면어느 쪽의 풀도 리퀘스트에응하여 TypeA에 대한 리퀘스트에해당하는 TypeA를50개, TypeB에 대한 리퀘스트에해당하는 TypeB를 50개대답해 온다고 한다(즉 2개의 풀을 맞추면리퀘스트에합치한TypeA,TypeB의 오브젝트가 각각 100개씩 있는 것이 된다).
  • 이번은(각 풀에서의 오브젝트의 믹스를 그만두고) 2개의 풀 각각을TypeA전용, TypeB전용으로 한다. 그리고 똑같이 클라이언트로부터TypeA에 대한 TypeB에 대한 2회의 리퀘스트를 각각의 풀에 던졌다고 한다. 그러면TypeA전용 풀은TypeA에 대한 리퀘스트에만응해 해당하는 TypeA를 100개대답하고, TypeB전용 풀은TypeB에 대한 리퀘스트에만응해 해당하는 TypeB를 100개대답한다. 이 상태로 네트워크의 밴드폭에도 문제가 없고, 게다가 후자의 구성이 리퀘스트에대해서 1개의 풀의 용량이 2배가 되고 있지 않을것이다.
  • 다른 예를 보자.
    2개의 풀이 어느쪽이나TypeA의 오브젝트를 보존하고 있다고 한다. 이 풀에 대해서 클라이언트가 100회의 리퀘스트를 던지면, 해당하는 50개의 오브젝트를 돌려주지만벌써 리퀘스트의 처리로 어느 쪽의 풀도 CPU가가득 차고 있다.
    CPU가 가득하면 3대째의 풀을 추가하여 TypeA의 오브젝트를 조금 그 쪽으로 배분하면, 각 풀이 대답하는 오브젝트수는 1대당 50개에서 33개(혹은 34개)로 감소하지만각 서버가 100 리퀘스트를클라이언트로부터 받아 CPU가 가득하게 되는 것은 변함 없다.
  • 이것을 해결하려면(추가한 서버에 오브젝트를 배분하는 것이 아니라) 추가한 서버에 오브젝트를 replication 한다. 그리고 클라이언트가 리퀘스트를분할하여각각의 서버에 보내도록하고, 각 풀이 받는 리퀘스트수를 줄이면 좋다.
    이와 같이 자원의 관리라고 하는 것은 매우 복잡하고어떻게 데이터의 분산을 옵티마이즈할까는 매우 어려운 문제다. 사실풀에 대해서 오브젝트를 어떻게 분산 배치시키면 좋은 것인지? 라고 하는 최적화는 사람이 수동 작업으로 하고 있다.
  • MySQL는 사용하고 있지만 RDB로서가 아니다
    Facebook에서데이터의 보존은 MySQL 서버를 사용하여쉐어드낫싱아키텍처를 채용하고 있다. 쉐어드아키텍처를 이용하지 않는 것이 기본적인 원칙으로가능한 한 모든 것을 독립 하게 하기로 하고 있다.
    MySQL는 뛰어난 RDB이지만우리는 그것을 RDB로서는 사용하지 않았다. 뛰어난 데이터 보전성(Data Integrity)을 위해서 사용하고 있다. 지금까지 사람의 실수 이외에 MySQL에 있는데이터가 망가지거나 없어지거나 했던 적은 없다.
  • 데이터 센터간에서의 일관성을 확보하는 방법
    Facebook은처음에는산타클라라에있는 데이터 센터에서 시작했다. 거기에는 Web 티어, Memcache티어, 데이타베이스티어의 3층이 포함되어 있었다.
  • 그 건물이 가득 차면샌프란시스코에 데이터 센터를 만들었다.
    거기에는 Web 티어와Memcache티어를 넣었지만샌프란시스코와 산타클라라는 그만큼 멀지 않았기 때문에데이타베이스티어는산타클라라를 공유하도록했다. 34밀리 세컨드 정도 불필요하게 걸리지만그 정도라면 거의 문제 없다
  • 그러나각각의 데이터 센터에 있는 Memcache티어의 일관성에 대한 과제를 해결해야 했다. 거기서각각의 데이터 센터에 Memcache프록시를 도입(그림의 오렌지 부분). 캐쉬내의 데이터가 삭제 되면, 프록시가 그 카피 데이터를 모두 삭제하도록했다.
    그 후, 우리는 동해안에도 데이터 센터를 만들었다. 처음 생각한 것은서해안과 동해안을 연결하여 캐쉬의 일관성을 얻기 위해서 Memcache프록시를 도입하는 것이었다.
    그러나 문제는Memcache티어는프록시를 통하여 정보를 얻고, 데이타베이스티어는replication를 실시하고 있는 것으로Memcache와 데이타베이스의 데이터의 경합 상태가 발생하는 것이었다.
  • 거기서 프록시를MySQL에 넣기로 하여 MySQL의 데이터의 변경을 Memcache티어에도 동시에 실시하는 기능을 추가했다. 이것에 의해서데이타베이스에 대한 변경은 자동적으로 리모트 데이터 센터 내의 캐쉬에도 반영되게 되었다
  • 세미나에서의 질문:네트워크의 보틀 넥 문제는 없었는가?
    네트워크도 보틀 넥이 되어 있다. 특히 데이터 센터의 인터널 네트워크는 리퀘스트에 대해서 수백 대의 서버로부터 대답이 되돌아 올 때의 스위치의 오버플로우에 접했지만, 특히 그러한 문제가 일어나지 않아도 네트워크에는 큰 스트레스가 되어 있다.
    아키텍처적으로는더 Web 티어로캐쉬를 활용하여 트래픽을 내리는 것은 검토 중이다.그러나고속의 네트워크에 의해서 스파이크가 발생했을 때에도 대응할 수 있도록 하는 등네트워크는 확장성에 있어서 중요한 요소다.
    세미나에서의 질문:(마이크가 꺼져 있어서 잘 모름)
    Facebook에서 가동하고 있는 서버 대수를 대답할 때언제나 그 대수는 잘못되어 있다. 왜냐하면 서버는 계속 증가하고 있으니까. 현재는 3만대 정도의 서버가 있다.