원문: http://www.erlang-factory.com/upload/presentations/558/efsf2012-whatsapp-scaling.pdf

 

WhatsApp Rick Reed(WhatsApp <- Yahoo! <- SGI)씨가 이 서비스를 지탱하는 시스템과 수 백만 사용자의 동시 접속 시스템에 대해 SanFranciscoErlang 회의에서 말한 것을 정리한 것이다.

 

 

메시지 트래픽은 멕시코의 지진, 스페인의 축구 등의 이슈에서 크게 튀었다

당초의 예상 컨넥션은 20. 얼마까지 트래픽이 늘어날지 예상이 어려웠고, 장애/과부하에 대해서 클러스터는 취약.

 

Yahoo!의 트래픽은 세계 Top 10으로 거대하면 그 스케일 업을 담당한 경험은 있었지만 균일한 액세스를 대량의 서버에서 처리 하는 형태였기 때문에 WatsApp과 같이 서버에 백만 컨넥션을 실현한다는 것은 아주 다른 차원이었다. 게다가 소프트웨어 장애, 하드웨어 장해(서버, 네트워크 기기), 세계에서 돌발적으로 일어난 뉴스 등에 대응할 수 있는 구조로 할 필요가 있었다.

 

표준 서버 설정: Dual Westmere Hex-core(24개의 로지컬 CPU), 100GB RAM/SSD, Dual NIC(대 사용자 측, 백엔드와 분배는 프라이베트 네트워크), FreeBSD 8.3, OTP R14B03

 

모니터링 장치를 도입. (자세한 것은 슬라이드 8-10을 참조) 처음에는 1분 단위의 스냅샷 이었으나 현재는 1초 단위로 하고 있다.

 

처음에는 인공적으로 부하를 만들려고 했지만 실제 환경의 트래픽은 클라이언트 단말기/국가별 차이 등을 고려하면 재현은 불가능하므로 튜닝에는 도움이 되지 않는다.

 

다음으로 실전 트래픽의 일부 파이프를 설치하고 별도 시스템에 출력하여 시뮬레이션 했다. 이것은 tee에서 input 할 뿐 output에 대응할 수 없었지만 튜닝에는 크게 도움이 되었다.

 

최종적으로는 IPFW에서 실전 트래픽의 일부를 서버에서 서버에 포워드 하여 정확하게 원하는 컨넥션을 시뮬레이션 할 수 있었지만, 커널 패닉이 약간 일어났다.

 

최초의 병목은 42.5만 컨넥션 근처. CPU 사용률 35%-40%에서도 스케줄 95%에서 경합이 발생했다. 이것을 대응(자세한 것은 후반) 하는 것으로 100만 컨넥션 달성. 다음 달에는 200만 컨넥션.

 

다음으로 앱의 코드 최적화에 착수. 컨넥션 당 2 프로세스인 것을 싱글 프로세스로 하였다. 피크는 280만 커넥션. 그 시점에서 57.1만 패킷(in&out)/, 20+ 메시지/. 다음은 300만 커넥션에 도전하고 싶다.

 

ErlangSMP 확장성이 대단하다. 24개의 로지컬 CPU 사용률 85% 초과. FreeBSD와의 궁합도 좋다. CPU 사용률과 컨넥션 수의 증가가 리니어로 올라간다.

 

200만 연결까지는 경합이 문제. BEAM에 대해서는 Erlang의 코드 수정이 필요하다. BEAM의 패치가 필요한 것 양쪽 모두 있었다. 앱 측에서 트래픽이 프로세스를 넘어서지 않도록 파티션을 확실하게 했다.

 

FreeBSD에 대해서는 TSC 기반의 커널 타임 카운터를 되 돌렸다. gettimeofday(2) 콜이 간편하고, 빠르다. Igb 네트워크 드라이버도 되 돌렸다. 복수의 인터렉티브 큐에서 카드를 lock 해서 문제가 있었다. 당연한 sysctl의 튜닝. 파일, 소켓의 수 늘리기나 tcp 해시 사이즈 넓히기.

 

BEAM의 통계에 대해서는 프로세스 실행 시간/시스템 실행 시간에 대한 사용률, wait/sleep의 횟수를 측정하기 위해 스케줄을 도입. message_queues 통계는 Erlang에서 보다 빨리 측정할 수 있다. enq/deq/send의 횟수와 률을 1/10/100초로 계측한 process_info.message_que_stats를 정리한 통계. fprof cpu 타임 스탬프가 없는 것을 고쳤다. 큰 비동기 스레드를 세기 위해 lock-counting이 작업하도록 했다. erts_debug:lock_counter에 몇 가지 옵션을 설정. 아웃바운드 dist 바이트의 계측을 고쳤다.

 

BEAM의 튜닝은 스케쥴러 waikup 스레드를 낮췄다. mseg을 맥스로 하고 malloc 아니라 mseg가 선택되도록. 스케쥴러 allocator instance. 2M malloc을 자동적으로 최대 superpage. 리얼 타임 스케쥴러를 우선으로 실행. 스케쥴러가 쓸데없이 스핀 하는 것을 수정.

 

BEAM의 경쟁에 대해서는 timeofday delivery의 락이 전체의 스케줄을 멈추는 것으로 최적화. timer wheel도 최적화. check_io 테이블 할당을 조정. prim_file:write_file은 포트 재이용.

 

OTP 산출량에 대해서는 message 큐 사인이 오래 걸릴 때 gc 슬롯 추가 조정. 기본적으로 dist를 받는 버퍼를 늘리고 설정 가능하도록 했다. mnesia_tm를 수정하고 테이블마다 병렬 처리하도록 했다.

 

 

 

MMS를 이용해 영상, 비디오, 음성 파일을 송신할 수 있다.

1)도전

송신자의 핸드폰 이외에서 기록된 데이터도 많다.

그룹 간 송신할 수 있다.

여러 플랫폼 대응: 트랜스 코딩 요점.

데이터 취득하고 전송, 보존하지 않았다.

사용자 증가, 사용자 당 이용량 증가, 이용에서 차지하는 멀티 미디어 비율 증가.

 

2)레거시 시스템

확장성 부족.

트랜스 코딩을 클라이언트에게 맡김.

확장성에 유효하다고 알고 있었던 Erlang로 쓰이지 않았다.

 

3)목표

확장성의 실현.

신뢰성.

사용자의 이용감 향상.

 

4)레거시 MMS 아키텍처

Lighttpd + PHP.

듀얼 헥사 코어.

DNS 라운드 로빈.

참조 카운트 없으므로 시간 기준으로 미디어 데이터 기한 설정.

클라이언트 주도의 트랜스 코딩.

 

5) MMS 아키텍처

네트워크 환경이 나빠도 재 접속 하여 업로드/다운로드 기능.

참조 카운트.

전송하는 데이터는 다시 올리지 않아도 되도록.

서버 측에서 컨트롤 하는 트랜스 코딩.

로우 엔드 단말에 대응하기 위해 서버 측에서 화상의 일부를 자르는 기능.

DB(객체, 레퍼런스, 트랜스 코딩)mnesia 채용.

Erlang 메세징 클라스터를 메인 클러스터로 도입. 이미 공유된 파일이라면 URL을 돌려주고 이중 게재를 막을 수 있게 되었다. 업로드 로드 균형과 참조 관리 기능도.

HTTP 업로드/다운로드: 다루기 쉽지만 SSL 네고시에이션, 단말기 별 차이로 지연은 난다.

웹 서버 Yaws: 기본적인 파일 서버 기능에 덧붙여 적절하게 필요한 앱 모듈을 짜 넣기 쉽다.

객체 스토리지: 이용 비율이 상승하고 있는 화상 파일을 동작이 빠른 스토리지에, 비디오와 음성 파일은 느린 스토리지를 준비.

미디어 종류 판별 기능: erl_img, MediaInfo, ffprobe.

트랜스 코딩: ffmpeg.

셸을 우회하기 위한 os: cmd 복제.

프록시 리퀘스트 조정: 빨리 스토리지가 준비되는 화상 파일에서도 집단들 사이에서 자주 이용하는 등 체류하는 경우는 보존된다. 그리고 리버스 프록시에서 호스트 명을 조사한다.

유지보수 프로세스: 데이터를 영원히는 보관 유지할 수 없으므로 시간 기반의 파일 제한 법을 하거나, 참조가 끊어져 있는 객체를 찾거나 느린 스토리지로 이행하기도 한다.

하드웨어 스펙: 듀얼 옥타 코어, 256GB RAM, 6 x 800GB SSD, 2x 듀얼 링크 어플리케이션 기가 비트 이더넷.

 

 

6) 남은 과제의 대처

SSL: Erlang로 쓰여진 SSL의 커넥션 쓰루풋은 기계의 RSA 레이트보다 매우 낮았다. Web 서버의 밖에서 SSL를 끄고, YAWS Ha 프록시형의 헤더를 받아들이게 패치.

YAWSsendfile를 무효화. 호스트의 메모리 대역을 확보.

Mnesia 테이블을 최적화한 패키지 포맷 변경하여 스토리지 사이즈 45% 개선.

참조 검사 논리를 개선하여 스피드 업.

100만 엔트리를 넘으면 백그라운드 프로세스가 mnesia:select가 상당히 시간이 걸린다. 계속 select에서 개선.

DB 이행: 레이지 이행으로 단계적으로 트랜잭션 하지는 않지만, 단일 ID가 단일 프로세스에. 시리얼라이즈 되고, 참조 일치를 그다지 신경 쓰지 않는다.

대역에 핍박: 비디오 프레임 레이트와 음성 파일의 샘플 레이트 등 모든 매체 파라미터에 캡을 붙여 관리. 대량으로 다운로드 되는 미디어의 화질을 떨어뜨려 대응.

아직도 꼬리를 잇는 문제: 스토리지의 용장성을 보장하고 DB 호스트의 메모리 릭 조사 중 로드 중의 mnesia 스키마 관리가 큰일. 플레이 백 해 버리는 문제 때문에 트랜스 코딩을 조정, 트랜스 코드 CPU의 관리, 캐퍼 계획.

 

 

7)결과

피크 시: 214,000,000 이미지/.

8,800 이미지/초 다운로드.

29Gb/초 아웃풋 대역.

Erlang은 대량의 byte를 푸쉬 하는 것에는 능하지만 SSL 건 등에서 보듯이 뭐든지 할 수 있는 것은 아니다. 트랜스 코드처럼 빈도 높은 조정이 필요한 코딩으로 산다.

 

 

출처: http://wazanova.jp/post/63627885995/erlang-whatsapp-1  
http://wazanova.jp/post/64102681954/erlang-whatsapp-2

 

저작자 표시
신고
by 흥배 2014.03.24 08:00
| 1 |

티스토리 툴바